public decimal ComputeNewLoanBalance(LoanAccount loanAccount, decimal receivableAdd, decimal newInterestRate, string type, string interestRateDescription) { var agreementItem = new AgreementItem(); decimal newLoanBalance = 0; var loanAmount = loanAccount.LoanAmount; loanAmount += receivableAdd; newLoanBalance = loanAmount; var payments = loanAccount.FinancialAccount.FinAcctTrans.Where(entity => entity.FinancialAcctTransTypeId == FinlAcctTransType.AccountPaymentType.Id).ToList(); var groupedPayments = from p in payments group p by p.TransactionDate.Month into g select new { Amount = g.Sum(entity => entity.Amount) }; if (payments.Count() != 0) { foreach (var pay in payments) { var balance = 0M; if (type == ProductFeature.DiminishingBalanceMethodType.Name) balance = ComputeInterestAmount(newLoanBalance, newInterestRate, interestRateDescription); else balance = ComputeInterestAmount(loanAmount, newInterestRate, interestRateDescription); newLoanBalance = (newLoanBalance + balance); var amountPaid = pay.Amount; newLoanBalance -= amountPaid; } } return newLoanBalance; }
public static decimal GenerateAndSaveInterest(LoanAccount loanAccount, AgreementItem agreementItem, string type,DateTime actualDate, DateTime validDueDate, DateTime entryDate) { DateTime lastDayChangeTo30Days = actualDate; var lastDayOfTheMonth = LastDayOfMonthFromDateTime(actualDate); // Day Difference must still be equal to 30 Days if (lastDayChangeTo30Days == lastDayOfTheMonth) lastDayChangeTo30Days = ChangeTo30Days(actualDate); decimal totalInterest = 0; if (loanAccount.InterestTypeId != InterestType.FixedInterestTYpe.Id && loanAccount.InterestTypeId != InterestType.ZeroInterestTYpe.Id && agreementItem.MethodOfChargingInterest != ProductFeature.DiscountedInterestType.Name) { totalInterest = GenerateInterestUsingRate(loanAccount, agreementItem,type,actualDate, validDueDate,entryDate); } else { totalInterest = GenerateInterestFixed(loanAccount, type, lastDayOfTheMonth,entryDate); } return totalInterest; }
public static AgreementItem Create(LoanApplication loanApplication, Agreement agreement) { AgreementItem agreementItem = new AgreementItem(); agreementItem.Agreement = agreement; agreementItem.LoanAmount = loanApplication.LoanAmount; if (loanApplication.IsInterestProductFeatureInd) { agreementItem.InterestRate = loanApplication.InterestRate ?? 0; agreementItem.InterestRateDescription = loanApplication.InterestRateDescription; } if (loanApplication.IsPastDueProductFeatureInd) { agreementItem.PastDueInterestRateDescript = loanApplication.PastDueInterestDescription; agreementItem.PastDueInterestRate = loanApplication.PastDueInterestRate; } //descriptive values var uom = Context.UnitOfMeasures.SingleOrDefault(entity => entity.Id == loanApplication.LoanTermUomId); var payment = Context.LoanApplications.FirstOrDefault(entity => entity.UnitOfMeasure.Id == loanApplication.PaymentModeUomId); var featureAppMode = ProductFeatureApplicability.RetrieveFeature(ProductFeatureCategory.InterestComputationModeType, loanApplication); var fetaureAppMethod = ProductFeatureApplicability.RetrieveFeature(ProductFeatureCategory.MethodofChargingInterestType, loanApplication); agreementItem.LoanTermLength = loanApplication.LoanTermLength; agreementItem.LoanTermUom = uom.Name; agreementItem.PaymentMode = payment.UnitOfMeasure.Name; agreementItem.InterestComputationMode = featureAppMode.ProductFeature.Name; agreementItem.MethodOfChargingInterest = fetaureAppMethod.ProductFeature.Name; return agreementItem; }
public static decimal GenerateInterestForLastMonth(DateTime selectedDate, LoanAccount loanAccount, AgreementItem agreementItem, string type) { decimal interest = 0; var diffTodayAndRelease = 0; DateTime firstDayOfTheMonth = new DateTime(selectedDate.Year, selectedDate.Month, 1); var lastDayOfLastMonth = firstDayOfTheMonth.AddDays(-1); var receivablesLastMonth = ObjectContext.Receivables.Where(entity => entity.FinancialAccountId == loanAccount.FinancialAccountId && entity.ValidityPeriod.Month == lastDayOfLastMonth.Month && entity.ValidityPeriod.Year == lastDayOfLastMonth.Year && entity.ValidityPeriod.Day == lastDayOfLastMonth.Day).OrderByDescending(entity => entity.ValidityPeriod); diffTodayAndRelease = lastDayOfLastMonth.Subtract(loanAccount.LoanReleaseDate.Value).Days; //If no receivables generated where validity period until end of last month, generated bill if (receivablesLastMonth.Count() == 0 && diffTodayAndRelease > 0 ) { interest = GenerateAndSaveInterest(loanAccount, agreementItem,type,lastDayOfLastMonth,lastDayOfLastMonth,selectedDate); } return interest; }
public static decimal GenerateInterest(LoanAccount loanAccount, AgreementItem agreementItem, int days, decimal balance) { decimal interest = 0; string interestDescription = agreementItem.InterestRateDescription; decimal interestRate = agreementItem.InterestRate; interest = GenerateInterest(interestDescription, balance, interestRate, days); interest = Math.Floor(interest); return interest; }
private static decimal GenerateWithAmmort(LoanAccount loanAccount, AgreementItem agreementItem, DateTime today) { decimal totalInterest = 0; var ammortItems = ObjectContext.AmortizationScheduleItems.Where(entity => entity.AmortizationSchedule.AgreementId == agreementItem.AgreementId && today >= entity.ScheduledPaymentDate && entity.IsBilledIndicator == false); foreach (var item in ammortItems) { var ammortItem = ObjectContext.AmortizationScheduleItems.FirstOrDefault(entity => entity.Id == item.Id); totalInterest = item.InterestPayment; CreateReceivableWithStatus(loanAccount.FinancialAccountId,item.InterestPayment,-1,GenerateBillSave,item.ScheduledPaymentDate,item.ScheduledPaymentDate,item.ScheduledPaymentDate); ammortItem.IsBilledIndicator = true; ObjectContext.SaveChanges(); } return totalInterest; }
private static decimal GenerateInterestUsingRate(LoanAccount loanAccount, AgreementItem agreementItem, string type,DateTime actualDate, DateTime validDueDate,DateTime entryDate) { DateTime lastDayChangeTo30Days = actualDate; var lastDayOfTheMonth = LastDayOfMonthFromDateTime(actualDate); var advanceChangeDay = SystemSetting.AdvanceChangeNoInterestStartDay; // Day Difference must still be equal to 30 Days if (lastDayChangeTo30Days == lastDayOfTheMonth) lastDayChangeTo30Days = ChangeTo30Days(actualDate); /*** INITIALISATIONS****/ var diffBetweenPaymentAndToday = SystemSetting.GracePeriod + 1; var diffBetweenReleaseandToday = SystemSetting.GracePeriod + 1; var firstDayOfTheMonth = new DateTime(actualDate.Year, actualDate.Month, 1); decimal totalInterest = 0; var loanDisbursemntVoucher = ObjectContext.LoanDisbursementVcrs.FirstOrDefault(entity => entity.AgreementId == agreementItem.AgreementId); decimal loanBalance = 0; if (agreementItem.InterestComputationMode == ProductFeature.StraightLineMethodType.Name && agreementItem.MethodOfChargingInterest == ProductFeature.AddonInterestType.Name) loanBalance = loanAccount.LoanAmount; else if (agreementItem.InterestComputationMode == ProductFeature.DiminishingBalanceMethodType.Name && agreementItem.MethodOfChargingInterest == ProductFeature.AddonInterestType.Name) loanBalance = loanAccount.LoanBalance; /*** INITIALISATIONS****/ //Check for last payment date var payments = ObjectContext.FinAcctTrans.Where(entity => entity.FinancialAccountId == loanAccount.FinancialAccountId && entity.TransactionDate.Month == actualDate.Month && entity.TransactionDate.Year == actualDate.Year).OrderByDescending(entity => entity.TransactionDate); var latestPayment = payments.FirstOrDefault(); if (latestPayment != null) diffBetweenPaymentAndToday = lastDayChangeTo30Days.Subtract(latestPayment.TransactionDate.Date).Days; if (lastDayChangeTo30Days.Month == loanAccount.LoanReleaseDate.Value.Month && lastDayChangeTo30Days.Year == loanAccount.LoanReleaseDate.Value.Year) diffBetweenReleaseandToday = lastDayChangeTo30Days.Subtract(loanAccount.LoanReleaseDate.Value.Date).Days; // If lastpayment date is < grace period, do not generate interest // if loanrelease is lesser < grace period, no interest if (diffBetweenPaymentAndToday > SystemSetting.GracePeriod && diffBetweenReleaseandToday > SystemSetting.GracePeriod) { decimal totalDisbursedAmount = 0; decimal interest = 0; var dayDiff = GetDays(agreementItem.PaymentMode); // default day difference is 30 days; var receivablesForCurrentMonth = ObjectContext.Receivables.Where(entity => entity.FinancialAccountId == loanAccount.FinancialAccountId && entity.ValidityPeriod.Month == actualDate.Month && entity.ValidityPeriod.Year == actualDate.Year).OrderByDescending(entity => entity.ValidityPeriod); var disbursementsForCurrentMonth = from pa in ObjectContext.PaymentApplications join d in ObjectContext.Disbursements on pa.PaymentId equals d.PaymentId join ld in ObjectContext.LoanDisbursements on d.PaymentId equals ld.PaymentId join p in ObjectContext.Payments on d.PaymentId equals p.Id where p.TransactionDate.Month == actualDate.Month && p.TransactionDate.Year == p.TransactionDate.Year && pa.LoanDisbursementVoucherId == loanDisbursemntVoucher.Id orderby p.TransactionDate ascending select new { payment = p, loandisbursement = ld }; if (disbursementsForCurrentMonth.Count() != 0) { totalDisbursedAmount = disbursementsForCurrentMonth.Sum(entity => entity.payment.TotalAmount); if (receivablesForCurrentMonth.Count() != 0) { var interestpayment = receivablesForCurrentMonth.Sum(entity => entity.Amount - entity.Balance); if (payments.Count() != 0) { // totalDisbursedAmount = disbursementsForCurrentMonth.Sum(entity => entity.payment.TotalAmount); loanBalance -= totalDisbursedAmount; if (loanBalance != 0) { var previousReceivable = receivablesForCurrentMonth.FirstOrDefault(entity => entity.PaymentId == null); if (previousReceivable != null) { if (previousReceivable.ValidityPeriod.Date < lastDayChangeTo30Days) dayDiff = lastDayChangeTo30Days.Subtract(previousReceivable.ValidityPeriod.Date).Days; else dayDiff = 0; } interest = GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); CreateReceivableWithStatus(loanAccount.FinancialAccountId,interest, -1,type,actualDate,validDueDate,entryDate); totalInterest += interest; } foreach (var disbursement in disbursementsForCurrentMonth) { var previousReceivable = receivablesForCurrentMonth.FirstOrDefault(entity => entity.PaymentId == disbursement.payment.Id); if (previousReceivable != null) { if (previousReceivable.ValidityPeriod.Date < lastDayChangeTo30Days) dayDiff = lastDayChangeTo30Days.Subtract(previousReceivable.ValidityPeriod.Date).Days; else dayDiff = 0; } else { //Check if advance change ang particular disbursement if (disbursement.loandisbursement.LoanDisbursementTypeId == LoanDisbursementType.ACCheque.Id && disbursement.payment.TransactionDate.Day >= advanceChangeDay) dayDiff = 0; else { dayDiff = lastDayChangeTo30Days.Subtract(disbursement.payment.TransactionDate).Days; if (disbursement.payment.TransactionDate.Day == 1) dayDiff += 1; } } if (dayDiff > SystemSetting.GracePeriod) { loanBalance = disbursement.payment.TotalAmount; interest = GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); CreateReceivableWithStatus(loanAccount.FinancialAccountId, interest, disbursement.payment.Id, type, actualDate, validDueDate, entryDate); totalInterest += interest; } } } else { //No payments, only additional loan loanBalance -= totalDisbursedAmount; if (loanBalance != 0) { var previousReceivable = receivablesForCurrentMonth.FirstOrDefault(entity => entity.PaymentId == null); if (previousReceivable != null) { if (previousReceivable.ValidityPeriod.Date < lastDayChangeTo30Days) dayDiff = lastDayChangeTo30Days.Subtract(previousReceivable.ValidityPeriod.Date).Days; else dayDiff = 0; } interest += GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); CreateReceivableWithStatus(loanAccount.FinancialAccountId, interest, -1, type, actualDate, validDueDate,entryDate); totalInterest += interest; } foreach (var disbursement in disbursementsForCurrentMonth) { var previousReceivable = receivablesForCurrentMonth.FirstOrDefault(entity => entity.PaymentId == disbursement.payment.Id); if (previousReceivable != null) { if (previousReceivable.ValidityPeriod.Date < lastDayChangeTo30Days) dayDiff = lastDayChangeTo30Days.Subtract(previousReceivable.ValidityPeriod.Date).Days; else dayDiff = 0; } else { //Check if advance change ang particular disbursement if (disbursement.loandisbursement.LoanDisbursementTypeId == LoanDisbursementType.ACCheque.Id && disbursement.payment.TransactionDate.Day >= advanceChangeDay) dayDiff = 0; else { dayDiff = lastDayChangeTo30Days.Subtract(disbursement.payment.TransactionDate).Days; if (disbursement.payment.TransactionDate.Day == 1) dayDiff += 1; } } if (dayDiff > SystemSetting.GracePeriod) { loanBalance = disbursement.payment.TotalAmount; interest = GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); CreateReceivableWithStatus(loanAccount.FinancialAccountId, interest, disbursement.payment.Id, type, actualDate, validDueDate, entryDate); totalInterest += interest; } } } } else { //No manual billed receivables totalDisbursedAmount = disbursementsForCurrentMonth.Sum(entity => entity.payment.TotalAmount); loanBalance -= totalDisbursedAmount; if (loanBalance != 0) { interest += GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); CreateReceivableWithStatus(loanAccount.FinancialAccountId, interest, -1, type, actualDate, validDueDate,entryDate); } totalInterest += interest; foreach (var disbursement in disbursementsForCurrentMonth) { interest = 0; if (disbursement.loandisbursement.LoanDisbursementTypeId == LoanDisbursementType.ACCheque.Id && disbursement.payment.TransactionDate.Day >= advanceChangeDay) dayDiff = 0; else { dayDiff = lastDayChangeTo30Days.Subtract(disbursement.payment.TransactionDate).Days; if (disbursement.payment.TransactionDate.Day == 1) dayDiff += 1; } if (dayDiff > SystemSetting.GracePeriod) { loanBalance = disbursement.payment.TotalAmount; interest = GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); CreateReceivableWithStatus(loanAccount.FinancialAccountId, interest, disbursement.payment.Id, type, actualDate, validDueDate, entryDate); totalInterest += interest; } } } } else { //No DISBURSEMENTS FOR THIS MONTH, Meaning no additional loan and no payments if (receivablesForCurrentMonth.Count() > 0) { if (receivablesForCurrentMonth.FirstOrDefault() != null) { if (receivablesForCurrentMonth.FirstOrDefault().ValidityPeriod < lastDayChangeTo30Days) dayDiff = lastDayChangeTo30Days.Subtract(receivablesForCurrentMonth.FirstOrDefault().ValidityPeriod).Days; else dayDiff = 0; } } else if (actualDate.Day != lastDayOfTheMonth.Day && actualDate.Month == lastDayOfTheMonth.Month) dayDiff = actualDate.Day; //for those manual billing like nov 28, day diff must be 28 //else it must use the default 30 days //if (dayDiff > SystemSetting.GracePeriod) //{ interest = GenerateInterest(loanAccount, agreementItem, dayDiff, loanBalance); totalInterest += interest; if (interest > 0) CreateReceivableWithStatus(loanAccount.FinancialAccountId, interest, -1, type, actualDate, validDueDate, entryDate); // } } } return totalInterest; }
private AgreementItem CreateAgreementItemFromOldInterest(Agreement agreement, DateTime today, AmortizationItemsModel item, AgreementItem oldItem) { AgreementItem agreementItemNew1 = new AgreementItem(); agreementItemNew1.Agreement = agreement; agreementItemNew1.InterestComputationMode = oldItem.InterestComputationMode; agreementItemNew1.InterestRateDescription = oldItem.InterestRateDescription; agreementItemNew1.InterestRate = item.NewInterestRate; agreementItemNew1.LoanAmount = oldItem.LoanAmount; agreementItemNew1.LoanTermLength = oldItem.LoanTermLength; agreementItemNew1.LoanTermUom = oldItem.LoanTermUom; agreementItemNew1.MethodOfChargingInterest = oldItem.MethodOfChargingInterest; agreementItemNew1.PaymentMode = oldItem.PaymentMode; agreementItemNew1.TransitionDateTime = today; agreementItemNew1.IsActive = true; return agreementItemNew1; }
private decimal ComputeInterestAmount(decimal amount, decimal interestRate, string interestRateDescription, DateTime paymentDate, AgreementItem agreementItem, LoanAccount loanAccount, DateTime today) { agreementItem.InterestRate = interestRate; var newLoanAccount = new LoanAccount(); newLoanAccount = loanAccount; //newLoanAccount.LoanBalance = amount; decimal interestAmount = GenerateBillFacade.GenerateAndSaveInterest(newLoanAccount, agreementItem, GenerateBillFacade.ManualBillingDisplay, paymentDate, paymentDate, today); return interestAmount; }
public OutstandingLoansModel(FinancialAccount fa, Agreement ag, FinancialAccountProduct fap, AgreementItem agreementItem, decimal totalPayments, DateTime date) { if (agreementItem == null) this.InterestRate = agreementItem.InterestRate; var loanAccount = fa.LoanAccount; this.LoanId = loanAccount.FinancialAccountId; this.LoanProduct = fap.FinancialProduct.Name; this.LoanAmount = loanAccount.LoanAmount; this.LoanTerm = agreementItem.LoanTermLength; this.LoanReleaseDate = loanAccount.LoanReleaseDate; this.LoanBalance = loanAccount.LoanBalance + totalPayments; this.MaturityDate = fa.LoanAccount.MaturityDate; this.LoanTerm = agreementItem.LoanTermLength; this.InterestRate = agreementItem.InterestRate; var status = loanAccount.LoanAccountStatus.OrderByDescending(entity => entity.TransitionDateTime <= date).FirstOrDefault(); this.Status = status.LoanAccountStatusType.Name; var partyRole = fa.FinancialAccountRoles.SingleOrDefault(entity => entity.FinancialAccountId == fa.Id && entity.PartyRole.RoleTypeId == RoleType.OwnerFinancialType.Id).PartyRole; var party = partyRole.Party; if (party.PartyTypeId == PartyType.PersonType.Id) { Person personAsCustomer = party.Person; this.Name = StringConcatUtility.Build(" ", personAsCustomer.LastNameString + "," , personAsCustomer.FirstNameString, personAsCustomer.MiddleInitialString, personAsCustomer.NameSuffixString); } }