@@ -2025,14 +2025,20 @@ private void handleAccelerateMaturityDate(final LoanTransaction loanTransaction,
20252025 final LoanRepaymentScheduleInstallment currentInstallment = loan .getRelatedRepaymentScheduleInstallment (transactionDate );
20262026
20272027 if (!installments .isEmpty () && transactionDate .isBefore (loan .getMaturityDate ()) && currentInstallment != null ) {
2028- if (currentInstallment .isNotFullyPaidOff ()) {
2028+ if (currentInstallment .isNotFullyPaidOff () || currentInstallment . isReAged () ) {
20292029 if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx
20302030 && loan .isInterestBearingAndInterestRecalculationEnabled ()) {
20312031 final BigDecimal interestOutstanding = currentInstallment .getInterestOutstanding (loan .getCurrency ()).getAmount ();
20322032 final BigDecimal newInterest = emiCalculator .getPeriodInterestTillDate (progressiveTransactionCtx .getModel (),
20332033 currentInstallment .getFromDate (), currentInstallment .getDueDate (), transactionDate , true , false ).getAmount ();
2034- if (interestOutstanding .compareTo (BigDecimal .ZERO ) > 0 || newInterest .compareTo (BigDecimal .ZERO ) > 0 ) {
2035- currentInstallment .updateInterestCharged (newInterest );
2034+ // Collect fixed interest from future re-aged periods that will be removed
2035+ final BigDecimal futureFixedInterest = progressiveTransactionCtx .getModel ().repaymentPeriods ().stream ()
2036+ .filter (rp -> DateUtils .isAfterInclusive (rp .getFromDate (), transactionDate )).filter (RepaymentPeriod ::isReAged )
2037+ .filter (rp -> !rp .getFixedInterest ().isZero ()).map (rp -> rp .getFixedInterest ().getAmount ())
2038+ .reduce (BigDecimal .ZERO , BigDecimal ::add );
2039+ final BigDecimal totalInterest = newInterest .add (futureFixedInterest );
2040+ if (interestOutstanding .compareTo (BigDecimal .ZERO ) > 0 || totalInterest .compareTo (BigDecimal .ZERO ) > 0 ) {
2041+ currentInstallment .updateInterestCharged (totalInterest );
20362042 }
20372043 } else {
20382044 final BigDecimal totalInterest = currentInstallment .getInterestOutstanding (transactionCtx .getCurrency ()).getAmount ();
@@ -2157,9 +2163,20 @@ private void handleZeroInterestChargeOff(final LoanTransaction loanTransaction,
21572163 calculatePartialPeriodInterest (transactionCtx , transactionDate );
21582164 }
21592165
2166+ // Check if re-aging (before charge-off) used equal amortization - in that case, preserve interest for
2167+ // re-aged installments
2168+ final boolean reAgingUsedEqualAmortization = loanTransaction .getLoan ().getLoanTransactions ().stream () //
2169+ .filter (LoanTransaction ::isReAge ) //
2170+ .filter (t -> !t .getTransactionDate ().isAfter (transactionDate )) //
2171+ .map (LoanTransaction ::getLoanReAgeParameter ) //
2172+ .filter (Objects ::nonNull ) //
2173+ .map (LoanReAgeParameter ::getInterestHandlingType ) //
2174+ .anyMatch (type -> type == LoanReAgeInterestHandlingType .EQUAL_AMORTIZATION_PAYABLE_INTEREST
2175+ || type == LoanReAgeInterestHandlingType .EQUAL_AMORTIZATION_FULL_INTEREST );
2176+
21602177 installments .stream ()
21612178 .filter (installment -> installment .getFromDate ().isAfter (transactionDate ) && !installment .isObligationsMet ())
2162- .forEach (installment -> {
2179+ .filter ( installment -> !( installment . isReAged () && reAgingUsedEqualAmortization )). forEach (installment -> {
21632180 final BigDecimal interestOutstanding = installment .getInterestOutstanding (currency ).getAmount ();
21642181 final BigDecimal updatedInterestCharged = installment .getInterestCharged (currency ).getAmount ()
21652182 .subtract (interestOutstanding );
@@ -3381,17 +3398,28 @@ private void updateRepaymentPeriodsAfterAccelerateMaturityDate(final Progressive
33813398 lastPeriod .setDueDate (transactionDate );
33823399 lastPeriod .getInterestPeriods ().removeIf (interestPeriod -> !interestPeriod .getFromDate ().isBefore (transactionDate ));
33833400
3384- transactionCtx .getModel ().repaymentPeriods ().removeAll (periodsToRemove );
3385-
33863401 final BigDecimal totalPrincipal = periodsToRemove .stream ().map (rp -> rp .getDuePrincipal ().getAmount ()).reduce (BigDecimal .ZERO ,
33873402 BigDecimal ::add );
33883403
3404+ final BigDecimal futureInterest = periodsToRemove .stream ().filter (RepaymentPeriod ::isReAged )
3405+ .filter (rp -> !rp .getFixedInterest ().isZero ()).map (rp -> rp .getFixedInterest ().getAmount ())
3406+ .reduce (BigDecimal .ZERO , BigDecimal ::add );
3407+
3408+ transactionCtx .getModel ().repaymentPeriods ().removeAll (periodsToRemove );
3409+
33893410 final BigDecimal newInterest = emiCalculator .getPeriodInterestTillDate (transactionCtx .getModel (), lastPeriod .getFromDate (),
33903411 lastPeriod .getDueDate (), transactionDate , false , false ).getAmount ();
33913412
3392- lastPeriod .setEmi (lastPeriod .getDuePrincipal ().add (totalPrincipal ).add (newInterest ));
3413+ if (futureInterest .compareTo (BigDecimal .ZERO ) > 0 ) {
3414+ final MonetaryCurrency currency = transactionCtx .getCurrency ();
3415+ final MathContext mc = transactionCtx .getModel ().mc ();
3416+ lastPeriod .setFixedInterest (lastPeriod .getFixedInterest ().add (Money .of (currency , futureInterest , mc ), mc ));
3417+ }
3418+
3419+ lastPeriod .setEmi (lastPeriod .getDuePrincipal ().add (totalPrincipal ).add (newInterest ).add (futureInterest ));
33933420
33943421 emiCalculator .calculateRateFactorForRepaymentPeriod (lastPeriod , transactionCtx .getModel ());
3422+
33953423 transactionCtx .getModel ().disableEMIRecalculation ();
33963424
33973425 for (LoanTransaction processTransaction : transactionsToBeReprocessed ) {
0 commit comments