final List<LoanRepaymentScheduleInstallment> previousSchedule, LoanScheduleModel loanScheduleModel,
List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency,
final List<RecalculationDetail> recalculationDetails, final Map<LocalDate, RecalculationDetail> retainRecalculationDetails,
boolean recalculate, int installmentNumber, List<LoanTransaction> processTransactions, LoanTransaction preCloseTransaction,
final LocalDate lastTransactionDate, final int penaltyWaitPeriod, final List<LoanTransaction> actualTransactions) {
LoanTransaction loanTransaction = processTransactions.remove(processTransactions.size() - 1);
if (!(loanTransaction.isRepayment() || loanTransaction.isInterestWaiver())) {
processTransactions.add(loanTransaction);
return loanScheduleModel;
}
LocalDate processTransactionsForInterestCompound = loanTransaction.getTransactionDate();
List<LoanRepaymentScheduleInstallment> scheduleInstallments = getInstallmentsForInterestCompound(installments,
processTransactionsForInterestCompound, retainRecalculationDetails.keySet());
if (!scheduleInstallments.isEmpty()) {
for (LoanRepaymentScheduleInstallment installment : installments) {
installment.resetDerivedComponents();
installment.updateDerivedFields(currency, loanApplicationTerms.getExpectedDisbursementDate());
}
loanRepaymentScheduleTransactionProcessor.applyTransaction(processTransactions, currency, installments);
Money principalUnprocessed = Money.zero(currency);
Money interestUnprocessed = Money.zero(currency);
Money feeUnprocessed = Money.zero(currency);
boolean isBeforeFirstInstallment = false;
if (scheduleInstallments.size() == 1) {
LoanRepaymentScheduleInstallment installment = scheduleInstallments.get(0);
if (installment.getInstallmentNumber() == 1
&& (installment.getDueDate().isAfter(processTransactionsForInterestCompound) || (installment
.isRecalculatedInterestComponent() && installment.getDueDate().isEqual(
processTransactionsForInterestCompound)))) {
isBeforeFirstInstallment = true;
}
}
if (!isBeforeFirstInstallment) {
for (LoanRepaymentScheduleInstallment installment : scheduleInstallments) {
principalUnprocessed = principalUnprocessed.plus(installment.getPrincipalOutstanding(currency));
interestUnprocessed = interestUnprocessed.plus(installment.getInterestOutstanding(currency));
feeUnprocessed = feeUnprocessed.plus(installment.getFeeChargesOutstanding(currency));
feeUnprocessed = feeUnprocessed.plus(installment.getPenaltyChargesOutstanding(currency));
}
}
if (interestUnprocessed.isLessThan(loanTransaction.getAmount(currency))) {
LoanRepaymentScheduleInstallment lastProcessedInstallment = scheduleInstallments.get(scheduleInstallments.size() - 1);
LocalDate startDate = lastProcessedInstallment.getDueDate();
if (isBeforeFirstInstallment) {
startDate = loanApplicationTerms.getExpectedDisbursementDate();
}