/// <summary> /// Gets the prorata amount. /// </summary> /// <param name="paymentSummaryDetail">The payment summary detail.</param> /// <param name="currentCompanyPaymentPackage">The current company payment package.</param> /// <param name="currentDiscountCodeUsage">The current discount code usage.</param> /// <param name="newtotalAmount">The newtotal amount.</param> /// <param name="currentTotalAmount">The current total amount.</param> /// <param name="endDate">The end date.</param> /// <param name="dateDifference">The date difference.</param> /// <returns></returns> public static decimal GetProrataAmount(PaymentSummaryDetails paymentSummaryDetail, CompanyPaymentPackage currentCompanyPaymentPackage, DiscountCodeUsage currentDiscountCodeUsage, decimal newtotalAmount, decimal currentTotalAmount, DateTime endDate, int dateDifference) { using (StageBitzDB dataContext = new StageBitzDB()) { int anualDurationCodeId = Utils.GetCodeIdByCodeValue("PaymentPackageDuration", "ANUAL"); decimal educationalDiscount = decimal.Parse(Utils.GetSystemValue("EducationalDiscount")); int datesPerCycle = 0; FinanceBL financeBL = new FinanceBL(dataContext); if (currentCompanyPaymentPackage.PaymentDurationCodeId == anualDurationCodeId) { datesPerCycle = (int)(endDate - endDate.AddYears(-1)).TotalDays; } else { datesPerCycle = (int)(endDate - endDate.AddMonths(-1)).TotalDays; } newtotalAmount = newtotalAmount * dateDifference / datesPerCycle; currentTotalAmount = currentTotalAmount * dateDifference / datesPerCycle; if (paymentSummaryDetail.IsEducationPackage) { newtotalAmount = newtotalAmount * (100 - educationalDiscount) / 100; } else if (paymentSummaryDetail.DiscountCodeUsageToApply != null) { newtotalAmount = financeBL.GetDiscountedAmount(paymentSummaryDetail.CompanyId, newtotalAmount, paymentSummaryDetail.PaymentDurationTypeCodeId, paymentSummaryDetail.DiscountCodeUsageToApply, paymentSummaryDetail.PackageStartDate, endDate); } if (currentCompanyPaymentPackage.IsEducationalPackage) { currentTotalAmount = currentTotalAmount * (100 - educationalDiscount) / 100; } else if (currentDiscountCodeUsage != null) { currentTotalAmount = financeBL.GetDiscountedAmount(paymentSummaryDetail.CompanyId, currentTotalAmount, currentCompanyPaymentPackage.PaymentDurationCodeId, currentDiscountCodeUsage, paymentSummaryDetail.PackageStartDate, endDate); } return(newtotalAmount - currentTotalAmount); } }
public void GetDiscountedAmountTest() { FinanceBL financeBL = new FinanceBL(DataContext); List <ProjectPaymentPackageDetails> projectPackageDetails = Utils.GetSystemProjectPackageDetails(); ProjectPaymentPackageDetails projectMegaPackage = projectPackageDetails.Where(ppd => ppd.PackageName == "MEGA").FirstOrDefault(); List <InventoryPaymentPackageDetails> inventoryPackageDetails = Utils.GetSystemInventoryPackageDetails(); InventoryPaymentPackageDetails inventoryMegaPackage = inventoryPackageDetails.Where(ppd => ppd.PackageName == "MEGA").FirstOrDefault(); // Create a company DiscountCodeUsage discountCodeUsage = new DiscountCodeUsageMock(DataContext).GetDiscountCodeUsage(true, null); DataContext.SaveChanges(); int monthlyPaymentDurationCodeId = Utils.GetCodeIdByCodeValue("PaymentPackageDuration", "MONTHLY"); int annualPaymentDurationCodeId = Utils.GetCodeIdByCodeValue("PaymentPackageDuration", "ANUAL"); decimal totalDue = financeBL.CalculateALLPackageAmountsByPeriod(projectMegaPackage.PackageTypeId, inventoryMegaPackage.PackageTypeId, monthlyPaymentDurationCodeId); decimal discountedAmount = financeBL.GetDiscountedAmount(discountCodeUsage.CompanyId, totalDue, monthlyPaymentDurationCodeId, discountCodeUsage, Utils.Today, Utils.Today.AddMonths(1)); Assert.IsTrue((projectMegaPackage.Amount + inventoryMegaPackage.Amount) * (discountCodeUsage.DiscountCode.Discount / 100) == discountedAmount); totalDue = financeBL.CalculateALLPackageAmountsByPeriod(projectMegaPackage.PackageTypeId, inventoryMegaPackage.PackageTypeId, annualPaymentDurationCodeId); discountedAmount = financeBL.GetDiscountedAmount(discountCodeUsage.CompanyId, totalDue, annualPaymentDurationCodeId, discountCodeUsage, Utils.Today, Utils.Today.AddYears(1)); decimal discountedDays = (discountCodeUsage.EndDate - discountCodeUsage.StartDate.Value).Days; decimal totalDays = (Utils.Today.AddYears(1) - Utils.Today).Days; decimal noDiscountedDays = totalDays - discountedDays; decimal testTotalAmount = (((discountedDays / totalDays) * (discountCodeUsage.DiscountCode.Discount / 100)) + (noDiscountedDays / totalDays)) * (projectMegaPackage.AnualAmount + inventoryMegaPackage.AnualAmount); Assert.IsTrue(decimal.Round(testTotalAmount, 2) == discountedAmount); }
/// <summary> /// Gets the payment package summaries. /// </summary> /// <param name="paymentSummaryDetail">The payment summary detail.</param> /// <param name="dateToConsider">The date to consider.</param> /// <param name="dataContext">The data context.</param> /// <returns></returns> public static List <CompanyPaymentSummary> GetPaymentPackageSummaries(PaymentSummaryDetails paymentSummaryDetail, DateTime dateToConsider, StageBitzDB dataContext) { int anualDurationCodeId = Utils.GetCodeIdByCodeValue("PaymentPackageDuration", "ANUAL"); int invoiceMethodCodeId = Utils.GetCodeIdByCodeValue("PaymentMethod", "INVOICE"); List <CompanyPaymentSummary> summaryList = new List <CompanyPaymentSummary>(); DateTime nextCycleStartDate = Utils.Today; decimal totalDue = 0; decimal educationalDiscount = decimal.Parse(Utils.GetSystemValue("EducationalDiscount")); FinanceBL financeBL = new FinanceBL(dataContext); CompanyBL companyBL = new CompanyBL(dataContext); CompanyPaymentSummary existingCompanyPackageSummary = dataContext.CompanyPaymentSummaries.Where(cps => cps.CompanyId == paymentSummaryDetail.CompanyId).OrderByDescending(cps => cps.CompanyPaymentSummaryId).FirstOrDefault(); CompanyPaymentPackage currentCompanyPaymentPackage = financeBL.GetPaymentPackageForCompanyByDay(dateToConsider, paymentSummaryDetail.CompanyId); if (existingCompanyPackageSummary != null && companyBL.IsFreeTrialCompany(paymentSummaryDetail.CompanyId)) //check whether there is an upgrade/downgrade during the freetrial { existingCompanyPackageSummary = null; } if (existingCompanyPackageSummary == null || currentCompanyPaymentPackage == null) { //This is for the very first time from UI. So return the amount based on promotional and educational discount amount. totalDue = financeBL.CalculateALLPackageAmountsByPeriod(paymentSummaryDetail.ProjectPaymentPackageTypeId, paymentSummaryDetail.InventoryPaymentPackageTypeId, paymentSummaryDetail.PaymentDurationTypeCodeId); if (paymentSummaryDetail.IsEducationPackage) { totalDue = totalDue * (100 - educationalDiscount) / 100; } else if (paymentSummaryDetail.DiscountCodeUsageToApply != null) { DateTime endDate = paymentSummaryDetail.PaymentDurationTypeCodeId == anualDurationCodeId?paymentSummaryDetail.PackageStartDate.AddYears(1) : paymentSummaryDetail.PackageStartDate.AddMonths(1); totalDue = financeBL.GetDiscountedAmount(paymentSummaryDetail.CompanyId, totalDue, paymentSummaryDetail.PaymentDurationTypeCodeId, paymentSummaryDetail.DiscountCodeUsageToApply, paymentSummaryDetail.PackageStartDate, endDate); } nextCycleStartDate = paymentSummaryDetail.PaymentDurationTypeCodeId == anualDurationCodeId?paymentSummaryDetail.PackageStartDate.AddYears(1) : paymentSummaryDetail.PackageStartDate.AddMonths(1); summaryList.Add(CreateCompanyPaymentSummary(totalDue, nextCycleStartDate, paymentSummaryDetail, paymentSummaryDetail.DiscountCodeUsageToApply, paymentSummaryDetail.PackageStartDate, nextCycleStartDate, (paymentSummaryDetail.PaymentMethodCodeId != null && paymentSummaryDetail.PaymentMethodCodeId == invoiceMethodCodeId), paymentSummaryDetail.PaymentMethodCodeId, paymentSummaryDetail.CompanyPaymentPackage)); } else { //This happens when a user upgrades or daily agent makes repeat payments at the end of the Payment Cycle. DateTime endDate = existingCompanyPackageSummary.NextPaymentCycleStartingDate; int dateDifference = 0; InventoryPaymentPackageDetails currentInventoryPaymentPackageDetails = Utils.GetSystemInventoryPackageDetailByPaymentPackageTypeId(currentCompanyPaymentPackage.InventoryPaymentPackageTypeId); InventoryPaymentPackageDetails newInventoryPaymentPackageDetails = Utils.GetSystemInventoryPackageDetailByPaymentPackageTypeId(paymentSummaryDetail.InventoryPaymentPackageTypeId); ProjectPaymentPackageDetails currentProjectPaymentPackageDetails = Utils.GetSystemProjectPackageDetailByPaymentPackageTypeId(currentCompanyPaymentPackage.ProjectPaymentPackageTypeId); ProjectPaymentPackageDetails newProjectPaymentPackageDetails = Utils.GetSystemProjectPackageDetailByPaymentPackageTypeId(paymentSummaryDetail.ProjectPaymentPackageTypeId); decimal currentTotalAmount, newTotalAmount; //Just Get the Amounts from tables if (currentCompanyPaymentPackage.PaymentDurationCodeId == anualDurationCodeId) { currentTotalAmount = currentInventoryPaymentPackageDetails.AnualAmount + currentProjectPaymentPackageDetails.AnualAmount; newTotalAmount = newInventoryPaymentPackageDetails.AnualAmount + newProjectPaymentPackageDetails.AnualAmount; } else { currentTotalAmount = currentInventoryPaymentPackageDetails.Amount + currentProjectPaymentPackageDetails.Amount; newTotalAmount = newInventoryPaymentPackageDetails.Amount + newProjectPaymentPackageDetails.Amount; } if (dateToConsider < endDate && paymentSummaryDetail.HasPackageChanged) //this happens only when a user upgrades during the payment cycle { dateDifference = (int)(endDate - dateToConsider).TotalDays; totalDue = GetProrataAmount(paymentSummaryDetail, currentCompanyPaymentPackage, existingCompanyPackageSummary.DiscountCodeUsage, newTotalAmount, currentTotalAmount, endDate, dateDifference); summaryList.Add(CreateCompanyPaymentSummary(totalDue, endDate, paymentSummaryDetail, paymentSummaryDetail.DiscountCodeUsageToApply, dateToConsider, endDate, (paymentSummaryDetail.PaymentMethodCodeId != null && paymentSummaryDetail.PaymentMethodCodeId == invoiceMethodCodeId), paymentSummaryDetail.PaymentMethodCodeId, paymentSummaryDetail.CompanyPaymentPackage)); } else { //this get executed by a user when changing the package during Agent down or on package virtual end date or during a gap filling execution // currentCompanyPaymentPackage will always be the existing package. DateTime startDate, tempNextCycleDate = endDate; while (tempNextCycleDate <= dateToConsider) { if (tempNextCycleDate == dateToConsider && paymentSummaryDetail.IsUserAction) { break; } //Find the next Package Start Date based on the duration startDate = tempNextCycleDate; tempNextCycleDate = currentCompanyPaymentPackage.PaymentDurationCodeId == anualDurationCodeId?tempNextCycleDate.AddYears(1) : tempNextCycleDate.AddMonths(1); decimal recordTotalAmount = currentTotalAmount; DiscountCodeUsage discountCodeUsage = null; //Get the relavent education or Discount if (currentCompanyPaymentPackage.IsEducationalPackage) { recordTotalAmount = recordTotalAmount * (100 - educationalDiscount) / 100; } else { //Get the DiscountCode Usage for the Day discountCodeUsage = financeBL.GetDiscountCodeUsageByDate(startDate, currentCompanyPaymentPackage.CompanyId); if (discountCodeUsage != null) { recordTotalAmount = financeBL.GetDiscountedAmount(currentCompanyPaymentPackage.CompanyId, recordTotalAmount, currentCompanyPaymentPackage.PaymentDurationCodeId, discountCodeUsage, startDate, tempNextCycleDate); } } if (paymentSummaryDetail.PaymentMethodCodeId != null) { //this will set is monthly agent processed to true for the past records when gap filling if the user has selected the invoice option. summaryList.Add(CreateCompanyPaymentSummary(recordTotalAmount, tempNextCycleDate, paymentSummaryDetail, discountCodeUsage, startDate, tempNextCycleDate, (paymentSummaryDetail.PaymentMethodCodeId == invoiceMethodCodeId), paymentSummaryDetail.PaymentMethodCodeId, currentCompanyPaymentPackage)); } else { summaryList.Add(CreateCompanyPaymentSummary(recordTotalAmount, tempNextCycleDate, paymentSummaryDetail, discountCodeUsage, startDate, tempNextCycleDate, (currentCompanyPaymentPackage.PaymentMethodCodeId != null && currentCompanyPaymentPackage.PaymentMethodCodeId == invoiceMethodCodeId), currentCompanyPaymentPackage.PaymentMethodCodeId, currentCompanyPaymentPackage)); } } if (tempNextCycleDate == dateToConsider && paymentSummaryDetail.IsUserAction) //if the user do any pricing plan change on the same summmnary end date, this will calculate amounts according to the new selections { startDate = tempNextCycleDate; tempNextCycleDate = paymentSummaryDetail.PaymentDurationTypeCodeId == anualDurationCodeId?tempNextCycleDate.AddYears(1) : tempNextCycleDate.AddMonths(1); decimal recordTotalAmount = newTotalAmount; if (paymentSummaryDetail.PaymentDurationTypeCodeId == anualDurationCodeId) { recordTotalAmount = newInventoryPaymentPackageDetails.AnualAmount + newProjectPaymentPackageDetails.AnualAmount; } else { recordTotalAmount = newInventoryPaymentPackageDetails.Amount + newProjectPaymentPackageDetails.Amount; } //Get the relevant education or Discount if (paymentSummaryDetail.IsEducationPackage) { recordTotalAmount = recordTotalAmount * (100 - educationalDiscount) / 100; } else if (paymentSummaryDetail.DiscountCodeUsageToApply != null) { recordTotalAmount = financeBL.GetDiscountedAmount(paymentSummaryDetail.CompanyId, recordTotalAmount, paymentSummaryDetail.PaymentDurationTypeCodeId, paymentSummaryDetail.DiscountCodeUsageToApply, startDate, tempNextCycleDate); } summaryList.Add(CreateCompanyPaymentSummary(recordTotalAmount, tempNextCycleDate, paymentSummaryDetail, paymentSummaryDetail.DiscountCodeUsageToApply, startDate, tempNextCycleDate, paymentSummaryDetail.PaymentMethodCodeId != null && paymentSummaryDetail.PaymentMethodCodeId == invoiceMethodCodeId, paymentSummaryDetail.PaymentMethodCodeId, paymentSummaryDetail.CompanyPaymentPackage)); } if (paymentSummaryDetail.HasPackageChanged && dateToConsider > endDate) // user upgrade after the yearly cycle (Calculcate Pro rata) { dateDifference = (int)(tempNextCycleDate - dateToConsider).TotalDays; totalDue = GetProrataAmount(paymentSummaryDetail, currentCompanyPaymentPackage, summaryList.Count() > 0 ? summaryList.Last().DiscountCodeUsage : null, newTotalAmount, currentTotalAmount, tempNextCycleDate, dateDifference); summaryList.Add(CreateCompanyPaymentSummary(totalDue, tempNextCycleDate, paymentSummaryDetail, paymentSummaryDetail.DiscountCodeUsageToApply, dateToConsider, tempNextCycleDate, paymentSummaryDetail.PaymentMethodCodeId != null && paymentSummaryDetail.PaymentMethodCodeId == invoiceMethodCodeId, paymentSummaryDetail.PaymentMethodCodeId, paymentSummaryDetail.CompanyPaymentPackage)); } } } return(summaryList); }