public static LoanDisbursmentEvent GenerateLoanDisbursmentEvent(Loan pLoan, ApplicationSettings pGeneralSettings, DateTime pDisburseDate, bool pAlignInstallmentsDatesOnRealDisbursmentDate, bool pDisableFees, User pUser) { if (pAlignInstallmentsDatesOnRealDisbursmentDate) { //pLoan.StartDate = pDisburseDate; //for (int i = 1; i <= pLoan.NbOfInstallments; i++) //{ // pLoan.InstallmentList[i - 1].ExpectedDate = pLoan.CalculateInstallmentDate(pLoan.StartDate, i); //} } else { if (pGeneralSettings.PayFirstInterestRealValue) { TimeSpan time = pDisburseDate - pLoan.StartDate; int diffDays = Math.Abs(time.Days); int nbOfDaysInPeriod = pLoan.InstallmentType.NbOfMonths * AVERAGE_NB_OF_DAYS_IN_MONTH + pLoan.InstallmentType.NbOfDays; if (pDisburseDate.CompareTo(pLoan.StartDate) < 0) { pLoan.GetInstallment(0).InterestsRepayment += (Convert.ToDecimal(pLoan.InterestRate) * diffDays * pLoan.Amount / (double)nbOfDaysInPeriod); } else { pLoan.GetInstallment(0).InterestsRepayment -= (Convert.ToDecimal(pLoan.InterestRate) * diffDays * pLoan.Amount / (double)nbOfDaysInPeriod); } if (AmountComparer.Compare(pLoan.GetInstallment(0).InterestsRepayment, 0) < 0) { pLoan.GetInstallment(0).InterestsRepayment = 0; } pLoan.GetInstallment(0).InterestsRepayment = Math.Round(pLoan.GetInstallment(0).InterestsRepayment.Value, 2); } } pLoan.Disbursed = true; LoanDisbursmentEvent lDe = !pDisableFees ? new LoanDisbursmentEvent { Date = pDisburseDate, Amount = pLoan.Amount, ClientType = pLoan.ClientType } : new LoanDisbursmentEvent { Date = pDisburseDate, Amount = pLoan.Amount, Commissions = null, ClientType = pLoan.ClientType }; pLoan.Events.Add(lDe); return(lDe); }
public void Repay(ref OCurrency pAmountPaid, ref OCurrency pFeesEvent, ref OCurrency pCommissionsEvent, ref OCurrency pInterestEvent) { if (_cco.CancelFees && (_cco.ManualFeesAmount + _cco.ManualCommissionAmount) >= 0) { pCommissionsEvent = _cco.ManualCommissionAmount; pFeesEvent = _cco.ManualFeesAmount; if (AmountComparer.Compare(pAmountPaid, _cco.ManualFeesAmount + _cco.ManualCommissionAmount) > 0) { //pAmountPaid -= _cco.ManualFeesAmount + _cco.ManualCommissionAmount; } else { pAmountPaid = 0; } } if (_cco.KeepExpectedInstallments) { if (_cco.CancelInterests && _cco.ManualInterestsAmount >= 0) { OCurrency manualInterestAmount = _cco.ManualInterestsAmount; for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment installment = _contract.GetInstallment(i); if (!installment.IsRepaid && pAmountPaid > 0 && manualInterestAmount > 0) { OCurrency interestHasToPay = installment.InterestsRepayment - installment.PaidInterests; if (AmountComparer.Compare(manualInterestAmount, interestHasToPay) > 0) { pInterestEvent += interestHasToPay; installment.PaidInterests = installment.InterestsRepayment; pAmountPaid -= interestHasToPay; manualInterestAmount -= interestHasToPay; } else { pInterestEvent += manualInterestAmount; installment.PaidInterests += manualInterestAmount; pAmountPaid -= manualInterestAmount; manualInterestAmount = 0; } PaidIstallments.Add(installment); } } } } }
private static void AutomaticRepayMethod(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pCommisionEvent) { if (AmountComparer.Compare(pAmountPaid, pInstallment.CommissionsUnpaid) > 0) { pCommisionEvent += pInstallment.CommissionsUnpaid; pAmountPaid -= pInstallment.CommissionsUnpaid; pInstallment.PaidCommissions += pInstallment.CommissionsUnpaid; pInstallment.CommissionsUnpaid = 0; } else { pCommisionEvent += pAmountPaid; pInstallment.PaidCommissions += pAmountPaid; pInstallment.CommissionsUnpaid -= pAmountPaid; pAmountPaid = 0; } }
public void CalculateFees(DateTime pDate, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent) { OCurrency fees = _loan.UseCents ? Math.Round(_bTcffar.CalculateFees(pDate).Value, 2) : Math.Round(_bTcffar.CalculateFees(pDate).Value, 0); if (AmountComparer.Compare(fees, pAmountPaid) > 0) { pFeesEvent += pAmountPaid; pAmountPaid = 0; } else { pAmountPaid -= fees; pFeesEvent += fees; } }
public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pFeesEvent) { if (AmountComparer.Compare(pAmountPaid, pInstallment.FeesUnpaid) > 0) { pFeesEvent += pInstallment.FeesUnpaid; pAmountPaid -= pInstallment.FeesUnpaid; pInstallment.PaidFees += pInstallment.FeesUnpaid; pInstallment.FeesUnpaid = 0; } else { pFeesEvent += pAmountPaid; pInstallment.PaidFees += pAmountPaid; pInstallment.FeesUnpaid -= pAmountPaid; pAmountPaid = 0; } }
public void Repay(Installment pInstallment, ref OCurrency pAmountPaid, ref OCurrency pInterestEvent, ref OCurrency pInterestPrepayment) { if (AmountComparer.Compare(pAmountPaid, pInstallment.InterestsRepayment - pInstallment.PaidInterests) > 0) { OCurrency interestHasToPay = pInstallment.InterestsRepayment - pInstallment.PaidInterests; pAmountPaid -= interestHasToPay; pInterestEvent += interestHasToPay; pInterestPrepayment += interestHasToPay; pInstallment.PaidInterests += interestHasToPay; } else { pInstallment.PaidInterests += pAmountPaid; pInterestEvent += pAmountPaid; pInterestPrepayment += pAmountPaid; pAmountPaid = 0; } }
public void RepayNextInstallments(ref OCurrency amountPaid, ref OCurrency interestEvent, ref OCurrency interestPrepayment, ref OCurrency principalEvent, ref OCurrency feesEvent, ref OCurrency commissionsEvent) { if (amountPaid > 0) { OCurrency totalInterest = 0; OCurrency totalPrincipal = 0; double nbInterest = 0; double nbPrincipal = 0; foreach (Installment _installment in _contract.InstallmentList) { if (_installment.InterestsRepayment - _installment.PaidInterests > 0) { totalInterest += (_installment.InterestsRepayment - _installment.PaidInterests); if (!_contract.GracePeriod.HasValue) { nbInterest += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1).InterestCoeff.Value; } else if (_installment.Number > _contract.GracePeriod.Value) { nbInterest += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1 - _contract.GracePeriod.Value).InterestCoeff.Value; } } if (_installment.CapitalRepayment - _installment.PaidCapital > 0) { totalPrincipal += (_installment.CapitalRepayment - _installment.PaidCapital); if (!_contract.GracePeriod.HasValue) { nbPrincipal += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1).PrincipalCoeff; } else if (_installment.Number > _contract.GracePeriod.Value) { nbPrincipal += _contract.Product.ExoticProduct.GetExoticInstallment(_installment.Number - 1 - _contract.GracePeriod.Value).PrincipalCoeff; } } } if (AmountComparer.Compare(amountPaid, totalInterest) > 0) { amountPaid -= totalInterest; interestEvent += totalInterest; interestPrepayment += totalInterest; totalInterest = 0; } else { totalInterest -= amountPaid; interestEvent += amountPaid; interestPrepayment += amountPaid; amountPaid = 0; } if (AmountComparer.Compare(amountPaid, totalPrincipal) > 0) { amountPaid -= totalPrincipal; principalEvent += totalPrincipal; totalPrincipal = 0; } else { totalPrincipal -= amountPaid; principalEvent += amountPaid; amountPaid = 0; } if (totalInterest != 0) { totalInterest = totalInterest / (Convert.ToDecimal(nbInterest) * 10); } if (totalPrincipal != 0) { totalPrincipal = totalPrincipal / (Convert.ToDecimal(nbPrincipal) * 10); } for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment _installment = _contract.GetInstallment(i); if (!_installment.IsRepaid) { ExoticInstallment exoticInstallment = null; if (!_contract.GracePeriod.HasValue) { exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i); _installment.InterestsRepayment = Convert.ToDecimal(exoticInstallment.InterestCoeff.Value) * totalInterest * (double)10; _installment.CapitalRepayment = Convert.ToDecimal(exoticInstallment.PrincipalCoeff) * totalPrincipal * (double)10; } else if (_installment.Number > _contract.GracePeriod.Value) { exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i - _contract.GracePeriod.Value); _installment.InterestsRepayment = Convert.ToDecimal(exoticInstallment.InterestCoeff.Value) * totalInterest * (double)10; _installment.CapitalRepayment = Convert.ToDecimal(exoticInstallment.PrincipalCoeff) * totalPrincipal * (double)10; } else { _installment.InterestsRepayment = totalInterest * Convert.ToDecimal(_contract.InterestRate); _installment.CapitalRepayment = 0; } } } } }
public void TestEqualsWhenFirstNumberGreaterThanSecondOne() { Assert.IsFalse(AmountComparer.Equals(243m, 242.97m)); }
public void TestCompareWhenAmount2MinusAmount1LowerThan002() { Assert.IsTrue(AmountComparer.Compare(154.014m, 154.033m) == 0); }
public void TestCompareWhenAmount2MinusAmount1GreaterThan002() { Assert.IsTrue(AmountComparer.Compare(154.011m, 154.033m) < 0); }
public void TestEqualsWhenSecondNumberGreaterThanFirstOneButDifferenceLowerThan002() { Assert.IsTrue(AmountComparer.Equals(1567.1234m, 1567.1238m)); }
public void TestCompareWhenAmount1MinusAmount2GreaterThan002() { Assert.IsTrue(AmountComparer.Compare(154.033m, 154.001m) > 0); }
public void TestEqualsWhenFirstNumberGreaterThanSecondOneButDifferenceLowerThan002() { Assert.IsTrue(AmountComparer.Equals(243.001m, 243.02m)); }
public void RepayNextInstallments(ref OCurrency amountPaid, ref OCurrency interestEvent, ref OCurrency interestPrepayment, ref OCurrency principalEvent, ref OCurrency feesEvent, ref OCurrency commissionsEvent) { if (amountPaid == 0) { return; } for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment installment = _contract.GetInstallment(i); if (!installment.IsRepaid && amountPaid > 0) { //commission _methodToRepayCommission.RepayCommission(installment, ref amountPaid, ref commissionsEvent); if (amountPaid == 0) { break; } //penalty _methodToRepayFees.RepayFees(installment, ref amountPaid, ref feesEvent); if (amountPaid == 0) { break; } //Interests if (amountPaid == 0) { return; } _methodToRepayInterest.RepayInterest(installment, ref amountPaid, ref interestEvent, ref interestPrepayment); //principal if (amountPaid == 0) { _paidInstallments.Add(installment); return; } OCurrency principalHasToPay = installment.CapitalRepayment - installment.PaidCapital; if (AmountComparer.Compare(amountPaid, principalHasToPay) < 0) { installment.PaidCapital += amountPaid; installment.PaidCapital = Math.Round(installment.PaidCapital.Value, 2); principalEvent += amountPaid; amountPaid = 0; } else if (AmountComparer.Compare(amountPaid, principalHasToPay) > 0) { installment.PaidCapital = installment.CapitalRepayment; amountPaid -= principalHasToPay; principalEvent += principalHasToPay; } else { installment.PaidCapital += amountPaid; installment.PaidCapital = Math.Round(installment.PaidCapital.Value, 2); principalEvent += amountPaid; amountPaid = 0; } _paidInstallments.Add(installment); } } }
public void RepayInstallments(DateTime payDate, ref OCurrency amountPaid, ref OCurrency interestEvent, ref OCurrency principalEvent, ref OCurrency feesEvent, ref OCurrency commissionsEvent, ref OPaymentType paymentType) { if (amountPaid == 0) { return; } // we need date without time part payDate = payDate.Date; Installment installment = null; int daysInTheYear = _generalSettings.GetDaysInAYear(_contract.StartDate.Year); int startNumber = 0; int roundingPoint = _contract.UseCents ? 2 : 0; OCurrency olb = _contract.CalculateActualOlb(); OCurrency actualOlb = _contract.CalculateActualOlb(); OCurrency interestsToRepay = 0; OCurrency movedPrincipal = 0; OCurrency paidPrincipal = 0; OCurrency paymentOfInterest = 0; OCurrency totalAmount = _calculateMaximumAmount.CalculateMaximumAmountAuthorizedToRepay(payDate); DateTime beginDate = _contract.StartDate; DateTime date = _contract.StartDate; bool recalculateSchedule = false; bool totalPayment = totalAmount == amountPaid && _contract.GetFirstUnpaidInstallment().Number != _contract.InstallmentList.Count; #region calculate interest payment) for (int i = 0; i < _contract.NbOfInstallments; i++) { installment = _contract.GetInstallment(i); if (!installment.IsRepaid) { //get last repDate if (date < _contract.GetLastRepaymentDate()) { date = _contract.GetLastRepaymentDate(); beginDate = date; } } } for (int i = 0; i < _contract.NbOfInstallments; i++) { installment = _contract.GetInstallment(i); if (installment.IsRepaid) { continue; } if (installment.Number == 1 && installment.ExpectedDate > payDate) { if (installment.PaidCapital == 0 && installment.PaidInterests > 0) { date = installment.Number == 1 ? _contract.StartDate : _contract.GetInstallment(installment.Number - 2).ExpectedDate; beginDate = date; } int daySpan = (payDate - _contract.StartDate).Days < 0 ? 0 : (payDate - _contract.StartDate).Days; installment.InterestsRepayment = olb * _contract.InterestRate * daySpan / daysInTheYear; installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value, roundingPoint, MidpointRounding.AwayFromZero); interestsToRepay += installment.InterestsRepayment; startNumber = 0; date = installment.ExpectedDate; } if (installment.Number > 1 && installment.ExpectedDate > payDate) { OCurrency paidInterests = installment.PaidInterests; int daySpan = (payDate - date).Days < 0 ? 0 : (payDate - date).Days; installment.InterestsRepayment = olb * _contract.InterestRate * daySpan / daysInTheYear + paidInterests; installment.InterestsRepayment = Math.Round(installment.InterestsRepayment.Value, roundingPoint, MidpointRounding.AwayFromZero); interestsToRepay += installment.InterestsRepayment - paidInterests; date = installment.ExpectedDate; } if (installment.ExpectedDate <= payDate) { OCurrency calculatedInterest = 0; OCurrency paidInterest = 0; if (installment.PaidInterests > 0 && installment.InterestsRepayment > installment.PaidInterests) { calculatedInterest = installment.PaidInterests; } if (installment.PaidCapital == 0 && installment.PaidInterests > 0 && installment.PaidInterests != installment.InterestsRepayment) { DateTime dateOfInstallment = installment.Number == 1 ? _contract.StartDate : _contract.GetInstallment(installment.Number - 2).ExpectedDate; int d = (date - dateOfInstallment).Days; OCurrency olbBeforePayment = _contract.Events.GetRepaymentEvents().Where( repaymentEvent => !repaymentEvent.Deleted && repaymentEvent.Date <= dateOfInstallment). Aggregate( _contract.Amount, (current, repaymentEvent) => current - repaymentEvent.Principal); calculatedInterest = (olbBeforePayment * Convert.ToDecimal(_contract.InterestRate) / daysInTheYear * d).Value; calculatedInterest = Math.Round(calculatedInterest.Value, roundingPoint, MidpointRounding.AwayFromZero); if (installment.PaidInterests < calculatedInterest && actualOlb == olbBeforePayment) { paidInterest = installment.PaidInterests.Value; calculatedInterest = 0; date = dateOfInstallment; } if (installment.PaidInterests < calculatedInterest && actualOlb != olbBeforePayment) { paidInterest = 0; calculatedInterest = installment.PaidInterests; } } DateTime expectedDate = installment.ExpectedDate; //in case very late repayment if (installment.Number == _contract.InstallmentList.Count && installment.ExpectedDate < payDate && installment.PaidCapital == 0) { expectedDate = payDate; } int daySpan = (expectedDate - date).Days < 0 ? 0 : (expectedDate - date).Days; if (daySpan == 0 && calculatedInterest > 0) { interestsToRepay += calculatedInterest - installment.PaidInterests; } if (daySpan > 0) { installment.InterestsRepayment = Math.Round((olb * _contract.InterestRate / daysInTheYear * daySpan).Value, roundingPoint, MidpointRounding.AwayFromZero); installment.InterestsRepayment = Math.Round(calculatedInterest.Value + installment.InterestsRepayment.Value, roundingPoint, MidpointRounding.AwayFromZero); interestsToRepay += installment.InterestsRepayment - calculatedInterest - paidInterest; date = installment.ExpectedDate; } } } #endregion #region Repay installment for (int i = 0; i < _contract.NbOfInstallments; i++) { installment = _contract.GetInstallment(i); #region payment on time if (installment.ExpectedDate == payDate) { OCurrency interestPrepayment = 0; installment.CommissionsUnpaid = 0; installment.FeesUnpaid = 0; installment.PaidFees = 0; //interest if (amountPaid == 0) { break; } _methodToRepayInterest.RepayInterest(installment, ref amountPaid, ref paymentOfInterest, ref interestPrepayment); interestsToRepay -= paymentOfInterest; if (interestsToRepay < amountPaid && amountPaid > 0) { if (!totalPayment) { if ( AmountComparer.Compare(amountPaid, installment.CapitalRepayment - installment.PaidCapital) > 0) { if (installment.CapitalRepayment - installment.PaidCapital == amountPaid) { OCurrency principalHasToPay = installment.CapitalRepayment - installment.PaidCapital; installment.PaidCapital = installment.CapitalRepayment; amountPaid -= principalHasToPay; paidPrincipal += principalHasToPay; } else { OCurrency paidCapital = installment.PaidCapital; movedPrincipal = amountPaid - installment.CapitalRepayment + paidCapital; installment.PaidCapital = amountPaid + paidCapital; installment.CapitalRepayment = amountPaid + paidCapital; paidPrincipal += amountPaid; amountPaid = 0; } } else { installment.PaidCapital += amountPaid; paidPrincipal += amountPaid; amountPaid = 0; } } else { installment.PaidCapital = amountPaid; installment.CapitalRepayment = amountPaid; paidPrincipal += amountPaid; amountPaid = 0; paymentType = OPaymentType.TotalPayment; } } PaidIstallments.Add(installment); if (installment.PaidCapital > 0) { olb -= paidPrincipal; } else { olb -= installment.CapitalRepayment; } beginDate = installment.ExpectedDate; startNumber = installment.Number; recalculateSchedule = true; principalEvent += paidPrincipal; interestEvent += paymentOfInterest; paidPrincipal = 0; paymentOfInterest = 0; if (amountPaid == 0) { break; } } #endregion #region payment installmets which is late if (installment.ExpectedDate < payDate) { OCurrency interestPrepayment = 0; installment.CommissionsUnpaid = 0; installment.FeesUnpaid = 0; installment.PaidFees = 0; recalculateSchedule = true; //interest if (amountPaid == 0) { break; } _methodToRepayInterest.RepayInterest(installment, ref amountPaid, ref paymentOfInterest, ref interestPrepayment); interestsToRepay -= paymentOfInterest; if (amountPaid - interestsToRepay > 0 && amountPaid > 0) { if (AmountComparer.Compare(amountPaid, installment.CapitalRepayment - installment.PaidCapital) > 0) { if (amountPaid - interestsToRepay < installment.CapitalRepayment - installment.PaidCapital) { OCurrency paidCapital = installment.PaidCapital; installment.PaidCapital = amountPaid - interestsToRepay + paidCapital; amountPaid -= installment.PaidCapital - paidCapital; paidPrincipal += installment.PaidCapital - paidCapital; } else { OCurrency principalHasToPay = installment.CapitalRepayment - installment.PaidCapital; installment.PaidCapital = installment.CapitalRepayment; amountPaid -= principalHasToPay; paidPrincipal += principalHasToPay; } } else { installment.PaidCapital += amountPaid - interestsToRepay; paidPrincipal += amountPaid - interestsToRepay; amountPaid -= paidPrincipal; } } if (paidPrincipal > 0 || paymentOfInterest > 0) { PaidIstallments.Add(installment); } if (installment.PaidCapital > 0) { olb -= paidPrincipal; } else { olb -= installment.CapitalRepayment; } startNumber = installment.Number; beginDate = installment.ExpectedDate; principalEvent += paidPrincipal; interestEvent += paymentOfInterest; paidPrincipal = 0; paymentOfInterest = 0; if (amountPaid == 0) { break; } } #endregion #region early payment if (installment.ExpectedDate > payDate) { OCurrency interestPrepayment = 0; installment.CommissionsUnpaid = 0; installment.FeesUnpaid = 0; installment.PaidFees = 0; recalculateSchedule = true; //interest if (amountPaid == 0) { break; } _methodToRepayInterest.RepayInterest(installment, ref amountPaid, ref paymentOfInterest, ref interestPrepayment); interestsToRepay -= paymentOfInterest; if (amountPaid - interestsToRepay > 0 && amountPaid > 0) { if (AmountComparer.Compare(amountPaid, installment.CapitalRepayment - installment.PaidCapital) > 0) { if (installment.CapitalRepayment - installment.PaidCapital == amountPaid) { OCurrency principalHasToPay = installment.CapitalRepayment - installment.PaidCapital; installment.PaidCapital = installment.CapitalRepayment; amountPaid -= principalHasToPay; paidPrincipal += principalHasToPay; } else { OCurrency paidCapital = installment.PaidCapital; movedPrincipal = amountPaid - installment.CapitalRepayment + paidCapital; installment.PaidCapital = amountPaid + paidCapital; installment.CapitalRepayment = amountPaid + paidCapital; paidPrincipal += amountPaid; amountPaid = 0; } } else { installment.PaidCapital += amountPaid; paidPrincipal += amountPaid; amountPaid = 0; } } if (paidPrincipal > 0) { startNumber = installment.Number; } if (installment.CapitalRepayment - installment.PaidCapital > 0 && installment.CapitalRepayment > 0) { startNumber = installment.Number - 1; } beginDate = startNumber > 0 ? installment.ExpectedDate : _contract.StartDate; if (installment.PaidCapital > 0) { olb -= paidPrincipal; } else { if (startNumber == installment.Number) { olb -= installment.CapitalRepayment; } } if (paidPrincipal > 0 || paymentOfInterest > 0) { PaidIstallments.Add(installment); } principalEvent += paidPrincipal; interestEvent += paymentOfInterest; paidPrincipal = 0; paymentOfInterest = 0; if (installment.CapitalRepayment > 0 && installment.CapitalRepayment - installment.PaidCapital == 0 && olb > 0) { OCurrency paidInterests = installment.PaidInterests; int daySpan = (installment.ExpectedDate - payDate).Days < 0 ? 0 : (installment.ExpectedDate - payDate).Days; installment.InterestsRepayment = paidInterests.Value + Math.Round((olb * _contract.InterestRate / daysInTheYear * daySpan).Value , roundingPoint, MidpointRounding.AwayFromZero); } if (amountPaid == 0) { break; } } #endregion } #endregion //recalculate installmets after repayment if (recalculateSchedule) { OCurrency o = _contract.CalculateActualOlb(); bool isCapitalRemoved = false; bool isInterestCalculated = false; for (int i = 0; i < _contract.NbOfInstallments; i++) { installment = _contract.GetInstallment(i); if (installment.Number > startNumber) { OCurrency remainingPrincipal = 0; Installment priorInstallment = null; Installment priorInstallment1 = null; if (installment.Number > 1) { priorInstallment = _contract.GetInstallment(installment.Number - 2); } if (installment.Number > 2) { priorInstallment1 = _contract.GetInstallment(installment.Number - 3); } if (priorInstallment != null && priorInstallment.CapitalRepayment - priorInstallment.PaidCapital > 0 && priorInstallment.PaidCapital > 0 && !isCapitalRemoved) { remainingPrincipal = priorInstallment.CapitalRepayment - priorInstallment.PaidCapital; isCapitalRemoved = true; } if (installment.CapitalRepayment - installment.PaidCapital > 0 && installment.PaidCapital > 0 && !isCapitalRemoved) { remainingPrincipal = -1 * installment.PaidCapital.Value; isCapitalRemoved = true; beginDate = payDate; } // balloon case ///////////////////// if (installment.CapitalRepayment == 0 && installment.PaidCapital == 0 && installment.PaidInterests == 0) { beginDate = installment.Number > 1 ? priorInstallment.ExpectedDate : _contract.StartDate; isInterestCalculated = false; isCapitalRemoved = true; } ///////////////////////////// if (priorInstallment != null && priorInstallment1 != null && priorInstallment.InterestHasToPay == 0 && installment.PaidCapital == 0 && priorInstallment1.PaidCapital > 0 && priorInstallment1.CapitalRepayment - priorInstallment1.PaidCapital > 0 && !isCapitalRemoved) { olb = o; remainingPrincipal = priorInstallment.CapitalRepayment + priorInstallment1.CapitalRepayment - priorInstallment1.PaidCapital; isCapitalRemoved = true; } if (installment.InterestsRepayment == 0) { o = olb; } installment.OLB = Math.Round(olb.Value, roundingPoint); if (installment.ExpectedDate > payDate && installment.PaidInterests > 0 && olb == actualOlb) { beginDate = installment.Number > 1 ? priorInstallment.ExpectedDate : _contract.StartDate; } DateTime expectedDate = installment.ExpectedDate; //in case very late repayment if (installment.Number == _contract.InstallmentList.Count && installment.ExpectedDate < payDate && installment.PaidCapital == 0) { expectedDate = payDate; beginDate = priorInstallment.ExpectedDate; } int days = (expectedDate - beginDate).Days; if (installment.PaidInterests == installment.InterestsRepayment && days < 0) { days = 0; } OCurrency interestPayment = (o * Convert.ToDecimal(_contract.InterestRate) / daysInTheYear * days).Value; if (olb == actualOlb && !isInterestCalculated) { installment.InterestsRepayment = Math.Round(interestPayment.Value, roundingPoint, MidpointRounding.AwayFromZero); isInterestCalculated = true; } else { installment.InterestsRepayment += Math.Round(interestPayment.Value, roundingPoint, MidpointRounding.AwayFromZero); } if (installment.PaidCapital == 0 && movedPrincipal > 0) { movedPrincipal -= installment.CapitalRepayment; if (movedPrincipal > 0) { installment.CapitalRepayment = 0; } else { installment.CapitalRepayment = installment.CapitalRepayment - (installment.CapitalRepayment + movedPrincipal); } } if (!totalPayment) { olb -= installment.CapitalRepayment + remainingPrincipal; } else { installment.CapitalRepayment = 0; } if (installment.PaidInterests != installment.InterestsRepayment && days >= 0) { beginDate = installment.ExpectedDate; } o = olb; } else { beginDate = payDate >= installment.ExpectedDate ? payDate : installment.ExpectedDate; } } } if (installment != null) { for (int i = installment.Number; i < _contract.NbOfInstallments; i++) { _contract.GetInstallment(i).FeesUnpaid = 0; } } }
public void TestEqualsWhenThe2NumbersAreReallyEquals() { Assert.IsTrue(AmountComparer.Equals(123.3456m, 123.3456m)); }
public void Sort() { AmountComparer ac = new AmountComparer(); list.Sort(ac); }
public void RepayNextInstallments(ref OCurrency amountPaid, ref OCurrency interestEvent, ref OCurrency interestPrepayment, ref OCurrency principalEvent, ref OCurrency feesEvent, ref OCurrency commissionsEvent) { if (amountPaid <= 0) return; OCurrency totalInterest = 0; OCurrency totalPrincipal = 0; double nbInterest = 0; double nbPrincipal = 0; foreach (Installment installment in _contract.InstallmentList) { if(installment.InterestsRepayment - installment.PaidInterests > 0) { totalInterest += (installment.InterestsRepayment - installment.PaidInterests); if (!_contract.GracePeriod.HasValue) { nbInterest += _contract.Product.ExoticProduct.GetExoticInstallment(installment.Number - 1).InterestCoeff.Value; } else if (installment.Number > _contract.GracePeriod.Value) { nbInterest += _contract.Product.ExoticProduct.GetExoticInstallment(installment.Number - 1 - _contract.GracePeriod.Value).InterestCoeff.Value; } } if(installment.CapitalRepayment - installment.PaidCapital > 0) { totalPrincipal += (installment.CapitalRepayment - installment.PaidCapital); if (!_contract.GracePeriod.HasValue) { nbPrincipal += _contract.Product.ExoticProduct.GetExoticInstallment(installment.Number - 1).PrincipalCoeff; } else if (installment.Number > _contract.GracePeriod.Value) { nbPrincipal += _contract.Product.ExoticProduct.GetExoticInstallment(installment.Number - 1 - _contract.GracePeriod.Value).PrincipalCoeff; } } } if(AmountComparer.Compare(amountPaid,totalInterest) > 0) { amountPaid -= totalInterest; interestEvent += totalInterest; interestPrepayment += totalInterest; totalInterest = 0; } else { totalInterest -= amountPaid; interestEvent += amountPaid; interestPrepayment += amountPaid; amountPaid = 0; } if(AmountComparer.Compare(amountPaid,totalPrincipal) > 0) { amountPaid -= totalPrincipal; principalEvent += totalPrincipal; totalPrincipal = 0; } else { totalPrincipal -= amountPaid; principalEvent += amountPaid; amountPaid = 0; } if(totalInterest != 0) totalInterest = totalInterest / (Convert.ToDecimal(nbInterest) * 10); if(totalPrincipal != 0) totalPrincipal = totalPrincipal / (Convert.ToDecimal(nbPrincipal) * 10); OCurrency interestForLastInstallment = 0; OCurrency capitalForLastInstallment = 0; for (int i = 0; i < _contract.NbOfInstallments; i++) { Installment installment = _contract.GetInstallment(i); if(!installment.IsRepaid) { ExoticInstallment exoticInstallment; if (!_contract.GracePeriod.HasValue) { exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i); OCurrency tempInterest = Convert.ToDecimal(exoticInstallment.InterestCoeff)*totalInterest*(double)10; OCurrency tempCapital = Convert.ToDecimal(exoticInstallment.PrincipalCoeff)*totalPrincipal*(double)10; installment.InterestsRepayment = Math.Truncate(tempInterest.Value); installment.CapitalRepayment = Math.Truncate(tempCapital.Value); interestForLastInstallment += tempInterest - installment.InterestsRepayment; capitalForLastInstallment += tempCapital - installment.CapitalRepayment; } else if (installment.Number > _contract.GracePeriod.Value) { exoticInstallment = _contract.Product.ExoticProduct.GetExoticInstallment(i - _contract.GracePeriod.Value); OCurrency tempInterest = Convert.ToDecimal(exoticInstallment.InterestCoeff) * totalInterest * (double)10; OCurrency tempCapital = Convert.ToDecimal(exoticInstallment.PrincipalCoeff) * totalPrincipal * (double)10; installment.InterestsRepayment = Math.Truncate(tempInterest.Value); installment.CapitalRepayment = Math.Truncate(tempCapital.Value); interestForLastInstallment += tempInterest - installment.InterestsRepayment; capitalForLastInstallment += tempCapital - installment.CapitalRepayment; } else { OCurrency tempInterest = 0; if (totalInterest != 0) tempInterest = totalPrincipal * Convert.ToDecimal(_contract.InterestRate); installment.InterestsRepayment = Math.Truncate(tempInterest.Value); installment.CapitalRepayment = 0; interestForLastInstallment += tempInterest - installment.InterestsRepayment; } } _paidInstallments.Add(installment); } Installment lastInstallment = _contract.GetInstallment(_contract.NbOfInstallments - 1); lastInstallment.InterestsRepayment += interestForLastInstallment; lastInstallment.CapitalRepayment += capitalForLastInstallment; lastInstallment.InterestsRepayment = lastInstallment.InterestsRepayment; lastInstallment.CapitalRepayment = lastInstallment.CapitalRepayment; lastInstallment.InterestsRepayment = Math.Round(lastInstallment.InterestsRepayment.Value, 0); lastInstallment.CapitalRepayment = Math.Round(lastInstallment.CapitalRepayment.Value, 0); }
public void TestEqualsWhenSecondNumberGreaterThanFirstOne() { Assert.IsFalse(AmountComparer.Equals(242.974321m, 243.0001m)); }