FINERACT-2081: Fix backdated multi disbursement on Progressive Loan
This commit is contained in:
committed by
Adam Saghy
parent
b4a68ba502
commit
0e08903811
+10
-4
@@ -26,6 +26,7 @@ import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -103,11 +104,15 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||
|
||||
prepareDisbursementsOnLoanApplicationTerms(loanApplicationTerms);
|
||||
|
||||
final ArrayList<DisbursementData> disbursementDataList = new ArrayList<>(loanApplicationTerms.getDisbursementDatas());
|
||||
disbursementDataList.sort(Comparator.comparing(DisbursementData::disbursementDate));
|
||||
|
||||
for (LoanScheduleModelRepaymentPeriod repaymentPeriod : expectedRepaymentPeriods) {
|
||||
scheduleParams.setPeriodStartDate(repaymentPeriod.getFromDate());
|
||||
scheduleParams.setActualRepaymentDate(repaymentPeriod.getDueDate());
|
||||
|
||||
processDisbursements(loanApplicationTerms, scheduleParams, interestScheduleModel, periods, chargesDueAtTimeOfDisbursement);
|
||||
processDisbursements(loanApplicationTerms, disbursementDataList, scheduleParams, interestScheduleModel, periods,
|
||||
chargesDueAtTimeOfDisbursement);
|
||||
repaymentPeriod.setPeriodNumber(scheduleParams.getInstalmentNumber());
|
||||
|
||||
for (var interestRateChange : loanApplicationTerms.getLoanTermVariations().getInterestRateFromInstallment()) {
|
||||
@@ -142,7 +147,7 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||
}
|
||||
|
||||
if (loanApplicationTerms.isMultiDisburseLoan()) {
|
||||
processDisbursements(loanApplicationTerms, scheduleParams, null, periods, chargesDueAtTimeOfDisbursement);
|
||||
processDisbursements(loanApplicationTerms, disbursementDataList, scheduleParams, null, periods, chargesDueAtTimeOfDisbursement);
|
||||
}
|
||||
|
||||
// determine fees and penalties for charges which depends on total
|
||||
@@ -169,11 +174,12 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
private void processDisbursements(final LoanApplicationTerms loanApplicationTerms, final LoanScheduleParams scheduleParams,
|
||||
private void processDisbursements(final LoanApplicationTerms loanApplicationTerms,
|
||||
final ArrayList<DisbursementData> disbursementDataList, final LoanScheduleParams scheduleParams,
|
||||
final ProgressiveLoanInterestScheduleModel interestScheduleModel, final List<LoanScheduleModelPeriod> periods,
|
||||
final BigDecimal chargesDueAtTimeOfDisbursement) {
|
||||
|
||||
for (DisbursementData disbursementData : loanApplicationTerms.getDisbursementDatas()) {
|
||||
for (DisbursementData disbursementData : disbursementDataList) {
|
||||
final LocalDate disbursementDate = disbursementData.disbursementDate();
|
||||
final LocalDate periodFromDate = scheduleParams.getPeriodStartDate();
|
||||
final LocalDate periodDueDate = scheduleParams.getActualRepaymentDate();
|
||||
|
||||
+65
@@ -674,6 +674,71 @@ class ProgressiveEMICalculatorTest {
|
||||
checkPeriod(interestSchedule, 5, 0, 37.53, 0.007901833333, 0.29, 37.24, 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEMICalculation_multiDisbursedAmt150InSamePeriod_dayInYears360_daysInMonth30_repayEvery1Month_backdated_disbursement() {
|
||||
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("9.4822");
|
||||
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);
|
||||
|
||||
final ProgressiveLoanInterestScheduleModel interestSchedule = emiCalculator.generateInterestScheduleModel(expectedRepaymentPeriods,
|
||||
loanProductRelatedDetail, installmentAmountInMultiplesOf, mc);
|
||||
|
||||
Money disbursedAmount = Money.of(monetaryCurrency, BigDecimal.valueOf(100));
|
||||
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 8), disbursedAmount);
|
||||
|
||||
checkDisbursementOnPeriod(interestSchedule, 0, disbursedAmount);
|
||||
checkPeriod(interestSchedule, 0, 0, 17.10, 0.001784284946, 0.00, 0.61, 16.49, 83.51);
|
||||
checkPeriod(interestSchedule, 0, 1, 17.10, 0.006117548387, 0.61, 0.61, 16.49, 83.51);
|
||||
checkPeriod(interestSchedule, 1, 0, 17.10, 0.007901833333, 0.66, 16.44, 67.07);
|
||||
checkPeriod(interestSchedule, 2, 0, 17.10, 0.007901833333, 0.53, 16.57, 50.50);
|
||||
checkPeriod(interestSchedule, 3, 0, 17.10, 0.007901833333, 0.40, 16.70, 33.80);
|
||||
checkPeriod(interestSchedule, 4, 0, 17.10, 0.007901833333, 0.27, 16.83, 16.97);
|
||||
checkPeriod(interestSchedule, 5, 0, 17.10, 0.007901833333, 0.13, 16.97, 0.0);
|
||||
|
||||
disbursedAmount = Money.of(monetaryCurrency, BigDecimal.valueOf(50));
|
||||
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 5), disbursedAmount);
|
||||
|
||||
checkDisbursementOnPeriod(interestSchedule, 0, 150);
|
||||
checkPeriod(interestSchedule, 0, 0, 25.66, 0.001019591398, 0.00, 0.96, 24.70, 125.30);
|
||||
checkPeriod(interestSchedule, 0, 1, 25.66, 0.000764693548, 0.04, 0.96, 24.70, 125.30);
|
||||
checkPeriod(interestSchedule, 0, 2, 25.66, 0.006117548387, 0.92, 0.96, 24.70, 125.30);
|
||||
checkPeriod(interestSchedule, 1, 0, 25.66, 0.007901833333, 0.99, 24.67, 100.63);
|
||||
checkPeriod(interestSchedule, 2, 0, 25.66, 0.007901833333, 0.80, 24.86, 75.77);
|
||||
checkPeriod(interestSchedule, 3, 0, 25.66, 0.007901833333, 0.60, 25.06, 50.71);
|
||||
checkPeriod(interestSchedule, 4, 0, 25.66, 0.007901833333, 0.40, 25.26, 25.45);
|
||||
checkPeriod(interestSchedule, 5, 0, 25.65, 0.007901833333, 0.20, 25.45, 0.0);
|
||||
|
||||
// add disbursement on same date
|
||||
disbursedAmount = Money.of(monetaryCurrency, BigDecimal.valueOf(25));
|
||||
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 8), disbursedAmount);
|
||||
|
||||
checkDisbursementOnPeriod(interestSchedule, 0, 175);
|
||||
checkPeriod(interestSchedule, 0, 0, 29.93, 0.001019591398, 0.00, 1.11, 28.82, 146.18);
|
||||
checkPeriod(interestSchedule, 0, 1, 29.93, 0.000764693548, 0.04, 1.11, 28.82, 146.18);
|
||||
checkPeriod(interestSchedule, 0, 2, 29.93, 0.006117548387, 1.07, 1.11, 28.82, 146.18);
|
||||
checkPeriod(interestSchedule, 1, 0, 29.93, 0.007901833333, 1.16, 28.77, 117.41);
|
||||
checkPeriod(interestSchedule, 2, 0, 29.93, 0.007901833333, 0.93, 29.00, 88.41);
|
||||
checkPeriod(interestSchedule, 3, 0, 29.93, 0.007901833333, 0.70, 29.23, 59.18);
|
||||
checkPeriod(interestSchedule, 4, 0, 29.93, 0.007901833333, 0.47, 29.46, 29.72);
|
||||
checkPeriod(interestSchedule, 5, 0, 29.95, 0.007901833333, 0.23, 29.72, 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEMICalculation_disbursedAmt100_dayInYearsActual_daysInMonthActual_repayEvery1Month() {
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
|
||||
Reference in New Issue
Block a user