Merge branch 'foreclosureissues' into develop

This commit is contained in:
Nazeer Hussain Shaik
2016-06-22 11:41:32 +05:30
5 changed files with 113 additions and 67 deletions
@@ -2986,13 +2986,13 @@ public class Loan extends AbstractPersistable<Long> {
boolean reprocess = true; boolean reprocess = true;
if (isTransactionChronologicallyLatest && adjustedTransaction == null 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()))) { && currentInstallment.getTotalOutstanding(getCurrency()).isEqualTo(loanTransaction.getAmount(getCurrency()))) {
reprocess = false; reprocess = false;
} }
if (isTransactionChronologicallyLatest && adjustedTransaction == null if (isTransactionChronologicallyLatest && adjustedTransaction == null
&& (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled())) { && (!reprocess || !this.repaymentScheduleDetail().isInterestRecalculationEnabled()) && !isForeclosure()) {
loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), this.repaymentScheduleInstallments, loanRepaymentScheduleTransactionProcessor.handleTransaction(loanTransaction, getCurrency(), this.repaymentScheduleInstallments,
charges()); charges());
reprocess = false; reprocess = false;
@@ -6004,8 +6004,9 @@ public class Loan extends AbstractPersistable<Long> {
} }
public LoanRepaymentScheduleInstallment fetchLoanForeclosureDetail(final LocalDate closureDate) { public LoanRepaymentScheduleInstallment fetchLoanForeclosureDetail(final LocalDate closureDate) {
Money totalPrincipal = Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding());
Money[] receivables = retriveIncomeOutstandingTillDate(closureDate); Money[] receivables = retriveIncomeOutstandingTillDate(closureDate);
Money totalPrincipal = (Money.of(getCurrency(), this.getSummary().getTotalPrincipalOutstanding()));
totalPrincipal = totalPrincipal.minus(receivables[3]);
final List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null; final List<LoanInterestRecalcualtionAdditionalDetails> compoundingDetails = null;
final LocalDate currentDate = DateUtils.getLocalDateOfTenant(); final LocalDate currentDate = DateUtils.getLocalDateOfTenant();
return new LoanRepaymentScheduleInstallment(null, 0, currentDate, currentDate, totalPrincipal.getAmount(), 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) { public Money[] retriveIncomeOutstandingTillDate(final LocalDate paymentDate) {
Money[] balances = new Money[3]; Money[] balances = new Money[4];
final MonetaryCurrency currency = getCurrency(); final MonetaryCurrency currency = getCurrency();
Money interest = Money.zero(currency); Money interest = Money.zero(currency);
Money paidFromFutureInstallments = Money.zero(currency);
Money fee = Money.zero(currency); Money fee = Money.zero(currency);
Money penalty = Money.zero(currency); Money penalty = Money.zero(currency);
for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) {
if (installment.isNotFullyPaidOff()) { if (!installment.getDueDate().isAfter(paymentDate)) {
if (!installment.getDueDate().isAfter(paymentDate)) { interest = interest.plus(installment.getInterestOutstanding(currency));
interest = interest.plus(installment.getInterestOutstanding(currency)); penalty = penalty.plus(installment.getPenaltyChargesOutstanding(currency));
fee = fee.plus(installment.getFeeChargesOutstanding(currency)); fee = fee.plus(installment.getFeeChargesOutstanding(currency));
penalty = penalty.plus(installment.getPenaltyChargesOutstanding(currency)); } else if (installment.getFromDate().isBefore(paymentDate)) {
} else if (installment.getFromDate().isBefore(paymentDate)) { Money[] balancesForCurrentPeroid = fetchInterestFeeAndPenaltyTillDate(paymentDate, currency, installment);
Money[] balancesForCurrentPeroid = fetchInterestFeeAndPenalty(paymentDate, currency, installment); if (balancesForCurrentPeroid[0].isGreaterThan(installment.getInterestPaid(currency))) {
interest = interest.plus(balancesForCurrentPeroid[0]); interest = interest.plus(balancesForCurrentPeroid[0].minus(installment.getInterestPaid(currency)));
fee = fee.plus(balancesForCurrentPeroid[1]); } else {
penalty = penalty.plus(balancesForCurrentPeroid[2]); 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[0] = interest;
balances[1] = fee; balances[1] = fee;
balances[2] = penalty; balances[2] = penalty;
balances[3] = paidFromFutureInstallments;
return balances; 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 penaltyForCurrentPeriod = Money.zero(getCurrency());
Money feeForCurrentPeriod = Money.zero(getCurrency()); Money feeForCurrentPeriod = Money.zero(getCurrency());
Money interestForCurrentPeriod=Money.zero(getCurrency());
int totalPeriodDays = Days.daysBetween(installment.getFromDate(), installment.getDueDate()).getDays(); int totalPeriodDays = Days.daysBetween(installment.getFromDate(), installment.getDueDate()).getDays();
int tillDays = Days.daysBetween(installment.getFromDate(), paymentDate).getDays(); int tillDays = Days.daysBetween(installment.getFromDate(), paymentDate).getDays();
Money interestForCurrentPeriod = Money.of(getCurrency(),BigDecimal.valueOf(calculateInterestForDays(totalPeriodDays, installment.getInterestOutstanding(getCurrency()) interestForCurrentPeriod = Money.of(getCurrency(),BigDecimal.valueOf(calculateInterestForDays(totalPeriodDays, installment.getInterestCharged(getCurrency())
.getAmount(), tillDays))); .getAmount(), tillDays)));
for (LoanCharge loanCharge : this.charges) { for (LoanCharge loanCharge : this.charges) {
if (loanCharge.isActive() if (loanCharge.isActive()
&& loanCharge.isDueForCollectionFromAndUpToAndIncluding(installment.getFromDate(), paymentDate)) { && loanCharge.isDueForCollectionFromAndUpToAndIncluding(installment.getFromDate(), paymentDate)) {
if (loanCharge.isPenaltyCharge()) { if (loanCharge.isPenaltyCharge()) {
penaltyForCurrentPeriod = loanCharge.getAmountOutstanding(getCurrency()); penaltyForCurrentPeriod = loanCharge.getAmount(getCurrency());
} else { } 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); balances[0] = balances[1] = balances[2] = Money.zero(currency);
for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) {
if (installment.getDueDate().isEqual(paymentDate)){ if (installment.getDueDate().isEqual(paymentDate)){
Money interest = installment.getInterestOutstanding(currency); Money interest = installment.getInterestCharged(currency);
Money fee = installment.getFeeChargesOutstanding(currency); Money fee = installment.getFeeChargesCharged(currency);
Money penalty = installment.getPenaltyChargesOutstanding(currency); Money penalty = installment.getPenaltyChargesCharged(currency);
balances[0] = interest; balances[0] = interest;
balances[1] = fee; balances[1] = fee;
balances[2] = penalty; balances[2] = penalty;
break; break;
}else if(installment.getDueDate().isAfter(paymentDate) && installment.getFromDate().isBefore(paymentDate)){ }else if(installment.getDueDate().isAfter(paymentDate) && installment.getFromDate().isBefore(paymentDate)){
balances = fetchInterestFeeAndPenalty(paymentDate, currency, installment); balances = fetchInterestFeeAndPenaltyTillDate(paymentDate, currency, installment);
break; break;
} }
} }
@@ -6126,24 +6147,25 @@ public class Loan extends AbstractPersistable<Long> {
return receivables; return receivables;
} }
public void handleForeClosureTransactions(final List<LoanTransaction> repaymentTransaction, public void reverseAccrualsAfter(final LocalDate tillDate) {
final LocalDate foreClosureDate, final LoanLifecycleStateMachine loanLifecycleStateMachine) { for (final LoanTransaction transaction : this.loanTransactions) {
if (transaction.isAccrual() && transaction.getTransactionDate().isAfter(tillDate)) {
transaction.reverse();
}
}
}
public ChangedTransactionDetail handleForeClosureTransactions(final LoanTransaction repaymentTransaction,
final LoanLifecycleStateMachine loanLifecycleStateMachine, final ScheduleGeneratorDTO scheduleGeneratorDTO,
final AppUser appUser) {
LoanEvent event = LoanEvent.LOAN_FORECLOSURE; LoanEvent event = LoanEvent.LOAN_FORECLOSURE;
validateAccountStatus(event); validateAccountStatus(event);
validateForForeclosure(repaymentTransaction.getTransactionDate());
MonetaryCurrency currency = getCurrency();
final LoanRepaymentScheduleTransactionProcessor loanRepaymentScheduleTransactionProcessor = this.transactionProcessorFactory
.determineProcessor(this.transactionProcessingStrategy);
loanRepaymentScheduleTransactionProcessor.processTransactionsFromDerivedFields(repaymentTransaction, currency,
this.repaymentScheduleInstallments, charges());
this.loanTransactions.addAll(repaymentTransaction);
this.loanSubStatus = LoanSubStatus.FORECLOSED.getValue(); this.loanSubStatus = LoanSubStatus.FORECLOSED.getValue();
updateLoanSummaryDerivedFields(); applyAccurals(appUser);
doPostLoanTransactionChecks(foreClosureDate, loanLifecycleStateMachine); return handleRepaymentOrRecoveryOrWaiverTransaction(repaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO,
appUser);
} }
public Money retrieveAccruedAmountAfterDate(final LocalDate tillDate) { public Money retrieveAccruedAmountAfterDate(final LocalDate tillDate) {
@@ -6200,11 +6222,10 @@ public class Loan extends AbstractPersistable<Long> {
Money [] balances = retriveIncomeForOverlappingPeriod(transactionDate); Money [] balances = retriveIncomeForOverlappingPeriod(transactionDate);
for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) { for (final LoanRepaymentScheduleInstallment installment : this.repaymentScheduleInstallments) {
if (!installment.getDueDate().isBefore(transactionDate)) { if (!installment.getDueDate().isBefore(transactionDate)) {
if (!installment.isPartlyPaid() && !installment.isObligationsMet()) { totalPrincipal = totalPrincipal.plus(installment.getPrincipal(currency));
totalPrincipal = totalPrincipal.plus(installment.getPrincipalOutstanding(currency));
newInstallments.remove(installment); newInstallments.remove(installment);
}
} }
} }
LocalDate installmentStartDate = getDisbursementDate(); LocalDate installmentStartDate = getDisbursementDate();
@@ -6244,4 +6265,13 @@ public class Loan extends AbstractPersistable<Long> {
return this.loanSubStatus; return this.loanSubStatus;
} }
private boolean isForeclosure(){
boolean isForeClosure = false;
if(this.loanSubStatus != null){
isForeClosure = LoanSubStatus.fromInt(loanSubStatus).isForeclosed();
}
return isForeClosure;
}
} }
@@ -586,26 +586,27 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
final List<Long> existingReversedTransactionIds = new ArrayList<>(); final List<Long> existingReversedTransactionIds = new ArrayList<>();
existingTransactionIds.addAll(loan.findExistingTransactionIds()); existingTransactionIds.addAll(loan.findExistingTransactionIds());
existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds()); existingReversedTransactionIds.addAll(loan.findExistingReversedTransactionIds());
final ScheduleGeneratorDTO scheduleGeneratorDTO = null;
AppUser appUser = getAppUserIfPresent();
final LoanRepaymentScheduleInstallment foreCloseDetail = loan.fetchLoanForeclosureDetail(foreClosureDate); final LoanRepaymentScheduleInstallment foreCloseDetail = loan.fetchLoanForeclosureDetail(foreClosureDate);
if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct() if (loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()
&& (loan.getAccruedTill() == null || !foreClosureDate.isEqual(loan.getAccruedTill()))) { && (loan.getAccruedTill() == null || !foreClosureDate.isEqual(loan.getAccruedTill()))) {
loan.reverseAccrualsAfter(foreClosureDate);
Money[] accruedReceivables = loan.getReceivableIncome(foreClosureDate); Money[] accruedReceivables = loan.getReceivableIncome(foreClosureDate);
Money interestPortion = foreCloseDetail.getInterestCharged(currency).minus(accruedReceivables[0]); Money interestPortion = foreCloseDetail.getInterestCharged(currency).minus(accruedReceivables[0]);
Money feePortion = foreCloseDetail.getFeeChargesCharged(currency).minus(accruedReceivables[1]); Money feePortion = foreCloseDetail.getFeeChargesCharged(currency).minus(accruedReceivables[1]);
Money penaltyPortion = foreCloseDetail.getPenaltyChargesCharged(currency).minus(accruedReceivables[2]); Money penaltyPortion = foreCloseDetail.getPenaltyChargesCharged(currency).minus(accruedReceivables[2]);
Money total = interestPortion.plus(feePortion).plus(penaltyPortion); Money total = interestPortion.plus(feePortion).plus(penaltyPortion);
if (total.isGreaterThanZero()) { if (total.isGreaterThanZero()) {
LoanTransaction accrualTransaction = LoanTransaction.accrual(loan, loan.getOffice(), total, interestPortion, feePortion, LoanTransaction accrualTransaction = LoanTransaction.accrueTransaction(loan, loan.getOffice(), foreClosureDate,
penaltyPortion, foreClosureDate); total.getAmount(), interestPortion.getAmount(), feePortion.getAmount(), penaltyPortion.getAmount(), appUser);
LocalDate fromDate = loan.getDisbursementDate(); LocalDate fromDate = loan.getDisbursementDate();
if (loan.getAccruedTill() != null) { if (loan.getAccruedTill() != null) {
fromDate = loan.getAccruedTill(); fromDate = loan.getAccruedTill();
} }
LoanRepaymentScheduleInstallment installment = fetchLoanRepaymentScheduleInstallment(fromDate, loan);
installment.updateAccrualPortion(interestPortion, feePortion, penaltyPortion);
accrualTransaction.updateCreatedDate(createdDate.toDate());
createdDate = createdDate.plusSeconds(1); createdDate = createdDate.plusSeconds(1);
newTransactions.add(accrualTransaction); newTransactions.add(accrualTransaction);
loan.getLoanTransactions().add(accrualTransaction);
Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid(); Set<LoanChargePaidBy> accrualCharges = accrualTransaction.getLoanChargesPaid();
for (LoanCharge loanCharge : loan.charges()) { for (LoanCharge loanCharge : loan.charges()) {
if (loanCharge.isActive() if (loanCharge.isActive()
@@ -620,16 +621,17 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
} }
} }
Money interestPayable = foreCloseDetail.getInterestCharged(currency);
Money interestPayable = foreCloseDetail.getInterestCharged(currency);
Money feePayable = foreCloseDetail.getFeeChargesCharged(currency); Money feePayable = foreCloseDetail.getFeeChargesCharged(currency);
Money penaltyPayable = foreCloseDetail.getPenaltyChargesCharged(currency); Money penaltyPayable = foreCloseDetail.getPenaltyChargesCharged(currency);
Money payPrincipal = foreCloseDetail.getPrincipal(currency); Money payPrincipal = foreCloseDetail.getPrincipal(currency);
loan.updateInstallmentsPostDate(foreClosureDate);
LoanTransaction payment = null; LoanTransaction payment = null;
if (payPrincipal.plus(interestPayable).plus(feePayable).plus(penaltyPayable).isGreaterThanZero()) { if (payPrincipal.plus(interestPayable).plus(feePayable).plus(penaltyPayable).isGreaterThanZero()) {
AppUser appUser = null;
final PaymentDetail paymentDetail = null; final PaymentDetail paymentDetail = null;
String externalId = null; String externalId = null;
final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant(); final LocalDateTime currentDateTime = DateUtils.getLocalDateTimeOfTenant();
@@ -637,18 +639,13 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
paymentDetail, foreClosureDate, externalId, currentDateTime, appUser); paymentDetail, foreClosureDate, externalId, currentDateTime, appUser);
createdDate = createdDate.plusSeconds(1); createdDate = createdDate.plusSeconds(1);
payment.updateCreatedDate(createdDate.toDate()); payment.updateCreatedDate(createdDate.toDate());
payment.updateComponents(payPrincipal, interestPayable, feePayable, penaltyPayable);
payment.updateLoan(loan); payment.updateLoan(loan);
newTransactions.add(payment); newTransactions.add(payment);
} }
List<Long> transactionIds = new ArrayList<>(); List<Long> transactionIds = new ArrayList<>();
loan.handleForeClosureTransactions(newTransactions, foreClosureDate, defaultLoanLifecycleStateMachine()); final ChangedTransactionDetail changedTransactionDetail = loan.handleForeClosureTransactions(payment,
for (LoanTransaction newTransaction : newTransactions) { defaultLoanLifecycleStateMachine(), scheduleGeneratorDTO, appUser);
saveLoanTransactionWithDataIntegrityViolationChecks(newTransaction);
transactionIds.add(newTransaction.getId());
}
changes.put("transactions", transactionIds);
changes.put("eventAmount", payPrincipal.getAmount().negate());
/*** /***
* TODO Vishwas Batch save is giving me a * TODO Vishwas Batch save is giving me a
@@ -658,6 +655,22 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
* recorded against the loan) * 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); saveAndFlushLoanWithDataIntegrityViolationChecks(loan);
if (StringUtils.isNotBlank(noteText)) { if (StringUtils.isNotBlank(noteText)) {
@@ -667,7 +680,6 @@ public class LoanAccountDomainServiceJpa implements LoanAccountDomainService {
} }
postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false); postJournalEntries(loan, existingTransactionIds, existingReversedTransactionIds, false);
return changes; return changes;
} }
@@ -791,4 +791,9 @@ public final class LoanRepaymentScheduleInstallment extends AbstractAuditableCus
.plus(getInterestWrittenOff(currency)); .plus(getInterestWrittenOff(currency));
return getInterestAccrued(currency).minus(interestAccountedFor); return getInterestAccrued(currency).minus(interestAccountedFor);
} }
public Money getTotalPaid(final MonetaryCurrency currency) {
return getPenaltyChargesPaid(currency).plus(getFeeChargesPaid(currency)).plus(getInterestPaid(currency))
.plus(getPrincipalCompleted(currency));
}
} }
@@ -98,7 +98,7 @@ public interface LoanWritePlatformService {
CommandProcessingResult makeLoanRefund(Long loanId, JsonCommand command); 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); void applyOverdueChargesForLoan(Long loanId, Collection<OverdueLoanScheduleData> overdueLoanScheduleDatas);
@@ -2898,7 +2898,6 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
final Loan loan = this.loanAssembler.assembleFrom(loanId); final Loan loan = this.loanAssembler.assembleFrom(loanId);
final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(LoanApiConstants.transactionDateParamName, element); final LocalDate transactionDate = this.fromApiJsonHelper.extractLocalDateNamed(LoanApiConstants.transactionDateParamName, element);
this.loanEventApiJsonValidator.validateLoanForeclosure(command.json()); this.loanEventApiJsonValidator.validateLoanForeclosure(command.json());
loan.validateForForeclosure(transactionDate);
final Map<String, Object> changes = new LinkedHashMap<>(); final Map<String, Object> changes = new LinkedHashMap<>();
changes.put("transactionDate", transactionDate); changes.put("transactionDate", transactionDate);
@@ -2906,7 +2905,7 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf
LoanRescheduleRequest loanRescheduleRequest = null; LoanRescheduleRequest loanRescheduleRequest = null;
this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.getRepaymentScheduleInstallments(), this.loanScheduleHistoryWritePlatformService.createAndSaveLoanScheduleArchive(loan.getRepaymentScheduleInstallments(),
loan, loanRescheduleRequest); loan, loanRescheduleRequest);
loan.updateInstallmentsPostDate(transactionDate);
final Map<String, Object> modifications = this.loanAccountDomainService.foreCloseLoan(loan, transactionDate, noteText); final Map<String, Object> modifications = this.loanAccountDomainService.foreCloseLoan(loan, transactionDate, noteText);
changes.putAll(modifications); changes.putAll(modifications);