You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2024/05/13 08:50:14 UTC

(fineract) branch develop updated: FINERACT-1971: Enhancing re-Amortization validation

This is an automated email from the ASF dual-hosted git repository.

adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new bcf04b7e6 FINERACT-1971: Enhancing re-Amortization validation
bcf04b7e6 is described below

commit bcf04b7e6f9e5030f830daed57c2aa4c7c188160
Author: Ruchi Dhamankar <ru...@gmail.com>
AuthorDate: Fri May 10 19:48:01 2024 +0530

    FINERACT-1971: Enhancing re-Amortization validation
---
 .../LoanReAmortizationValidator.java               |  4 +-
 .../integrationtests/BaseLoanIntegrationTest.java  |  4 +
 .../LoanReAmortizationIntegrationTest.java         | 99 ++++++++++++++++++++++
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
index b530714c1..28087f74a 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/reamortization/LoanReAmortizationValidator.java
@@ -114,8 +114,8 @@ public class LoanReAmortizationValidator {
         }
 
         // validate if there's no payment between the reamortization and today
-        boolean repaymentExistsAfterReAmortization = loan.getLoanTransactions().stream()
-                .anyMatch(tx -> tx.getTypeOf().isRepaymentType() && transactionHappenedAfterOther(tx, optionalReAmortizationTx.get()));
+        boolean repaymentExistsAfterReAmortization = loan.getLoanTransactions().stream().anyMatch(tx -> tx.getTypeOf().isRepaymentType()
+                && !tx.isReversed() && transactionHappenedAfterOther(tx, optionalReAmortizationTx.get()));
         if (repaymentExistsAfterReAmortization) {
             throw new GeneralPlatformDomainRuleException("error.msg.loan.reamortize.repayment.exists.after.reamortization",
                     "Undoing a reamortization can only be done if there hasn't been any repayment afterwards", loan.getId());
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
index 6b56a36b6..800474ada 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
@@ -481,6 +481,10 @@ public abstract class BaseLoanIntegrationTest {
         loanTransactionHelper.undoDisbursal(loanId);
     }
 
+    protected void undoLastDisbursement(Long loanId) {
+        loanTransactionHelper.undoLastDisbursalLoan(loanId, new PostLoansLoanIdRequest());
+    }
+
     protected void verifyJournalEntries(Long loanId, Journal... entries) {
         GetJournalEntriesTransactionIdResponse journalEntriesForLoan = journalEntryHelper.getJournalEntriesForLoan(loanId);
         Assertions.assertEquals(entries.length, journalEntriesForLoan.getPageItems().size());
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java
index fb555ad4a..c1f81ab17 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/loan/reamortization/LoanReAmortizationIntegrationTest.java
@@ -797,6 +797,105 @@ public class LoanReAmortizationIntegrationTest extends BaseLoanIntegrationTest {
         });
     }
 
+    @Test
+    public void undoReAmortizationAfterSecondDownPaymentWhenDisbursementIsReversedTest() {
+
+        runAt("01 January 2023", () -> {
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            Long loanProductId = createLoanProductWithMultiDisbursalAndRepaymentsWithEnableDownPayment(3, 15);
+
+            loanId.set(applyAndApproveLoan(clientId, loanProductId, "01 January 2023", 1000.0, 3, req -> {
+                req.setRepaymentEvery(15);
+                req.setLoanTermFrequency(45);
+                req.setTransactionProcessingStrategyCode("advanced-payment-allocation-strategy");
+                req.setLoanScheduleProcessingType(LoanScheduleType.PROGRESSIVE.toString());
+                req.setLoanScheduleProcessingType(LoanScheduleProcessingType.HORIZONTAL.toString());
+            }));
+
+            disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "01 January 2023");
+
+            verifyRepaymentSchedule(loanId.get(), //
+                    installment(500, null, "01 January 2023"), //
+                    installment(125.0, true, "01 January 2023"), //
+                    installment(125.0, false, "16 January 2023"), //
+                    installment(125.0, false, "31 January 2023"), //
+                    installment(125.0, false, "15 February 2023") //
+            );
+        });
+        runAt("25 January 2023", () -> {
+
+            reAmortizeLoan(loanId.get());
+
+            verifyRepaymentSchedule(loanId.get(), //
+                    installment(500, null, "01 January 2023"), //
+                    installment(125.0, true, "01 January 2023"), //
+                    installment(0.0, true, "16 January 2023"), //
+                    installment(187.5, false, "31 January 2023"), //
+                    installment(187.5, false, "15 February 2023") //
+            );
+
+            // verify transactions
+            verifyTransactions(loanId.get(), //
+                    transaction(500.0, "Disbursement", "01 January 2023"), //
+                    transaction(125.0, "Down Payment", "01 January 2023"), //
+                    transaction(125.0, "Re-amortize", "25 January 2023") //
+            );
+        });
+        runAt("26 January 2023", () -> {
+            disburseLoan(loanId.get(), BigDecimal.valueOf(500.00), "26 January 2023");
+
+            verifyRepaymentSchedule(loanId.get(), //
+                    installment(500, null, "01 January 2023"), //
+                    installment(125.0, true, "01 January 2023"), //
+                    installment(0.0, true, "16 January 2023"), //
+                    installment(500.0, null, "26 January 2023"), //
+                    installment(125.0, true, "26 January 2023"), //
+                    installment(375.0, false, "31 January 2023"), //
+                    installment(375.0, false, "15 February 2023") //
+            );
+
+            // verify transactions
+            verifyTransactions(loanId.get(), //
+                    transaction(500.0, "Disbursement", "01 January 2023"), //
+                    transaction(125.0, "Down Payment", "01 January 2023"), //
+                    transaction(125.0, "Re-amortize", "25 January 2023"), //
+                    transaction(500.0, "Disbursement", "26 January 2023"), //
+                    transaction(125.0, "Down Payment", "26 January 2023") //
+            );
+
+            // undo second disbursal
+            undoLastDisbursement(loanId.get());
+
+            verifyRepaymentSchedule(loanId.get(), //
+                    installment(500, null, "01 January 2023"), //
+                    installment(125.0, true, "01 January 2023"), //
+                    installment(0.0, true, "16 January 2023"), //
+                    installment(187.5, false, "31 January 2023"), //
+                    installment(187.5, false, "15 February 2023") //
+            );
+
+            // verify transactions
+            verifyTransactions(loanId.get(), //
+                    transaction(500.0, "Disbursement", "01 January 2023"), //
+                    transaction(125.0, "Down Payment", "01 January 2023"), //
+                    transaction(125.0, "Re-amortize", "25 January 2023") //
+            );
+
+            // undo re-Amortization
+            undoReAmortizeLoan(loanId.get());
+
+            verifyRepaymentSchedule(loanId.get(), //
+                    installment(500, null, "01 January 2023"), //
+                    installment(125.0, true, "01 January 2023"), //
+                    installment(125.0, false, "16 January 2023"), //
+                    installment(125.0, false, "31 January 2023"), //
+                    installment(125.0, false, "15 February 2023") //
+            );
+
+        });
+
+    }
+
     private Long createLoanProductWithMultiDisbursalAndRepaymentsWithEnableDownPayment(int numberOfInstallments, int repaymentEvery) {
         return createLoanProductWithMultiDisbursalAndRepaymentsWithEnableDownPayment(numberOfInstallments, repaymentEvery,
                 DOWN_PAYMENT_PERCENTAGE);