예제 #1
0
        public ChangePayRunInvoiceStatusUseCaseTests()
        {
            _payRunGateway        = new Mock <IPayRunGateway>();
            _payRunInvoiceGateway = new Mock <IPayRunInvoiceGateway>();
            _dbManager            = new Mock <IDatabaseManager>();
            _payrun = TestDataHelper.CreatePayRun(type: PayrunType.ResidentialRecurring, status: PayrunStatus.WaitingForApproval);

            var fixture = new Fixture();

            _payrunInvoice = fixture.Build <PayrunInvoice>()
                             .OmitAutoProperties()
                             .With(pi => pi.PayrunId, _payrun.Id)
                             .With(pi => pi.InvoiceStatus, InvoiceStatus.Draft)
                             .Create();
            _payrun.PayrunInvoices.Add(_payrunInvoice);

            _payRunGateway.Setup(g => g.GetPayRunAsync(It.IsAny <Guid>(), It.IsAny <PayRunFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrun);

            _payRunInvoiceGateway.Setup(g => g.GetPayRunInvoiceAsync(It.IsAny <Guid>(), It.IsAny <PayRunInvoiceFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrunInvoice);

            _useCase = new ChangePayRunInvoiceStatusUseCase(_dbManager.Object, _payRunGateway.Object,
                                                            _payRunInvoiceGateway.Object);
        }
        public Payrun CreatePayRun(Payrun payrun)
        {
            _context.Payruns.Add(payrun);
            _context.SaveChanges();

            return(payrun);
        }
예제 #3
0
        public HoldInvoiceUseCaseTests()
        {
            _dbManager            = new Mock <IDatabaseManager>();
            _heldInvoiceGateway   = new Mock <IHeldInvoiceGateway>();
            _payRunInvoiceGateway = new Mock <IPayRunInvoiceGateway>();
            _payRunGateway        = new Mock <IPayRunGateway>();

            _payrun = TestDataHelper.CreatePayRun(type: PayrunType.ResidentialRecurring, status: PayrunStatus.WaitingForApproval);

            var fixture = new Fixture();

            _payrunInvoice = fixture.Build <PayrunInvoice>()
                             .OmitAutoProperties()
                             .With(pi => pi.PayrunId, _payrun.Id)
                             .With(pi => pi.InvoiceStatus, InvoiceStatus.Draft)
                             .Create();
            _payrun.PayrunInvoices.Add(_payrunInvoice);

            _payRunGateway.Setup(g => g.GetPayRunAsync(It.IsAny <Guid>(), It.IsAny <PayRunFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrun);

            _payRunInvoiceGateway.Setup(g => g.GetPayRunInvoiceAsync(It.IsAny <Guid>(), It.IsAny <PayRunInvoiceFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrunInvoice);

            _useCase = new HoldInvoiceUseCase(_dbManager.Object, _heldInvoiceGateway.Object,
                                              _payRunInvoiceGateway.Object, _payRunGateway.Object);

            _heldInvoiceCreationDomain = new HeldInvoiceCreationDomain
            {
                PayRunInvoiceId      = _payrunInvoice.Id,
                ActionRequiredFromId = 1,
                ReasonForHolding     = "Incorrect values"
            };
        }
예제 #4
0
        public async Task <IActionResult> OnDeletePayrun(int month, int year)
        {
            Payrun payrun = PayrunAppService.Repository.WithDetails().SingleOrDefault(x => x.Month == month && x.Year == year);

            if (payrun != null && payrun.IsPosted == false)
            {
                List <PayrunDetail> details = payrun.PayrunDetails.ToList();
                for (int i = 0; i < details.Count; i++)
                {
                    List <PayrunAllowanceSummary> allowanceSummaries = details[i].PayrunAllowancesSummaries.ToList();
                    for (int j = 0; j < allowanceSummaries.Count; j++)
                    {
                        await PayrunAppService.PayrunAllowanceSummaryRepo.DeleteAsync(allowanceSummaries[j].Id);
                    }
                    await PayrunAppService.PayrunDetailsRepo.DeleteAsync(details[i].Id);
                }
                await PayrunAppService.Repository.DeleteAsync(payrun.Id);

                return(new OkResult());
            }
            else
            {
                return(StatusCode(500));
            }
        }
예제 #5
0
        private static IList <PayrunInvoice> CreatePayRunInvoices(Payrun payrun, IList <Invoice> invoices,
                                                                  bool hasHeldInvoices, bool hasReleasedInvoices)
        {
            if (!hasHeldInvoices && !hasReleasedInvoices)
            {
                return(invoices.Select(invoice => TestDataHelper.CreatePayrunInvoice(payrun.Id, invoice)).ToList());
            }

            var payrunInvoices = new List <PayrunInvoice>();
            var half           = invoices.Count / 2;

            if (hasHeldInvoices)
            {
                payrunInvoices.AddRange(invoices.GetPage(1, half).ToList()
                                        .Select(invoice => TestDataHelper.CreatePayrunInvoice(payrun.Id, invoice, InvoiceStatus.Held)));
            }
            if (hasReleasedInvoices)
            {
                payrunInvoices.AddRange(invoices.GetPage(1, half).ToList()
                                        .Select(invoice => TestDataHelper.CreatePayrunInvoice(payrun.Id, invoice, InvoiceStatus.Released)));
            }
            payrunInvoices.AddRange(invoices.GetPage(2, half).ToList()
                                    .Select(invoice => TestDataHelper.CreatePayrunInvoice(payrun.Id, invoice)));
            return(payrunInvoices);
        }
예제 #6
0
        public async Task <IActionResult> OnPostPayrun(int month, int year, string note)
        {
            var formData = Request.Form;

            Payrun    payrun     = PayrunAppService.Repository.SingleOrDefault(x => x.Month == month && x.Year == year);
            IFormFile attachment = formData.Files.Count > 0? formData.Files[0] : null;

            if (attachment != null)
            {
                string uploadedFileName = UploadedFile(attachment);
                payrun.AttachmentFile = uploadedFileName;
            }

            if (payrun != null)
            {
                payrun.IsPosted     = true;
                payrun.Note         = note;
                payrun.PostedByTemp = CurrentUser.UserName;
                payrun.PostedDate   = DateTime.Now;

                var result = await PayrunAppService.Repository.UpdateAsync(payrun);

                return(NoContent());
            }
            else
            {
                return(StatusCode(500));
            }
        }
예제 #7
0
        private async Task GenerateInvoices(IList <Guid> packageIds, Payrun payrun, InvoiceTypes invoiceType)
        {
            var lastInvoiceNumber = await _invoiceGateway.GetInvoicesCountAsync();

            var iterations = Math.Ceiling((double)packageIds.Count / PackageBatchSize);

            for (var i = 0; i < iterations; i++)
            {
                var batchIds = packageIds.Skip(i * PackageBatchSize).Take(PackageBatchSize).ToList();
                var packages = await _carePackageGateway.GetListAsync(batchIds);

                var invoices = await _invoiceGenerator.GenerateAsync(packages, payrun.EndDate, invoiceType, lastInvoiceNumber);

                _logger.LogDebug("Generated invoices: {Invoices}", JsonConvert.SerializeObject(invoices, Formatting.Indented));

                foreach (var invoice in invoices)
                {
                    if (!invoice.Items.Any())
                    {
                        continue;
                    }

                    var payrunInvoice = new PayrunInvoice
                    {
                        Payrun        = payrun,
                        Invoice       = invoice,
                        InvoiceStatus = InvoiceStatus.Accepted
                    };

                    payrun.PayrunInvoices.Add(payrunInvoice);
                }

                lastInvoiceNumber += invoices.Count;
            }
        }
예제 #8
0
        private void ImpersonateCurrentUser(Payrun payrun)
        {
            // Don't have a logged-in user in lambda, so impersonate it as a payrun creator
            // Database context will then use it as Creator / Updater
            var userIdClaim = new Claim(ClaimTypes.NameIdentifier, payrun.CreatorId.ToString());

            ((ClaimsIdentity)_httpContextAccessor.HttpContext.User.Identity).AddClaim(userIdClaim);
        }
        public GetPayRunDetailsUseCaseTests()
        {
            _payrun  = TestDataHelper.CreatePayRun();
            _fixture = new Fixture();

            _payRunGateway        = new Mock <IPayRunGateway>();
            _payRunInvoiceGateway = new Mock <IPayRunInvoiceGateway>();

            _useCase = new GetPayRunDetailsUseCase(_payRunGateway.Object, _payRunInvoiceGateway.Object);
        }
예제 #10
0
        public RejectPayRunUseCaseTests()
        {
            _payrun        = TestDataHelper.CreatePayRun(type: PayrunType.ResidentialRecurring, status: PayrunStatus.Approved);
            _payRunGateway = new Mock <IPayRunGateway>();
            _dbManager     = new Mock <IDatabaseManager>();

            _payRunGateway.Setup(g => g.GetPayRunAsync(It.IsAny <Guid>(), It.IsAny <PayRunFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrun);

            _useCase = new ArchivePayRunUseCase(_payRunGateway.Object, _dbManager.Object);
        }
예제 #11
0
        private async Task ArchivePayrun(Payrun payrun, Exception ex)
        {
            payrun.Status = PayrunStatus.Archived;
            payrun.Histories.Add(new PayrunHistory
            {
                PayRunId = payrun.Id,
                Status   = PayrunStatus.Archived,
                Notes    = ex.Message
            });

            await _payrunGateway.SaveAsync();
        }
예제 #12
0
        public async Task <IActionResult> OnDeletePayrun(int year, int month)
        {
            Payrun payrun = PayrunAppService.Repository.SingleOrDefault(x => x.Month == month && x.Year == year);

            if (payrun != null && payrun.IsPosted == false)
            {
                await PayrunAppService.Repository.DeleteAsync(payrun);

                return(NoContent());
            }
            else
            {
                return(StatusCode(500));
            }
        }
예제 #13
0
        public IActionResult OnGetPaymentsSheet(int payrunId)
        {
            Payrun payrun = PayrunAppService.Repository.WithDetails().SingleOrDefault(x => x.Id == payrunId);

            if (payrun != null)
            {
                List <PayrunDetail> payrunDetails = payrun.PayrunDetails.ToList();
                List <dynamic>      dynamicDS     = new List <dynamic>();

                for (int i = 0; i < payrunDetails.Count; i++)
                {
                    PayrunDetail curDetail = payrunDetails[i];
                    List <PayrunAllowanceSummary> payrunAllowances = curDetail.PayrunAllowancesSummaries.ToList();
                    PayrunAllowanceSummary        housingAllowance = payrunAllowances.LastOrDefault(x => x.AllowanceType.Value == "Housing");
                    string   otherAllowancesSum = "" + (payrunAllowances.Sum(x => x.Value) - (housingAllowance == null ? 0 : housingAllowance.Value)).ToString("N2");
                    DateTime curPeriod          = new DateTime(curDetail.Year, curDetail.Month, 1);

                    dynamic paymentSlipDSRow = new ExpandoObject();
                    paymentSlipDSRow.payrunId      = payrunId;
                    paymentSlipDSRow.sNo           = i + 1;
                    paymentSlipDSRow.getEmpRefCode = curDetail.Employee.GetReferenceId;
                    paymentSlipDSRow.getEmpName    = curDetail.Employee.Name;

                    FinancialDetails financialDetails = JsonSerializer.Deserialize <FinancialDetails>(curDetail.Employee.ExtraProperties["financialDetails"].ToString());
                    BanksRDTO        curBank          = financialDetails.Banks.Last();//financialDetails.Banks.SingleOrDefault(x => DateTime.Parse(x.FromDate).Month >= curPeriod.Month && DateTime.Parse(x.ToDate).Month <= curPeriod.Month);
                    paymentSlipDSRow.getBankName = curBank.GetBankName;
                    paymentSlipDSRow.getBankIBAN = curBank.BankIBAN;

                    paymentSlipDSRow.getBasicSalary      = "" + curDetail.BasicSalary.ToString("N2");
                    paymentSlipDSRow.getAllowanceHousing = housingAllowance == null ? "—" : "" + housingAllowance.Value.ToString("N2");
                    paymentSlipDSRow.getOtherIncome      = otherAllowancesSum;
                    paymentSlipDSRow.getDeductions       = "" + curDetail.GrossDeductions.ToString("N2");
                    paymentSlipDSRow.getPayment          = "" + curDetail.NetAmount.ToString("N2");

                    paymentSlipDSRow.month    = curDetail.Month;
                    paymentSlipDSRow.year     = curDetail.Year;
                    paymentSlipDSRow.isPosted = payrun.IsPSPosted;
                    dynamicDS.Add(paymentSlipDSRow);
                }

                return(new JsonResult(dynamicDS));
            }
            return(StatusCode(500));
        }
        public ApprovePayRunUseCaseTests()
        {
            _payrun = TestDataHelper.CreatePayRun(type: PayrunType.ResidentialRecurring, status: PayrunStatus.Approved);
            var fixture        = new Fixture();
            var payRunInvoices = fixture.Build <PayrunInvoice>()
                                 .OmitAutoProperties()
                                 .With(pi => pi.PayrunId, _payrun.Id)
                                 .With(pi => pi.InvoiceStatus, InvoiceStatus.Accepted)
                                 .CreateMany(5).ToList();

            _payrun.PayrunInvoices = payRunInvoices;

            _payRunGateway = new Mock <IPayRunGateway>();
            _dbManager     = new Mock <IDatabaseManager>();

            _payRunGateway.Setup(g => g.GetPayRunAsync(It.IsAny <Guid>(), It.IsAny <PayRunFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrun);

            _useCase = new ApprovePayRunUseCase(_payRunGateway.Object, _dbManager.Object);
        }
예제 #15
0
 public async Task <IActionResult> OnPostPaymentSheet(int id)
 {
     try
     {
         Payrun payrun = PayrunAppService.Repository.WithDetails().SingleOrDefault(x => x.Id == id);
         if (payrun != null && payrun.IsPosted)
         {
             payrun.IsPSPosted = true;
             await PayrunAppService.Repository.UpdateAsync(payrun);
         }
         else
         {
             return(StatusCode(500));
         }
         return(StatusCode(200));
     }
     catch (Exception ex)
     {
         return(StatusCode(500));
     }
 }
        public async Task CreateDraftPayRun(Payrun payRun)
        {
            var currentDate = DateTimeOffset.UtcNow.Date;

            // TODO: VK: Customers in different timezones may create repeating numbers and fail
            // Move to DB side (calculated field / sequence)
            var payrunsCount =
                await _dbContext.Payruns
                .AnyAsync(payrun =>
                          payrun.Number.Length == 15 &&
                          _dbContext.CompareDates(payrun.DateCreated, currentDate) == 0) // temp prevention of fail on legacy numbers
                ? await _dbContext.Payruns
                .Where(payrun => _dbContext.CompareDates(payrun.DateCreated, currentDate) == 0)
                .Select(payrun => Convert.ToInt32(payrun.Number.Substring(11, 4)))
                .MaxAsync()
                : 0;

            payRun.Number = $"PYR-{DateTimeOffset.UtcNow:yyMMdd}-{++payrunsCount:0000}";

            await _dbContext.Payruns.AddAsync(payRun);
        }
예제 #17
0
        public async void ShouldCreatePayRun(PayrunType type)
        {
            var newPayRun = new Payrun();

            _payRunGateway
            .Setup(g => g.CreateDraftPayRun(It.IsAny <Payrun>()))
            .Callback <Payrun>(payRun => newPayRun = payRun).Returns(Task.CompletedTask);
            var payRunCreationDomain = new DraftPayRunCreationDomain
            {
                Type         = type,
                PaidFromDate = _periodFrom,
                PaidUpToDate = _periodTo,
                StartDate    = _periodFrom
            };

            await _useCase.CreateDraftPayRun(payRunCreationDomain);

            newPayRun.Should().BeEquivalentTo(payRunCreationDomain, options =>
                                              options.ExcludingNestedObjects().ExcludingMissingMembers());
            newPayRun.Status.Should().Be(PayrunStatus.Draft);
            _dbManager.VerifySaved();
        }
예제 #18
0
        public async Task <IActionResult> OnPostIndemnity(string indemnitiesDS, int payrunId)
        {
            try
            {
                var            indemnitiesToPost = JsonSerializer.Deserialize <List <PayrunDetailIndemnity> >(indemnitiesDS);
                Payrun         payrun            = PayrunAppService.Repository.WithDetails().SingleOrDefault(x => x.Id == payrunId);
                PayrunDetail[] payrunDetails     = payrun.PayrunDetails.ToArray();
                for (int i = 0; i < payrunDetails.Length; i++)
                {
                    try
                    {
                        PayrunDetail          detail          = payrunDetails[i];
                        PayrunDetailIndemnity detailIndemnity = indemnitiesToPost.First(x => x.PayrunDetailId == detail.Id);
                        detailIndemnity.TenantId = CurrentTenant.Id;
                        detail.Indemnity         = detailIndemnity;
                    }
                    catch (Exception ex)
                    {
                        continue;
                    }
                }
                if (payrun != null && payrun.IsPosted)
                {
                    payrun.IsIndemnityPosted = true;
                    await PayrunAppService.Repository.UpdateAsync(payrun);
                }
                else
                {
                    return(StatusCode(500));
                }

                return(StatusCode(200));
            }
            catch (Exception ex)
            {
                return(StatusCode(500));
            }
        }
예제 #19
0
        public MakePayRunPaymentUseCaseTests()
        {
            _payrun         = TestDataHelper.CreatePayRun(type: PayrunType.ResidentialRecurring, status: PayrunStatus.Approved);
            _payRunInsights = new PayRunInsightsDomain
            {
                TotalInvoiceAmount = 1000M,
                HoldsCount         = 5,
                TotalHeldAmount    = 100M
            };

            var payRunInvoiceGateway = new Mock <IPayRunInvoiceGateway>();

            _payRunGateway = new Mock <IPayRunGateway>();
            _dbManager     = new Mock <IDatabaseManager>();

            _payRunGateway.Setup(g => g.GetPayRunAsync(It.IsAny <Guid>(), It.IsAny <PayRunFields>(), It.IsAny <bool>()))
            .ReturnsAsync(_payrun);

            payRunInvoiceGateway.Setup(g => g.GetPayRunInsightsAsync(It.IsAny <Guid>())).ReturnsAsync(_payRunInsights);

            _useCase = new MakePayRunPaymentUseCase(_payRunGateway.Object, _dbManager.Object,
                                                    payRunInvoiceGateway.Object);
        }
        private static PayRunInvoiceDetailViewResponse CreateResponse(Payrun payrun, PayRunInvoiceDomain payRunInvoice)
        {
            var result = new PayRunInvoiceDetailViewResponse
            {
                PayRunId     = payrun.Id,
                PayRunNumber = payrun.Number,
                DateCreated  = payrun.DateCreated,
                StartDate    = payrun.StartDate,
                EndDate      = payrun.EndDate,
            };

            var(supplierReclaimsTotal, hackneyReclaimsTotal) = CalculateTotals(payRunInvoice.InvoiceItems);
            var invoiceRes = new PayRunInvoiceResponse
            {
                Id                    = payRunInvoice.Id,
                InvoiceId             = payRunInvoice.InvoiceId,
                CarePackageId         = payRunInvoice.CarePackageId,
                ServiceUserId         = payRunInvoice.ServiceUserId,
                ServiceUserName       = payRunInvoice.ServiceUserName,
                SupplierId            = payRunInvoice.SupplierId,
                SupplierName          = payRunInvoice.SupplierName,
                InvoiceNumber         = payRunInvoice.InvoiceNumber,
                PackageTypeId         = (int)payRunInvoice.PackageType,
                PackageType           = payRunInvoice.PackageType.GetDisplayName(),
                GrossTotal            = decimal.Round(payRunInvoice.GrossTotal, 2),
                NetTotal              = decimal.Round(payRunInvoice.NetTotal, 2),
                SupplierReclaimsTotal = decimal.Round(supplierReclaimsTotal, 2),
                HackneyReclaimsTotal  = decimal.Round(hackneyReclaimsTotal, 2),
                InvoiceStatus         = payRunInvoice.InvoiceStatus,
                AssignedBrokerName    = payRunInvoice.AssignedBrokerName,
                InvoiceItems          = payRunInvoice.InvoiceItems.ToResponse()
            };

            result.Invoice = invoiceRes;

            return(result);
        }
        public static PayRunDetailsViewResponse CreateDetailsViewResponse(Payrun payrun, IEnumerable <PayRunInvoiceDomain> payRunInvoices, PagingMetaData pagingMetaData)
        {
            var result = new PayRunDetailsViewResponse
            {
                PayRunId     = payrun.Id,
                PayRunStatus = payrun.Status,
                PayRunNumber = payrun.Number,
                DateCreated  = payrun.DateCreated,
                StartDate    = payrun.StartDate,
                EndDate      = payrun.EndDate
            };

            var invoices = new List <PayRunInvoiceResponse>();

            foreach (var invoice in payRunInvoices)
            {
                var(supplierReclaimsTotal, hackneyReclaimsTotal) = PayrunExtensions.CalculateTotals(invoice.InvoiceItems.Where(i => i.PriceEffect != PriceEffect.None).ToList());
                var invoiceStatus = invoice.InvoiceStatus;
                if (payrun.Status.In(PayrunStatus.Paid, PayrunStatus.PaidWithHold) &&
                    invoice.InvoiceStatus.In(InvoiceStatus.Released, InvoiceStatus.ReleaseAccepted))
                {
                    invoiceStatus = InvoiceStatus.Held;
                }

                var invoiceRes = invoice.ToResponse(invoiceStatus, supplierReclaimsTotal, hackneyReclaimsTotal);
                invoices.Add(invoiceRes);
            }

            result.PayRunItems = new PagedResponse <PayRunInvoiceResponse>
            {
                PagingMetaData = pagingMetaData,
                Data           = invoices
            };

            return(result);
        }