FINERACT-2265: Progressive Loan - Interest Recalculation fails for - RecalculationRestFrequencyType SameAsRepaymentPeriod
This commit is contained in:
+14
-27
@@ -1220,44 +1220,31 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
LocalDate toDate = currentInstallment.getDueDate();
|
||||
boolean hasUpdate = false;
|
||||
|
||||
if (currentInstallment.getLoan().getLoanInterestRecalculationDetails().getRestFrequencyType().isSameAsRepayment()) {
|
||||
if (!currentDate.equals(ctx.getLastOverdueBalanceChange())) {
|
||||
// if we have same date for fromDate & last overdue balance change then it means we have the up-to-date
|
||||
// model.
|
||||
if (ctx.getLastOverdueBalanceChange() == null || fromDate.isAfter(ctx.getLastOverdueBalanceChange())) {
|
||||
emiCalculator.addBalanceCorrection(ctx.getModel(), fromDate, overduePrincipal);
|
||||
ctx.setLastOverdueBalanceChange(fromDate);
|
||||
hasUpdate = true;
|
||||
|
||||
if (currentDate.isAfter(fromDate) && !currentDate.isAfter(toDate)) {
|
||||
emiCalculator.addBalanceCorrection(ctx.getModel(), currentInstallment.getDueDate(),
|
||||
aggregatedOverDuePrincipal.negated());
|
||||
ctx.setLastOverdueBalanceChange(currentInstallment.getDueDate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentInstallment.getLoan().getLoanInterestRecalculationDetails().getRestFrequencyType().isDaily()
|
||||
// if we have same date for currentDate & last overdue balance change then it meas we have the
|
||||
// up-to-date model.
|
||||
&& !currentDate.equals(ctx.getLastOverdueBalanceChange())) {
|
||||
if (ctx.getLastOverdueBalanceChange() == null || currentInstallment.getFromDate().isAfter(ctx.getLastOverdueBalanceChange())) {
|
||||
// first overdue hit for installment. setting overdue balance correction from instalment from date.
|
||||
emiCalculator.addBalanceCorrection(ctx.getModel(), fromDate, overduePrincipal);
|
||||
} else {
|
||||
// not the first balance correction on installment period, then setting overdue balance correction from
|
||||
// last balance change's current date. previous interest period already has the correct balanec
|
||||
// correction
|
||||
// last balance change's current date. previous interest period already has the correct balance
|
||||
// correction.
|
||||
emiCalculator.addBalanceCorrection(ctx.getModel(), ctx.getLastOverdueBalanceChange(), overduePrincipal);
|
||||
}
|
||||
|
||||
// setting negative correction for the period from current date, expecting the overdue balance's full
|
||||
// repayment on that day.
|
||||
// TODO: we might need to do it outside of this method only for the current date at the end
|
||||
if (currentDate.isAfter(currentInstallment.getFromDate()) && !currentDate.isAfter(currentInstallment.getDueDate())) {
|
||||
emiCalculator.addBalanceCorrection(ctx.getModel(), currentDate, aggregatedOverDuePrincipal.negated());
|
||||
ctx.setLastOverdueBalanceChange(currentDate);
|
||||
}
|
||||
hasUpdate = true;
|
||||
|
||||
if (currentDate.isAfter(fromDate) && !currentDate.isAfter(toDate)) {
|
||||
LocalDate lastOverdueBalanceChange;
|
||||
if (currentInstallment.getLoan().getLoanInterestRecalculationDetails().getRestFrequencyType().isSameAsRepayment()) {
|
||||
lastOverdueBalanceChange = toDate;
|
||||
} else {
|
||||
lastOverdueBalanceChange = currentDate;
|
||||
}
|
||||
emiCalculator.addBalanceCorrection(ctx.getModel(), lastOverdueBalanceChange, aggregatedOverDuePrincipal.negated());
|
||||
ctx.setLastOverdueBalanceChange(lastOverdueBalanceChange);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUpdate) {
|
||||
|
||||
+2
-2
@@ -675,8 +675,8 @@ public class LoanCOBCreateAccrualsTest extends BaseLoanIntegrationTest {
|
||||
validateTransactionsExist(loanDetails, //
|
||||
transaction(0.30, "Accrual", "19 February 2025", 0.0, 0.0, 0.30, 0.0, 0.0, 0.0, 0.0), //
|
||||
transaction(0.30, "Accrual", "20 February 2025", 0.0, 0.0, 0.30, 0.0, 0.0, 0.0, 0.0), //
|
||||
transaction(0.23, "Accrual", "21 February 2025", 0.0, 0.0, 0.23, 0.0, 0.0, 0.0, 0.0), //
|
||||
transaction(0.22, "Accrual", "22 February 2025", 0.0, 0.0, 0.22, 0.0, 0.0, 0.0, 0.0)); //
|
||||
transaction(0.33, "Accrual", "21 February 2025", 0.0, 0.0, 0.33, 0.0, 0.0, 0.0, 0.0), //
|
||||
transaction(0.34, "Accrual", "22 February 2025", 0.0, 0.0, 0.34, 0.0, 0.0, 0.0, 0.0)); //
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+47
@@ -93,6 +93,53 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
|
||||
period.getPrincipalDue(), period.getFeeChargesDue(), period.getPenaltyChargesDue(), period.getInterestDue()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterestRecalculationInCaseOfTinyAmountOfRepaymentsEveryRepaymentPeriodForProgressiveLoanSameAsRepaymentPeriod() {
|
||||
AtomicReference<Long> loanIdRef = new AtomicReference<>();
|
||||
runAt("1 January 2023", () -> {
|
||||
PostLoanProductsResponse loanProduct = loanProductHelper.createLoanProduct(create4IProgressive() //
|
||||
.recalculationRestFrequencyType(RecalculationRestFrequencyType.SAME_AS_REPAYMENT_PERIOD) //
|
||||
);//
|
||||
Long loanId = applyAndApproveProgressiveLoan(client.getClientId(), loanProduct.getResourceId(), "1 January 2023", 10000.0,
|
||||
86.42, 6, null);
|
||||
loanIdRef.set(loanId);
|
||||
disburseLoan(loanId, BigDecimal.valueOf(8000), "1 January 2023");
|
||||
});
|
||||
runAt("1 February 2023", () -> {
|
||||
Long loanId = loanIdRef.get();
|
||||
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "1 February 2023", 0.01);
|
||||
});
|
||||
runAt("1 March 2023", () -> {
|
||||
Long loanId = loanIdRef.get();
|
||||
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "1 March 2023", 0.01);
|
||||
});
|
||||
runAt("1 April 2023", () -> {
|
||||
Long loanId = loanIdRef.get();
|
||||
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "1 April 2023", 0.01);
|
||||
});
|
||||
runAt("1 May 2023", () -> {
|
||||
Long loanId = loanIdRef.get();
|
||||
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "1 May 2023", 0.01);
|
||||
});
|
||||
runAt("1 June 2023", () -> {
|
||||
Long loanId = loanIdRef.get();
|
||||
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "1 June 2023", 0.01);
|
||||
});
|
||||
runAt("17 June 2023", () -> {
|
||||
Long loanId = loanIdRef.get();
|
||||
inlineLoanCOBHelper.executeInlineCOB(List.of(loanId));
|
||||
verifyRepaymentSchedule(loanId, //
|
||||
installment(8000.0, null, "01 January 2023"), //
|
||||
installment(1112.7, 576.13, 1688.78, false, "01 February 2023"), //
|
||||
installment(1112.7, 576.13, 1688.83, false, "01 March 2023"), //
|
||||
installment(1112.7, 576.13, 1688.83, false, "01 April 2023"), //
|
||||
installment(1112.7, 576.13, 1688.83, false, "01 May 2023"), //
|
||||
installment(1112.7, 576.13, 1688.83, false, "01 June 2023"), //
|
||||
installment(2436.5, 576.13, 3012.63, false, "01 July 2023") //
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyLoanInstallmentRecalculatedIfThereIsOverdueInstallmentOn4IProgressiveLoanCOBStepDaily() {
|
||||
AtomicReference<Long> loanIdRef = new AtomicReference<>();
|
||||
|
||||
Reference in New Issue
Block a user