FINERACT-2308: Allow approval and disbursal above loan applied amount with non multibursal loan product

This commit is contained in:
Jose Alberto Hernandez
2025-06-18 15:15:28 +02:00
committed by Adam Saghy
parent 38a5686df8
commit bb29932658
5 changed files with 82 additions and 20 deletions
@@ -2124,7 +2124,7 @@ public final class LoanApplicationValidator {
}
private void compareApprovedToProposedPrincipal(Loan loan, BigDecimal approvedLoanAmount) {
if (loan.loanProduct().isDisallowExpectedDisbursements() && loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
if (loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
BigDecimal maxApprovedLoanAmount = getOverAppliedMax(loan);
if (approvedLoanAmount.compareTo(maxApprovedLoanAmount) > 0) {
final String errorMessage = "Loan approved amount can't be greater than maximum applied loan amount calculation.";
@@ -37,26 +37,34 @@ public final class LoanDisbursementValidator {
final BigDecimal totalDisbursed) {
final BigDecimal capitalizedIncome = loan.getSummary().getTotalCapitalizedIncome();
if (loan.loanProduct().isDisallowExpectedDisbursements() && loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
final BigDecimal maxDisbursedAmount = loanApplicationValidator.getOverAppliedMax(loan);
if (totalDisbursed.add(capitalizedIncome).compareTo(maxDisbursedAmount) > 0) {
final String errorMessage = String.format(
"Loan disbursal amount can't be greater than maximum applied loan amount calculation. "
+ "Total disbursed amount: %s Maximum disbursal amount: %s",
totalDisbursed.stripTrailingZeros().toPlainString(), maxDisbursedAmount.stripTrailingZeros().toPlainString());
throw new InvalidLoanStateTransitionException("disbursal",
"amount.can't.be.greater.than.maximum.applied.loan.amount.calculation", errorMessage, disbursedAmount,
maxDisbursedAmount);
}
validateOverMaximumAmount(loan, totalDisbursed, capitalizedIncome);
} else {
if ((totalDisbursed.compareTo(loan.getApprovedPrincipal()) > 0)
|| (totalDisbursed.add(capitalizedIncome).compareTo(loan.getApprovedPrincipal()) > 0)) {
final String errorMsg = "Loan can't be disbursed,disburse amount is exceeding approved principal ";
throw new LoanDisbursalException(errorMsg, "disburse.amount.must.be.less.than.approved.principal", totalDisbursed,
loan.getApprovedPrincipal());
if (loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
validateOverMaximumAmount(loan, disbursedAmount, capitalizedIncome);
} else {
if ((totalDisbursed.compareTo(loan.getApprovedPrincipal()) > 0)
|| (totalDisbursed.add(capitalizedIncome).compareTo(loan.getApprovedPrincipal()) > 0)) {
final String errorMsg = "Loan can't be disbursed,disburse amount is exceeding approved principal ";
throw new LoanDisbursalException(errorMsg, "disburse.amount.must.be.less.than.approved.principal", totalDisbursed,
loan.getApprovedPrincipal());
}
}
}
}
public void validateOverMaximumAmount(final Loan loan, final BigDecimal totalDisbursed, final BigDecimal capitalizedIncome) {
final BigDecimal maxDisbursedAmount = loanApplicationValidator.getOverAppliedMax(loan);
if (totalDisbursed.add(capitalizedIncome).compareTo(maxDisbursedAmount) > 0) {
final String errorMessage = String.format(
"Loan disbursal amount can't be greater than maximum applied loan amount calculation. "
+ "Total disbursed amount: %s Maximum disbursal amount: %s",
totalDisbursed.stripTrailingZeros().toPlainString(), maxDisbursedAmount.stripTrailingZeros().toPlainString());
throw new InvalidLoanStateTransitionException("disbursal",
"amount.can't.be.greater.than.maximum.applied.loan.amount.calculation", errorMessage, totalDisbursed,
maxDisbursedAmount);
}
}
public void validateDisburseAmountNotExceedingApprovedAmount(final Loan loan, final BigDecimal diff,
final BigDecimal principalDisbursed) {
if (!loan.loanProduct().isMultiDisburseLoan() && diff.compareTo(BigDecimal.ZERO) < 0) {
@@ -146,10 +146,10 @@ public class LoanDisbursementService {
disbursementDetails.updatePrincipal(principalDisbursed);
}
}
BigDecimal totalAmount = BigDecimal.ZERO;
if (loan.loanProduct().isMultiDisburseLoan()) {
Collection<LoanDisbursementDetails> loanDisburseDetails = loan.getDisbursementDetails();
BigDecimal setPrincipalAmount = BigDecimal.ZERO;
BigDecimal totalAmount = BigDecimal.ZERO;
for (LoanDisbursementDetails disbursementDetails : loanDisburseDetails) {
if (disbursementDetails.actualDisbursementDate() != null) {
setPrincipalAmount = setPrincipalAmount.add(disbursementDetails.principal());
@@ -157,12 +157,11 @@ public class LoanDisbursementService {
totalAmount = totalAmount.add(disbursementDetails.principal());
}
loan.getLoanRepaymentScheduleDetail().setPrincipal(setPrincipalAmount);
loanDisbursementValidator.compareDisbursedToApprovedOrProposedPrincipal(loan, disburseAmount.getAmount(), totalAmount);
} else {
loan.getLoanRepaymentScheduleDetail()
.setPrincipal(loan.getLoanRepaymentScheduleDetail().getPrincipal().minus(diff).getAmount());
}
loanDisbursementValidator.validateDisburseAmountNotExceedingApprovedAmount(loan, diff, principalDisbursed);
loanDisbursementValidator.compareDisbursedToApprovedOrProposedPrincipal(loan, disburseAmount.getAmount(), totalAmount);
}
return disburseAmount;
}