Skip to content

Commit 69c1b7e

Browse files
committed
FINERACT-2413: Re-amortization:- Accrual and Accrual Activity handling - Equal outstanding interest split
1 parent f4d5e49 commit 69c1b7e

File tree

3 files changed

+22
-18
lines changed

3 files changed

+22
-18
lines changed

fineract-e2e-tests-runner/src/test/resources/features/LoanReAmortization.feature

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7056,14 +7056,14 @@ Feature: LoanReAmortization
70567056
When Admin runs inline COB job for Loan
70577057
Then Loan Transactions tab has the following new accrual data:
70587058
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
7059-
| 01 April 2024 | Accrual Adjustment | 0.42 | 0.0 | 0.42 | 0.0 | 0.0 | 0.0 | false | false |
7059+
| 01 April 2024 | Accrual Adjustment | 0.86 | 0.0 | 0.86 | 0.0 | 0.0 | 0.0 | false | false |
70607060

70617061
When Admin sets the business date to "01 May 2024"
70627062
When Admin runs inline COB job for Loan
70637063
## Why we have accrual adjustment on 02 april
70647064
Then Loan Transactions tab has the following new accrual data:
70657065
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
7066-
| 02 April 2024 | Accrual Adjustment | 0.4 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | false | false |
7066+
| 02 April 2024 | Accrual | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false | false |
70677067
| 03 April 2024 | Accrual | 0.05 | 0.0 | 0.05 | 0.0 | 0.0 | 0.0 | false | false |
70687068
| 04 April 2024 | Accrual | 0.04 | 0.0 | 0.04 | 0.0 | 0.0 | 0.0 | false | false |
70697069
| 05 April 2024 | Accrual | 0.05 | 0.0 | 0.05 | 0.0 | 0.0 | 0.0 | false | false |

fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,10 @@ public Money getPeriodInterestTillDate(@NotNull final ProgressiveLoanInterestSch
528528
final MathContext mc = recalculatedScheduleModelTillDate.mc();
529529
final RepaymentPeriod repaymentPeriod = recalculatedScheduleModelTillDate
530530
.findRepaymentPeriodByFromAndDueDate(periodFromDate, periodDueDate).orElseThrow();
531+
// uj
532+
// Money calculatedDueInterest =
533+
// repaymentPeriod.getDueInterest().add(repaymentPeriod.getUnrecognizedInterest());
534+
// regi
531535
Money calculatedDueInterest = repaymentPeriod.getCalculatedDueInterest();
532536
if (fixedInterestTillDate) {
533537
calculatedDueInterest = MathUtil.negativeToZero(
@@ -884,7 +888,7 @@ private void moveOutstandingAmountsFromPeriodsBeforeTransactionDateForEqualInter
884888
}
885889
rp.setEmi(rp.getTotalPaidAmount());
886890
rp.moveOutstandingDueToReAging();
887-
rp.setNoUnrecognisedInterest(true);
891+
rp.setInterestMovedDownward(true);
888892
});
889893
}
890894

@@ -1086,7 +1090,7 @@ private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestSchedu
10861090
findLastUnpaidRepaymentPeriod.ifPresent(repaymentPeriod -> {
10871091
repaymentPeriod.setFutureUnrecognizedInterest(scheduleModel.zero());
10881092
scheduleModel.repaymentPeriods().forEach(rp -> {
1089-
rp.setInterestMoved(false);
1093+
rp.setInterestMovedUpward(false);
10901094
});
10911095

10921096
MathContext mc = scheduleModel.mc();
@@ -1132,7 +1136,7 @@ private void calculateUnrecognizedInterestTillDateOnScheduleModelCopyAndDefer(Pr
11321136
repaymentPeriod.setFutureUnrecognizedInterest(period.getUnrecognizedInterest());
11331137
scheduleModel.repaymentPeriods().stream().filter(rp -> rp.getDueDate().isAfter(repaymentPeriod.getDueDate())) //
11341138
.forEach(rp -> {
1135-
rp.setInterestMoved(true);
1139+
rp.setInterestMovedUpward(true);
11361140
});
11371141
});
11381142
}
@@ -1965,11 +1969,11 @@ public void reAgeEqualAmortization(ProgressiveLoanInterestScheduleModel interest
19651969
.addCreditedInterestAmount(MathUtil.min(rp.getOutstandingInterest(), rp.getCreditedInterest(), false).negated());
19661970
rp.setEmi(rp.getTotalPaidAmount());
19671971
rp.moveOutstandingDueToReAging();
1968-
rp.setNoUnrecognisedInterest(true);
1972+
rp.setInterestMovedDownward(true);
19691973
});
19701974

19711975
// stop calculate unrecognised interest at this point because all
1972-
interestSchedule.getLastRepaymentPeriod().setNoUnrecognisedInterest(true);
1976+
interestSchedule.getLastRepaymentPeriod().setInterestMovedDownward(true);
19731977

19741978
if (!originalMaturityDate.isBefore(transactionDate)) {
19751979
createRepaymentPeriodForEarlyRepaidAmountsDuringReAgeing(interestSchedule,

fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/data/RepaymentPeriod.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public class RepaymentPeriod {
7777
private Memo<Money> outstandingBalanceCalculation;
7878
@Getter
7979
@Setter
80-
private boolean isInterestMoved = false;
80+
private boolean isInterestMovedUpward = false;
8181

8282
@Setter
8383
private Money totalDisbursedAmount;
@@ -99,7 +99,7 @@ public class RepaymentPeriod {
9999
private Money creditedInterestMovedDueReAge;
100100
@Setter
101101
@Getter
102-
private boolean noUnrecognisedInterest;
102+
private boolean isInterestMovedDownward;
103103
@Setter
104104
@Getter
105105
private boolean reAged;
@@ -111,7 +111,7 @@ public class RepaymentPeriod {
111111

112112
protected RepaymentPeriod(RepaymentPeriod previous, LocalDate fromDate, LocalDate dueDate, List<InterestPeriod> interestPeriods,
113113
Money emi, Money originalEmi, Money paidPrincipal, Money paidInterest, Money futureUnrecognizedInterest, MathContext mc,
114-
ILoanConfigurationDetails loanProductRelatedDetail, boolean noUnrecognisedInterest, boolean reAged,
114+
ILoanConfigurationDetails loanProductRelatedDetail, boolean isInterestMovedDownward, boolean reAged,
115115
boolean reAgedEarlyRepaymentHolder, Money fixedInterest) {
116116
this.previous = previous;
117117
this.fromDate = fromDate;
@@ -124,7 +124,7 @@ protected RepaymentPeriod(RepaymentPeriod previous, LocalDate fromDate, LocalDat
124124
this.futureUnrecognizedInterest = futureUnrecognizedInterest;
125125
this.mc = mc;
126126
this.loanProductRelatedDetail = loanProductRelatedDetail;
127-
this.noUnrecognisedInterest = noUnrecognisedInterest;
127+
this.isInterestMovedDownward = isInterestMovedDownward;
128128
this.reAged = reAged;
129129
this.reAgedEarlyRepaymentHolder = reAgedEarlyRepaymentHolder;
130130
this.fixedInterest = fixedInterest;
@@ -151,13 +151,13 @@ public static RepaymentPeriod copy(RepaymentPeriod previous, RepaymentPeriod rep
151151
final RepaymentPeriod newRepaymentPeriod = new RepaymentPeriod(previous, repaymentPeriod.getFromDate(),
152152
repaymentPeriod.getDueDate(), new ArrayList<>(), repaymentPeriod.getEmi(), repaymentPeriod.getOriginalEmi(),
153153
repaymentPeriod.getPaidPrincipal(), repaymentPeriod.getPaidInterest(), repaymentPeriod.getFutureUnrecognizedInterest(), mc,
154-
repaymentPeriod.getLoanProductRelatedDetail(), repaymentPeriod.isNoUnrecognisedInterest(), repaymentPeriod.isReAged(),
154+
repaymentPeriod.getLoanProductRelatedDetail(), repaymentPeriod.isInterestMovedDownward(), repaymentPeriod.isReAged(),
155155
repaymentPeriod.isReAgedEarlyRepaymentHolder(), repaymentPeriod.getFixedInterest());
156156
newRepaymentPeriod.setCreditedPrincipalMovedDueReAge(repaymentPeriod.getCreditedPrincipalMovedDueReAge());
157157
newRepaymentPeriod.setCreditedInterestMovedDueReAge(repaymentPeriod.getCreditedInterestMovedDueReAge());
158158
newRepaymentPeriod.setTotalDisbursedAmount(repaymentPeriod.getTotalDisbursedAmount());
159159
newRepaymentPeriod.setTotalCapitalizedIncomeAmount(repaymentPeriod.getTotalCapitalizedIncomeAmount());
160-
newRepaymentPeriod.setInterestMoved(repaymentPeriod.isInterestMoved());
160+
newRepaymentPeriod.setInterestMovedUpward(repaymentPeriod.isInterestMovedUpward());
161161
newRepaymentPeriod.setCurrency(repaymentPeriod.getCurrency());
162162
// There is always at least 1 interest period, by default with same from-due date as repayment period
163163
for (InterestPeriod interestPeriod : repaymentPeriod.getInterestPeriods()) {
@@ -170,13 +170,13 @@ public static RepaymentPeriod copyWithoutPaidAmounts(RepaymentPeriod previous, R
170170
final Money zero = Money.zero(repaymentPeriod.getCurrency(), mc);
171171
final RepaymentPeriod newRepaymentPeriod = new RepaymentPeriod(previous, repaymentPeriod.getFromDate(),
172172
repaymentPeriod.getDueDate(), new ArrayList<>(), repaymentPeriod.getEmi(), repaymentPeriod.getOriginalEmi(), zero, zero,
173-
zero, mc, repaymentPeriod.getLoanProductRelatedDetail(), repaymentPeriod.isNoUnrecognisedInterest(),
173+
zero, mc, repaymentPeriod.getLoanProductRelatedDetail(), repaymentPeriod.isInterestMovedDownward(),
174174
repaymentPeriod.isReAged(), repaymentPeriod.isReAgedEarlyRepaymentHolder(), repaymentPeriod.getFixedInterest());
175175
newRepaymentPeriod.setCreditedPrincipalMovedDueReAge(repaymentPeriod.getCreditedPrincipalMovedDueReAge());
176176
newRepaymentPeriod.setCreditedInterestMovedDueReAge(repaymentPeriod.getCreditedInterestMovedDueReAge());
177177
newRepaymentPeriod.setTotalDisbursedAmount(repaymentPeriod.getTotalDisbursedAmount());
178178
newRepaymentPeriod.setTotalCapitalizedIncomeAmount(repaymentPeriod.getTotalCapitalizedIncomeAmount());
179-
newRepaymentPeriod.setInterestMoved(repaymentPeriod.isInterestMoved());
179+
newRepaymentPeriod.setInterestMovedUpward(repaymentPeriod.isInterestMovedUpward());
180180
newRepaymentPeriod.setCurrency(repaymentPeriod.getCurrency());
181181
// There is always at least 1 interest period, by default with same from-due date as repayment period
182182
for (InterestPeriod interestPeriod : repaymentPeriod.getInterestPeriods()) {
@@ -218,7 +218,7 @@ private BigDecimal calculateRateFactorPlus1() {
218218
public Money getCalculatedDueInterest() {
219219
if (calculatedDueInterestCalculation == null) {
220220
calculatedDueInterestCalculation = Memo.of(this::calculateCalculatedDueInterest, () -> new Object[] { previous, interestPeriods,
221-
futureUnrecognizedInterest, isInterestMoved, totalDisbursedAmount, fixedInterest, reAged });
221+
futureUnrecognizedInterest, isInterestMovedUpward, totalDisbursedAmount, fixedInterest, reAged });
222222
}
223223
return calculatedDueInterestCalculation.get();
224224
}
@@ -242,7 +242,7 @@ public Money calculateFixedInterestTillDate() {
242242

243243
public Money calculateCalculatedDueInterest() {
244244
Money calculatedDueInterest = getZero();
245-
if (!isInterestMoved()) {
245+
if (!isInterestMovedUpward() && !isInterestMovedDownward()) {
246246
calculatedDueInterest = Money.of(getEmi().getCurrencyData(),
247247
getInterestPeriods().stream().map(InterestPeriod::getCalculatedDueInterest).reduce(BigDecimal.ZERO, BigDecimal::add),
248248
mc);
@@ -367,7 +367,7 @@ public boolean isFullyPaid() {
367367
* @return
368368
*/
369369
public Money getUnrecognizedInterest() {
370-
return noUnrecognisedInterest ? getZero() : getCalculatedDueInterest().minus(getDueInterest(), getMc());
370+
return getCalculatedDueInterest().minus(getDueInterest(), getMc());
371371
}
372372

373373
public Money getCreditedAmounts() {

0 commit comments

Comments
 (0)