FINERACT-2232: add income capitalization principal handling and repayment schedule calculations on loans

This commit is contained in:
mark.vituska
2025-05-27 18:35:39 +02:00
committed by Adam Saghy
parent c89ec910d8
commit aac62a92bb
38 changed files with 686 additions and 148 deletions
@@ -78,7 +78,7 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
transaction(100.0, "Disbursement", "01 January 2024"), //
transaction(50.0, "Capitalized Income", "01 January 2024"), //
transaction(0.55, "Capitalized Income Amortization", "01 January 2024"), //
transaction(0.02, "Accrual", "02 January 2024"), //
transaction(0.03, "Accrual", "02 January 2024"), //
transaction(0.55, "Capitalized Income Amortization", "02 January 2024") //
);
@@ -89,8 +89,8 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
journalEntry(50, deferredIncomeLiabilityAccount, "CREDIT"), //
journalEntry(0.55, deferredIncomeLiabilityAccount, "DEBIT"), //
journalEntry(0.55, feeIncomeAccount, "CREDIT"), //
journalEntry(0.02, interestReceivableAccount, "DEBIT"), //
journalEntry(0.02, interestIncomeAccount, "CREDIT"), //
journalEntry(0.03, interestReceivableAccount, "DEBIT"), //
journalEntry(0.03, interestIncomeAccount, "CREDIT"), //
journalEntry(0.55, deferredIncomeLiabilityAccount, "DEBIT"), //
journalEntry(0.55, feeIncomeAccount, "CREDIT") //
);
@@ -19,7 +19,9 @@
package org.apache.fineract.integrationtests;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
import org.apache.fineract.client.models.PostLoanProductsResponse;
import org.apache.fineract.client.models.PostLoansResponse;
@@ -248,4 +250,37 @@ public class LoanSummaryTest extends BaseLoanIntegrationTest {
});
}
@Test
public void testCapitalizedIncomeExistsInRepaymentScheduleAndModifiesPrincipal() {
runAt("01 March 2023", () -> {
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
.createLoanProduct(create4IProgressiveWithCapitalizedIncome());
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applyLP2ProgressiveLoanRequest(clientId,
loanProductsResponse.getResourceId(), "01 March 2023", 10000.00, 12.00, 4, null));
loanId = postLoansResponse.getLoanId();
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(10000.00, "01 March 2023"));
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 March 2023");
});
runAt("02 March 2023", () -> {
loanTransactionHelper.addCapitalizedIncome(loanId, "02 March 2023", 100.00);
});
BigDecimal thousand = BigDecimal.valueOf(1000.0);
BigDecimal hundred = BigDecimal.valueOf(100.0);
BigDecimal thousandOneHundred = BigDecimal.valueOf(1100.0);
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId);
Assertions.assertEquals(thousand, loanDetails.getPrincipal().setScale(1, RoundingMode.HALF_UP));
Assertions.assertEquals(thousand, loanDetails.getSummary().getPrincipalDisbursed().setScale(1, RoundingMode.HALF_UP));
Assertions.assertEquals(hundred, loanDetails.getSummary().getTotalCapitalizedIncome().setScale(1, RoundingMode.HALF_UP));
Assertions.assertEquals(thousandOneHundred, loanDetails.getSummary().getTotalPrincipal().setScale(1, RoundingMode.HALF_UP));
Assertions.assertEquals(thousandOneHundred, loanDetails.getSummary().getPrincipalOutstanding().setScale(1, RoundingMode.HALF_UP));
List<GetLoansLoanIdRepaymentPeriod> periods = loanDetails.getRepaymentSchedule().getPeriods();
Assertions.assertEquals(6, periods.size());
Assertions.assertEquals(thousand, periods.get(0).getPrincipalLoanBalanceOutstanding().setScale(1, RoundingMode.HALF_UP));
Assertions.assertEquals(hundred, periods.get(1).getPrincipalLoanBalanceOutstanding().setScale(1, RoundingMode.HALF_UP));
}
}