Repository: incubator-fineract Updated Branches: refs/heads/develop e338658a4 -> dfd33bd2d
fineract(185,182,173,175) Project: http://git-wip-us.apache.org/repos/asf/incubator-fineract/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-fineract/commit/b5be4d25 Tree: http://git-wip-us.apache.org/repos/asf/incubator-fineract/tree/b5be4d25 Diff: http://git-wip-us.apache.org/repos/asf/incubator-fineract/diff/b5be4d25 Branch: refs/heads/develop Commit: b5be4d25040be3817c9c1ec1bdf60bdc7ccafced Parents: a89a43a Author: keshav10 <[email protected]> Authored: Tue Jun 21 19:15:43 2016 +0530 Committer: keshav10 <[email protected]> Committed: Tue Jun 21 19:15:43 2016 +0530 ---------------------------------------------------------------------- .../portfolio/loanaccount/domain/Loan.java | 120 ++++++++++++------- .../domain/LoanAccountDomainServiceJpa.java | 50 +++++--- .../LoanRepaymentScheduleInstallment.java | 5 + .../service/LoanWritePlatformService.java | 2 +- ...anWritePlatformServiceJpaRepositoryImpl.java | 3 +- 5 files changed, 113 insertions(+), 67 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b5be4d25/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index 42427c4..e0428b0 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -2986,13 +2986,13 @@ public class Loan extends AbstractPersistable<Long> { boolean reprocess = true; if (isTransactionChronologicallyLatest && adjustedTransaction == null - && loanTransaction.getTransactionDate().isEqual(LocalDate.now()) && currentInstallment != null + && loanTransaction.getTransactionDate().isEqual(DateUtils.getLocalDateOfTenant()) && currentInstallment != null && currentInstallment.getTotalOutstanding(getCurrency()).isEqualTo(loanTransaction.getAmount(getCurrency()))) { reprocess = false; } if (isTransactionChronologicallyLatest && adjustedTransaction == null - && (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled())) { + && (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled()) && !isForeclosure()) { loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), this.repaymentScheduleInstallments, charges()); reprocess = false; @@ -6003,9 +6003,10 @@ public class Loan extends AbstractPersistable<Long> { return loanProduct; } - public LoanRepaymentScheduleInstallment fetchLoanForeclosureDetail(final LocalDate closureDate) { - Money totalPrincipal = Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding()); + public LoanRepaymentScheduleInstallment fetchLoanForeclosureDetail(final LocalDate closureDate) { Money[] receivables = retriveIncomeOutstandingTillDate(closureDate); + Money totalPrincipal = (Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding())); + totalPrincipal = totalPrincipal.minus(receivables[3]); final List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null; final LocalDate currentDate = DateUtils.getLocalDateOfTenant(); return new LoanRepaymentScheduleInstallment(null, 0, currentDate, currentDate, totalPrincipal.getAmount(), @@ -6013,45 +6014,65 @@ public class Loan extends AbstractPersistable<Long> { } public Money[] retriveIncomeOutstandingTillDate(final LocalDate paymentDate) { - Money[] balances = new Money[3]; - final MonetaryCurrency currency = getCurrency(); + Money[] balances = new Money[4]; + final MonetaryCurrency currency = getCurrency(); Money interest = Money.zero(currency); + Money paidFromFutureInstallments = Money.zero(currency); Money fee = Money.zero(currency); - Money penalty = Money.zero(currency); + Money penalty = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { - if (installment.isNotFullyPaidOff()) { - if (!installment.getDueDate().isAfter(paymentDate)) { - interest = interest.plus(installment.getInterestOutstanding(currency)); - fee = fee.plus(installment.getFeeChargesOutstanding(currency)); - penalty = penalty.plus(installment.getPenaltyChargesOutstanding(currency)); - } else if (installment.getFromDate().isBefore(paymentDate)) { - Money[] balancesForCurrentPeroid = fetchInterestFeeAndPenalty(paymentDate, currency, installment); - interest = interest.plus(balancesForCurrentPeroid[0]); - fee = fee.plus(balancesForCurrentPeroid[1]); - penalty = penalty.plus(balancesForCurrentPeroid[2]); + if (!installment.getDueDate().isAfter(paymentDate)) { + interest = interest.plus(installment.getInterestOutstanding(currency)); + penalty = penalty.plus(installment.getPenaltyChargesOutstanding(currency)); + fee = fee.plus(installment.getFeeChargesOutstanding(currency)); + } else if (installment.getFromDate().isBefore(paymentDate)) { + Money[] balancesForCurrentPeroid = fetchInterestFeeAndPenaltyTillDate(paymentDate, currency, installment); + if (balancesForCurrentPeroid[0].isGreaterThan(installment.getInterestPaid(currency))) { + interest = interest.plus(balancesForCurrentPeroid[0].minus(installment.getInterestPaid(currency))); + } else { + paidFromFutureInstallments = paidFromFutureInstallments.plus(installment.getInterestPaid(currency).minus( + balancesForCurrentPeroid[0])); + } + if (balancesForCurrentPeroid[1].isGreaterThan(installment.getFeeChargesPaid(currency))) { + fee = fee.plus(balancesForCurrentPeroid[1].minus(installment.getFeeChargesPaid(currency))); + } else { + paidFromFutureInstallments = paidFromFutureInstallments.plus(installment.getFeeChargesPaid(currency).minus( + balancesForCurrentPeroid[1])); + } + if (balancesForCurrentPeroid[2].isGreaterThan(installment.getPenaltyChargesPaid(currency))) { + penalty = penalty.plus(balancesForCurrentPeroid[2].minus(installment.getPenaltyChargesPaid(currency))); + } else { + paidFromFutureInstallments = paidFromFutureInstallments.plus(installment.getPenaltyChargesPaid(currency).minus( + balancesForCurrentPeroid[2])); } + } else if (installment.getDueDate().isAfter(paymentDate)) { + paidFromFutureInstallments = paidFromFutureInstallments.plus(installment.getInterestPaid(currency)) + .plus(installment.getPenaltyChargesPaid(currency)).plus(installment.getFeeChargesPaid(currency)); } + } balances[0] = interest; balances[1] = fee; balances[2] = penalty; + balances[3] = paidFromFutureInstallments; return balances; } - private Money[] fetchInterestFeeAndPenalty(final LocalDate paymentDate, final MonetaryCurrency currency, final LoanRepaymentScheduleInstallment installment) { + private Money[] fetchInterestFeeAndPenaltyTillDate(final LocalDate paymentDate, final MonetaryCurrency currency, final LoanRepaymentScheduleInstallment installment) { Money penaltyForCurrentPeriod = Money.zero(getCurrency()); Money feeForCurrentPeriod = Money.zero(getCurrency()); + Money interestForCurrentPeriod=Money.zero(getCurrency()); int totalPeriodDays = Days.daysBetween(installment.getFromDate(), installment.getDueDate()).getDays(); - int tillDays = Days.daysBetween(installment.getFromDate(), paymentDate).getDays(); - Money interestForCurrentPeriod = Money.of(getCurrency(),BigDecimal.valueOf(calculateInterestForDays(totalPeriodDays, installment.getInterestOutstanding(getCurrency()) + int tillDays = Days.daysBetween(installment.getFromDate(), paymentDate).getDays(); + interestForCurrentPeriod = Money.of(getCurrency(),BigDecimal.valueOf(calculateInterestForDays(totalPeriodDays, installment.getInterestCharged(getCurrency()) .getAmount(), tillDays))); for (LoanCharge loanCharge : this.charges) { if (loanCharge.isActive() && loanCharge.isDueForCollectionFromAndUpToAndIncluding(installment.getFromDate(), paymentDate)) { if (loanCharge.isPenaltyCharge()) { - penaltyForCurrentPeriod = loanCharge.getAmountOutstanding(getCurrency()); + penaltyForCurrentPeriod = loanCharge.getAmount(getCurrency()); } else { - feeForCurrentPeriod = loanCharge.getAmountOutstanding(currency); + feeForCurrentPeriod = loanCharge.getAmount(currency); } } } @@ -6071,15 +6092,15 @@ public class Loan extends AbstractPersistable<Long> { balances[0] = balances[1] = balances[2] = Money.zero(currency); for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { if (installment.getDueDate().isEqual(paymentDate)){ - Money interest = installment.getInterestOutstanding(currency); - Money fee = installment.getFeeChargesOutstanding(currency); - Money penalty = installment.getPenaltyChargesOutstanding(currency); + Money interest = installment.getInterestCharged(currency); + Money fee = installment.getFeeChargesCharged(currency); + Money penalty = installment.getPenaltyChargesCharged(currency); balances[0] = interest; balances[1] = fee; balances[2] = penalty; break; }else if(installment.getDueDate().isAfter(paymentDate) && installment.getFromDate().isBefore(paymentDate)){ - balances = fetchInterestFeeAndPenalty(paymentDate, currency, installment); + balances = fetchInterestFeeAndPenaltyTillDate(paymentDate, currency, installment); break; } } @@ -6125,25 +6146,26 @@ public class Loan extends AbstractPersistable<Long> { receivables[2] = receivablePenalty; return receivables; } + + public void reverseAccrualsAfter(final LocalDate tillDate) { + for (final LoanTransaction transaction : this.loanTransactions) { + if (transaction.isAccrual() && transaction.getTransactionDate().isAfter(tillDate)) { + transaction.reverse(); + } + } + } - public void handleForeClosureTransactions(final List<LoanTransaction> repaymentTransaction, - final LocalDate foreClosureDate, final LoanLifecycleStateMachine loanLifecycleStateMachine) { + public ChangedTransactionDetail handleForeClosureTransactions(final LoanTransaction repaymentTransaction, + final LoanLifecycleStateMachine loanLifecycleStateMachine, final ScheduleGeneratorDTO scheduleGeneratorDTO, + final AppUser appUser) { LoanEvent event = LoanEvent.LOAN_FORECLOSURE; - validateAccountStatus(event); - - MonetaryCurrency currency = getCurrency(); - - final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory - .determineProcessor(this.transactionProcessingStrategy); - - loanRepaymentScheduleTransactionProcessor.processTransactionsFromDerivedFields(repaymentTransaction, currency, - this.repaymentScheduleInstallments, charges()); - this.loanTransactions.addAll(repaymentTransaction); + validateForForeclosure(repaymentTransaction.getTransactionDate()); this.loanSubStatus = LoanSubStatus.FORECLOSED.getValue(); - updateLoanSummaryDerivedFields(); - doPostLoanTransactionChecks(foreClosureDate, loanLifecycleStateMachine); + applyAccurals(appUser); + return handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO, + appUser); } public Money retrieveAccruedAmountAfterDate(final LocalDate tillDate) { @@ -6200,11 +6222,10 @@ public class Loan extends AbstractPersistable<Long> { Money [] balances = retriveIncomeForOverlappingPeriod(transactionDate); for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { if (!installment.getDueDate().isBefore(transactionDate)) { - if (!installment.isPartlyPaid() && !installment.isObligationsMet()) { - totalPrincipal = totalPrincipal.plus(installment.getPrincipalOutstanding(currency)); + totalPrincipal = totalPrincipal.plus(installment.getPrincipal(currency)); newInstallments.remove(installment); - } - } + } + } LocalDate installmentStartDate = getDisbursementDate(); @@ -6218,7 +6239,7 @@ public class Loan extends AbstractPersistable<Long> { installmentStartDate, transactionDate, totalPrincipal.getAmount(), balances[0].getAmount(), balances[1].getAmount(), balances[2].getAmount(), true, null); newInstallment.updateInstallmentNumber(newInstallments.size() + 1); - newInstallments.add(newInstallment); + newInstallments.add(newInstallment); updateLoanScheduleOnForeclosure(newInstallments); Set<LoanCharge> charges = this.charges(); @@ -6243,5 +6264,14 @@ public class Loan extends AbstractPersistable<Long> { public Integer getLoanSubStatus() { return this.loanSubStatus; } + + private boolean isForeclosure(){ + boolean isForeClosure = false; + if(this.loanSubStatus != null){ + isForeClosure = LoanSubStatus.fromInt(loanSubStatus).isForeclosed(); + } + + return isForeClosure; + } } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b5be4d25/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanAccountDomainServiceJpa.java ---------------------------------------------------------------------- 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 63796cc..2287072 100755 --- 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 @@ -586,26 +586,27 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { final List<Long> existingReversedTransactionIds = new ArrayList<>(); existingTransactionIds.addAll(loan.findExistingTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); + final ScheduleGeneratorDTO scheduleGeneratorDTO = null; + AppUser appUser = getAppUserIfPresent(); final LoanRepaymentScheduleInstallment foreCloseDetail = loan.fetchLoanForeclosureDetail(foreClosureDate); if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() && (loan.getAccruedTill() == null || !foreClosureDate.isEqual(loan.getAccruedTill()))) { + loan.reverseAccrualsAfter(foreClosureDate); Money[] accruedReceivables = loan.getReceivableIncome(foreClosureDate); Money interestPortion = foreCloseDetail.getInterestCharged(currency).minus(accruedReceivables[0]); Money feePortion = foreCloseDetail.getFeeChargesCharged(currency).minus(accruedReceivables[1]); Money penaltyPortion = foreCloseDetail.getPenaltyChargesCharged(currency).minus(accruedReceivables[2]); Money total = interestPortion.plus(feePortion).plus(penaltyPortion); if (total.isGreaterThanZero()) { - LoanTransaction accrualTransaction = LoanTransaction.accrual(loan, loan.getOffice(), total, interestPortion, feePortion, - penaltyPortion, foreClosureDate); + LoanTransaction accrualTransaction = LoanTransaction.accrueTransaction(loan, loan.getOffice(), foreClosureDate, + total.getAmount(), interestPortion.getAmount(), feePortion.getAmount(), penaltyPortion.getAmount(), appUser); LocalDate fromDate = loan.getDisbursementDate(); if (loan.getAccruedTill() != null) { fromDate = loan.getAccruedTill(); } - LoanRepaymentScheduleInstallment installment = fetchLoanRepaymentScheduleInstallment(fromDate, loan); - installment.updateAccrualPortion(interestPortion, feePortion, penaltyPortion); - accrualTransaction.updateCreatedDate(createdDate.toDate()); createdDate = createdDate.plusSeconds(1); newTransactions.add(accrualTransaction); + loan.getLoanTransactions().add(accrualTransaction); Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid(); for (LoanCharge loanCharge : loan.charges()) { if (loanCharge.isActive() @@ -619,36 +620,32 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } } } + Money interestPayable = foreCloseDetail.getInterestCharged(currency); - Money feePayable = foreCloseDetail.getFeeChargesCharged(currency); Money penaltyPayable = foreCloseDetail.getPenaltyChargesCharged(currency); - - Money payPrincipal = foreCloseDetail.getPrincipal(currency); + Money payPrincipal = foreCloseDetail.getPrincipal(currency); + loan.updateInstallmentsPostDate(foreClosureDate); LoanTransaction payment = null; + + if (payPrincipal.plus(interestPayable).plus(feePayable).plus(penaltyPayable).isGreaterThanZero()) { - AppUser appUser = null; final PaymentDetail paymentDetail = null; - String externalId = null; + String externalId = null; final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant(); payment = LoanTransaction.repayment(loan.getOffice(), payPrincipal.plus(interestPayable).plus(feePayable).plus(penaltyPayable), paymentDetail, foreClosureDate, externalId, currentDateTime, appUser); createdDate = createdDate.plusSeconds(1); payment.updateCreatedDate(createdDate.toDate()); - payment.updateComponents(payPrincipal, interestPayable, feePayable, penaltyPayable); payment.updateLoan(loan); newTransactions.add(payment); } + List<Long> transactionIds = new ArrayList<>(); - loan.handleForeClosureTransactions(newTransactions, foreClosureDate, defaultLoanLifecycleStateMachine()); - for (LoanTransaction newTransaction : newTransactions) { - saveLoanTransactionWithDataIntegrityViolationChecks(newTransaction); - transactionIds.add(newTransaction.getId()); - } - changes.put("transactions", transactionIds); - changes.put("eventAmount", payPrincipal.getAmount().negate()); + final ChangedTransactionDetail changedTransactionDetail = loan.handleForeClosureTransactions(payment, + defaultLoanLifecycleStateMachine(), scheduleGeneratorDTO, appUser); /*** * TODO Vishwas Batch save is giving me a @@ -658,6 +655,22 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { * recorded against the loan) ***/ + for (LoanTransaction newTransaction : newTransactions) { + saveLoanTransactionWithDataIntegrityViolationChecks(newTransaction); + transactionIds.add(newTransaction.getId()); + } + changes.put("transactions", transactionIds); + changes.put("eventAmount", payPrincipal.getAmount().negate()); + + if (changedTransactionDetail != null) { + for (Map.Entry<Long, LoanTransaction> mapEntry : changedTransactionDetail.getNewTransactionMappings().entrySet()) { + saveLoanTransactionWithDataIntegrityViolationChecks(mapEntry.getValue()); + // update loan with references to the newly created transactions + loan.getLoanTransactions().add(mapEntry.getValue()); + updateLoanTransaction(mapEntry.getKey(), mapEntry.getValue()); + } + } + saveAndFlushLoanWithDataIntegrityViolationChecks(loan); if (StringUtils.isNotBlank(noteText)) { @@ -667,7 +680,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService { } postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false); - return changes; } http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b5be4d25/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java index c305514..0e5ce09 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanRepaymentScheduleInstallment.java @@ -791,4 +791,9 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus .plus(getInterestWrittenOff(currency)); return getInterestAccrued(currency).minus(interestAccountedFor); } + + public Money getTotalPaid(final MonetaryCurrency currency) { + return getPenaltyChargesPaid(currency).plus(getFeeChargesPaid(currency)).plus(getInterestPaid(currency)) + .plus(getPrincipalCompleted(currency)); + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b5be4d25/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java ---------------------------------------------------------------------- diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java index 49a52fb..b21c9a8 100755 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformService.java @@ -98,7 +98,7 @@ public interface LoanWritePlatformService { CommandProcessingResult makeLoanRefund(Long loanId, JsonCommand command); - CommandProcessingResult addAndDeleteLoanDisburseDetails(Long loanId, JsonCommand command); + CommandProcessingResult addAndDeleteLoanDisburseDetails(Long loanId, JsonCommand command); void applyOverdueChargesForLoan(Long loanId, Collection<OverdueLoanScheduleData> overdueLoanScheduleDatas); http://git-wip-us.apache.org/repos/asf/incubator-fineract/blob/b5be4d25/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java ---------------------------------------------------------------------- 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 6e35e51..c9845ad 100755 --- 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 @@ -2898,7 +2898,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf final Loan loan = this.loanAssembler.assembleFrom(loanId); final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(LoanApiConstants.transactionDateParamName, element); this.loanEventApiJsonValidator.validateLoanForeclosure(command.json()); - loan.validateForForeclosure(transactionDate); final Map<String, Object> changes = new LinkedHashMap<>(); changes.put("transactionDate", transactionDate); @@ -2906,7 +2905,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf LoanRescheduleRequest loanRescheduleRequest = null; this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.getRepaymentScheduleInstallments(), loan, loanRescheduleRequest); - loan.updateInstallmentsPostDate(transactionDate); + final Map<String, Object> modifications = this.loanAccountDomainService.foreCloseLoan(loan, transactionDate, noteText); changes.putAll(modifications);
