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) {