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 ea55ddac1 FINERACT-1968: Fix repayment schedule reprocessing for N+1 
situations
ea55ddac1 is described below

commit ea55ddac13e3b3e2568f71bb8570442849a01b99
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Oct 31 13:50:54 2023 +0100

    FINERACT-1968: Fix repayment schedule reprocessing for N+1 situations
---
 ...dvancedPaymentScheduleTransactionProcessor.java |  5 +--
 ...PaymentAllocationLoanRepaymentScheduleTest.java | 40 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 2 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
index 7ab5a8a91..aeca0d77d 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
@@ -205,8 +205,9 @@ public class AdvancedPaymentScheduleTransactionProcessor 
extends AbstractLoanRep
     private void updateLoanSchedule(LoanTransaction disbursementTransaction, 
MonetaryCurrency currency,
             List<LoanRepaymentScheduleInstallment> installments) {
         final MathContext mc = MoneyHelper.getMathContext();
-        List<LoanRepaymentScheduleInstallment> candidateRepaymentInstallments 
= installments.stream()
-                .filter(i -> 
!i.getDueDate().isBefore(disbursementTransaction.getTransactionDate()) && 
!i.isDownPayment()).toList();
+        List<LoanRepaymentScheduleInstallment> candidateRepaymentInstallments 
= installments.stream().filter(
+                i -> 
!i.getDueDate().isBefore(disbursementTransaction.getTransactionDate()) && 
!i.isDownPayment() && !i.isAdditional())
+                .toList();
         int noCandidateRepaymentInstallments = 
candidateRepaymentInstallments.size();
         LoanProductRelatedDetail loanProductRelatedDetail = 
disbursementTransaction.getLoan().getLoanRepaymentScheduleDetail();
         Integer installmentAmountInMultiplesOf = 
disbursementTransaction.getLoan().getLoanProduct().getInstallmentAmountInMultiplesOf();
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
index a5deb6d74..c177431ec 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
@@ -19,6 +19,7 @@
 package org.apache.fineract.integrationtests;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import io.restassured.builder.RequestSpecBuilder;
@@ -49,6 +50,7 @@ import 
org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
 import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.accounting.Account;
 import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
+import org.apache.fineract.integrationtests.common.charges.ChargesHelper;
 import 
org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder;
 import 
org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension;
 import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper;
@@ -1774,6 +1776,22 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
             validateRepaymentPeriod(loanDetails, 5, 250.0, 0.0, 250.0, 0.0, 
0.0);
             assertTrue(loanDetails.getStatus().getActive());
 
+            // Add Charge Penalty
+            Integer penalty = ChargesHelper.createCharges(requestSpec, 
responseSpec,
+                    
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
 "100", true));
+            Integer penalty1LoanChargeId = 
loanTransactionHelper.addChargesForLoan(loanResponse.getLoanId().intValue(),
+                    
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
 "22 February 2023", "100"));
+            assertNotNull(penalty1LoanChargeId);
+
+            loanDetails = 
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+            validateLoanSummaryBalances(loanDetails, 925.0, 175.0, 825.0, 
175.0, null);
+            validateRepaymentPeriod(loanDetails, 1, 125.0, 125.0, 0.0, 0.0, 
125.0);
+            validateRepaymentPeriod(loanDetails, 2, 125.0, 0.0, 125.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 3, 250.0, 50.0, 200.0, 50.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 4, 250.0, 0.0, 250.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 5, 250.0, 0.0, 250.0, 0.0, 
0.0);
+            validateRepaymentPeriod(loanDetails, 6, 0.0, 0.0, 0.0, 0.0, 0.0, 
0.0, 100.0, 0.0, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+            assertTrue(loanDetails.getStatus().getActive());
         } finally {
             GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.FALSE);
         }
@@ -1860,6 +1878,28 @@ public class 
AdvancedPaymentAllocationLoanRepaymentScheduleTest {
         assertEquals(paidLate, period.getTotalPaidLateForPeriod());
     }
 
+    private static void validateRepaymentPeriod(GetLoansLoanIdResponse 
loanDetails, Integer index, double principalDue,
+            double principalPaid, double principalOutstanding, double feeDue, 
double feePaid, double feeOutstanding, double penaltyDue,
+            double penaltyPaid, double penaltyOutstanding, double interestDue, 
double interestPaid, double interestOutstanding,
+            double paidInAdvance, double paidLate) {
+        GetLoansLoanIdRepaymentPeriod period = 
loanDetails.getRepaymentSchedule().getPeriods().stream()
+                .filter(p -> Objects.equals(p.getPeriod(), 
index)).findFirst().orElseThrow();
+        assertEquals(principalDue, period.getPrincipalDue());
+        assertEquals(principalPaid, period.getPrincipalPaid());
+        assertEquals(principalOutstanding, period.getPrincipalOutstanding());
+        assertEquals(feeDue, period.getFeeChargesDue());
+        assertEquals(feePaid, period.getFeeChargesPaid());
+        assertEquals(feeOutstanding, period.getFeeChargesOutstanding());
+        assertEquals(penaltyDue, period.getPenaltyChargesDue());
+        assertEquals(penaltyPaid, period.getPenaltyChargesPaid());
+        assertEquals(penaltyOutstanding, 
period.getPenaltyChargesOutstanding());
+        assertEquals(interestDue, period.getInterestDue());
+        assertEquals(interestPaid, period.getInterestPaid());
+        assertEquals(interestOutstanding, period.getInterestOutstanding());
+        assertEquals(paidInAdvance, period.getTotalPaidInAdvanceForPeriod());
+        assertEquals(paidLate, period.getTotalPaidLateForPeriod());
+    }
+
     private static PostLoansResponse applyForLoanApplication(final Long 
clientId, final Integer loanProductId, final Long principal,
             final int loanTermFrequency, final int repaymentAfterEvery, final 
int numberOfRepayments, final int interestRate,
             final String expectedDisbursementDate, final String 
submittedOnDate) {

Reply via email to