Mario Lopez created FINERACT-3015:
-------------------------------------

             Summary: Bullet Progressive Loans Rescheduling with wrong interest
                 Key: FINERACT-3015
                 URL: https://issues.apache.org/jira/browse/FINERACT-3015
             Project: Apache Fineract
          Issue Type: Bug
    Affects Versions: 1.16.0
            Reporter: Mario Lopez
            Assignee: Mario Lopez


h2. Progressive reschedule bills capped interest on principal grace


*Project:* FINERACT
*Type:* Bug
*Component:* Loan / Progressive loan
h3. Summary


On a progressive loan, a principal-grace repayment can bill less interest than 
the period accrued after an interest-rate reschedule, and the unpaid difference 
is pushed onto a later installment. Separately, `changeInterestRate` starts the 
new rate on the day before the date that was submitted.
h3. Environment


Progressive loan schedule (`loanScheduleType = PROGRESSIVE`), declining 
balance, daily interest. Reproduced in `ProgressiveEMICalculator` on current 
`develop`.
h3. Principal-grace rows bill the capped installment
h4. Steps
1. Create a bullet loan: principal 100,000, grace on principal for the first 11 
of 12 monthly repayments, actual days, 360-day year, 20%.
2. Disburse on 1 January 2026.
3. Reschedule the interest rate to 15% from 1 May 2026.
4. Read the interest due on the repayment for 1 June 2026.
h4. Actual
June bills 1,291.49. The missing 0.18 is unrecognized interest and is carried 
forward. Later grace rows do the same whenever that month's accrual is above 
the installment solved for the reschedule, and the balloon collects the 
accumulated difference.

`100,000 × 15% × 31 ÷ 360 = 1,291.67`
h4. Expected
Each principal-grace row bills the interest that period accrued. June bills 
1,291.67, unrecognized interest on that row is 0, and the balloon bills only 
its own month of interest plus the 100,000 principal.

An amortizing loan is unchanged: its installment is already principal plus 
interest, so one period of interest fits inside it. A 30-day month (`rate ÷ 
12`) is also unchanged, because the solved installment is already above that 
flat accrual.
h4. Cause
`calculateEMIValueAndRateFactorsForDecliningBalanceInterestMethod` solves one 
equal installment and writes it onto every related period, then 
`applyPrincipalMoratoriumIfRequired` copies `getDueInterest()` onto each grace 
row.

`getDueInterest()` is already `min(calculated interest, installment)`. At 
origination the solved installment is the full annuity, which is larger than 
one month of interest, so the grace row gets the full accrual. After a rate 
change the new installment can be smaller than a 31-day accrual. Grace then 
copies the smaller number.

The outstanding balance also has to be refreshed while walking the grace rows. 
The solved installment is still charging a little principal on earlier rows in 
the slice, so the next row accrues on a balance slightly under the real 
outstanding and its calculated interest is already short before the cap is 
applied.
h4. Fix
For each in-slice grace period, in due-date order:

1. Refresh that row's outstanding balance from the previous row.
2. Set the installment to `getCalculatedDueInterest()` (the uncapped accrual, 
including any unrecognized interest already carried in).
3. Do not lower the installment below principal and interest already paid, net 
of credits.

The row stays principal-grace, so principal due stays 0. The installment for 
the remaining amortizing period is solved again afterwards. With one period 
left, that is principal plus that period's own accrual.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to