This is an automated email from the ASF dual-hosted git repository.
arnold 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 2f38d284d FINERACT-1968: Fix when multiple disbursement happens on the
1st day of the loan
2f38d284d is described below
commit 2f38d284df59ec441852f8297048408cdd781e71
Author: Adam Saghy <[email protected]>
AuthorDate: Tue Jan 2 21:53:23 2024 +0100
FINERACT-1968: Fix when multiple disbursement happens on the 1st day of the
loan
---
.../AbstractProgressiveLoanScheduleGenerator.java | 11 +++--
...PaymentAllocationLoanRepaymentScheduleTest.java | 57 ++++++++++++++++++++++
...hAdvancedPaymentAllocationIntegrationTests.java | 14 +++---
3 files changed, 70 insertions(+), 12 deletions(-)
diff --git
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
index a5738aec0..98d75ffc7 100644
---
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
+++
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractProgressiveLoanScheduleGenerator.java
@@ -77,7 +77,8 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
: loanApplicationTerms.getSubmittedOnDate();
LoanScheduleParams scheduleParams =
LoanScheduleParams.createLoanScheduleParams(currency,
- Money.of(currency, chargesDueAtTimeOfDisbursement),
periodStartDate, getPrincipalToBeScheduled(loanApplicationTerms));
+ Money.of(currency, chargesDueAtTimeOfDisbursement),
periodStartDate,
+ getPrincipalToBeScheduled(loanApplicationTerms,
periodStartDate));
List<LoanScheduleModelPeriod> periods =
createNewLoanScheduleListWithDisbursementDetails(loanApplicationTerms,
scheduleParams,
chargesDueAtTimeOfDisbursement);
@@ -233,12 +234,14 @@ public abstract class
AbstractProgressiveLoanScheduleGenerator implements LoanSc
/**
* this method calculates the principal amount for generating the
repayment schedule.
*/
- private Money getPrincipalToBeScheduled(final LoanApplicationTerms
loanApplicationTerms) {
+ private Money getPrincipalToBeScheduled(final LoanApplicationTerms
loanApplicationTerms, LocalDate periodStartDate) {
Money principalToBeScheduled;
if (loanApplicationTerms.isMultiDisburseLoan()) {
if
(loanApplicationTerms.getTotalDisbursedAmount().isGreaterThanZero()) {
- principalToBeScheduled =
Money.of(loanApplicationTerms.getCurrency(),
-
loanApplicationTerms.getDisbursementDatas().get(0).getPrincipal());
+ BigDecimal totalDisbursalAmountsOnThe =
loanApplicationTerms.getDisbursementDatas().stream()
+ .filter(d ->
d.getActualDisbursementDate().equals(periodStartDate)).map(DisbursementData::getPrincipal)
+ .reduce(BigDecimal.ZERO, BigDecimal::add);
+ principalToBeScheduled =
Money.of(loanApplicationTerms.getCurrency(), totalDisbursalAmountsOnThe);
} else if
(loanApplicationTerms.getApprovedPrincipal().isGreaterThanZero()) {
principalToBeScheduled =
loanApplicationTerms.getApprovedPrincipal();
} else {
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 dcf631239..380da4921 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
@@ -3033,6 +3033,63 @@ public class
AdvancedPaymentAllocationLoanRepaymentScheduleTest extends BaseLoan
});
}
+ // UC120: Advanced payment allocation with auto down payment and multiple
disbursement on the first day
+ // ADVANCED_PAYMENT_ALLOCATION_STRATEGY
+ // 1. Create a Loan product with Adv. Pment. Alloc., and auto down payment
+ // 2. Submit Loan and approve
+ // 3. Disburse only 100 from 1000
+ // 4. Disburse again on the same day but now 901
+ @Test
+ public void uc120() {
+ runAt("22 November 2023", () -> {
+ final Account assetAccount = accountHelper.createAssetAccount();
+ final Account incomeAccount = accountHelper.createIncomeAccount();
+ final Account expenseAccount =
accountHelper.createExpenseAccount();
+ final Account overpaymentAccount =
accountHelper.createLiabilityAccount();
+ Integer localLoanProductId = createLoanProduct("1000", "15", "3",
true, "25", true, LoanScheduleType.PROGRESSIVE,
+ LoanScheduleProcessingType.HORIZONTAL, assetAccount,
incomeAccount, expenseAccount, overpaymentAccount);
+ final PostLoansResponse loanResponse =
applyForLoanApplication(client.getClientId(), localLoanProductId,
+ BigDecimal.valueOf(1000.0), 45, 15, 3, BigDecimal.ZERO,
"22 November 2023", "01 January 2023");
+
+ loanTransactionHelper.approveLoan(loanResponse.getLoanId(),
+ new
PostLoansLoanIdRequest().approvedLoanAmount(BigDecimal.valueOf(1000)).dateFormat(DATETIME_PATTERN)
+ .approvedOnDate("22 November 2023").locale("en"));
+
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("22
November 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(100.0)).locale("en"));
+
+ GetLoansLoanIdResponse loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 75.0, 25.0, 75.0, 25.0,
null);
+ validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 11,
22), 25.0, 25.0, 0.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 2, LocalDate.of(2023, 12, 7),
25.0, 0.0, 25.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 12,
22), 25.0, 0.0, 25.0, 0.0, 0.0);
+ validateRepaymentPeriod(loanDetails, 4, LocalDate.of(2024, 1, 6),
25.0, 0.0, 25.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ loanTransactionHelper.disburseLoan(loanResponse.getLoanId(),
+ new PostLoansLoanIdRequest().actualDisbursementDate("22
November 2023").dateFormat(DATETIME_PATTERN)
+
.transactionAmount(BigDecimal.valueOf(901.0)).locale("en"));
+ loanDetails =
loanTransactionHelper.getLoanDetails(loanResponse.getLoanId());
+ validateLoanSummaryBalances(loanDetails, 750.75, 250.25, 750.75,
250.25, null);
+ validatePeriod(loanDetails, 0, LocalDate.of(2023, 11, 22), null,
100.0, null, null, null, 0.0, 0.0, null, null, null, null,
+ null, null, null, null, null);
+ validatePeriod(loanDetails, 1, LocalDate.of(2023, 11, 22), null,
901.0, null, null, null, 0.0, 0.0, null, null, null, null,
+ null, null, null, null, null);
+ validatePeriod(loanDetails, 2, LocalDate.of(2023, 11, 22),
LocalDate.of(2023, 11, 22), 976.0, 25.0, 25.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 3, LocalDate.of(2023, 11, 22),
LocalDate.of(2023, 11, 22), 750.75, 225.25, 225.25, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 4, LocalDate.of(2023, 12, 7), null,
500.50, 250.25, 0.0, 250.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 5, LocalDate.of(2023, 12, 22), null,
250.25, 250.25, 0.0, 250.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0, 0.0);
+ validatePeriod(loanDetails, 6, LocalDate.of(2024, 1, 6), null,
0.0, 250.25, 0.0, 250.25, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+ assertTrue(loanDetails.getStatus().getActive());
+ });
+ }
+
private static void validateLoanSummaryBalances(GetLoansLoanIdResponse
loanDetails, Double totalOutstanding, Double totalRepayment,
Double principalOutstanding, Double principalPaid, Double
totalOverpaid) {
assertEquals(totalOutstanding,
loanDetails.getSummary().getTotalOutstanding());
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
index 371cf9e92..2d57ea6fa 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWithAdvancedPaymentAllocationIntegrationTests.java
@@ -57,8 +57,6 @@ import org.junit.jupiter.api.extension.ExtendWith;
public class LoanWithAdvancedPaymentAllocationIntegrationTests {
private static ClientHelper CLIENT_HELPER;
- private static ResponseSpecification RESPONSE_SPEC;
- private static RequestSpecification REQUEST_SPEC;
private static Account ASSET_ACCOUNT;
private static Account FEE_PENALTY_ACCOUNT;
private static Account EXPENSE_ACCOUNT;
@@ -69,12 +67,12 @@ public class
LoanWithAdvancedPaymentAllocationIntegrationTests {
@BeforeAll
public static void setupTests() {
Utils.initializeRESTAssured();
- REQUEST_SPEC = new
RequestSpecBuilder().setContentType(ContentType.JSON).build();
- REQUEST_SPEC.header("Authorization", "Basic " +
Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
- RESPONSE_SPEC = new
ResponseSpecBuilder().expectStatusCode(200).build();
- AccountHelper accountHelper = new AccountHelper(REQUEST_SPEC,
RESPONSE_SPEC);
- LOAN_TRANSACTION_HELPER = new LoanTransactionHelper(REQUEST_SPEC,
RESPONSE_SPEC);
- CLIENT_HELPER = new ClientHelper(REQUEST_SPEC, RESPONSE_SPEC);
+ RequestSpecification requestSpec = new
RequestSpecBuilder().setContentType(ContentType.JSON).build();
+ requestSpec.header("Authorization", "Basic " +
Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
+ ResponseSpecification responseSpec = new
ResponseSpecBuilder().expectStatusCode(200).build();
+ AccountHelper accountHelper = new AccountHelper(requestSpec,
responseSpec);
+ LOAN_TRANSACTION_HELPER = new LoanTransactionHelper(requestSpec,
responseSpec);
+ CLIENT_HELPER = new ClientHelper(requestSpec, responseSpec);
ASSET_ACCOUNT = accountHelper.createAssetAccount();
FEE_PENALTY_ACCOUNT = accountHelper.createAssetAccount();