Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3304,7 +3304,7 @@ Then Loan Repayment schedule has 4 periods, with the following data for periods:
When Loan Pay-off is made on "02 January 2025"
Then Loan is closed with zero outstanding balance and it's all installments have obligations met

@Skip @TestRailId:C4080 @AdvancedPaymentAllocation
@TestRailId:C4080 @AdvancedPaymentAllocation
Scenario: Verify Loan re-aging transaction at 1st installment with charge - before maturity date and removes additional normal installments and not modifies n+1 - UC13
When Admin sets the business date to "01 January 2025"
When Admin creates a client with random data
Expand Down Expand Up @@ -3340,12 +3340,12 @@ Then Loan Repayment schedule has 4 periods, with the following data for periods:
| frequencyNumber | frequencyType | startDate | numberOfInstallments |
| 1 | MONTHS | 11 January 2025 | 2 |
Then Loan Repayment schedule has 4 periods, with the following data for periods:
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 0 | 01 January 2025 | 01 January 2025 | 750.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 |
| 2 | 9 | 10 January 2025 | 10 January 2025 | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 3 | 1 | 11 January 2025 | | 375.0 | 375.0 | 0.0 | 0.0 | 20.0 | 395.0 | 0.0 | 0.0 | 0.0 | 395.0 |
| 4 | 31 | 11 February 2025 | | 0.0 | 375.0 | 0.0 | 0.0 | 0.0 | 375.0 | 0.0 | 0.0 | 0.0 | 375.0 |
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| | | 01 January 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 0 | 01 January 2025 | 01 January 2025 | 750.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 |
| 2 | 9 | 10 January 2025 | | 750.0 | 0.0 | 0.0 | 0.0 | 20.0 | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 |
| 3 | 1 | 11 January 2025 | | 375.0 | 375.0 | 0.0 | 0.0 | 0.0 | 375.0 | 0.0 | 0.0 | 0.0 | 375.0 |
| 4 | 31 | 11 February 2025 | | 0.0 | 375.0 | 0.0 | 0.0 | 0.0 | 375.0 | 0.0 | 0.0 | 0.0 | 375.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 1000.0 | 0.0 | 0.0 | 20.0 | 1020.0 | 250.0 | 0.0 | 0.0 | 770.0 |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,48 @@ public void addToCreditedPenalty(final BigDecimal amount) {
}
}

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3688,6 +3688,7 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
MonetaryCurrency currency = ctx.getCurrency();
Loan loan = loanTransaction.getLoan();
List<LoanRepaymentScheduleInstallment> installments = ctx.getInstallments();
int firstNormalInstallmentNumber = LoanRepaymentScheduleProcessingWrapper.fetchFirstNormalInstallmentNumber(installments);
LoanReAgeParameter loanReAgeParameter = loanTransaction.getLoanReAgeParameter();
LocalDate transactionDate = loanTransaction.getTransactionDate();
LocalDate originalMaturityDate = installments.stream()
Expand Down Expand Up @@ -3764,10 +3765,39 @@ private void handleReAgeWithCommonStrategy(LoanTransaction loanTransaction, Comm
balances.getPrincipal().getAmount(), balances.getInterest().getAmount(), balances.getFee().getAmount(),
balances.getPenalty().getAmount(), null, null, null);

if (!settings.isEqualInstallmentForFeesAndPenalties) {
Set<LoanCharge> charges = getLoanChargesOfInstallment(ctx.getCharges(), earlyRepaidInstallment,
firstNormalInstallmentNumber);
Integer reAgedInstallmentNumber = firstReAgeInstallmentProps.reAgedInstallmentNumber();
Optional<LoanRepaymentScheduleInstallment> originalInstallment = installments.stream()
.filter(i -> Objects.equals(i.getInstallmentNumber(), reAgedInstallmentNumber)).findFirst();
originalInstallment.ifPresent(source -> {
List<LoanCharge> fees = charges.stream().filter(LoanCharge::isNotFullyPaid).filter(LoanCharge::isFeeCharge).toList();
fees.forEach(loanCharge -> {
source.setFeeChargesCharged(MathUtil.subtract(source.getFeeChargesCharged(), loanCharge.chargeAmount()));
source.setFeeChargesPaid(MathUtil.subtract(source.getFeeChargesPaid(), loanCharge.getAmountPaid()));

earlyRepaidInstallment.addToFeeCharges(loanCharge.getAmount(currency));
earlyRepaidInstallment.addToFeeChargesPaid(loanCharge.getAmountPaid());
});
// remove penalties from original
List<LoanCharge> penalties = charges.stream().filter(LoanCharge::isNotFullyPaid).filter(LoanCharge::isPenaltyCharge)
.toList();
penalties.forEach(loanCharge -> {
source.setPenaltyCharges(MathUtil.subtract(source.getPenaltyCharges(), loanCharge.chargeAmount()));
source.setPenaltyChargesPaid(MathUtil.subtract(source.getPenaltyChargesPaid(), loanCharge.getAmountPaid()));

earlyRepaidInstallment.addPenaltyCharges(loanCharge.getAmount(currency));
earlyRepaidInstallment.addToPenaltyPaid(loanCharge.getAmountPaid());
});
});

}

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());

Expand Down
Loading