FINERACT-1981: Progressive Loan schedule handling - Installment charges

This commit is contained in:
mariiaKraievska
2025-07-08 23:22:50 +02:00
committed by Adam Saghy
parent f76a65ed99
commit d165a3feda
22 changed files with 2484 additions and 89 deletions
@@ -202,18 +202,6 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
final Long chargeDefinitionId = command.longValueOfParameterNamed("chargeId");
final Charge chargeDefinition = this.chargeRepository.findOneWithNotFoundDetection(chargeDefinitionId);
/*
* TODO: remove this check once handling for Installment fee charges is implemented for Advanced Payment
* strategy
*/
if (ChargeTimeType.fromInt(chargeDefinition.getChargeTimeType()).isInstalmentFee()
&& AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY
.equals(loan.transactionProcessingStrategy())) {
final String errorMessageInstallmentChargeNotSupported = "Charge with identifier " + chargeDefinition.getId()
+ " cannot be applied: Installment fee charges are not supported for Advanced payment allocation strategy";
throw new ChargeCannotBeAppliedToException("loan", errorMessageInstallmentChargeNotSupported, chargeDefinition.getId());
}
if (loan.isDisbursed() && chargeDefinition.isDisbursementCharge()) {
// validates whether any pending disbursements are available to
// apply this charge
@@ -1079,11 +1067,6 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
chargeDefinition.getName());
}
} else if (loan.isInterestBearingAndInterestRecalculationEnabled()) {
if (loanCharge.isInstalmentFee() && loan.getStatus().isActive()) {
final String defaultUserMessage = "installment charge addition not allowed after disbursement";
throw new LoanChargeCannotBeAddedException("loanCharge", "installment.charge", defaultUserMessage, null,
chargeDefinition.getName());
}
final List<ApiParameterError> dataValidationErrors = new ArrayList<>();
final Set<LoanCharge> loanCharges = new HashSet<>(1);
loanCharges.add(loanCharge);
@@ -36,6 +36,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.imp
import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.RBILoanRepaymentScheduleTransactionProcessor;
import org.apache.fineract.portfolio.loanaccount.serialization.LoanChargeValidator;
import org.apache.fineract.portfolio.loanaccount.service.LoanBalanceService;
import org.apache.fineract.portfolio.loanaccount.service.LoanChargeService;
import org.apache.fineract.portfolio.loanaccount.service.ProgressiveLoanInterestRefundServiceImpl;
import org.apache.fineract.portfolio.loanaccount.service.schedule.LoanScheduleComponent;
import org.apache.fineract.portfolio.loanproduct.calc.EMICalculator;
@@ -139,8 +140,8 @@ public class LoanAccountAutoStarter {
final @Lazy ProgressiveLoanInterestRefundServiceImpl progressiveLoanInterestRefundService,
final ExternalIdFactory externalIdFactory, final LoanScheduleComponent loanSchedule,
final LoanTransactionRepository loanTransactionRepository, final LoanChargeValidator loanChargeValidator,
final LoanBalanceService loanBalanceService) {
final LoanBalanceService loanBalanceService, @Lazy final LoanChargeService loanChargeService) {
return new AdvancedPaymentScheduleTransactionProcessor(emiCalculator, loanRepositoryWrapper, progressiveLoanInterestRefundService,
externalIdFactory, loanSchedule, loanTransactionRepository, loanChargeValidator, loanBalanceService);
externalIdFactory, loanSchedule, loanTransactionRepository, loanChargeValidator, loanBalanceService, loanChargeService);
}
}
@@ -199,7 +199,7 @@ class LoanChargeWritePlatformServiceImplTest {
when(loan.getDisbursementDate()).thenReturn(LocalDate.now(ZoneId.systemDefault()));
when(loan.getRepaymentScheduleInstallments()).thenReturn(new ArrayList<>());
when(loanChargeService.calculateAmountPercentageAppliedTo(any(Loan.class), any(LoanCharge.class))).thenReturn(BigDecimal.TEN);
when(loan.fetchNumberOfInstallmensAfterExceptions()).thenReturn(5);
when(loan.fetchNumberOfInstallmentsAfterExceptions()).thenReturn(5);
when(loan.updateSummaryWithTotalFeeChargesDueAtDisbursement(any(BigDecimal.class))).thenReturn(null);
when(loan.deriveSumTotalOfChargesDueAtDisbursement()).thenReturn(BigDecimal.ZERO);
when(loanCharge.getDueLocalDate()).thenReturn(LocalDate.now(ZoneId.systemDefault()));