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 authored and adamsaghy committed Sep 18, 2024
1 parent e007171 commit c511385
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ public Money payPenaltyChargesComponent(final LocalDate transactionDate, final M
Money penaltyPortionOfTransaction = Money.zero(currency);

if (transactionAmountRemaining.isZero()) {
// checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
return penaltyPortionOfTransaction;
}

Expand All @@ -538,6 +539,7 @@ public Money payFeeChargesComponent(final LocalDate transactionDate, final Money
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
Money feePortionOfTransaction = Money.zero(currency);
if (transactionAmountRemaining.isZero()) {
// checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
return feePortionOfTransaction;
}
final Money feeChargesDue = getFeeChargesOutstanding(currency);
Expand All @@ -563,6 +565,7 @@ public Money payInterestComponent(final LocalDate transactionDate, final Money t
final MonetaryCurrency currency = transactionAmountRemaining.getCurrency();
Money interestPortionOfTransaction = Money.zero(currency);
if (transactionAmountRemaining.isZero()) {
// checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
return interestPortionOfTransaction;
}
final Money interestDue = getInterestOutstanding(currency);
Expand All @@ -588,6 +591,7 @@ public Money payPrincipalComponent(final LocalDate transactionDate, final Money
final MonetaryCurrency currency = transactionAmount.getCurrency();
Money principalPortionOfTransaction = Money.zero(currency);
if (transactionAmount.isZero()) {
checkIfRepaymentPeriodObligationsAreMet(transactionDate, currency);
return principalPortionOfTransaction;
}
final Money principalDue = getPrincipalOutstanding(currency);
Expand Down
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.get(0)).getDueDate();
case NONE -> throw new IllegalStateException("Unexpected PreClosureInterestCalculationStrategy: NONE");
};

Expand Down

0 comments on commit c511385

Please sign in to comment.