FINERACT-2354: [BE] pay-off to close re-aged loan with charge outcomes with Active loan status
This commit is contained in:
+42
@@ -945,6 +945,48 @@ public class LoanRepaymentScheduleInstallment extends AbstractAuditableWithUTCDa
|
||||
}
|
||||
}
|
||||
|
||||
public void addPenaltyCharges(final Money amount) {
|
||||
if (amount != null) {
|
||||
addPenaltyCharges(amount.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
public void addPenaltyCharges(final BigDecimal amount) {
|
||||
if (this.penaltyCharges == null) {
|
||||
setPenaltyCharges(amount);
|
||||
} else {
|
||||
setPenaltyCharges(this.penaltyCharges.add(amount));
|
||||
}
|
||||
}
|
||||
|
||||
public void addToPenaltyPaid(final Money amount) {
|
||||
if (amount != null) {
|
||||
addToPenaltyPaid(amount.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
public void addToPenaltyPaid(final BigDecimal amount) {
|
||||
if (this.penaltyChargesPaid == null) {
|
||||
setPenaltyChargesPaid(amount);
|
||||
} else {
|
||||
setPenaltyChargesPaid(this.penaltyChargesPaid.add(amount));
|
||||
}
|
||||
}
|
||||
|
||||
public void addToFeeChargesPaid(final Money amount) {
|
||||
if (amount != null) {
|
||||
addToFeeChargesPaid(amount.getAmount());
|
||||
}
|
||||
}
|
||||
|
||||
public void addToFeeChargesPaid(final BigDecimal amount) {
|
||||
if (this.feeChargesPaid == null) {
|
||||
setFeeChargesPaid(amount);
|
||||
} else {
|
||||
setFeeChargesPaid(this.feeChargesPaid.add(amount));
|
||||
}
|
||||
}
|
||||
|
||||
/********** UNPAY COMPONENTS ****/
|
||||
|
||||
public Money unpayPenaltyChargesComponent(final LocalDate transactionDate, final Money transactionAmountRemaining) {
|
||||
|
||||
+42
-2
@@ -3764,10 +3764,18 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
balances.getPrincipal().getAmount(), balances.getInterest().getAmount(), balances.getFee().getAmount(),
|
||||
balances.getPenalty().getAmount(), null, null, null);
|
||||
|
||||
if (!settings.isEqualInstallmentForFeesAndPenalties) {
|
||||
// If charges should NOT reamortize by reage, we should manage to keep them related to the correct
|
||||
// installment.
|
||||
LoanRepaymentScheduleInstallment target = earlyRepaidInstallment;
|
||||
Set<LoanCharge> charges = ctx.getCharges();
|
||||
moveRelatedChargesToInstallment(charges, target, installments, currency);
|
||||
}
|
||||
|
||||
earlyRepaidInstallment.setPrincipalCompleted(balances.getPrincipal().getAmount());
|
||||
earlyRepaidInstallment.setInterestPaid(balances.getInterest().getAmount());
|
||||
earlyRepaidInstallment.setFeeChargesPaid(balances.getFee().getAmount());
|
||||
earlyRepaidInstallment.setPenaltyChargesPaid(balances.getPenalty().getAmount());
|
||||
earlyRepaidInstallment.addToFeeChargesPaid(balances.getFee());
|
||||
earlyRepaidInstallment.addToPenaltyPaid(balances.getPenalty());
|
||||
|
||||
earlyRepaidInstallment.setTotalPaidInAdvance(balances.getPaidInAdvance().getAmount());
|
||||
|
||||
@@ -3820,6 +3828,38 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
|
||||
reprocessInstallments(installments);
|
||||
}
|
||||
|
||||
private void moveRelatedChargesToInstallment(Set<LoanCharge> charges, LoanRepaymentScheduleInstallment target,
|
||||
List<LoanRepaymentScheduleInstallment> installments, MonetaryCurrency currency) {
|
||||
int firstNormalInstallmentNumber = LoanRepaymentScheduleProcessingWrapper.fetchFirstNormalInstallmentNumber(installments);
|
||||
Set<LoanCharge> chargesOfNewInstallment = getLoanChargesOfInstallment(charges, target, firstNormalInstallmentNumber);
|
||||
Integer targetInstallmentNumber = target.getInstallmentNumber();
|
||||
installments.stream().filter(i -> Objects.equals(i.getInstallmentNumber(), targetInstallmentNumber)).findFirst()
|
||||
.filter(source -> source != target).ifPresent(source -> {
|
||||
// move fees
|
||||
chargesOfNewInstallment.stream().filter(LoanCharge::isNotFullyPaid).filter(LoanCharge::isFeeCharge)
|
||||
.forEach(loanCharge -> moveFeeCharge(loanCharge, source, target, currency));
|
||||
// move penalties
|
||||
chargesOfNewInstallment.stream().filter(LoanCharge::isNotFullyPaid).filter(LoanCharge::isPenaltyCharge)
|
||||
.forEach(loanCharge -> movePenaltyCharge(loanCharge, source, target, currency));
|
||||
});
|
||||
}
|
||||
|
||||
private void movePenaltyCharge(LoanCharge loanCharge, LoanRepaymentScheduleInstallment source, LoanRepaymentScheduleInstallment target,
|
||||
MonetaryCurrency currency) {
|
||||
source.setPenaltyCharges(MathUtil.subtract(source.getPenaltyCharges(), loanCharge.chargeAmount()));
|
||||
source.setPenaltyChargesPaid(MathUtil.subtract(source.getPenaltyChargesPaid(), loanCharge.getAmountPaid()));
|
||||
target.addPenaltyCharges(loanCharge.getAmount(currency));
|
||||
target.addToPenaltyPaid(loanCharge.getAmountPaid());
|
||||
}
|
||||
|
||||
private void moveFeeCharge(LoanCharge loanCharge, LoanRepaymentScheduleInstallment source, LoanRepaymentScheduleInstallment target,
|
||||
MonetaryCurrency currency) {
|
||||
source.setFeeChargesCharged(MathUtil.subtract(source.getFeeChargesCharged(), loanCharge.chargeAmount()));
|
||||
source.setFeeChargesPaid(MathUtil.subtract(source.getFeeChargesPaid(), loanCharge.getAmountPaid()));
|
||||
target.addToFeeCharges(loanCharge.getAmount(currency));
|
||||
target.addToFeeChargesPaid(loanCharge.getAmountPaid());
|
||||
}
|
||||
|
||||
private void createChargeMappingsForInstallment(final LoanRepaymentScheduleInstallment installment,
|
||||
List<ReAgedChargeEqualAmortizationValues> reAgedChargeEqualAmortizationValues, Integer index) {
|
||||
reAgedChargeEqualAmortizationValues.forEach(amortizationValue -> installment.getInstallmentCharges().add(new LoanInstallmentCharge(
|
||||
|
||||
Reference in New Issue
Block a user