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;
        }
Пример #2
0
        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;
        }
Пример #4
0
        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;
        }
Пример #5
0
        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;
        }
Пример #6
0
        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;
        }
Пример #7
0
        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;
        }
Пример #10
0
        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);
            }
        }