You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2025/06/18 17:43:13 UTC
(fineract) 01/02: FINERACT-2181: Prevent Infinite Loop on MIR when last installment principal got updated to null
This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 74d079bc3d88b8d206507eac809f8203f2bfc10f
Author: Soma Sörös <so...@dpc.hu>
AuthorDate: Thu Jun 12 16:15:46 2025 +0200
FINERACT-2181: Prevent Infinite Loop on MIR when last installment principal got updated to null
---
...dvancedPaymentScheduleTransactionProcessor.java | 27 +++++++++++-----------
1 file changed, 14 insertions(+), 13 deletions(-)
diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
index 61eb53fc8f..d8d4bda2fe 100644
--- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
+++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java
@@ -1649,14 +1649,12 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
Money penaltyChargesPortion = Money.zero(transactionCtx.getCurrency());
if (transactionCtx.getInstallments().stream().anyMatch(this::isNotObligationsMet)) {
- if (loanTransaction.getLoan().isProgressiveSchedule()) {
- if (LoanChargeOffBehaviour.ZERO_INTEREST
- .equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
- handleZeroInterestChargeOff(loanTransaction, transactionCtx);
- } else if (LoanChargeOffBehaviour.ACCELERATE_MATURITY
- .equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
- handleAccelerateMaturityDate(loanTransaction, transactionCtx);
- }
+ if (LoanChargeOffBehaviour.ZERO_INTEREST
+ .equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
+ handleZeroInterestChargeOff(loanTransaction, transactionCtx);
+ } else if (LoanChargeOffBehaviour.ACCELERATE_MATURITY
+ .equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
+ handleAccelerateMaturityDate(loanTransaction, transactionCtx);
}
final BigDecimal newInterest = getInterestTillChargeOffForPeriod(loanTransaction.getLoan(),
@@ -1809,8 +1807,9 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
final BigDecimal interestOutstanding = installment.getInterestOutstanding(currency).getAmount();
final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(),
installment.getDueDate(), transactionDate, true).getAmount();
- if (interestOutstanding.compareTo(BigDecimal.ZERO) > 0 || newInterest.compareTo(BigDecimal.ZERO) > 0) {
- final BigDecimal interestRemoved = installment.getInterestCharged().subtract(newInterest);
+ if (MathUtil.isGreaterThanZero(interestOutstanding) || MathUtil.isGreaterThanZero(newInterest)) {
+ final BigDecimal interestRemoved = MathUtil.subtract(MathUtil.nullToZero(installment.getInterestCharged()),
+ newInterest);
installment.updatePrincipal(MathUtil.nullToZero(installment.getPrincipal()).add(interestRemoved));
installment.updateInterestCharged(newInterest);
}
@@ -1845,6 +1844,9 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
final BigDecimal installmentPrincipal = MathUtil.nullToZero(installment.getPrincipal());
installment.updatePrincipal(MathUtil.negativeToZero(installmentPrincipal.add(principalBalance)));
+ if (!installment.isObligationsMet()) {
+ installment.checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
+ }
if (MathUtil.isLessThanOrEqualTo(MathUtil.abs(principalBalance), installmentPrincipal)) {
principalBalance = BigDecimal.ZERO;
} else {
@@ -2215,10 +2217,9 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
paymentAllocationContext.setTransactionAmountUnprocessed(transactionAmountUnprocessed);
boolean interestBearingAndInterestRecalculationEnabled = loanTransaction.getLoan()
.isInterestBearingAndInterestRecalculationEnabled();
- boolean isProgressiveCtx = ctx instanceof ProgressiveTransactionCtx;
- if (isProgressiveCtx && interestBearingAndInterestRecalculationEnabled) {
- ProgressiveTransactionCtx progressiveTransactionCtx = (ProgressiveTransactionCtx) ctx;
+ if (interestBearingAndInterestRecalculationEnabled && ctx instanceof ProgressiveTransactionCtx progressiveTransactionCtx
+ && !progressiveTransactionCtx.isChargedOff() && !progressiveTransactionCtx.isContractTerminated()) {
// Clear any previously skipped installments before re-evaluating
progressiveTransactionCtx.getSkipRepaymentScheduleInstallments().clear();
paymentAllocationContext