FINERACT-1981: Fix down-payment handling on overpaid loan (Advanced payment allocation loan)
This commit is contained in:
+19
-12
@@ -2955,7 +2955,7 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
|
||||
}
|
||||
|
||||
public LoanTransaction handleDownPayment(final BigDecimal disbursedAmount, final JsonCommand command,
|
||||
public LoanTransaction handleDownPayment(final LoanTransaction disbursementTransaction, final JsonCommand command,
|
||||
final ScheduleGeneratorDTO scheduleGeneratorDTO) {
|
||||
LocalDate disbursedOn = command.localDateValueOfParameterNamed(ACTUAL_DISBURSEMENT_DATE);
|
||||
BigDecimal disbursedAmountPercentageForDownPayment = this.loanRepaymentScheduleDetail.getDisbursedAmountPercentageForDownPayment();
|
||||
@@ -2964,19 +2964,26 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
||||
externalId = ExternalId.generate();
|
||||
}
|
||||
Money downPaymentMoney = Money.of(getCurrency(),
|
||||
MathUtil.percentageOf(disbursedAmount, disbursedAmountPercentageForDownPayment, 19));
|
||||
LoanTransaction downPaymentTransaction = LoanTransaction.downPayment(getOffice(), downPaymentMoney, null, disbursedOn, externalId);
|
||||
MathUtil.percentageOf(disbursementTransaction.getAmount(), disbursedAmountPercentageForDownPayment, 19));
|
||||
|
||||
LoanEvent event = LoanEvent.LOAN_REPAYMENT_OR_WAIVER;
|
||||
validateRepaymentTypeAccountStatus(downPaymentTransaction, event);
|
||||
HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();
|
||||
validateRepaymentDateIsOnHoliday(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(),
|
||||
holidayDetailDTO.getHolidays());
|
||||
validateRepaymentDateIsOnNonWorkingDay(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(),
|
||||
holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
|
||||
Money adjustedDownPaymentMoney = MathUtil
|
||||
.negativeToZero(downPaymentMoney.minus(disbursementTransaction.getOverPaymentPortion(getCurrency())));
|
||||
if (adjustedDownPaymentMoney.isGreaterThanZero()) {
|
||||
LoanTransaction downPaymentTransaction = LoanTransaction.downPayment(getOffice(), adjustedDownPaymentMoney, null, disbursedOn,
|
||||
externalId);
|
||||
LoanEvent event = LoanEvent.LOAN_REPAYMENT_OR_WAIVER;
|
||||
validateRepaymentTypeAccountStatus(downPaymentTransaction, event);
|
||||
HolidayDetailDTO holidayDetailDTO = scheduleGeneratorDTO.getHolidayDetailDTO();
|
||||
validateRepaymentDateIsOnHoliday(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.isAllowTransactionsOnHoliday(),
|
||||
holidayDetailDTO.getHolidays());
|
||||
validateRepaymentDateIsOnNonWorkingDay(downPaymentTransaction.getTransactionDate(), holidayDetailDTO.getWorkingDays(),
|
||||
holidayDetailDTO.isAllowTransactionsOnNonWorkingDay());
|
||||
|
||||
handleRepaymentOrRecoveryOrWaiverTransaction(downPaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||
return downPaymentTransaction;
|
||||
handleRepaymentOrRecoveryOrWaiverTransaction(downPaymentTransaction, loanLifecycleStateMachine, null, scheduleGeneratorDTO);
|
||||
return downPaymentTransaction;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isAutoRepaymentForDownPaymentEnabled() {
|
||||
|
||||
+8
-6
@@ -465,10 +465,13 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
newLoanTransaction.adjustInterestComponent(currency);
|
||||
}
|
||||
/*
|
||||
* Check if the transaction amounts have changed. If so, reverse the original transaction and update
|
||||
* changedTransactionDetail accordingly
|
||||
* Check if the transaction amounts have changed or was there any transaction for the same date which was
|
||||
* reverse-replayed. If so, reverse the original transaction and update changedTransactionDetail accordingly
|
||||
*/
|
||||
if (LoanTransaction.transactionAmountsMatch(currency, loanTransaction, newLoanTransaction)) {
|
||||
boolean aTransactionWasAlreadyReplayedForTheSameDate = changedTransactionDetail.getNewTransactionMappings().values().stream()
|
||||
.anyMatch(lt -> lt.getTransactionDate().equals(loanTransaction.getTransactionDate()));
|
||||
if (LoanTransaction.transactionAmountsMatch(currency, loanTransaction, newLoanTransaction)
|
||||
&& !aTransactionWasAlreadyReplayedForTheSameDate) {
|
||||
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(
|
||||
newLoanTransaction.getLoanTransactionToRepaymentScheduleMappings());
|
||||
} else {
|
||||
@@ -503,6 +506,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
|
||||
private void updateLoanSchedule(LoanTransaction disbursementTransaction, MonetaryCurrency currency,
|
||||
List<LoanRepaymentScheduleInstallment> installments, MoneyHolder overpaymentHolder) {
|
||||
disbursementTransaction.resetDerivedComponents();
|
||||
final MathContext mc = MoneyHelper.getMathContext();
|
||||
List<LoanRepaymentScheduleInstallment> candidateRepaymentInstallments = installments.stream().filter(
|
||||
i -> i.getDueDate().isAfter(disbursementTransaction.getTransactionDate()) && !i.isDownPayment() && !i.isAdditional())
|
||||
@@ -570,9 +574,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
transactionAmountUnprocessed = processPeriodsVertically(loanTransaction, currency, installments,
|
||||
overpaymentHolder.getMoneyObject(), defaultPaymentAllocationRule, transactionMappings, Set.of(), balances);
|
||||
}
|
||||
if (transactionAmountUnprocessed != null && transactionAmountUnprocessed.isGreaterThanZero()) {
|
||||
overpaymentHolder.setMoneyObject(transactionAmountUnprocessed);
|
||||
}
|
||||
overpaymentHolder.setMoneyObject(transactionAmountUnprocessed);
|
||||
loanTransaction.updateLoanTransactionToRepaymentScheduleMappings(transactionMappings);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user