public List <Installment> CalculateInstallments(bool changeDate) { List <Installment> schedule = new List <Installment>(); OCurrency olb = _contract.Amount; OCurrency totalInterestsRepayment = _contract.Amount * Convert.ToDecimal(_contract.InterestRate) * (_contract.NbOfInstallments - _contract.GracePeriod.Value); decimal decCr = 0; decimal decIr = 0; for (int number = 1; number <= _contract.NbOfInstallments; number++) { Installment installment = new Installment { Number = number, FeesUnpaid = 0, OLB = olb }; if (changeDate) { installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number); } else { installment = _contract.GetInstallment(number - 1); } if (number <= _contract.GracePeriod) { if (!_contract.Product.ChargeInterestWithinGracePeriod) { installment.InterestsRepayment = 0; } installment.CapitalRepayment = 0; installment.InterestsRepayment = Math.Round(installment.OLB.Value * Convert.ToDecimal(_contract.InterestRate) + decIr, _roundingPoint); decIr = _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) - installment.InterestsRepayment.Value; } else { ExoticInstallment exoInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(number - _contract.GracePeriod.Value - 1); OCurrency cr = Convert.ToDecimal(exoInstallment.PrincipalCoeff) * _contract.Amount.Value + decCr; installment.CapitalRepayment = Math.Round(cr.Value, _roundingPoint); decCr = cr.Value - installment.CapitalRepayment.Value; OCurrency ir = totalInterestsRepayment.Value * Convert.ToDecimal(exoInstallment.InterestCoeff) + decIr; installment.InterestsRepayment = Math.Round(ir.Value, _roundingPoint); decIr = ir.Value - installment.InterestsRepayment.Value; } olb -= installment.CapitalRepayment.Value; if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue) { installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint); } schedule.Add(installment); } return(schedule); }
public List <Installment> CalculateInstallments(bool changeDate) { List <Installment> schedule = new List <Installment>(); OCurrency olb = _contract.Amount; DateTime date = _contract.AlignDisbursementDate; int daysInTheYear = GetDaysInAYear(_contract.AlignDisbursementDate.Date.Year); for (int number = 1; number <= _contract.NbOfInstallments; number++) { Installment installment = new Installment { Number = number, FeesUnpaid = 0 }; if (changeDate) { installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number); } installment.OLB = Math.Round(olb.Value, _roundingPoint); int days = (installment.ExpectedDate - date).Days; if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue) { installment.InterestsRepayment = Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate) / daysInTheYear * (installment.ExpectedDate - _contract.StartDate).Days, _roundingPoint); } else { installment.InterestsRepayment = Math.Round((olb * _contract.InterestRate / daysInTheYear * days).Value, _roundingPoint, MidpointRounding.AwayFromZero); } if (number <= _contract.GracePeriod) { if (!_contract.Product.ChargeInterestWithinGracePeriod) { installment.InterestsRepayment = 0; } installment.CapitalRepayment = 0; } else { OCurrency principal = olb / (double)(_contract.NbOfInstallments - number + 1); installment.CapitalRepayment = Math.Round(principal.Value, _roundingPoint); } olb -= installment.CapitalRepayment; date = installment.ExpectedDate; schedule.Add(installment); } return(schedule); }
private DateTime[] _Reschedule_AdjustDates(ReschedulingOptions ro) { DateTime[] retval = new DateTime[2]; DateTime oldDate = DateTime.MinValue; DateTime newDate = DateTime.MinValue; bool first = false; int number = 0; for (int i = 0; i < _contract.InstallmentList.Count; i++) { Installment installment = _contract.GetInstallment(i); if (installment.IsRepaid) { continue; } if (!first) { first = true; oldDate = installment.ExpectedDate; newDate = installment.ExpectedDate; if (0 == ro.RepaymentDateOffset) { break; } newDate = newDate.AddDays(ro.RepaymentDateOffset); DateTime actualNewDate = _nwdS.GetTheNearestValidDate(newDate, _generalSettings.IsIncrementalDuringDayOff, _generalSettings.DoNotSkipNonWorkingDays, true); installment.ExpectedDate = actualNewDate; } installment.ExpectedDate = _contract.CalculateInstallmentDate(newDate, number); number++; } retval[0] = oldDate; retval[1] = newDate; return(retval); }
public void TestCalculateInstallmentDateWhenWeekEndDay2IsSunday() { LoanProduct package = new LoanProduct { InstallmentType = new InstallmentType(1, "Monthly", 0, 1), LoanType = OLoanTypes.DecliningFixedInstallments, ChargeInterestWithinGracePeriod = true, Currency = new Currency { Id = 1 } }; Loan myContract = new Loan(package, 1000, 0.03m, 6, 0, new DateTime(2006, 6, 30), new User(), ApplicationSettings.GetInstance(""), NonWorkingDateSingleton.GetInstance(""), ProvisionTable.GetInstance(new User()), ChartOfAccounts.GetInstance(new User())); Assert.AreEqual(new DateTime(2006, 7, 31), myContract.CalculateInstallmentDate(myContract.StartDate, 1)); }
public List <Installment> CalculateInstallments(bool changeDate) { List <Installment> schedule = new List <Installment>(); OCurrency olb = _contract.Amount; for (int number = 1; number <= _contract.NbOfInstallments; number++) { Installment installment = new Installment { Number = number, FeesUnpaid = 0 }; if (changeDate) { installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number); } decimal olbValue = olb.Value; installment.OLB = Math.Round(olbValue, _roundingPoint); decimal interestRepayment = (olbValue * _contract.InterestRate); installment.InterestsRepayment = Math.Round(interestRepayment, _roundingPoint); if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue) { installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint); } if (number <= _contract.GracePeriod) { if (!_contract.Product.ChargeInterestWithinGracePeriod) { installment.InterestsRepayment = 0; } installment.CapitalRepayment = 0; } else { OCurrency principal = olb / (double)(_contract.NbOfInstallments - number + 1); installment.CapitalRepayment = Math.Round(principal.Value, _roundingPoint); } olb -= installment.CapitalRepayment; schedule.Add(installment); } return(schedule); }
private void TrancheExtendMaturity(int newInstallments, DateTime pFirstInstallmentDate) { if (newInstallments > 0) { List <Installment> listInstallment = new List <Installment>(); listInstallment.AddRange(_currentLoan.InstallmentList); foreach (Installment _installment in _currentLoan.InstallmentList) { if (!_installment.IsRepaid) { listInstallment.Remove(_installment); } } int lastNumber = listInstallment.Count; _trancheEvent.StartedFromInstallment = lastNumber; for (int i = 1; i <= newInstallments; i++) { DateTime expectedDate = _currentLoan.CalculateInstallmentDate(pFirstInstallmentDate, i); Installment installment = new Installment { Number = lastNumber + i, CapitalRepayment = 0, PaidCapital = 0, CommissionsUnpaid = 0, FeesUnpaid = 0, InterestsRepayment = 1, PaidInterests = 0, ExpectedDate = expectedDate }; listInstallment.Add(installment); } _currentLoan.InstallmentList = listInstallment; _currentLoan.NbOfInstallments = _currentLoan.InstallmentList.Count; } }
public List <Installment> CalculateInstallments(bool changeDate) { List <Installment> schedule = new List <Installment>(); OCurrency olb = _contract.Amount; OCurrency totalAmount = _contract.Amount; OCurrency totalInterest = _contract.GracePeriod.HasValue && !_contract.Product.ChargeInterestWithinGracePeriod ? Math.Round( _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) * (_contract.NbOfInstallments - _contract.GracePeriod.Value), _roundingPoint, MidpointRounding.AwayFromZero) : Math.Round( _contract.Amount.Value * Convert.ToDecimal(_contract.InterestRate) * _contract.NbOfInstallments, _roundingPoint, MidpointRounding.AwayFromZero); int nbOfInstallmentWithoutGracePeriod = _contract.GracePeriod.HasValue ? _contract.NbOfInstallments - _contract.GracePeriod.Value : _contract.NbOfInstallments; OCurrency sumOfPrincipal = 0; OCurrency sumOfInterest = 0; OCurrency interestBase = _contract.Product.ChargeInterestWithinGracePeriod ? Math.Round( (totalInterest.Value - sumOfInterest.Value) / (nbOfInstallmentWithoutGracePeriod + _contract.GracePeriod.Value), _roundingPoint, MidpointRounding.AwayFromZero) : Math.Round( (totalInterest.Value - sumOfInterest.Value) / (nbOfInstallmentWithoutGracePeriod), _roundingPoint, MidpointRounding.AwayFromZero); OCurrency principalBase = Math.Round( (totalAmount.Value - sumOfPrincipal.Value) / (nbOfInstallmentWithoutGracePeriod), _roundingPoint, MidpointRounding.AwayFromZero); int installmentNumberWithoutGracePeriodForCapital = 0; int installmentNumberWithoutGracePeriodForInterest = 0; if (!_contract.Rescheduled) { for (int number = 1; number <= _contract.NbOfInstallments; number++) { Installment installment = new Installment { Number = number, FeesUnpaid = 0 }; if (changeDate) { installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number); } installment.OLB = olb; OCurrency interest = Math.Round( (totalInterest.Value - sumOfInterest.Value) / (_contract.NbOfInstallments - installmentNumberWithoutGracePeriodForInterest), _roundingPoint, MidpointRounding.AwayFromZero); OCurrency principal = Math.Round( (totalAmount.Value - sumOfPrincipal.Value) / (nbOfInstallmentWithoutGracePeriod - installmentNumberWithoutGracePeriodForCapital), _roundingPoint, MidpointRounding.AwayFromZero); if (_contract.Product.RoundingType == ORoundingType.End || _contract.Product.RoundingType == ORoundingType.Begin) { interest = interestBase; principal = principalBase; } if (_contract.GracePeriod.HasValue && number <= _contract.GracePeriod) { installment.CapitalRepayment = 0; if (_contract.Product.ChargeInterestWithinGracePeriod) { installment.InterestsRepayment = interest; sumOfInterest += installment.InterestsRepayment; installmentNumberWithoutGracePeriodForInterest++; } else { installment.InterestsRepayment = 0; installmentNumberWithoutGracePeriodForInterest++; } } else { installment.CapitalRepayment = principal; sumOfPrincipal += installment.CapitalRepayment; installmentNumberWithoutGracePeriodForCapital++; installment.InterestsRepayment = interest; sumOfInterest += installment.InterestsRepayment; installmentNumberWithoutGracePeriodForInterest++; } if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue) { installment.InterestsRepayment = Math.Round( installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint, MidpointRounding.AwayFromZero); } olb -= installment.CapitalRepayment.Value; schedule.Add(installment); } } if (_contract.Product.RoundingType == ORoundingType.End) { schedule[_contract.NbOfInstallments - 1].InterestsRepayment += totalInterest - sumOfInterest; schedule[_contract.NbOfInstallments - 1].CapitalRepayment += totalAmount - sumOfPrincipal; } if (_contract.Product.RoundingType == ORoundingType.Begin) { schedule[0].CapitalRepayment += totalInterest - sumOfInterest; schedule[0].CapitalRepayment += totalAmount - sumOfPrincipal; } return(schedule); }
public List <Installment> CalculateInstallments(bool pChangeDate) { List <Installment> schedule = new List <Installment>(); OCurrency olb = _startAmount; OCurrency VPM = 0; for (int number = 1; number <= _contract.NbOfInstallments; number++) { Installment installment; if (pChangeDate) { installment = new Installment { Number = number }; installment.ExpectedDate = _contract.CalculateInstallmentDate(_contract.AlignDisbursementDate, installment.Number); } else { installment = _contract.GetInstallment(number - 1); } installment.FeesUnpaid = 0; installment.InterestsRepayment = Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate), _roundingPoint, MidpointRounding.AwayFromZero); if (installment.Number <= _contract.GracePeriod) { if (!_contract.Product.ChargeInterestWithinGracePeriod) { installment.InterestsRepayment = 0; } installment.CapitalRepayment = 0; } else { OCurrency installmentVpm = Math.Round(_contract.VPM(olb, _numberOfInstallmentsToPay - installment.Number + 1).Value, _roundingPoint, MidpointRounding.AwayFromZero); if ((_contract.Product.RoundingType == ORoundingType.End || _contract.Product.RoundingType == ORoundingType.Begin) && VPM == 0) { VPM = installmentVpm; } else if (_contract.Product.RoundingType == ORoundingType.Approximate) { VPM = installmentVpm; } OCurrency capital = Math.Round((VPM.Value - Math.Round(olb.Value * Convert.ToDecimal(_contract.InterestRate), _roundingPoint)), _roundingPoint, MidpointRounding.AwayFromZero); installment.CapitalRepayment = capital; //to count the difference in case End and Beging rounding type OCurrency installemtDiff = VPM - (installment.CapitalRepayment + installment.InterestsRepayment); if (installemtDiff != 0) { installment.CapitalRepayment += installemtDiff; } olb -= capital + installemtDiff; /////////////////////////////////////////////////////////////// } if (installment.Number == 1 && _generalSettings.PayFirstInterestRealValue) { installment.InterestsRepayment = Math.Round( installment.InterestsRepayment.Value / _contract.NbOfDaysInTheInstallment * (_contract.FirstInstallmentDate - _contract.StartDate).Days, _roundingPoint, MidpointRounding.AwayFromZero); } if (pChangeDate) { schedule.Add(installment); } } if (_contract.Product.RoundingType == ORoundingType.End && olb != 0) { schedule[_contract.NbOfInstallments - 1].CapitalRepayment += olb; } if (_contract.Product.RoundingType == ORoundingType.Begin && olb != 0) { schedule[0].CapitalRepayment += olb; } olb = _startAmount; OCurrency capetalRepayment = 0; //OLB Calculation foreach (Installment installment in schedule) { olb -= capetalRepayment; installment.OLB = olb; capetalRepayment = installment.CapitalRepayment; } return(schedule); }