Skip to content

Commit

Permalink
FINERACT-1981: fix pay-off for TILL_REST_FREQUENCY_DATE
Browse files Browse the repository at this point in the history
  • Loading branch information
kjozsa committed Sep 17, 2024
1 parent 1cb9a36 commit 5522269
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import static org.apache.fineract.portfolio.loanproduct.domain.AllocationType.INTEREST;
import static org.apache.fineract.portfolio.loanproduct.domain.AllocationType.PENALTY;
import static org.apache.fineract.portfolio.loanproduct.domain.AllocationType.PRINCIPAL;
import static org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCalculationStrategy.TILL_PRE_CLOSURE_DATE;
import static org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCalculationStrategy.TILL_REST_FREQUENCY_DATE;
import static org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationTransactionType.DEFAULT;

import java.math.BigDecimal;
Expand Down Expand Up @@ -85,6 +87,7 @@
import org.apache.fineract.portfolio.loanproduct.domain.CreditAllocationTransactionType;
import org.apache.fineract.portfolio.loanproduct.domain.DueType;
import org.apache.fineract.portfolio.loanproduct.domain.FutureInstallmentAllocationRule;
import org.apache.fineract.portfolio.loanproduct.domain.LoanPreClosureInterestCalculationStrategy;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
import org.jetbrains.annotations.NotNull;
Expand Down Expand Up @@ -1231,10 +1234,21 @@ private Money processAllocationsHorizontally(LoanTransaction loanTransaction, Tr
if (transactionCtx instanceof ProgressiveTransactionCtx ctx && loan.isInterestBearing()
&& loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled()) {
ProgressiveLoanInterestScheduleModel model = ctx.getModel();
LocalDate transactionDate = loanTransaction.getTransactionDate();
LocalDate payDate = inAdvanceInstallment.getFromDate().isAfter(transactionDate)
? inAdvanceInstallment.getFromDate()
: transactionDate;
LoanPreClosureInterestCalculationStrategy strategy = loanTransaction.getLoan().getLoanProduct()
.preCloseInterestCalculationStrategy();

LocalDate payDate = switch (strategy) {
case TILL_PRE_CLOSURE_DATE -> {
LocalDate transactionDate = loanTransaction.getTransactionDate();
yield inAdvanceInstallment.getFromDate().isAfter(transactionDate)
? inAdvanceInstallment.getFromDate()
: transactionDate;
}
case TILL_REST_FREQUENCY_DATE -> inAdvanceInstallment.getDueDate();
case NONE ->
throw new IllegalStateException("Unexpected PreClosureInterestCalculationStrategy: NONE");
};

ProgressiveLoanInterestRepaymentModel payableDetails = emiCalculator
.getPayableDetails(model, inAdvanceInstallment.getDueDate(), payDate).orElseThrow();

Expand All @@ -1253,13 +1267,19 @@ private Money processAllocationsHorizontally(LoanTransaction loanTransaction, Tr

switch (paymentAllocationType) {
case IN_ADVANCE_PRINCIPAL -> {
emiCalculator.addBalanceCorrection(model, payDate,
payableDetails.getOutstandingBalance().multipliedBy(-1));
Money balance = switch (strategy) {
case TILL_PRE_CLOSURE_DATE -> payableDetails.getOutstandingBalance();
case TILL_REST_FREQUENCY_DATE -> payableDetails.getRemainingBalance();
default -> throw new IllegalStateException();
};
emiCalculator.addBalanceCorrection(model, payDate, balance.multipliedBy(-1));
emiCalculator.addBalanceCorrection(model, payDate,
payableDetails.getPrincipalDue().minus(paidPortion));
}
case IN_ADVANCE_INTEREST -> emiCalculator.addBalanceCorrection(model, payDate,
payableDetails.getInterestDue().minus(paidPortion));
case IN_ADVANCE_INTEREST -> {
emiCalculator.addBalanceCorrection(model, payDate,
payableDetails.getInterestDue().minus(paidPortion));
}
default -> {
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ public OutstandingAmountsDTO calculatePrepaymentAmount(MonetaryCurrency currency
case TILL_PRE_CLOSURE_DATE -> onDate;
case TILL_REST_FREQUENCY_DATE -> // find due date of current installment
installments.stream().filter(it -> it.getFromDate().isBefore(onDate) && it.getDueDate().isAfter(onDate)).findFirst()
.orElseThrow(() -> new IllegalStateException("No installment found for transaction date: " + onDate)).getDueDate();
.orElse(installments.getLast()).getDueDate();
case NONE -> throw new IllegalStateException("Unexpected PreClosureInterestCalculationStrategy: NONE");
};

Expand Down

0 comments on commit 5522269

Please sign in to comment.