Skip to content

Commit

Permalink
FINERACT-2081: Charge-off optimalization
Browse files Browse the repository at this point in the history
  • Loading branch information
adamsaghy committed Feb 20, 2025
1 parent e02420f commit 696c15c
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import org.apache.fineract.portfolio.loanaccount.data.HolidayDetailDTO;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent;
import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
Expand Down Expand Up @@ -154,7 +155,8 @@ public void handleRepaymentOrRecoveryOrWaiverTransaction(final Loan loan, final
if (reprocess) {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
reprocessLoanTransactionsService.reprocessTransactions(loan);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -891,7 +891,8 @@ public Pair<LoanTransaction, LoanTransaction> makeRefund(final Loan loan, final
} else {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
loan.getLoanTransactions().add(refundTransaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargePaidBy;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeRepository;
import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails;
Expand Down Expand Up @@ -288,7 +289,8 @@ public CommandProcessingResult addLoanCharge(final Long loanId, final JsonComman
}

if (reprocessRequired) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
Expand Down Expand Up @@ -830,7 +832,8 @@ public void applyOverdueChargesForLoan(final Long loanId, Collection<OverdueLoan

if (reprocessRequired) {
addInstallmentIfPenaltyAppliedAfterLastDueDate(loan, lastChargeDate);
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
Expand Down Expand Up @@ -865,7 +868,8 @@ private LoanTransaction applyChargeAdjustment(final Loan loan, final LoanCharge
.determineProcessor(loan.transactionProcessingStrategy());
loan.addLoanTransaction(loanChargeAdjustmentTransaction);
if (loan.isInterestBearingAndInterestRecalculationEnabled()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
Expand Down Expand Up @@ -1446,7 +1450,8 @@ public LoanTransaction waiveLoanCharge(final Loan loan, final LoanCharge loanCha
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()
&& DateUtils.isBefore(loanCharge.getDueLocalDate(), businessDate)) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
// Waive of charges whose due date falls after latest 'repayment' transaction don't require entire loan schedule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountDomainService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanAccountService;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanDisbursementDetails;
import org.apache.fineract.portfolio.loanaccount.domain.LoanEvent;
import org.apache.fineract.portfolio.loanaccount.domain.LoanLifecycleStateMachine;
Expand Down Expand Up @@ -1106,7 +1107,8 @@ private void recalculateLoanWithInterestPaymentWaiverTxn(Loan loan, LoanTransact
private void reprocessChangedLoanTransactions(Loan loan, ScheduleGeneratorDTO scheduleGeneratorDTO) {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}

Expand Down Expand Up @@ -2628,7 +2630,8 @@ private CommandProcessingResult processLoanDisbursementDetail(Loan loan, Long lo

if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
reprocessLoanTransactionsService.processPostDisbursementTransactions(loan);
}
Expand Down Expand Up @@ -2782,7 +2785,8 @@ private void regenerateScheduleOnDisbursement(final JsonCommand command, final L
|| rescheduledRepaymentDate != null) {
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
}
Expand Down Expand Up @@ -3502,7 +3506,8 @@ private void closeDisbursements(final Loan loan, final ScheduleGeneratorDTO sche
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
reprocessLoanTransactionsService.reprocessTransactions(loan);
Expand Down Expand Up @@ -3615,7 +3620,8 @@ private void updateDisbursementDateAndAmountForTranche(final Loan loan, final Lo

if (loan.isCumulativeSchedule() && loan.isInterestBearingAndInterestRecalculationEnabled()) {
loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO);
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
} else if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}

Expand Down Expand Up @@ -3684,7 +3690,8 @@ private void undoWrittenOff(final Loan loan, final LoanLifecycleStateMachine loa
"reversed");
writeOffTransaction.reverse();
loanLifecycleStateMachine.transition(LoanEvent.WRITE_OFF_OUTSTANDING_UNDO, loan);
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType;
Expand Down Expand Up @@ -84,7 +85,8 @@ private Money recalculateTotalInterest(AdvancedPaymentScheduleTransactionProcess
List<LoanRepaymentScheduleInstallment> installmentsToReprocess = new ArrayList<>(
loan.getRepaymentScheduleInstallments().stream().filter(i -> !i.isReAged() && !i.isAdditional()).toList());

if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import org.apache.fineract.portfolio.loanaccount.api.LoanReAgingApiConstants;
import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRepository;
Expand Down Expand Up @@ -128,7 +129,8 @@ public CommandProcessingResult undoReAge(Long loanId, JsonCommand command) {
}
reverseReAgeTransaction(reAgeTransaction, command);
loanTransactionRepository.saveAndFlush(reAgeTransaction);
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()) {
if (loan.isProgressiveSchedule() && loan.hasChargeOffTransaction()
&& LoanChargeOffBehaviour.ACCELERATE_MATURITY.equals(loan.getLoanProductRelatedDetail().getChargeOffBehaviour())) {
final ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, null);
loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO);
}
Expand Down

0 comments on commit 696c15c

Please sign in to comment.