Skip to content

Commit

Permalink
FINERACT-2114: Fix EMI Calculator get payment details
Browse files Browse the repository at this point in the history
  • Loading branch information
janez89 authored and kjozsa committed Sep 10, 2024
1 parent f1b4ea9 commit c9bdc2a
Showing 1 changed file with 81 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ public void testEMICalculation_disbursedAmt100_dayInYears360_daysInMonth30_repay
* This test case tests a period early and late repayment with balance correction
*/
@Test
public void testEMICalculation_disbursedAmt100_dayInYears360_daysInMonth30_repayEvery1Month_add_balance_on0215() {
public void testEMICalculation_disbursedAmt100_dayInYears360_daysInMonth30_repayEvery1Month_add_balance_correction_on0215() {
final MathContext mc = MoneyHelper.getMathContext();
final List<LoanScheduleModelRepaymentPeriod> expectedRepaymentPeriods = new ArrayList<>();

Expand Down Expand Up @@ -444,6 +444,86 @@ public void testEMICalculation_disbursedAmt100_dayInYears360_daysInMonth30_repay
Assertions.assertEquals(0.14, toDouble(repaymentDetails4th.getInterestDue().getAmount()));
}

@Test
public void testEMICalculation_disbursedAmt100_dayInYears360_daysInMonth30_repayEvery1Month_payoff_on0215() {
final MathContext mc = MoneyHelper.getMathContext();
final List<LoanScheduleModelRepaymentPeriod> expectedRepaymentPeriods = new ArrayList<>();

expectedRepaymentPeriods.add(repayment(1, LocalDate.of(2024, 1, 1), LocalDate.of(2024, 2, 1)));
expectedRepaymentPeriods.add(repayment(2, LocalDate.of(2024, 2, 1), LocalDate.of(2024, 3, 1)));
expectedRepaymentPeriods.add(repayment(3, LocalDate.of(2024, 3, 1), LocalDate.of(2024, 4, 1)));
expectedRepaymentPeriods.add(repayment(4, LocalDate.of(2024, 4, 1), LocalDate.of(2024, 5, 1)));
expectedRepaymentPeriods.add(repayment(5, LocalDate.of(2024, 5, 1), LocalDate.of(2024, 6, 1)));
expectedRepaymentPeriods.add(repayment(6, LocalDate.of(2024, 6, 1), LocalDate.of(2024, 7, 1)));

final BigDecimal interestRate = new BigDecimal("7");
final Integer installmentAmountInMultiplesOf = null;

Mockito.when(loanProductRelatedDetail.getNominalInterestRatePerPeriod()).thenReturn(interestRate);
Mockito.when(loanProductRelatedDetail.getDaysInYearType()).thenReturn(DaysInYearType.DAYS_360.getValue());
Mockito.when(loanProductRelatedDetail.getDaysInMonthType()).thenReturn(DaysInMonthType.DAYS_30.getValue());
Mockito.when(loanProductRelatedDetail.getRepaymentPeriodFrequencyType()).thenReturn(PeriodFrequencyType.MONTHS);
Mockito.when(loanProductRelatedDetail.getRepayEvery()).thenReturn(1);
Mockito.when(loanProductRelatedDetail.getCurrency()).thenReturn(monetaryCurrency);

threadLocalContextUtil.when(ThreadLocalContextUtil::getBusinessDate).thenReturn(LocalDate.of(2024, 2, 15));

final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generateInterestScheduleModel(expectedRepaymentPeriods,
loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);

final Money disbursedAmount = Money.of(monetaryCurrency, BigDecimal.valueOf(100));
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 1), disbursedAmount);

// partially pay off a period with balance correction
final LocalDate op1stCorrectionPeriodDueDate = LocalDate.of(2024, 3, 1);
final LocalDate op1stCorrectionDate = LocalDate.of(2024, 2, 15);
final Money op1stCorrectionAmount = Money.of(monetaryCurrency, BigDecimal.valueOf(-83.57));

// get remaining balance and dues for a date
final ProgressiveLoanInterestRepaymentModel repaymentDetails1st = emiCalculator
.getPayableDetails(interestSchedule, op1stCorrectionPeriodDueDate, op1stCorrectionDate).get();
Assertions.assertEquals(83.57, toDouble(repaymentDetails1st.getOutstandingBalance().getAmount()));
Assertions.assertEquals(16.77, toDouble(repaymentDetails1st.getPrincipalDue().getAmount()));
Assertions.assertEquals(0.24, toDouble(repaymentDetails1st.getInterestDue().getAmount()));

ProgressiveLoanInterestRepaymentModel details = null;
// check getPayableDetails forcast
details = emiCalculator.getPayableDetails(interestSchedule, LocalDate.of(2024, 3, 1), LocalDate.of(2024, 3, 1)).get();
Assertions.assertEquals(83.57, toDouble(details.getOutstandingBalance().getAmount()));
Assertions.assertEquals(83.57, toDouble(details.getCorrectedOutstandingBalance().getAmount()));
Assertions.assertEquals(16.52, toDouble(details.getPrincipalDue().getAmount()));
Assertions.assertEquals(0.49, toDouble(details.getInterestDue().getAmount()));

// apply balance change and check again
emiCalculator.addBalanceCorrection(interestSchedule, op1stCorrectionDate, op1stCorrectionAmount);
details = emiCalculator.getPayableDetails(interestSchedule, LocalDate.of(2024, 3, 1), LocalDate.of(2024, 3, 1)).get();
Assertions.assertEquals(83.57, toDouble(details.getOutstandingBalance().getAmount()));
Assertions.assertEquals(0, toDouble(details.getCorrectedOutstandingBalance().getAmount()));
Assertions.assertEquals(16.77, toDouble(details.getPrincipalDue().getAmount()));
Assertions.assertEquals(0.24, toDouble(details.getInterestDue().getAmount()));

emiCalculator.addBalanceCorrection(interestSchedule, LocalDate.of(2024, 3, 1), Money.of(monetaryCurrency, BigDecimal.valueOf(-66.80)));
emiCalculator.addBalanceCorrection(interestSchedule, LocalDate.of(2024, 4, 1), Money.of(monetaryCurrency, BigDecimal.valueOf(-49.79)));
emiCalculator.addBalanceCorrection(interestSchedule, LocalDate.of(2024, 5, 1), Money.of(monetaryCurrency, BigDecimal.valueOf(-32.78)));
emiCalculator.addBalanceCorrection(interestSchedule, LocalDate.of(2024, 6, 1), Money.of(monetaryCurrency, BigDecimal.valueOf(-15.77)));

details = emiCalculator.getPayableDetails(interestSchedule, LocalDate.of(2024, 7, 1), LocalDate.of(2024, 7, 1)).get();
Assertions.assertEquals(15.77, toDouble(details.getOutstandingBalance().getAmount()));
Assertions.assertEquals(0, toDouble(details.getCorrectedOutstandingBalance().getAmount()));
Assertions.assertEquals(15.77, toDouble(details.getPrincipalDue().getAmount()));
Assertions.assertEquals(0.0, toDouble(details.getInterestDue().getAmount()));

// check periods in model
checkDisbursementOnPeriod(interestSchedule, 0, disbursedAmount);
checkPeriod(interestSchedule, 0, 0, 17.01, 0.005833333333, 0.58, 16.43, 83.57);
checkPeriod(interestSchedule, 1, 0, 17.01, 0.002816091954, 0.24, 0.24, 16.77, 66.80);
checkPeriod(interestSchedule, 1, 1, 17.01, 0.003017241379, 0.0, 0.24, 16.77, 66.80);
checkPeriod(interestSchedule, 2, 0, 17.01, 0.005833333333, 0, 17.01, 49.79);
checkPeriod(interestSchedule, 3, 0, 17.01, 0.005833333333, 0, 17.01, 32.78);
checkPeriod(interestSchedule, 4, 0, 17.01, 0.005833333333, 0, 17.01, 15.77);
checkPeriod(interestSchedule, 5, 0, 15.77, 0.005833333333, 0, 15.77, 0.0);
}

// @Test
// public void testEMICalculation_disbursedAmt100_dayInYearsActual_daysInMonthActual_repayEvery1Month_reschedule() {
// final MathContext mc = MoneyHelper.getMathContext();
Expand Down

0 comments on commit c9bdc2a

Please sign in to comment.