FINERACT-2232: fix capitalized income balance handling during reverse replay situations
This commit is contained in:
+1
-3
@@ -104,9 +104,7 @@ public final class LoanRefundValidator {
|
||||
if (loan.getLoanProduct().isMultiDisburseLoan() && adjustedTransaction == null) {
|
||||
final BigDecimal totalDisbursed = loan.getDisbursedAmount();
|
||||
final BigDecimal totalPrincipalAdjusted = loan.getSummary().getTotalPrincipalAdjustments();
|
||||
final BigDecimal totalCapitalizedIncome = loan.getLoanTransactions(LoanTransaction::isCapitalizedIncome).stream()
|
||||
.filter(LoanTransaction::isNotReversed).map(LoanTransaction::getPrincipalPortion)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
final BigDecimal totalCapitalizedIncome = loan.getSummary().getTotalCapitalizedIncome();
|
||||
final BigDecimal totalPrincipalCredited = totalDisbursed.add(totalPrincipalAdjusted).add(totalCapitalizedIncome);
|
||||
if (totalPrincipalCredited.compareTo(loan.getSummary().getTotalPrincipalRepaid()) < 0) {
|
||||
final String errorMessage = "The transaction amount cannot exceed threshold.";
|
||||
|
||||
+1
-3
@@ -174,9 +174,7 @@ public class LoanDownPaymentHandlerServiceImpl implements LoanDownPaymentHandler
|
||||
if (loan.getLoanProduct().isMultiDisburseLoan()) {
|
||||
final BigDecimal totalDisbursed = loan.getDisbursedAmount();
|
||||
final BigDecimal totalPrincipalAdjusted = loan.getSummary().getTotalPrincipalAdjustments();
|
||||
final BigDecimal totalCapitalizedIncome = loan.getLoanTransactions(LoanTransaction::isCapitalizedIncome).stream()
|
||||
.filter(LoanTransaction::isNotReversed).map(LoanTransaction::getPrincipalPortion)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
final BigDecimal totalCapitalizedIncome = loan.getSummary().getTotalCapitalizedIncome();
|
||||
final BigDecimal totalPrincipalCredited = totalDisbursed.add(totalPrincipalAdjusted).add(totalCapitalizedIncome);
|
||||
if (totalPrincipalCredited.compareTo(loan.getSummary().getTotalPrincipalRepaid()) < 0
|
||||
&& loan.getLoanProductRelatedDetail().getPrincipal().minus(totalDisbursed).isGreaterThanZero()) {
|
||||
|
||||
+74
@@ -21,6 +21,7 @@ package org.apache.fineract.integrationtests;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||
@@ -30,6 +31,7 @@ import org.apache.fineract.client.models.PostLoanProductsRequest;
|
||||
import org.apache.fineract.client.models.PostLoanProductsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest;
|
||||
import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
|
||||
import org.apache.fineract.client.models.PostLoansResponse;
|
||||
import org.apache.fineract.client.util.CallFailedRuntimeException;
|
||||
import org.apache.fineract.integrationtests.common.BusinessStepHelper;
|
||||
import org.apache.fineract.integrationtests.common.ClientHelper;
|
||||
@@ -683,4 +685,76 @@ public class LoanCapitalizedIncomeTest extends BaseLoanIntegrationTest {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testOverpaymentAmountWhenCapitalizedIncomeTransactionsAreReversed() {
|
||||
final AtomicReference<Long> loanIdRef = new AtomicReference<>();
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
runAt("01 March 2023", () -> {
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
|
||||
.createLoanProduct(create4IProgressiveWithCapitalizedIncome());
|
||||
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applyLP2ProgressiveLoanRequest(client.getClientId(),
|
||||
loanProductsResponse.getResourceId(), "01 March 2023", 10000.00, 12.00, 4, null));
|
||||
Long loanId = postLoansResponse.getLoanId();
|
||||
loanIdRef.set(loanId);
|
||||
|
||||
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(10000.00, "01 March 2023"));
|
||||
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 March 2023");
|
||||
|
||||
loanTransactionHelper.addCapitalizedIncome(loanId, "01 March 2023", 500.00);
|
||||
PostLoansLoanIdTransactionsResponse transactionsResponse = loanTransactionHelper.addCapitalizedIncome(loanId, "01 March 2023",
|
||||
500.00);
|
||||
|
||||
loanTransactionHelper.makeLoanRepayment(loanId, "Repayment", "1 March 2023", 2000.00);
|
||||
loanTransactionHelper.reverseLoanTransaction(loanId, transactionsResponse.getResourceId(), "1 March 2023");
|
||||
});
|
||||
|
||||
BigDecimal zero = BigDecimal.ZERO;
|
||||
BigDecimal thousand = BigDecimal.valueOf(1000.0);
|
||||
BigDecimal fiveHundred = BigDecimal.valueOf(500.0);
|
||||
BigDecimal thousandFiveHundred = BigDecimal.valueOf(1500.0);
|
||||
|
||||
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanIdRef.get());
|
||||
Assertions.assertEquals(thousand, loanDetails.getPrincipal().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousand, loanDetails.getSummary().getPrincipalDisbursed().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(fiveHundred, loanDetails.getSummary().getTotalCapitalizedIncome().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousandFiveHundred, loanDetails.getSummary().getTotalPrincipal().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(zero, loanDetails.getSummary().getPrincipalOutstanding().setScale(0, RoundingMode.HALF_UP));
|
||||
|
||||
Assertions.assertEquals(fiveHundred, loanDetails.getTotalOverpaid().setScale(1, RoundingMode.HALF_UP));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOverpaymentAmountCorrectlyCalculatedWhenBackdatedRepaymentIsMade() {
|
||||
final AtomicReference<Long> loanIdRef = new AtomicReference<>();
|
||||
final PostClientsResponse client = clientHelper.createClient(ClientHelper.defaultClientCreationRequest());
|
||||
runAt("01 March 2023", () -> {
|
||||
final PostLoanProductsResponse loanProductsResponse = loanProductHelper
|
||||
.createLoanProduct(create4IProgressiveWithCapitalizedIncome());
|
||||
PostLoansResponse postLoansResponse = loanTransactionHelper.applyLoan(applyLP2ProgressiveLoanRequest(client.getClientId(),
|
||||
loanProductsResponse.getResourceId(), "01 March 2023", 10000.00, 12.00, 4, null));
|
||||
Long loanId = postLoansResponse.getLoanId();
|
||||
loanIdRef.set(loanId);
|
||||
|
||||
loanTransactionHelper.approveLoan(loanId, approveLoanRequest(10000.00, "01 March 2023"));
|
||||
disburseLoan(loanId, BigDecimal.valueOf(1000.00), "01 March 2023");
|
||||
});
|
||||
|
||||
runAt("15 March 2023", () -> {
|
||||
loanTransactionHelper.addCapitalizedIncome(loanIdRef.get(), "15 March 2023", 500.00);
|
||||
loanTransactionHelper.makeLoanRepayment(loanIdRef.get(), "Repayment", "1 March 2023", 1500.00);
|
||||
});
|
||||
|
||||
BigDecimal zero = BigDecimal.ZERO;
|
||||
BigDecimal thousand = BigDecimal.valueOf(1000.0);
|
||||
BigDecimal fiveHundred = BigDecimal.valueOf(500.0);
|
||||
BigDecimal thousandFiveHundred = BigDecimal.valueOf(1500.0);
|
||||
|
||||
GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanIdRef.get());
|
||||
Assertions.assertEquals(thousand, loanDetails.getPrincipal().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousand, loanDetails.getSummary().getPrincipalDisbursed().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(fiveHundred, loanDetails.getSummary().getTotalCapitalizedIncome().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(thousandFiveHundred, loanDetails.getSummary().getTotalPrincipal().setScale(1, RoundingMode.HALF_UP));
|
||||
Assertions.assertEquals(zero, loanDetails.getSummary().getPrincipalOutstanding().setScale(0, RoundingMode.HALF_UP));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user