adamsaghy commented on code in PR #6546:
URL: https://github.com/apache/fineract/pull/6546#discussion_r4393993078
##########
fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java:
##########
@@ -1551,6 +1558,11 @@ BigDecimal calculateRateFactorPerPeriodForInterest(final
ProgressiveLoanInterest
return rateFactorByRepaymentPeriod(interestRate,
BigDecimal.ONE, repaymentEvery, BigDecimal.valueOf(52), actualDaysInPeriod,
calculatedDaysInPeriod, mc);
}
+ if
(loanProductRelatedDetail.getRepaymentPeriodFrequencyType().isSemiMonthly()) {
Review Comment:
**Re-aged monthly installments are charged half the interest.**
This affects a progressive semi-monthly loan with interest recalculation and
interest calculated "same as repayment period". Re-aging can't use
`SEMI_MONTHLY`, so it always switches the loan to another frequency (here
months). The re-aged periods are attached in
`attachTemporaryScheduleModelReAgedPeriodsToExistingModel` with the loan's own
configuration, so their interest is worked out here: 1/24 of the annual rate
per period, even though each re-aged period is a month.
I ran it on this head. All three loans have 24% interest and were re-aged on
20 March 2023, before maturity, into 3 monthly installments starting 15 April:
| Loan | 2nd re-aged installment | 3rd re-aged installment |
|---|---|---|
| Semi-monthly 15/31, same as repayment | **7.03** on 703.15 (1%) | **3.53**
on 353.33 (1%) |
| Monthly, same as repayment (control) | 14.26 on 712.85 (2%) | 7.20 on
359.96 (2%) |
| Semi-monthly 15/31, daily interest | 13.79 (30 days) | 7.19 (31 days) |
The EMI is computed at the halved rate too (356.85 against 367.15 on the
monthly loan). The loan still amortises, but it charges half the interest.
Daily interest is fine.
Could the re-aged periods be charged by their own frequency? Alternatively,
could re-aging a semi-monthly loan be restricted to combinations that charge
correctly, with a test for a re-age with `MONTHS`?
##########
fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/DefaultScheduledDateGenerator.java:
##########
@@ -124,6 +124,11 @@ public LocalDate generateNextRepaymentDate(final LocalDate
lastRepaymentDate, fi
LocalDate seedDate = null;
String reccuringString = null;
Calendar currentCalendar = loanApplicationTerms.getLoanCalendar();
+ if
(loanApplicationTerms.getRepaymentPeriodFrequencyType().isSemiMonthly()) {
+ // The two due days are fixed points of the calendar month, so
the next date is the first of them
+ // after the previous one rather than an offset added to it.
+ return SemiMonthlyScheduleDates.next(lastRepaymentDate,
loanApplicationTerms.semiMonthlyDueDays());
Review Comment:
**A one-day first period is charged a full half-month by default.**
Without a pinned first repayment date, the first due date is simply the next
due day after disbursement, so it can be a day away. I ran this on this head
with due days 1 and 16, disbursed on 15 January 2023, 1000 at 24% over 4
installments:
| Interest | 1st installment (15 → 16 January) | Interest in it |
|---|---|---|
| Same as repayment | 256.28 | **10.00** (a full 1/24) |
| Daily | 253.90 | 0.66 |
This happens even with `allowPartialPeriodInterestCalculation` on. A monthly
loan behaves the same if its first date is pinned one day out (20.00 for one
day). The difference is that a monthly loan's default first date is a full
month away, while a semi-monthly loan gets the short period without anyone
asking for it. Only `minimumDaysBetweenDisbursalAndFirstRepayment` avoids it.
Is that intended? If not, the default first due date could skip a due day
that is closer than some minimum gap, or the docs could say to set the minimum
gap for semi-monthly products.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]