FINERACT-2326: Capitalized Income transaction template considering over applied amount when enabled

This commit is contained in:
Jose Alberto Hernandez
2025-07-31 09:59:50 +02:00
committed by Adam Saghy
parent 59c98b7329
commit 54f055d9c7
7 changed files with 140 additions and 21 deletions
@@ -43,7 +43,6 @@ import org.apache.fineract.infrastructure.core.serialization.FromJsonHelper;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.infrastructure.core.service.MathUtil;
import org.apache.fineract.organisation.holiday.domain.Holiday;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.organisation.workingdays.domain.WorkingDays;
import org.apache.fineract.portfolio.common.service.Validator;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
@@ -61,7 +60,6 @@ import org.apache.fineract.portfolio.loanaccount.exception.LoanTransactionProces
import org.apache.fineract.portfolio.loanaccount.repository.LoanBuyDownFeeBalanceRepository;
import org.apache.fineract.portfolio.loanaccount.repository.LoanCapitalizedIncomeBalanceRepository;
import org.apache.fineract.portfolio.loanaccount.serialization.LoanTransactionValidator;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProduct;
@Slf4j
@RequiredArgsConstructor
@@ -73,6 +71,7 @@ public class ProgressiveLoanTransactionValidatorImpl implements ProgressiveLoanT
private final LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository;
private final LoanBuyDownFeeBalanceRepository loanBuydownFeeBalanceRepository;
private final LoanTransactionRepository loanTransactionRepository;
private final LoanMaximumAmountCalculator loanMaximumAmountCalculator;
@Override
public void validateCapitalizedIncome(final JsonCommand command, final Long loanId) {
@@ -137,7 +136,7 @@ public class ProgressiveLoanTransactionValidatorImpl implements ProgressiveLoanT
final BigDecimal newTotal = totalDisbursed.add(capitalizedIncome).add(transactionAmount);
if (loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
final BigDecimal maxAppliedAmount = getOverAppliedMax(loan);
final BigDecimal maxAppliedAmount = loanMaximumAmountCalculator.getOverAppliedMax(loan);
if (newTotal.compareTo(maxAppliedAmount) > 0) {
baseDataValidator.reset().parameter("transactionAmount").failWithCode("exceeds.approved.amount",
"Sum of disbursed amount and capitalized income can't be greater than maximum applied loan amount calculation.");
@@ -595,16 +594,4 @@ public class ProgressiveLoanTransactionValidatorImpl implements ProgressiveLoanT
return new HashSet<>(
Arrays.asList("transactionDate", "dateFormat", "locale", "transactionAmount", "paymentTypeId", "note", "externalId"));
}
private BigDecimal getOverAppliedMax(final Loan loan) {
final LoanProduct loanProduct = loan.getLoanProduct();
if ("percentage".equals(loanProduct.getOverAppliedCalculationType())) {
final BigDecimal overAppliedNumber = BigDecimal.valueOf(loanProduct.getOverAppliedNumber());
final BigDecimal totalPercentage = BigDecimal.valueOf(1)
.add(overAppliedNumber.divide(BigDecimal.valueOf(100L), MoneyHelper.getMathContext()));
return loan.getProposedPrincipal().multiply(totalPercentage);
} else {
return loan.getProposedPrincipal().add(BigDecimal.valueOf(loanProduct.getOverAppliedNumber()));
}
}
}
@@ -36,6 +36,7 @@ import org.apache.fineract.portfolio.loanaccount.service.CapitalizedIncomeWriteP
import org.apache.fineract.portfolio.loanaccount.service.LoanAssembler;
import org.apache.fineract.portfolio.loanaccount.service.LoanBalanceService;
import org.apache.fineract.portfolio.loanaccount.service.LoanJournalEntryPoster;
import org.apache.fineract.portfolio.loanaccount.service.LoanMaximumAmountCalculator;
import org.apache.fineract.portfolio.loanaccount.service.ProgressiveLoanTransactionValidator;
import org.apache.fineract.portfolio.loanaccount.service.ProgressiveLoanTransactionValidatorImpl;
import org.apache.fineract.portfolio.loanaccount.service.ReprocessLoanTransactionsService;
@@ -68,9 +69,11 @@ public class ProgressiveLoanAccountConfiguration {
public ProgressiveLoanTransactionValidator progressiveLoanTransactionValidator(FromJsonHelper fromApiJsonHelper,
LoanTransactionValidator loanTransactionValidator, LoanRepositoryWrapper loanRepositoryWrapper,
LoanCapitalizedIncomeBalanceRepository loanCapitalizedIncomeBalanceRepository,
LoanBuyDownFeeBalanceRepository loanBuydownFeeBalanceRepository, LoanTransactionRepository loanTransactionRepository) {
LoanBuyDownFeeBalanceRepository loanBuydownFeeBalanceRepository, LoanTransactionRepository loanTransactionRepository,
LoanMaximumAmountCalculator loanMaximumAmountCalculator) {
return new ProgressiveLoanTransactionValidatorImpl(fromApiJsonHelper, loanTransactionValidator, loanRepositoryWrapper,
loanCapitalizedIncomeBalanceRepository, loanBuydownFeeBalanceRepository, loanTransactionRepository);
loanCapitalizedIncomeBalanceRepository, loanBuydownFeeBalanceRepository, loanTransactionRepository,
loanMaximumAmountCalculator);
}
@Bean