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 <[email protected]>
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);

Reply via email to