You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@fineract.apache.org by "Ashhar Ahmad Khan (Jira)" <ji...@apache.org> on 2026/09/03 11:41:00 UTC

[jira] [Created] (FINERACT-2802) Progressive Loan charge-off crashes with NoSuchElementException for loans with an "additional" installment

Ashhar Ahmad Khan created FINERACT-2802:
-------------------------------------------

             Summary: Progressive Loan charge-off crashes with NoSuchElementException for loans with an "additional" installment
                 Key: FINERACT-2802
                 URL: https://issues.apache.org/jira/browse/FINERACT-2802
             Project: Apache Fineract
          Issue Type: Bug
            Reporter: Ashhar Ahmad Khan


*What is broken*
A charge-off on a progressive, interest-recalculation-enabled loan crashes with an unwrapped {{NoSuchElementException}} when the loan carries an "additional" installment (left over from a prior re-age or a specified-due-date charge that falls after maturity). The root cause is shared with FINERACT-2790: additional installments are excluded from {{ProgressiveLoanInterestScheduleModel.repaymentPeriods()}} when the model is built, so any code that resolves a repayment period by an installment's raw from/due dates fails, since that installment was never added to the model.

FINERACT-2790 only guards the Merchant Issued Refund path. Two call sites in {{AdvancedPaymentScheduleTransactionProcessor}} — {{handleAccelerateMaturityDate()}} and {{handleZeroInterestChargeOff()}} — call {{ProgressiveEMICalculator#getPeriodInterestTillDate}} directly with an additional installment's raw dates, with no guard, reproducing the same crash through charge-off instead.

While fixing this, a second, previously-unguarded lookup was found one level deeper: {{ProgressiveEMICalculator#recalculateScheduleModelTillDate}} calls {{findRepaymentPeriod(targetDate).orElseThrow()}} with no fallback for a target date that falls inside an additional installment's range. This throws the same unwrapped {{NoSuchElementException}} even after the two call-site guards are added, since it runs earlier in the call chain.

*Why it matters*
Loans that go through a re-age or accrue a late specified-due-date charge, then get charged off, hit an internal server error instead of completing the charge-off. This is the same defect class as FINERACT-2790, reachable through a different, previously untested code path.

*Changes made*
 * {{{}handleAccelerateMaturityDate(){}}}: guard the {{getPeriodInterestTillDate()}} call so additional installments are skipped.
 * {{{}handleZeroInterestChargeOff(){}}}: exclude additional installments before the {{getPeriodInterestTillDate()}} call.
 * {{{}getPeriodInterestTillDate(){}}}: throw a descriptive domain exception instead of a bare {{{}NoSuchElementException{}}}.
 * {{{}recalculateScheduleModelTillDate(){}}}: same hardening for a second, previously-unguarded lookup.

Reproducer: unit tests in {{AdvancedPaymentScheduleTransactionProcessorTest}} and {{{}ProgressiveEMICalculatorTest{}}}.

*Related*
FINERACT-2790



--
This message was sent by Atlassian Jira
(v8.20.10#820010)