public async Task RejectAsync(Guid payRunId, string notes) { var payRun = await _payRunGateway .GetPayRunAsync(payRunId, PayRunFields.None, true) .EnsureExistsAsync($"Pay Run {payRunId} not found"); if (payRun.Status == PayrunStatus.Archived) { throw new ApiException($"Pay run with id {payRunId} already archived", HttpStatusCode.BadRequest); } if (payRun.Status.In(PayrunStatus.Paid, PayrunStatus.PaidWithHold)) { throw new ApiException($"Can not archive pay run in status {payRun.Status.GetDisplayName()}", HttpStatusCode.BadRequest); } payRun.Status = payRun.Status == PayrunStatus.Approved ? PayrunStatus.WaitingForApproval : PayrunStatus.Archived; var history = new PayrunHistory { Status = payRun.Status, Notes = $"Pay run declined with note: {notes}" }; // payRun.Histories = histories; payRun.Histories.Add(history); await _dbManager.SaveAsync(); }
public async Task ExecuteAsync(Guid payRunId, string notes) { var payRun = await _payRunGateway .GetPayRunAsync(payRunId, PayRunFields.PayrunInvoices, true) .EnsureExistsAsync($"Pay Run {payRunId} not found"); var validPayRunStatuses = new[] { PayrunStatus.WaitingForReview, PayrunStatus.WaitingForApproval }; if (!validPayRunStatuses.Contains(payRun.Status)) { throw new ApiException($"Pay run status should be in review or waiting for approval to approve", HttpStatusCode.BadRequest); } if (payRun.PayrunInvoices.Any(invoice => invoice.InvoiceStatus == InvoiceStatus.Draft)) { throw new ApiException("Can not approve pay run with draft invoice status", HttpStatusCode.BadRequest); } payRun.Status = PayrunStatus.Approved; var histories = new List <PayrunHistory> { new PayrunHistory { Status = payRun.Status, Notes = notes } }; payRun.Histories = histories; await _dbManager.SaveAsync(); }
public async Task ExecuteAsync(Guid payRunId, string notes) { var payRun = await _payRunGateway .GetPayRunAsync(payRunId, PayRunFields.None, true) .EnsureExistsAsync($"Pay Run {payRunId} not found"); if (payRun.Status != PayrunStatus.WaitingForReview) { throw new ApiException("Pay run status should be in progress for send to approval", HttpStatusCode.BadRequest); } payRun.Status = PayrunStatus.WaitingForApproval; var histories = new List <PayrunHistory> { new PayrunHistory { Status = payRun.Status, Notes = notes } }; payRun.Histories = histories; await _dbManager.SaveAsync(); }
public async Task <HeldInvoiceFlatResponse> ExecuteAsync(Guid payRunId, Guid invoiceId, HeldInvoiceCreationDomain heldInvoiceCreationDomain) { heldInvoiceCreationDomain.PayRunInvoiceId = invoiceId; var payRun = await _payRunGateway.GetPayRunAsync(payRunId) .EnsureExistsAsync($"Pay run with id {payRunId} not found"); var validPayRunStatuses = new[] { PayrunStatus.WaitingForReview, PayrunStatus.WaitingForApproval }; if (!validPayRunStatuses.Contains(payRun.Status)) { throw new ApiException($"Pay run must be in review or waiting for approval to allow status change", HttpStatusCode.BadRequest); } var payRunInvoice = await _payRunInvoiceGateway.GetPayRunInvoiceAsync(heldInvoiceCreationDomain.PayRunInvoiceId, PayRunInvoiceFields.None, true).EnsureExistsAsync($"Pay run invoice with id {heldInvoiceCreationDomain.PayRunInvoiceId} not found"); // Update pay run invoice status payRunInvoice.InvoiceStatus = InvoiceStatus.Held; // Create held invoice record var heldInvoice = heldInvoiceCreationDomain.ToEntity(); _heldInvoiceGateway.AddHeldInvoice(heldInvoice); await _dbManager.SaveAsync(); return(heldInvoice.ToFlatDomain().ToResponse()); }
public async Task <PayRunInsightsResponse> GetAsync(Guid payRunId) { var payRun = await _payRunGateway.GetPayRunAsync(payRunId).EnsureExistsAsync($"Pay run with id {payRunId} not found"); var insights = await _payRunInvoiceGateway.GetPayRunInsightsAsync(payRunId); var previousPayRun = await _payRunGateway.GetPreviousPayRunAsync(payRun.Type); // Get pay run invoiced totals var previousPayRunTotal = 0M; if (previousPayRun != null) { previousPayRunTotal = await _payRunInvoiceGateway.GetPayRunInvoicedTotalAsync(previousPayRun.Id, new[] { InvoiceStatus.Accepted }); } var result = new PayRunInsightsResponse { PayRunId = payRun.Id, PayRunStatus = payRun.Status, TotalInvoiceAmount = insights.TotalInvoiceAmount, TotalDifferenceFromLastCycle = insights.TotalInvoiceAmount - previousPayRunTotal, SupplierCount = insights.SupplierCount, ServiceUserCount = insights.ServiceUserCount, HoldsCount = insights.HoldsCount, TotalHeldAmount = insights.TotalHeldAmount, IsCedarFileDownloaded = insights.IsCedarFileDownloaded, PaidBy = insights.PaidBy, PaidOn = insights.PaidOn }; return(result); }
public async Task <bool> ExecuteAsync(Guid payRunId, Guid payRunInvoiceId, InvoiceStatus newStatus) { var payRun = await _payRunGateway.GetPayRunAsync(payRunId) .EnsureExistsAsync($"Pay run with id {payRunId} not found"); var validPayRunStatuses = new[] { PayrunStatus.WaitingForReview, PayrunStatus.WaitingForApproval }; if (!validPayRunStatuses.Contains(payRun.Status)) { throw new ApiException($"Pay run must be in review or waiting for approval to allow status change", HttpStatusCode.BadRequest); } var payRunInvoice = await _payRunInvoiceGateway.GetPayRunInvoiceAsync(payRunInvoiceId, PayRunInvoiceFields.None, true) .EnsureExistsAsync($"Pay run invoice with id {payRunInvoiceId} not found"); // If invoice is held, released from a different endpoint. // Status change here is limited based on pay run status but release can happen regardless of pay run status if (payRunInvoice.InvoiceStatus == InvoiceStatus.Held) { throw new ApiException("Status change not allowed. Use release endpoint", HttpStatusCode.BadRequest); } var validStatuses = new[] { InvoiceStatus.Accepted, InvoiceStatus.Rejected, InvoiceStatus.Draft }; if ((validStatuses.Contains(newStatus) && payRunInvoice.InvoiceStatus != InvoiceStatus.Held) || (payRunInvoice.InvoiceStatus == InvoiceStatus.Held && newStatus == InvoiceStatus.Released)) { payRunInvoice.InvoiceStatus = newStatus; await _dbManager.SaveAsync(); return(true); } throw new ApiException($"Status change for pay run invoice with id {payRunInvoiceId} not allowed", HttpStatusCode.BadRequest); }
public async Task <PayRunInvoiceDetailViewResponse> GetDetailsAsync(Guid payRunId, Guid invoiceId) { // Get pay run var payRun = await _payRunGateway .GetPayRunAsync(payRunId) .EnsureExistsAsync($"Pay Run with id {payRunId} not found"); // Get pay run invoice var invoice = await _payRunInvoiceGateway.GetPayRunInvoiceDetailAsync(payRunId, invoiceId, false); return(CreateResponse(payRun, invoice)); }
public async Task <PayRunDetailsViewResponse> ExecuteAsync(Guid payrunId, PayRunDetailsQueryParameters parameters) { // Get pay run var payRun = await _payRunGateway .GetPayRunAsync(payrunId) .EnsureExistsAsync($"Pay Run {payrunId} not found"); // Get pay run items var payRunInvoices = await _payRunInvoiceGateway.GetPayRunInvoicesSummaryAsync(payrunId, parameters); var result = PayrunExtensions.CreateDetailsViewResponse(payRun, payRunInvoices, payRunInvoices.PagingMetaData); return(result); }
public async Task ExecuteAsync(Guid payRunId) { var payRun = await _payRunGateway .GetPayRunAsync(payRunId, PayRunFields.None, true) .EnsureExistsAsync($"Pay Run with id {payRunId} not found"); var paidStatuses = new[] { PayrunStatus.Paid, PayrunStatus.PaidWithHold }; if (paidStatuses.Contains(payRun.Status)) { throw new ApiException($"Pay run with id {payRunId} already marked as paid", HttpStatusCode.BadRequest); } if (payRun.Status == PayrunStatus.Archived) { throw new ApiException($"Status change not allowed. Pay run with id {payRunId} is archived", HttpStatusCode.BadRequest); } if (payRun.Status != PayrunStatus.Approved) { throw new ApiException($"Pay run must be approved before marking as paid", HttpStatusCode.BadRequest); } // Change status of pay run var invoices = await _payRunInvoiceGateway.GetPayRunInsightsAsync(payRunId); payRun.Status = PayrunStatus.Paid; payRun.Paid = invoices.TotalInvoiceAmount; payRun.Held = invoices.TotalHeldAmount; if (invoices.HoldsCount > 0) { payRun.Status = PayrunStatus.PaidWithHold; } var history = new PayrunHistory { Status = payRun.Status, Notes = $"Pay run marked as paid", Type = PayRunHistoryType.PaidPayrun }; payRun.Histories.Add(history); await _dbManager.SaveAsync("Failed to mark pay run as paid"); }
public async Task <CedarFileResponse> ExecuteAsync(Guid payRunId) { var payRun = await _payRunGateway.GetPayRunAsync(payRunId, PayRunFields.None, true) .EnsureExistsAsync($"Pay run with id {payRunId} not found"); if (payRun.Status.NotIn(PayrunStatus.Approved, PayrunStatus.PaidWithHold, PayrunStatus.Paid)) { throw new ApiException($"Pay run must be approved or paid to download file", HttpStatusCode.BadRequest); } // Return header info var headerInfo = await _payRunGateway.GetPayRunInvoicesInfoAsync(payRunId); // Return invoice list var invoiceList = await _payRunGateway.GetCedarFileList(payRunId); var stream = new MemoryStream(); ExcelPackage.LicenseContext = LicenseContext.NonCommercial; using (var package = new ExcelPackage(stream)) { // set excel file settings var workSheet = package.Workbook.Worksheets.Add("Sheet1"); workSheet.Cells.Style.Font.Size = 10; workSheet.Cells.Style.Font.Name = "Arial"; // Set header info var headerIndex = 1; workSheet.Cells[headerIndex, 1].Value = 1; workSheet.Cells[headerIndex, 2].Value = 0; workSheet.Cells[headerIndex, 3].Value = "AP"; workSheet.Cells[headerIndex, 4].Value = headerInfo.TotalValueOfInvoices; workSheet.Cells[headerIndex, 5].Value = headerInfo.TotalNumberOfInvoices; workSheet.Cells[headerIndex, 6].Value = "E5013"; workSheet.Cells[headerIndex, 7].Value = "HA"; // Set background color for invoice header workSheet.Cells[headerIndex, 1, headerIndex, 11].Style.Fill.PatternType = ExcelFillStyle.Solid; workSheet.Cells[headerIndex, 1, headerIndex, 11].Style.Fill.BackgroundColor.SetColor(Color.Yellow); var invoiceRowIndex = 2; // Set initial invoice line number var invoiceNumber = 1; foreach (var invoice in invoiceList.OrderBy(x => x.InvoiceReferenceNumber)) { // Get Property Value of invoice header using Reflection var invoiceModel = new CedarFileInvoiceHeader(); var cellIndex = 0; foreach (PropertyInfo property in invoiceModel.GetType().GetProperties()) { if (property.Name == "InvoiceItems") { continue; } if (property.Name == "InvoiceNumber") { invoice.InvoiceNumber = invoiceNumber; } cellIndex++; workSheet.Cells[invoiceRowIndex, cellIndex].Value = property.GetValue(invoice, null); if (property.PropertyType == typeof(DateTime)) { workSheet.Cells[invoiceRowIndex, cellIndex].Style.Numberformat.Format = "dd/mm/yyyy"; } } // Set background color for invoice line workSheet.Cells[invoiceRowIndex, 1, invoiceRowIndex, cellIndex].Style.Fill.PatternType = ExcelFillStyle.Solid; workSheet.Cells[invoiceRowIndex, 1, invoiceRowIndex, cellIndex].Style.Fill.BackgroundColor.SetColor(Color.Orange); // Set invoice item row index var invoiceItemRowIndex = invoiceRowIndex + 1; // Set initial invoice item number var invoiceLineNumber = 1; foreach (var invoiceItem in invoice.InvoiceItems) { // Get Property Value of invoice item using Reflection var invoiceLineModel = new CedarFileInvoiceLineDomain(); var cellIndexInvoiceLine = 0; foreach (PropertyInfo propertyInvoiceItem in invoiceLineModel.GetType().GetProperties()) { cellIndexInvoiceLine++; if (propertyInvoiceItem.Name == "InvoiceNumber") { invoiceItem.InvoiceNumber = invoiceNumber; } if (propertyInvoiceItem.Name == "InvoiceLineNumber") { invoiceItem.InvoiceLineNumber = invoiceLineNumber; } workSheet.Cells[invoiceItemRowIndex, cellIndexInvoiceLine].Value = propertyInvoiceItem.GetValue(invoiceItem, null); } workSheet.Cells[invoiceItemRowIndex, 1, invoiceItemRowIndex, cellIndexInvoiceLine].Style.Fill.PatternType = ExcelFillStyle.Solid; workSheet.Cells[invoiceItemRowIndex, 1, invoiceItemRowIndex, cellIndexInvoiceLine].Style.Fill.BackgroundColor.SetColor(Color.LawnGreen); invoiceItemRowIndex++; invoiceLineNumber++; } // Set next invoice header row index invoiceRowIndex = invoiceItemRowIndex; invoiceNumber++; } await package.SaveAsync(); } stream.Position = 0; // Record download history then return stream var history = new PayrunHistory { Notes = "Cedar file downloaded", Status = payRun.Status, Type = PayRunHistoryType.CedarFileDownload }; payRun.Histories.Add(history); await _dbManager.SaveAsync($"Failed to add pay run history"); return(new CedarFileResponse() { Stream = stream, PayRunNumber = payRun.Number }); }