From 001ad2fa1f08a5e9a1844439f19e1dd93addefe1 Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Tue, 29 Aug 2023 11:01:34 +0200 Subject: [PATCH] FINERACT-1839: Fix N+1 installment due date --- ...oanRepaymentScheduleTransactionProcessor.java | 6 +++++- .../LoanTransactionReverseReplayTest.java | 16 ++++++++++++++-- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java index ec10ad8a6..3f448f738 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/AbstractLoanRepaymentScheduleTransactionProcessor.java @@ -372,9 +372,13 @@ public abstract class AbstractLoanRepaymentScheduleTransactionProcessor implemen loanTransactionMapped = true; break; - // If already exists an additional installment just update + // If already exists an additional installment just update the due date and // principal from the Loan chargeback / CBR transaction } else if (currentInstallment.isAdditional()) { + if (transactionDate.isAfter(currentInstallment.getDueDate())) { + currentInstallment.updateDueDate(transactionDate); + } + currentInstallment.updateCredits(transactionDate, transactionAmount); if (repaidAmount.isGreaterThanZero()) { currentInstallment.payPrincipalComponent(loanTransaction.getTransactionDate(), repaidAmount); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java index 3fbb1314c..309a1c101 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java @@ -143,7 +143,8 @@ public class LoanTransactionReverseReplayTest { /** * 1 create a loan account - approve and disburse // 2. make repayment (fully paid) // 3. add the charge greater * than the maturity date // 4. make 2nd payment with excess amount - the loan will move to overpaid state. // 5. Do - * a CBR transaction // 6. reverse the 2nd payment // 7. check the repayment schedule due date. // + * a CBR transaction // 6. reverse the 2nd payment // 7. check the repayment schedule due date. 8. add chargeback + * for 1st repayment 9. check the repayment schedule due date // */ @Test public void loanTransactionReverseReplayWithAdditionalInstallmentAndChargesScheduleDueDateTest() { @@ -167,8 +168,9 @@ public class LoanTransactionReverseReplayTest { ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", true)); // make repayment + String loanTransactionExternalIdStr = UUID.randomUUID().toString(); loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, new PostLoansLoanIdTransactionsRequest().dateFormat(DATE_PATTERN) - .transactionDate("03 October 2022").locale("en").transactionAmount(1000.0)); + .transactionDate("03 October 2022").locale("en").transactionAmount(1000.0).externalId(loanTransactionExternalIdStr)); LocalDate targetDate = LocalDate.of(2022, 10, 10); final String penaltyCharge1AddedDate = dateFormatter.format(targetDate); @@ -202,6 +204,16 @@ public class LoanTransactionReverseReplayTest { lastPeriodIndex = loansLoanIdResponse.getRepaymentSchedule().getPeriods().size() - 1; assertEquals(LocalDate.of(2022, 10, 10), loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate()); + + businessDateHelper.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) + .date("11 October 2022").dateFormat(DATE_PATTERN).locale("en")); + loanTransactionHelper.chargebackLoanTransaction(loanExternalIdStr, loanTransactionExternalIdStr, + new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(100.0).paymentTypeId(1L)); + + loansLoanIdResponse = loanTransactionHelper.getLoanDetails(loanExternalIdStr); + lastPeriodIndex = loansLoanIdResponse.getRepaymentSchedule().getPeriods().size() - 1; + assertEquals(LocalDate.of(2022, 10, 11), + loansLoanIdResponse.getRepaymentSchedule().getPeriods().get(lastPeriodIndex).getDueDate()); } finally { GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE); }