From 79c5fc164959937114d76cfc4b16d05481258f20 Mon Sep 17 00:00:00 2001 From: Adam Saghy Date: Thu, 6 Feb 2025 09:36:40 +0100 Subject: [PATCH] FINERACT-2081: Interest recalculation only for interest bearing loans --- .../portfolio/loanaccount/domain/Loan.java | 9 +- ...stractCumulativeLoanScheduleGenerator.java | 12 +- .../domain/LoanApplicationTerms.java | 8 ++ .../service/LoanArrearsAgingServiceImpl.java | 2 +- .../LoanDownPaymentHandlerServiceImpl.java | 6 +- .../service/LoanScheduleService.java | 4 +- ...edPaymentScheduleTransactionProcessor.java | 18 +-- ...ymentScheduleTransactionProcessorTest.java | 9 +- ...nInterestRecalculationCOBBusinessStep.java | 3 +- .../domain/LoanAccountDomainServiceJpa.java | 26 ++-- ...cheduleCalculationPlatformServiceImpl.java | 3 +- .../LoanForeclosureValidator.java | 2 +- .../LoanTransactionValidator.java | 5 +- ...WritePlatformServiceJpaRepositoryImpl.java | 2 +- .../LoanChargeWritePlatformServiceImpl.java | 21 ++-- .../loanaccount/service/LoanUtilService.java | 2 +- ...WritePlatformServiceJpaRepositoryImpl.java | 118 +++++++++--------- ...LoanDownPaymentHandlerServiceImplTest.java | 1 + 18 files changed, 128 insertions(+), 123 deletions(-) diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index 0ce2a3473..10f0ba6e6 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -2658,6 +2658,10 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom { return BigDecimal.ZERO.compareTo(getLoanRepaymentScheduleDetail().getAnnualNominalInterestRate()) < 0; } + public boolean isInterestBearingAndInterestRecalculationEnabled() { + return isInterestBearing() && isInterestRecalculationEnabled(); + } + public boolean isInterestRecalculationEnabled() { return this.loanRepaymentScheduleDetail.isInterestRecalculationEnabled(); } @@ -2705,8 +2709,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom { } public LoanScheduleDTO getRecalculatedSchedule(final ScheduleGeneratorDTO generatorDTO) { - if (!this.repaymentScheduleDetail().isEnableDownPayment() - && (!this.repaymentScheduleDetail().isInterestRecalculationEnabled() || isNpa || isChargedOff())) { + if (!isInterestBearingAndInterestRecalculationEnabled() || isNpa || isChargedOff()) { return null; } final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod(); @@ -2726,7 +2729,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom { public OutstandingAmountsDTO fetchPrepaymentDetail(final ScheduleGeneratorDTO scheduleGeneratorDTO, final LocalDate onDate) { OutstandingAmountsDTO outstandingAmounts; - if (this.loanRepaymentScheduleDetail.isInterestRecalculationEnabled() && !isChargeOffOnDate(onDate)) { + if (isInterestBearingAndInterestRecalculationEnabled() && !isChargeOffOnDate(onDate)) { final MathContext mc = MoneyHelper.getMathContext(); final InterestMethod interestMethod = this.loanRepaymentScheduleDetail.getInterestMethod(); diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java index 149654f74..e8ed744c7 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/AbstractCumulativeLoanScheduleGenerator.java @@ -250,7 +250,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch isNextRepaymentAvailable = false; } - if (loanApplicationTerms.isInterestRecalculationEnabled()) { + if (loanApplicationTerms.isInterestBearingAndInterestRecalculationEnabled()) { populateCompoundingDatesInPeriod(scheduleParams.getPeriodStartDate(), scheduledDueDate, loanApplicationTerms, holidayDetailDTO, scheduleParams, loanCharges, monetaryCurrency, mc); } @@ -495,7 +495,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch LoanScheduleParams scheduleParams, LocalDate scheduledDueDate, ScheduleCurrentPeriodParams currentPeriodParams, LoanScheduleModelPeriod installment, LocalDate lastRestDate) { LocalDate amountApplicableDate = installment.periodDueDate(); - if (loanApplicationTerms.isInterestRecalculationEnabled()) { + if (loanApplicationTerms.isInterestBearingAndInterestRecalculationEnabled()) { amountApplicableDate = getNextRestScheduleDate(installment.periodDueDate().minusDays(1), loanApplicationTerms, holidayDetailDTO); } @@ -1681,7 +1681,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch private void updateCompoundingMap(final LoanApplicationTerms loanApplicationTerms, final HolidayDetailDTO holidayDetailDTO, final LoanScheduleParams params, final LocalDate lastRestDate, final LocalDate scheduledDueDate) { - if (loanApplicationTerms.isInterestRecalculationEnabled() + if (loanApplicationTerms.isInterestBearingAndInterestRecalculationEnabled() && loanApplicationTerms.getInterestRecalculationCompoundingMethod().isCompoundingEnabled()) { final MonetaryCurrency currency = MonetaryCurrency.fromCurrencyData(params.getCurrency()); Money totalCompoundedAmount = Money.zero(currency); @@ -2186,7 +2186,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch LoanTransaction.copyTransactionProperties(loanTransaction))); } } - final boolean applyInterestRecalculation = loanApplicationTerms.isInterestRecalculationEnabled(); + final boolean applyInterestRecalculation = loanApplicationTerms.isInterestBearingAndInterestRecalculationEnabled(); // for complete schedule generation LoanScheduleParams loanScheduleParams = LoanScheduleParams.createLoanScheduleParamsForCompleteUpdate(recalculationDetails, @@ -2239,7 +2239,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch final Map> compoundingDateVariations = new HashMap<>(); LocalDate currentDate = DateUtils.getBusinessLocalDate(); LocalDate lastRestDate = currentDate; - if (loanApplicationTerms.isInterestRecalculationEnabled()) { + if (loanApplicationTerms.isInterestBearingAndInterestRecalculationEnabled()) { lastRestDate = getNextRestScheduleDate(currentDate.minusDays(1), loanApplicationTerms, holidayDetailDTO); } LocalDate actualRepaymentDate = RepaymentStartDateType.DISBURSEMENT_DATE @@ -2412,7 +2412,7 @@ public abstract class AbstractCumulativeLoanScheduleGenerator implements LoanSch instalmentNumber++; loanTermInDays = DateUtils.getExactDifferenceInDays(installment.getFromDate(), installment.getDueDate()); - if (loanApplicationTerms.isInterestRecalculationEnabled()) { + if (loanApplicationTerms.isInterestBearingAndInterestRecalculationEnabled()) { // populates the collection with transactions till the due // date diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java index 2c33bfa1d..7dde2c14b 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/domain/LoanApplicationTerms.java @@ -1677,6 +1677,14 @@ public final class LoanApplicationTerms { return LoanRescheduleStrategyMethod.REDUCE_EMI_AMOUNT; } + public boolean isInterestBearing() { + return BigDecimal.ZERO.compareTo(getAnnualNominalInterestRate()) < 0; + } + + public boolean isInterestBearingAndInterestRecalculationEnabled() { + return isInterestBearing() && isInterestRecalculationEnabled(); + } + public boolean isInterestRecalculationEnabled() { return this.interestRecalculationEnabled; } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java index 377de9310..aa27fc5ca 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanArrearsAgingServiceImpl.java @@ -385,7 +385,7 @@ public class LoanArrearsAgingServiceImpl implements LoanArrearsAgingService { } private void handleArrearsForLoan(Loan loan) { - if (loan != null && loan.isOpen() && loan.repaymentScheduleDetail().isInterestRecalculationEnabled() + if (loan != null && loan.isOpen() && loan.isInterestBearingAndInterestRecalculationEnabled() && loan.loanProduct().isArrearsBasedOnOriginalSchedule()) { updateLoanArrearsAgeingDetailsWithOriginalSchedule(loan); } else { diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java index 93abc3746..f6819f4dd 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImpl.java @@ -137,12 +137,12 @@ public class LoanDownPaymentHandlerServiceImpl implements LoanDownPaymentHandler || !currentInstallment.getTotalOutstanding(loan.getCurrency()).isEqualTo(loanTransaction.getAmount(loan.getCurrency())); if (isTransactionChronologicallyLatest && adjustedTransaction == null - && (!reprocess || !loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) && !loan.isForeclosure()) { + && (!reprocess || !loan.isInterestBearingAndInterestRecalculationEnabled()) && !loan.isForeclosure()) { loanRepaymentScheduleTransactionProcessor.processLatestTransaction(loanTransaction, new TransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(), loan.getActiveCharges(), new MoneyHolder(loan.getTotalOverpaidAsMoney()), null)); reprocess = false; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { if (currentInstallment == null || currentInstallment.isNotFullyPaidOff()) { reprocess = true; } else { @@ -155,7 +155,7 @@ public class LoanDownPaymentHandlerServiceImpl implements LoanDownPaymentHandler } } if (reprocess) { - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() + if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.getLoanProductRelatedDetail().getLoanScheduleType().equals(LoanScheduleType.PROGRESSIVE)) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else if (loan.getLoanProductRelatedDetail() != null diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanScheduleService.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanScheduleService.java index 86cb820a7..a04de6c7b 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanScheduleService.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanScheduleService.java @@ -54,7 +54,7 @@ public class LoanScheduleService { } public void recalculateScheduleFromLastTransaction(final Loan loan, final ScheduleGeneratorDTO generatorDTO) { - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && !loan.isChargedOff()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.isChargedOff()) { regenerateRepaymentScheduleWithInterestRecalculation(loan, generatorDTO); } else { regenerateRepaymentSchedule(loan, generatorDTO); @@ -73,7 +73,7 @@ public class LoanScheduleService { * loanTransaction.getTransactionDate().isAfter(recalculateFrom)) { recalculateFrom = * loanTransaction.getTransactionDate(); } } generatorDTO.setRecalculateFrom(recalculateFrom); */ - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && !loan.isChargedOff()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.isChargedOff()) { regenerateRepaymentScheduleWithInterestRecalculation(loan, generatorDTO); } else { regenerateRepaymentSchedule(loan, generatorDTO); diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java index e51758985..3c845ac76 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessor.java @@ -987,7 +987,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep private void recalculateInterestForDate(LocalDate targetDate, ProgressiveTransactionCtx ctx) { if (ctx.getInstallments() != null && !ctx.getInstallments().isEmpty()) { Loan loan = ctx.getInstallments().get(0).getLoan(); - if (loan.isInterestRecalculationEnabled() && !loan.isNpa() && !ctx.isChargedOff()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.isNpa() && !ctx.isChargedOff()) { List overdueInstallmentsSortedByInstallmentNumber = findOverdueInstallmentsBeforeDateSortedByInstallmentNumber( targetDate, ctx); @@ -1226,7 +1226,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep if (!installments.isEmpty() && transactionDate.isBefore(loan.getMaturityDate())) { if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx - && loanTransaction.getLoan().isInterestRecalculationEnabled()) { + && loanTransaction.getLoan().isInterestBearingAndInterestRecalculationEnabled()) { final BigDecimal newInterest = emiCalculator .getPeriodInterestTillDate(progressiveTransactionCtx.getModel(), currentInstallment.getDueDate(), transactionDate) .getAmount(); @@ -1291,7 +1291,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep if (!installments.isEmpty()) { if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx - && loanTransaction.getLoan().isInterestRecalculationEnabled()) { + && loanTransaction.getLoan().isInterestBearingAndInterestRecalculationEnabled()) { installments.stream().filter(installment -> !installment.getFromDate().isAfter(transactionDate) && installment.getDueDate().isAfter(transactionDate)).forEach(installment -> { final BigDecimal newInterest = emiCalculator.getPeriodInterestTillDate(progressiveTransactionCtx.getModel(), @@ -1683,8 +1683,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep LoanTransactionToRepaymentScheduleMapping loanTransactionToRepaymentScheduleMapping = getTransactionMapping( transactionMappings, loanTransaction, oldestPastDueInstallment, currency); Loan loan = loanTransaction.getLoan(); - if (transactionCtx instanceof ProgressiveTransactionCtx ctx && loan.isInterestBearing() - && loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled() && !ctx.isChargedOff()) { + if (transactionCtx instanceof ProgressiveTransactionCtx ctx + && loan.isInterestBearingAndInterestRecalculationEnabled() && !ctx.isChargedOff()) { paidPortion = handlingPaymentAllocationForInterestBearingProgressiveLoan(loanTransaction, transactionAmountUnprocessed, balances, paymentAllocationType, oldestPastDueInstallment, ctx, loanTransactionToRepaymentScheduleMapping, oldestPastDueInstallmentCharges); @@ -1705,8 +1705,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep LoanTransactionToRepaymentScheduleMapping loanTransactionToRepaymentScheduleMapping = getTransactionMapping( transactionMappings, loanTransaction, dueInstallment, currency); Loan loan = loanTransaction.getLoan(); - if (transactionCtx instanceof ProgressiveTransactionCtx ctx && loan.isInterestBearing() - && loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled() && !ctx.isChargedOff()) { + if (transactionCtx instanceof ProgressiveTransactionCtx ctx + && loan.isInterestBearingAndInterestRecalculationEnabled() && !ctx.isChargedOff()) { paidPortion = handlingPaymentAllocationForInterestBearingProgressiveLoan(loanTransaction, transactionAmountUnprocessed, balances, paymentAllocationType, dueInstallment, ctx, loanTransactionToRepaymentScheduleMapping, dueInstallmentCharges); @@ -1740,8 +1740,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep if (inAdvanceInstallment.equals(inAdvanceInstallments.get(numberOfInstallments - 1))) { evenPortion = evenPortion.add(balanceAdjustment); } - if (transactionCtx instanceof ProgressiveTransactionCtx ctx && loan.isInterestBearing() - && loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled() && !ctx.isChargedOff()) { + if (transactionCtx instanceof ProgressiveTransactionCtx ctx + && loan.isInterestBearingAndInterestRecalculationEnabled() && !ctx.isChargedOff()) { paidPortion = handlingPaymentAllocationForInterestBearingProgressiveLoan(loanTransaction, evenPortion, balances, paymentAllocationType, inAdvanceInstallment, ctx, loanTransactionToRepaymentScheduleMapping, inAdvanceInstallmentCharges); diff --git a/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java b/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java index 4b7d1e98a..362a0f95e 100644 --- a/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java +++ b/fineract-progressive-loan/src/test/java/org/apache/fineract/portfolio/loanaccount/domain/transactionprocessor/impl/AdvancedPaymentScheduleTransactionProcessorTest.java @@ -449,16 +449,13 @@ class AdvancedPaymentScheduleTransactionProcessorTest { Loan loan = mock(Loan.class); LoanProductRelatedDetail loanProductRelatedDetail = mock(LoanProductRelatedDetail.class); LoanPaymentAllocationRule loanPaymentAllocationRule = mock(LoanPaymentAllocationRule.class); - when(loan.isInterestBearing()).thenReturn(true); - when(loanProductRelatedDetail.isInterestRecalculationEnabled()).thenReturn(true); + when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail); + when(loanProductRelatedDetail.getLoanScheduleProcessingType()).thenReturn(LoanScheduleProcessingType.HORIZONTAL); + when(loan.isInterestBearingAndInterestRecalculationEnabled()).thenReturn(Boolean.TRUE); when(loanTransaction.getLoan()).thenReturn(loan); when(loan.getCurrency()).thenReturn(currency); - when(loan.getLoanProductRelatedDetail()).thenReturn(loanProductRelatedDetail); - when(loanProductRelatedDetail.getLoanScheduleProcessingType()).thenReturn(LoanScheduleProcessingType.HORIZONTAL); when(loan.getPaymentAllocationRules()).thenReturn(List.of(loanPaymentAllocationRule)); - when(loan.isInterestBearing()).thenReturn(true); - when(loanProductRelatedDetail.isInterestRecalculationEnabled()).thenReturn(true); when(loanPaymentAllocationRule.getTransactionType()).thenReturn(PaymentAllocationTransactionType.DEFAULT); when(loanPaymentAllocationRule.getAllocationTypes()) diff --git a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInterestRecalculationCOBBusinessStep.java b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInterestRecalculationCOBBusinessStep.java index 26dceb627..099e7cc2e 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInterestRecalculationCOBBusinessStep.java +++ b/fineract-provider/src/main/java/org/apache/fineract/cob/loan/LoanInterestRecalculationCOBBusinessStep.java @@ -35,8 +35,7 @@ public class LoanInterestRecalculationCOBBusinessStep implements LoanCOBBusiness @Override public Loan execute(Loan loan) { - if (!loan.isInterestBearing() || !loan.getStatus().isActive() || loan.isNpa() || loan.isChargedOff() - || !loan.isInterestRecalculationEnabled() + if (!loan.getStatus().isActive() || loan.isNpa() || loan.isChargedOff() || !loan.isInterestBearingAndInterestRecalculationEnabled() || loan.getLoanInterestRecalculationDetails().disallowInterestCalculationOnPastDue()) { log.debug( "Skip processing loan interest recalculation [{}] - Possible reasons: Loan is not an interest bearing loan, Loan is not active, Interest recalculation on past due is disabled on this loan", diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java index f29078d6e..3318e6a89 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java @@ -246,7 +246,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } LocalDate recalculateFrom = null; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { recalculateFrom = transactionDate; } final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom, @@ -267,7 +267,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { final ChangedTransactionDetail changedTransactionDetail = makeRepayment(loan, newRepaymentTransaction, defaultLoanLifecycleStateMachine, existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.reprocessExistingAccruals(loan); loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -294,8 +294,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { this.noteRepository.save(note); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); setLoanDelinquencyTag(loan, transactionDate); @@ -495,8 +495,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { this.noteRepository.save(note); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanChargePaymentPostBusinessEvent(newPaymentTransaction)); @@ -729,8 +729,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { this.noteRepository.save(note); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService .notifyPostBusinessEvent(new LoanCreditBalanceRefundPostBusinessEvent(newCreditBalanceRefundTransaction)); @@ -783,8 +783,8 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { this.noteRepository.save(note); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanRefundPostBusinessEvent(newRefundTransaction)); @@ -845,7 +845,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { defaultLoanLifecycleStateMachine, scheduleGeneratorDTO); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -959,7 +959,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { final LoanRepaymentScheduleInstallment currentInstallment = loan.fetchLoanRepaymentScheduleInstallmentByDueDate(transactionDate); - boolean reprocess = loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled() // + boolean reprocess = loan.isInterestBearingAndInterestRecalculationEnabled() // || loan.isForeclosure() // || !isTransactionChronologicallyLatest // || !DateUtils.isEqualBusinessDate(transactionDate) // @@ -978,7 +978,7 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { new MoneyHolder(loan.getTotalOverpaidAsMoney()), null)); } } else { - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else if (loan.getLoanProductRelatedDetail() != null && loan.getLoanProductRelatedDetail().getLoanScheduleType().equals(LoanScheduleType.PROGRESSIVE) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java index 6baf6e320..f5d493511 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/loanschedule/service/LoanScheduleCalculationPlatformServiceImpl.java @@ -88,8 +88,7 @@ public class LoanScheduleCalculationPlatformServiceImpl implements LoanScheduleC final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loanRepaymentScheduleTransactionProcessorFactory .determineProcessor(loan.transactionProcessingStrategy()); - if (!loan.repaymentScheduleDetail().isInterestRecalculationEnabled() || loan.isNpa() || loan.isChargedOff() - || !loan.getStatus().isActive() + if (!loan.isInterestBearingAndInterestRecalculationEnabled() || loan.isNpa() || loan.isChargedOff() || !loan.getStatus().isActive() || !loanRepaymentScheduleTransactionProcessor.isInterestFirstRepaymentScheduleTransactionProcessor()) { return; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanForeclosureValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanForeclosureValidator.java index 8eba2c376..78a1377d9 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanForeclosureValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanForeclosureValidator.java @@ -28,7 +28,7 @@ import org.springframework.stereotype.Component; public final class LoanForeclosureValidator { public void validateForForeclosure(final Loan loan, final LocalDate transactionDate) { - if (loan.isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { final String defaultUserMessage = "The loan with interest recalculation enabled cannot be foreclosed."; throw new LoanForeclosureException("loan.with.interest.recalculation.enabled.cannot.be.foreclosured", defaultUserMessage, loan.getId()); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidator.java index 35f6dc693..ac65ac45f 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidator.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidator.java @@ -685,7 +685,7 @@ public final class LoanTransactionValidator { } public void validateActivityNotBeforeLastTransactionDate(final Loan loan, final LocalDate activityDate, final LoanEvent event) { - if (!(loan.repaymentScheduleDetail().isInterestRecalculationEnabled() || loan.loanProduct().isHoldGuaranteeFunds()) + if (!(loan.isInterestBearingAndInterestRecalculationEnabled() || loan.loanProduct().isHoldGuaranteeFunds()) || !loan.getLoanRepaymentScheduleDetail().getLoanScheduleType().equals(LoanScheduleType.CUMULATIVE)) { return; } @@ -985,8 +985,7 @@ public final class LoanTransactionValidator { private void validateTransactionNotBeforeLastTransactionDate(final Loan loan, LoanTransactionType loanTransactionType, final LocalDate transactionDate) { if (!((LoanScheduleType.CUMULATIVE.equals(loan.getLoanProductRelatedDetail().getLoanScheduleType()) - && loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) - || loan.getLoanProduct().isHoldGuaranteeFunds())) { + && loan.isInterestBearingAndInterestRecalculationEnabled()) || loan.getLoanProduct().isHoldGuaranteeFunds())) { return; } LocalDate lastTransactionDate = loan.getLastUserTransactionDate(); diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java index 4499fae5e..c481fb163 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanApplicationWritePlatformServiceJpaRepositoryImpl.java @@ -280,7 +280,7 @@ public class LoanApplicationWritePlatformServiceJpaRepositoryImpl implements Loa // TODO: check whether this is needed! this.loanRepositoryWrapper.saveAndFlush(loan); // Save interest recalculation calendar - if (loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled() + if (loan.isInterestBearingAndInterestRecalculationEnabled() && changes.containsKey(LoanProductConstants.IS_INTEREST_RECALCULATION_ENABLED_PARAMETER_NAME)) { createAndPersistCalendarInstanceForInterestRecalculation(loan); } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java index 6f52d0903..dff251e36 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanChargeWritePlatformServiceImpl.java @@ -268,7 +268,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo boolean reprocessRequired = true; // overpaid transactions will be reprocessed and pay this charge boolean overpaidReprocess = !loanCharge.isDueAtDisbursement() && !loanCharge.isPaid() && loan.getStatus().isOverpaid(); - if (!overpaidReprocess && loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (!overpaidReprocess && loan.isInterestBearingAndInterestRecalculationEnabled()) { if (isAppliedOnBackDate && loan.isFeeCompoundingEnabledForInterestRecalculation()) { loan = runScheduleRecalculation(loan, recalculateFrom); reprocessRequired = false; @@ -308,7 +308,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo loan = loanAccountDomainService.saveAndFlushLoanWithDataIntegrityViolationChecks(loan); } - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && isAppliedOnBackDate + if (loan.isInterestBearingAndInterestRecalculationEnabled() && isAppliedOnBackDate && loan.isFeeCompoundingEnabledForInterestRecalculation()) { loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, true, false); } @@ -558,7 +558,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo existingTransactionIds, existingReversedTransactionIds, loanInstallmentNumber, scheduleGeneratorDTO, accruedCharge, externalId); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled() + if (loan.isInterestBearingAndInterestRecalculationEnabled() && DateUtils.isBefore(loanCharge.getDueLocalDate(), DateUtils.getBusinessLocalDate())) { loanAccrualsProcessingService.reprocessExistingAccruals(loan); loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); @@ -810,7 +810,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo recalculateFrom = recalculatedTill; } - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { if (runInterestRecalculation && loan.isFeeCompoundingEnabledForInterestRecalculation()) { loan = runScheduleRecalculation(loan, recalculateFrom); reprocessRequired = false; @@ -839,7 +839,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo loan = loanAccountDomainService.saveAndFlushLoanWithDataIntegrityViolationChecks(loan); } - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && runInterestRecalculation + if (loan.isInterestBearingAndInterestRecalculationEnabled() && runInterestRecalculation && loan.isFeeCompoundingEnabledForInterestRecalculation()) { loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, true, false); } @@ -865,7 +865,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = loanRepaymentScheduleTransactionProcessorFactory .determineProcessor(loan.transactionProcessingStrategy()); loan.addLoanTransaction(loanChargeAdjustmentTransaction); - if (loan.isInterestBearing() && loan.getLoanProductRelatedDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loan.getLoanProductRelatedDetail() != null && loan.getLoanProductRelatedDetail().getLoanScheduleType().equals(LoanScheduleType.PROGRESSIVE) && loan.getLoanTransactions().stream().anyMatch(LoanTransaction::isChargeOff)) { @@ -1019,7 +1019,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo } else if (loanCharge.getDueLocalDate() != null) { // TODO: Review, error message seems not valid if interest recalculation is not enabled. boolean isCumulative = loan.getLoanRepaymentScheduleDetail().getLoanScheduleType().equals(LoanScheduleType.CUMULATIVE); - LocalDate validationDate = loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && isCumulative + LocalDate validationDate = loan.isInterestBearingAndInterestRecalculationEnabled() && isCumulative ? loan.getLastUserTransactionDate() : loan.getDisbursementDate(); if (DateUtils.isBefore(loanCharge.getDueLocalDate(), validationDate)) { @@ -1027,7 +1027,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo throw new LoanChargeCannotBeAddedException("loanCharge", "date.is.before.last.transaction.date", defaultUserMessage, null, chargeDefinition.getName()); } - } else if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + } else if (loan.isInterestBearingAndInterestRecalculationEnabled()) { if (loanCharge.isInstalmentFee() && loan.getStatus().isActive()) { final String defaultUserMessage = "installment charge addition not allowed after disbursement"; throw new LoanChargeCannotBeAddedException("loanCharge", "installment.charge", defaultUserMessage, null, @@ -1173,7 +1173,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo } public Loan runScheduleRecalculation(Loan loan, final LocalDate recalculateFrom) { - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && !loan.isChargedOff()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.isChargedOff()) { final List existingTransactionIds = loan.findExistingTransactionIds(); ScheduleGeneratorDTO generatorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); ChangedTransactionDetail changedTransactionDetail = loanScheduleService @@ -1456,8 +1456,7 @@ public class LoanChargeWritePlatformServiceImpl implements LoanChargeWritePlatfo waiveLoanChargeTransaction.getAmount(loan.getCurrency()).getAmount(), loanInstallmentNumber); waiveLoanChargeTransaction.getLoanChargesPaid().add(loanChargePaidBy); loan.addLoanTransaction(waiveLoanChargeTransaction); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() - && DateUtils.isBefore(loanCharge.getDueLocalDate(), businessDate)) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() && DateUtils.isBefore(loanCharge.getDueLocalDate(), businessDate)) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else if (loan.getLoanProductRelatedDetail() != null && loan.getLoanProductRelatedDetail().getLoanScheduleType().equals(LoanScheduleType.PROGRESSIVE) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java index 482ad8398..7a0c5f953 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanUtilService.java @@ -92,7 +92,7 @@ public class LoanUtilService { CalendarInstance restCalendarInstance = null; CalendarInstance compoundingCalendarInstance = null; Long overdurPenaltyWaitPeriod = null; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { restCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(), CalendarEntityType.LOAN_RECALCULATION_REST_DETAIL.getValue()); compoundingCalendarInstance = calendarInstanceRepository.findCalendarInstaneByEntityId(loan.loanInterestRecalculationDetailId(), diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index b089fab99..132f43c14 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -426,7 +426,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, rescheduledRepaymentDate); boolean downPaymentEnabled = loan.repaymentScheduleDetail().isEnableDownPayment(); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() || downPaymentEnabled) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() || downPaymentEnabled) { createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO); } ChangedTransactionDetail changedTransactionDetail = disburseLoan(command, isPaymentTypeApplicableForDisbursementCharge, @@ -436,7 +436,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loanAccrualsProcessingService.reprocessExistingAccruals(loan); LocalDate firstInstallmentDueDate = loan.fetchRepaymentScheduleInstallment(1).getDueDate(); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled() + if (loan.isInterestBearingAndInterestRecalculationEnabled() && (DateUtils.isBeforeBusinessDate(firstInstallmentDueDate) || loan.isDisbursementMissed())) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -481,7 +481,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } else { loanDownPaymentHandlerService.handleDownPayment(scheduleGeneratorDTO, command, disbursementTransaction, loan); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } } @@ -518,8 +518,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.accountTransfersWritePlatformService.transferFunds(accountTransferDTO); } updateRecurringCalendarDatesForInterestRecalculation(loan); - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); this.loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); // Post Dated Checks @@ -584,7 +584,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf boolean disbursementMissedParam = loan.isDisbursementMissed(); LocalDate firstInstallmentDueDate = loan.fetchRepaymentScheduleInstallment(1).getDueDate(); - if ((loan.repaymentScheduleDetail().isInterestRecalculationEnabled() + if ((loan.isInterestBearingAndInterestRecalculationEnabled() && (DateUtils.isBeforeBusinessDate(firstInstallmentDueDate) || disbursementMissedParam))) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } @@ -681,7 +681,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private void updateRecurringCalendarDatesForInterestRecalculation(final Loan loan) { - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() + if (loan.isInterestBearingAndInterestRecalculationEnabled() && loan.loanInterestRecalculationDetails().getRestFrequencyType().isSameAsRepayment()) { final CalendarInstance calendarInstanceForInterestRecalculation = this.calendarInstanceRepository .findByEntityIdAndEntityTypeIdAndCalendarTypeId(loan.loanInterestRecalculationDetailId(), @@ -810,7 +810,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf regenerateScheduleOnDisbursement(command, loan, recalculateSchedule, scheduleGeneratorDTO, nextPossibleRepaymentDate, rescheduledRepaymentDate); boolean downPaymentEnabled = loan.repaymentScheduleDetail().isEnableDownPayment(); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() || downPaymentEnabled) { + if (loan.isInterestBearingAndInterestRecalculationEnabled() || downPaymentEnabled) { createAndSaveLoanScheduleArchive(loan, scheduleGeneratorDTO); } changedTransactionDetail = disburseLoan(command, configurationDomainService.isPaymentTypeApplicableForDisbursementCharge(), @@ -819,7 +819,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loanAccrualsProcessingService.reprocessExistingAccruals(loan); LocalDate firstInstallmentDueDate = loan.fetchRepaymentScheduleInstallment(1).getDueDate(); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled() + if (loan.isInterestBearingAndInterestRecalculationEnabled() && (DateUtils.isBeforeBusinessDate(firstInstallmentDueDate) || loan.isDisbursementMissed())) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -865,7 +865,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } updateRecurringCalendarDatesForInterestRecalculation(loan); loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), true); + loan.isInterestBearingAndInterestRecalculationEnabled(), true); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); businessEventNotifierService.notifyPostBusinessEvent(new LoanDisbursalBusinessEvent(loan)); } @@ -1081,7 +1081,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LoanTransaction newInterestPaymentWaiverTransaction) { LocalDate recalculateFrom = null; LocalDate transactionDate = newInterestPaymentWaiverTransaction.getTransactionDate(); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { recalculateFrom = transactionDate; } final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom, null); @@ -1107,13 +1107,13 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf reprocess = false; } - if (isTransactionChronologicallyLatest && (!reprocess || !loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) + if (isTransactionChronologicallyLatest && (!reprocess || !loan.isInterestBearingAndInterestRecalculationEnabled()) && !loan.isForeclosure()) { loanRepaymentScheduleTransactionProcessor.processLatestTransaction(newInterestPaymentWaiverTransaction, new TransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(), loan.getActiveCharges(), new MoneyHolder(loan.getTotalOverpaidAsMoney()), null)); reprocess = false; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { if (currentInstallment == null || currentInstallment.isNotFullyPaidOff()) { reprocess = true; } else { @@ -1140,7 +1140,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf private ChangedTransactionDetail reprocessChangedLoanTransactions(Loan loan, LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor, ScheduleGeneratorDTO scheduleGeneratorDTO) { - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else if (loan.getLoanProductRelatedDetail() != null @@ -1151,7 +1151,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf ChangedTransactionDetail changedTransactionDetail = loan.reprocessTransactions(); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.reprocessExistingAccruals(loan); loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -1192,8 +1192,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf saveNote(noteText, loan, newInterestPaymentWaiverTransaction); - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); loanAccountDomainService.setLoanDelinquencyTag(loan, newInterestPaymentWaiverTransaction.getTransactionDate()); // disable all active standing orders linked to this loan if status changes to closed @@ -1432,7 +1432,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LocalDate recalculateFrom = null; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { recalculateFrom = DateUtils.isAfter(transactionToAdjust.getTransactionDate(), transactionDate) ? transactionDate : transactionToAdjust.getTransactionDate(); } @@ -1456,7 +1456,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf scheduleGeneratorDTO, reversalTxnExternalId); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -1512,8 +1512,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loan.updateLoanSummaryAndStatus(); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); this.loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); @@ -1635,7 +1635,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf throw new PlatformServiceUnavailableException("error.msg.loan.chargeback.operation.not.allowed", "Loan transaction:" + transactionId + " chargeback not allowed as loan status is written off", transactionId); } - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { throw new PlatformServiceUnavailableException("error.msg.loan.chargeback.operation.not.allowed", "Loan transaction:" + transactionId + " chargeback not allowed as loan product is interest recalculation enabled", transactionId); @@ -1753,7 +1753,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf transactionDate, interestComponent, unrecognizedIncome, externalId); businessEventNotifierService.notifyPreBusinessEvent(new LoanWaiveInterestBusinessEvent(waiveInterestTransaction)); LocalDate recalculateFrom = null; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { recalculateFrom = transactionDate; } @@ -1766,7 +1766,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final ChangedTransactionDetail changedTransactionDetail = waiveInterest(loan, waiveInterestTransaction, loanLifecycleStateMachine, existingTransactionIds, existingReversedTransactionIds, scheduleGeneratorDTO); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.reprocessExistingAccruals(loan); loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -1796,8 +1796,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.noteRepository.save(note); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); @@ -1856,7 +1856,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf updateLoanCounters(loan, loan.getDisbursementDate()); LocalDate recalculateFrom = null; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { recalculateFrom = command.localDateValueOfParameterNamed("transactionDate"); } @@ -1879,7 +1879,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (changedTransactionDetail != null) { loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } LoanTransaction writeOff = changedTransactionDetail.getNewTransactionMappings().remove(0L); @@ -1896,7 +1896,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf this.noteRepository.save(note); } loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loan.isInterestBearingAndInterestRecalculationEnabled(), false); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanWrittenOffPostBusinessEvent(writeOff)); @@ -1938,7 +1938,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf updateLoanCounters(loan, loan.getDisbursementDate()); LocalDate recalculateFrom = null; - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { recalculateFrom = command.localDateValueOfParameterNamed("transactionDate"); } @@ -1950,7 +1950,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf existingReversedTransactionIds, scheduleGeneratorDTO); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -1972,8 +1972,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } loanAccrualTransactionBusinessEventService.raiseBusinessEventForAccrualTransactions(loan, existingTransactionIds); - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); @@ -2387,7 +2387,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } holidays = this.holidayRepository.findByOfficeIdAndGreaterThanDate(loan.getOfficeId(), loan.getDisbursementDate()); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { ScheduleGeneratorDTO scheduleGeneratorDTO = loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); loan.setHelpers(null, this.transactionProcessingStrategy); loanScheduleService.recalculateScheduleFromLastTransaction(loan, scheduleGeneratorDTO, existingTransactionIds, @@ -2402,7 +2402,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } saveLoanWithDataIntegrityViolationChecks(loan); @@ -2592,7 +2592,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf ChangedTransactionDetail changedTransactionDetail = undoWrittenOff(loan, loanLifecycleStateMachine, existingTransactionIds, existingReversedTransactionIds); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } if (changedTransactionDetail != null) { @@ -2605,8 +2605,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan); - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); businessEventNotifierService.notifyPostBusinessEvent(new LoanUndoWrittenOffBusinessEvent(writeOffTransaction)); @@ -2739,7 +2739,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } else { loan.repaymentScheduleDetail().setPrincipal(loan.getPrincipalAmountForRepaymentSchedule()); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else { loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); @@ -2748,7 +2748,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -2761,11 +2761,11 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail); } loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { createLoanScheduleArchive(loan, scheduleGeneratorDTO); } - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); this.loanAccountDomainService.setLoanDelinquencyTag(loan, DateUtils.getBusinessLocalDate()); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); @@ -2821,7 +2821,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf existingTransactionIds, existingReversedTransactionIds); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -2834,8 +2834,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf replayedTransactionBusinessEventService.raiseTransactionReplayedEvents(changedTransactionDetail); } loan = saveAndFlushLoanWithDataIntegrityViolationChecks(loan); - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); businessEventNotifierService.notifyPostBusinessEvent(new LoanInterestRecalculationBusinessEvent(loan)); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds); @@ -2860,7 +2860,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf @Override public void updateOriginalSchedule(Loan loan) { - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { final LocalDate recalculateFrom = null; ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom); createLoanScheduleArchive(loan, scheduleGeneratorDTO); @@ -2909,7 +2909,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (loan.isActualDisbursedOnDateEarlierOrLaterThanExpected(actualDisbursementDate) || recalculateSchedule || isEmiAmountChanged || rescheduledRepaymentDate != null) { - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else { loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); @@ -2917,7 +2917,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf } loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -3098,7 +3098,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loan); loanAccrualsProcessingService.reprocessExistingAccruals(loan); - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -3224,7 +3224,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final LoanTransaction chargeOffTransaction = LoanTransaction.chargeOff(loan, transactionDate, txnExternalId); - if (loan.isInterestBearing() && loan.isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, null, null); loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); loan.addLoanTransaction(chargeOffTransaction); @@ -3310,7 +3310,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf if (loan.isProgressiveSchedule()) { final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, null, null); - if (loan.isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } else { loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); @@ -3359,7 +3359,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf Loan loan = this.loanAssembler.assembleFrom(loanId); // Build loan schedule generator dto - LocalDate recalculateFrom = loan.repaymentScheduleDetail().isInterestRecalculationEnabled() ? transactionDate : null; + LocalDate recalculateFrom = loan.isInterestBearingAndInterestRecalculationEnabled() ? transactionDate : null; final ScheduleGeneratorDTO scheduleGeneratorDTO = this.loanUtilService.buildScheduleGeneratorDTO(loan, recalculateFrom, null); // Domain rule validations this.loanTransactionValidator.validateRefund(loan, loanTransactionType, transactionDate, scheduleGeneratorDTO); @@ -3376,7 +3376,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LoanTransaction refundTransaction = refundTransactions.getLeft(); LoanTransaction interestRefundTransaction = refundTransactions.getRight(); // Accrual reprocessing - if (loan.getLoanRepaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanAccrualsProcessingService.reprocessExistingAccruals(loan); loanAccrualsProcessingService.processIncomePostingAndAccruals(loan); } @@ -3398,8 +3398,8 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loanAccountDomainService.updateAndSaveLoanCollateralTransactionsForIndividualAccounts(loan, refundTransaction); } // Raise business events - loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, - loan.repaymentScheduleDetail().isInterestRecalculationEnabled(), false); + loanAccrualsProcessingService.processAccrualsOnInterestRecalculation(loan, loan.isInterestBearingAndInterestRecalculationEnabled(), + false); businessEventNotifierService.notifyPostBusinessEvent(new LoanBalanceChangedBusinessEvent(loan)); // Create journal entries for the new transaction(s) @@ -3504,7 +3504,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf updateLoanToPreDisbursalState(loan); if (isScheduleRegenerateRequired || isDisbursedAmountChanged || isEmiAmountChanged - || loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + || loan.isInterestBearingAndInterestRecalculationEnabled()) { // clear off actual disbusrement date so schedule regeneration // uses expected date. @@ -3644,7 +3644,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loan.getLoanRepaymentScheduleDetail().setPrincipal(loan.getDisbursedAmount()); loan.removeDisbursementDetail(); loanScheduleService.regenerateRepaymentSchedule(loan, scheduleGeneratorDTO); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled()) { + if (loan.isInterestBearingAndInterestRecalculationEnabled()) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); } if (loan.getLoanProductRelatedDetail() != null @@ -3766,7 +3766,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf loan.getLoanRepaymentScheduleDetail().setPrincipal(loan.getPrincipalAmountForRepaymentSchedule()); - if (loan.repaymentScheduleDetail().isInterestRecalculationEnabled() && !(loan.getLoanProductRelatedDetail() != null + if (loan.isInterestBearingAndInterestRecalculationEnabled() && !(loan.getLoanProductRelatedDetail() != null && loan.getLoanProductRelatedDetail().getLoanScheduleType().equals(LoanScheduleType.PROGRESSIVE) && loan.getLoanTransactions().stream().anyMatch(LoanTransaction::isChargeOff))) { loanScheduleService.regenerateRepaymentScheduleWithInterestRecalculation(loan, scheduleGeneratorDTO); diff --git a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java index 14c233033..47db3cde1 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/portfolio/loanaccount/service/LoanDownPaymentHandlerServiceImplTest.java @@ -145,6 +145,7 @@ public class LoanDownPaymentHandlerServiceImplTest { when(loanForProcessing.getLoanRepaymentScheduleDetail()).thenReturn(loanRepaymentRelatedDetail); when(loanForProcessing.repaymentScheduleDetail()).thenReturn(loanRepaymentRelatedDetail); when(loanRepaymentRelatedDetail.isInterestRecalculationEnabled()).thenReturn(true); + when(loanForProcessing.isInterestBearingAndInterestRecalculationEnabled()).thenReturn(true); when(loanRepaymentRelatedDetail.getDisbursedAmountPercentageForDownPayment()).thenReturn(BigDecimal.valueOf(10)); when(loanForProcessing.getCurrency()).thenReturn(loanCurrency); when(loanForProcessing.loanCurrency()).thenReturn(loanCurrency);