FINERACT-2081: Interest recalculation only for interest bearing loans

This commit is contained in:
Adam Saghy
2025-02-06 14:11:06 +01:00
parent 493012bf8c
commit 79c5fc1649
18 changed files with 128 additions and 123 deletions
@@ -2658,6 +2658,10 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
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<Long> {
}
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<Long> {
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();
@@ -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<LocalDate, Map<LocalDate, Money>> 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
@@ -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;
}
@@ -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 {
@@ -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
@@ -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);
@@ -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<LoanRepaymentScheduleInstallment> 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);
@@ -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())
@@ -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",
@@ -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)
@@ -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;
}
@@ -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());
@@ -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();
@@ -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);
}
@@ -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<Long> 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)
@@ -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(),
@@ -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);
@@ -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);