Skip to content

Commit

Permalink
FINERACT-2148: Add 'Accelerate maturity' charge-off behaviour option.…
Browse files Browse the repository at this point in the history
… Manage charge-off in the middle of installment
  • Loading branch information
leksinomi committed Dec 20, 2024
1 parent 97e770d commit c5dde93
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1591,10 +1591,8 @@ public List<LoanTransaction> retrieveListOfTransactionsForReprocessing() {
}

private static Predicate<LoanTransaction> loanTransactionForReprocessingPredicate() {
return transaction -> (transaction.isNotReversed() && (transaction.isChargeOff() || transaction.isReAge()
|| transaction.isAccrualActivity() || transaction.isReAmortize() || !transaction.isNonMonetaryTransaction()))
|| (transaction.isReversed() && transaction.isChargeOff() && LoanChargeOffBehaviour.ZERO_INTEREST
.equals(transaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour()));
return transaction -> transaction.isNotReversed() && (transaction.isChargeOff() || transaction.isReAge()
|| transaction.isAccrualActivity() || transaction.isReAmortize() || !transaction.isNonMonetaryTransaction());
}

public List<LoanTransaction> retrieveListOfTransactionsExcludeAccruals() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,8 @@ private void handleChargeOff(final LoanTransaction loanTransaction, final Transa
if (LoanChargeOffBehaviour.ZERO_INTEREST.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())
&& !loanTransaction.isReversed()) {
handleZeroInterestChargeOff(loanTransaction, progressiveTransactionCtx);
} else if (LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
} else if (LoanChargeOffBehaviour.ACCELERATE_MATURITY
.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
handleAccelerateMaturityChargeOff(loanTransaction, progressiveTransactionCtx);
}
}
Expand Down Expand Up @@ -1203,18 +1204,38 @@ private void handleAccelerateMaturityChargeOff(LoanTransaction loanTransaction,
final LocalDate transactionDate = loanTransaction.getTransactionDate();
final List<LoanRepaymentScheduleInstallment> installments = progressiveTransactionCtx.getInstallments();
Loan loan = loanTransaction.getLoan();
LoanRepaymentScheduleInstallment currentInstallment = loan.getRelatedRepaymentScheduleInstallment(transactionDate);

if (!installments.isEmpty()) {
if (loan.isInterestRecalculationEnabled()) {

final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(),
currentInstallment.getDueDate(), transactionDate).getAmount();
final BigDecimal interestRemoved = currentInstallment.getInterestCharged().subtract(newInterest);
currentInstallment.updatePrincipal(MathUtil.nullToZero(currentInstallment.getPrincipal()).add(interestRemoved));
currentInstallment.updateInterestCharged(newInterest);
} else {

final BigDecimal totalInterest = currentInstallment.getInterestOutstanding(progressiveTransactionCtx.getCurrency())
.getAmount();
final long totalDaysInPeriod = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), currentInstallment.getDueDate());
final long daysTillChargeOff = ChronoUnit.DAYS.between(currentInstallment.getFromDate(), transactionDate);

final BigDecimal interestTillChargeOff = totalInterest
.divide(BigDecimal.valueOf(totalDaysInPeriod), MoneyHelper.getMathContext())
.multiply(BigDecimal.valueOf(daysTillChargeOff));

final BigDecimal interestRemoved = totalInterest.subtract(interestTillChargeOff);
currentInstallment.updatePrincipal(MathUtil.nullToZero(currentInstallment.getPrincipal()).add(interestRemoved));
currentInstallment.updateInterestCharged(interestTillChargeOff);
}

currentInstallment.updateDueDate(transactionDate);
BigDecimal futurePrincipal = installments.stream().filter(installment -> transactionDate.isBefore(installment.getDueDate()))
.map(LoanRepaymentScheduleInstallment::getPrincipal).reduce(BigDecimal.ZERO, BigDecimal::add);
currentInstallment.updatePrincipal(MathUtil.nullToZero(currentInstallment.getPrincipal()).add(futurePrincipal));
List<LoanRepaymentScheduleInstallment> installmentsUpToTransactionDate = installments.stream()
.filter(installment -> transactionDate.isAfter(installment.getFromDate()))
.toList();
.filter(installment -> transactionDate.isAfter(installment.getFromDate())).toList();
loan.updateLoanSchedule(installmentsUpToTransactionDate);

loan.updateLoanScheduleDependentDerivedFields();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3290,6 +3290,18 @@ public CommandProcessingResult undoChargeOff(JsonCommand command) {

loan.liftChargeOff();
loanTransactionRepository.saveAndFlush(chargedOffTransaction);
if (loan.isProgressiveSchedule()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, null, null);
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions();
if (changedTransactionDetail != null) {
for (final Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) {
loanAccountDomainService.saveLoanTransactionWithDataIntegrityViolationChecks(mapEntry.getValue());
accountTransfersWritePlatformService.updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue());
}
replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail);
}
}
saveLoanWithDataIntegrityViolationChecks(loan);
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds);
businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoChargeOffBusinessEvent(chargedOffTransaction));
Expand Down

0 comments on commit c5dde93

Please sign in to comment.