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)