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();
        }
示例#2
0
        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();
        }
示例#3
0
        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());
        }
示例#5
0
        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);
        }
示例#6
0
        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));
        }
示例#8
0
        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
            });
        }