FINERACT-1958-Overlapping-installment-payment-allocation
This commit is contained in:
committed by
Adam Saghy
parent
001ad2fa1f
commit
e7013309ca
+55
-7
@@ -367,6 +367,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
|
||||
periods.add(installment);
|
||||
|
||||
if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.isDownPaymentEnabled()) {
|
||||
createDownPaymentInstallmentForOverlappingInstallments(loanApplicationTerms, scheduleParams, periods, scheduledDueDate);
|
||||
}
|
||||
|
||||
// Updates principal paid map with efective date for reducing
|
||||
// the amount from outstanding balance(interest calculation)
|
||||
updateAmountsWithEffectiveDate(loanApplicationTerms, holidayDetailDTO, scheduleParams, scheduledDueDate, currentPeriodParams,
|
||||
@@ -427,6 +431,29 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
totalOutstanding);
|
||||
}
|
||||
|
||||
private void createDownPaymentInstallmentForOverlappingInstallments(LoanApplicationTerms loanApplicationTerms,
|
||||
LoanScheduleParams scheduleParams, Collection<LoanScheduleModelPeriod> periods, LocalDate scheduledDueDate) {
|
||||
for (Map.Entry<LocalDate, Money> disburseDetail : scheduleParams.getDisburseDetailMap().entrySet()) {
|
||||
if (disburseDetail.getKey().isAfter(scheduleParams.getPeriodStartDate()) && disburseDetail.getKey().isEqual(scheduledDueDate)) {
|
||||
scheduleParams.incrementPeriodNumber();
|
||||
scheduleParams.incrementInstalmentNumber();
|
||||
|
||||
BigDecimal downPaymentAmount = MathUtil.percentageOf(disburseDetail.getValue().getAmount(),
|
||||
loanApplicationTerms.getDisbursedAmountPercentageForDownPayment(), 19);
|
||||
Money downPayment = Money.of(loanApplicationTerms.getCurrency(), downPaymentAmount);
|
||||
LoanScheduleModelDownPaymentPeriod installment = LoanScheduleModelDownPaymentPeriod.downPayment(
|
||||
scheduleParams.getInstalmentNumber(), disburseDetail.getKey(), downPayment, scheduleParams.getOutstandingBalance());
|
||||
|
||||
addLoanRepaymentScheduleInstallment(scheduleParams.getInstallments(), installment);
|
||||
periods.add(installment);
|
||||
scheduleParams.reduceOutstandingBalance(downPayment);
|
||||
scheduleParams.addTotalCumulativePrincipal(downPayment);
|
||||
scheduleParams.addTotalRepaymentExpected(downPayment);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateCompoundingDetails(final Collection<LoanScheduleModelPeriod> periods, final LoanScheduleParams params,
|
||||
final LoanApplicationTerms loanApplicationTerms) {
|
||||
final Map<LocalDate, Map<LocalDate, Money>> compoundingDetails = params.getCompoundingDateVariations();
|
||||
@@ -998,8 +1025,10 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
periods.add(disbursementPeriod);
|
||||
|
||||
if (loanApplicationTerms.isDownPaymentEnabled()) {
|
||||
createDownPaymentPeriod(loanApplicationTerms, scheduleParams, periods, disburseDetail.getKey(),
|
||||
disburseDetail.getValue().getAmount());
|
||||
if (!disburseDetail.getKey().isEqual(scheduledDueDate)) {
|
||||
createDownPaymentPeriod(loanApplicationTerms, scheduleParams, periods, disburseDetail.getKey(),
|
||||
disburseDetail.getValue().getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
// updates actual outstanding balance with new
|
||||
@@ -2348,11 +2377,14 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
.disbursement(disburseDetail.getKey(), disburseDetail.getValue(), chargesDueAtTimeOfDisbursement);
|
||||
periods.add(disbursementPeriod);
|
||||
if (loanApplicationTerms.isDownPaymentEnabled()) {
|
||||
loanScheduleParams = LoanScheduleParams.createLoanScheduleParams(currency,
|
||||
Money.of(currency, chargesDueAtTimeOfDisbursement), loanApplicationTerms.getExpectedDisbursementDate(),
|
||||
getPrincipalToBeScheduled(loanApplicationTerms));
|
||||
createDownPaymentPeriod(loanApplicationTerms, loanScheduleParams, periods, disburseDetail.getKey(),
|
||||
disbursementPeriod.principalDue());
|
||||
if (!disburseDetail.getKey().isEqual(installment.getDueDate())) {
|
||||
loanScheduleParams = LoanScheduleParams.createLoanScheduleParams(currency,
|
||||
Money.of(currency, chargesDueAtTimeOfDisbursement),
|
||||
loanApplicationTerms.getExpectedDisbursementDate(),
|
||||
getPrincipalToBeScheduled(loanApplicationTerms));
|
||||
createDownPaymentPeriod(loanApplicationTerms, loanScheduleParams, periods, disburseDetail.getKey(),
|
||||
disbursementPeriod.principalDue());
|
||||
}
|
||||
}
|
||||
// updates actual outstanding balance with new
|
||||
// disbursement detail
|
||||
@@ -2369,6 +2401,22 @@ public abstract class AbstractLoanScheduleGenerator implements LoanScheduleGener
|
||||
outstandingBalance = outstandingBalance.minus(installment.getPrincipal(currency));
|
||||
final LoanScheduleModelPeriod loanScheduleModelPeriod = createLoanScheduleModelPeriod(installment, outstandingBalance);
|
||||
periods.add(loanScheduleModelPeriod);
|
||||
|
||||
// downpayment installment for overlapping case
|
||||
|
||||
if (loanApplicationTerms.isMultiDisburseLoan() && loanApplicationTerms.isDownPaymentEnabled()) {
|
||||
for (Map.Entry<LocalDate, Money> disburseDetail : disburseDetailMap.entrySet()) {
|
||||
if (disburseDetail.getKey().isAfter(installment.getFromDate())
|
||||
&& disburseDetail.getKey().isEqual(installment.getDueDate())) {
|
||||
loanScheduleParams = LoanScheduleParams.createLoanScheduleParams(currency,
|
||||
Money.of(currency, chargesDueAtTimeOfDisbursement), loanApplicationTerms.getExpectedDisbursementDate(),
|
||||
getPrincipalToBeScheduled(loanApplicationTerms));
|
||||
createDownPaymentPeriod(loanApplicationTerms, loanScheduleParams, periods, disburseDetail.getKey(),
|
||||
disburseDetail.getValue().getAmount());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
totalCumulativePrincipal = totalCumulativePrincipal.plus(installment.getPrincipal(currency));
|
||||
totalCumulativeInterest = totalCumulativeInterest.plus(installment.getInterestCharged(currency));
|
||||
totalFeeChargesCharged = totalFeeChargesCharged.plus(installment.getFeeChargesCharged(currency));
|
||||
|
||||
+5
-4
@@ -447,7 +447,8 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
RepaymentTransactionTemplateMapper mapper = new RepaymentTransactionTemplateMapper(sqlGenerator);
|
||||
String sql = "select " + mapper.schema();
|
||||
LoanTransactionData loanTransactionData = this.jdbcTemplate.queryForObject(sql, mapper, // NOSONAR
|
||||
LoanTransactionType.REPAYMENT.getValue(), LoanTransactionType.REPAYMENT.getValue(), loanId, loanId);
|
||||
LoanTransactionType.REPAYMENT.getValue(), LoanTransactionType.DOWN_PAYMENT.getValue(),
|
||||
LoanTransactionType.REPAYMENT.getValue(), LoanTransactionType.DOWN_PAYMENT.getValue(), loanId, loanId);
|
||||
final Collection<PaymentTypeData> paymentOptions = this.paymentTypeReadPlatformService.retrieveAllPaymentTypes();
|
||||
return LoanTransactionData.templateOnTop(loanTransactionData, paymentOptions);
|
||||
}
|
||||
@@ -2494,9 +2495,9 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
StringBuilder sqlBuilder = new StringBuilder();
|
||||
sqlBuilder.append("(CASE ");
|
||||
sqlBuilder.append(
|
||||
"WHEN (select max(tr.transaction_date) as transaction_date from m_loan_transaction tr where tr.loan_id = l.id AND tr.transaction_type_enum = ? AND tr.is_reversed = false) > ls.dueDate ");
|
||||
"WHEN (select max(tr.transaction_date) as transaction_date from m_loan_transaction tr where tr.loan_id = l.id AND tr.transaction_type_enum in (?,?) AND tr.is_reversed = false) > ls.dueDate ");
|
||||
sqlBuilder.append(
|
||||
"THEN (select max(tr.transaction_date) as transaction_date from m_loan_transaction tr where tr.loan_id = l.id AND tr.transaction_type_enum = ? AND tr.is_reversed = false) ");
|
||||
"THEN (select max(tr.transaction_date) as transaction_date from m_loan_transaction tr where tr.loan_id = l.id AND tr.transaction_type_enum in (?,?) AND tr.is_reversed = false) ");
|
||||
sqlBuilder.append("ELSE ls.dueDate END) as transactionDate, ");
|
||||
sqlBuilder.append(
|
||||
"ls.principal_amount - coalesce(ls.principal_writtenoff_derived, 0) - coalesce(ls.principal_completed_derived, 0) as principalDue, ");
|
||||
@@ -2516,7 +2517,7 @@ public class LoanReadPlatformServiceImpl implements LoanReadPlatformService, Loa
|
||||
sqlBuilder.append(
|
||||
"JOIN((SELECT ls.loan_id, ls.duedate as datedue FROM m_loan_repayment_schedule ls WHERE ls.loan_id = ? and ls.completed_derived = false ORDER BY ls.duedate LIMIT 1)) asq on asq.loan_id = ls.loan_id ");
|
||||
sqlBuilder.append("AND asq.datedue = ls.duedate ");
|
||||
sqlBuilder.append("WHERE l.id = ?");
|
||||
sqlBuilder.append("WHERE l.id = ? LIMIT 1");
|
||||
return sqlBuilder.toString();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user