FINERACT-2081: Charge-off optimalization

This commit is contained in:
Adam Saghy
2025-02-21 14:09:23 +01:00
parent e02420f998
commit 5137fd65af
7 changed files with 18 additions and 14 deletions
@@ -3584,4 +3584,8 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
public boolean hasChargeOffTransaction() { public boolean hasChargeOffTransaction() {
return getLoanTransactions().stream().anyMatch(LoanTransaction::isChargeOff); return getLoanTransactions().stream().anyMatch(LoanTransaction::isChargeOff);
} }
public boolean hasAccelerateChargeOffStrategy() {
return LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(getLoanProductRelatedDetail().getChargeOffBehaviour());
}
} }
@@ -154,7 +154,7 @@ public class LoanDownPaymentHandlerServiceImpl implements LoanDownPaymentHandler
if (reprocess) { if (reprocess) {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
reprocessLoanTransactionsService.reprocessTransactions(loan); reprocessLoanTransactionsService.reprocessTransactions(loan);
@@ -891,7 +891,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
} else { } else {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
loan.getLoanTransactions().add(refundTransaction); loan.getLoanTransactions().add(refundTransaction);
@@ -288,7 +288,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
} }
if (reprocessRequired) { if (reprocessRequired) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null); final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -830,7 +830,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
if (reprocessRequired) { if (reprocessRequired) {
addInstallmentIfPenaltyAppliedAfterLastDueDate(loan, lastChargeDate); addInstallmentIfPenaltyAppliedAfterLastDueDate(loan, lastChargeDate);
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null); final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -865,7 +865,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
.determineProcessor(loan.transactionProcessingStrategy()); .determineProcessor(loan.transactionProcessingStrategy());
loan.addLoanTransaction(loanChargeAdjustmentTransaction); loan.addLoanTransaction(loanChargeAdjustmentTransaction);
if (loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isInterestBearingAndInterestRecalculationEnabled()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null); final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -1446,7 +1446,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled() if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()
&& DateUtils.isBefore(loanCharge.getDueLocalDate(), businessDate)) { && DateUtils.isBefore(loanCharge.getDueLocalDate(), businessDate)) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
// Waive of charges whose due date falls after latest 'repayment' transaction don't require entire loan schedule // Waive of charges whose due date falls after latest 'repayment' transaction don't require entire loan schedule
@@ -1106,7 +1106,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
private void reprocessChangedLoanTransactions(Loan loan, ScheduleGeneratorDTO scheduleGeneratorDTO) { private void reprocessChangedLoanTransactions(Loan loan, ScheduleGeneratorDTO scheduleGeneratorDTO) {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -2628,7 +2628,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
reprocessLoanTransactionsService.processPostDisbursementTransactions(loan); reprocessLoanTransactionsService.processPostDisbursementTransactions(loan);
} }
@@ -2782,7 +2782,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
|| rescheduledRepaymentDate != null) { || rescheduledRepaymentDate != null) {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
} }
@@ -3502,7 +3502,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
reprocessLoanTransactionsService.reprocessTransactions(loan); reprocessLoanTransactionsService.reprocessTransactions(loan);
@@ -3615,7 +3615,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { } else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -3684,7 +3684,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
"reversed"); "reversed");
writeOffTransaction.reverse(); writeOffTransaction.reverse();
loanLifecycleStateMachine.transition(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO, loan); loanLifecycleStateMachine.transition(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO, loan);
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null); final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -84,7 +84,7 @@ public class ProgressiveLoanInterestRefundServiceImpl implements InterestRefundS
List<LoanRepaymentScheduleInstallment> installmentsToReprocess = new ArrayList<>( List<LoanRepaymentScheduleInstallment> installmentsToReprocess = new ArrayList<>(
loan.getRepaymentScheduleInstallments().stream().filter(i -> !i.isReAged() && !i.isAdditional()).toList()); loan.getRepaymentScheduleInstallments().stream().filter(i -> !i.isReAged() && !i.isAdditional()).toList());
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null); final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }
@@ -128,7 +128,7 @@ public class LoanReAgingServiceImpl {
} }
reverseReAgeTransaction(reAgeTransaction, command); reverseReAgeTransaction(reAgeTransaction, command);
loanTransactionRepository.saveAndFlush(reAgeTransaction); loanTransactionRepository.saveAndFlush(reAgeTransaction);
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) { if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction() && loan.hasAccelerateChargeOffStrategy()) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null); final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
} }