Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FINERACT-2268: added test scenarios to cover repayment schedule with large charge amounts #4342

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
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 @@ -48,4 +48,26 @@ public static String randomNameGenerator(final String prefix, final int lenOfRan
public static LocalDate now() {
return LocalDate.now(Clock.systemUTC());
}

/**
* A record that formats a double value based on whether it's a whole number or not.
* <p>
* If the value is a whole number, the output will have one decimal place (e.g., 16.0).
* Otherwise, it will have two decimal places (e.g., 16.90), but if the second decimal
* place is zero, it will be removed (so 16.90 becomes 16.9).
*/
public record DoubleFormatter(double value) {

public String format() {
boolean isWholeNumber = (value % 1.0 == 0);

String result = isWholeNumber ? String.format("%.1f", value) : String.format("%.2f", value);

// For non-whole numbers, remove trailing '0' if it exists
if (!isWholeNumber && result.endsWith("0")) {
result = result.substring(0, result.length() - 1);
}
return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2003,10 +2003,11 @@ private List<List<String>> getActualValuesList(List<GetLoansLoanIdLoanChargeData
actualValues.add(t.getChargeTimeType().getValue() == null ? null : t.getChargeTimeType().getValue());
actualValues.add(t.getDueDate() == null ? null : FORMATTER.format(t.getDueDate()));
actualValues.add(t.getChargeCalculationType().getValue() == null ? null : t.getChargeCalculationType().getValue());
actualValues.add(t.getAmount() == null ? null : String.valueOf(t.getAmount()));
actualValues.add(t.getAmount() == null ? null : String.valueOf(new Utils.DoubleFormatter(t.getAmount()).format()));
actualValues.add(t.getAmountPaid() == null ? null : String.valueOf(t.getAmountPaid()));
actualValues.add(t.getAmountWaived() == null ? null : String.valueOf(t.getAmountWaived()));
actualValues.add(t.getAmountOutstanding() == null ? null : String.valueOf(t.getAmountOutstanding()));
actualValues.add(
t.getAmountOutstanding() == null ? null : String.valueOf(new Utils.DoubleFormatter(t.getAmountOutstanding()).format()));
return actualValues;
}).collect(Collectors.toList());
}
Expand Down Expand Up @@ -3181,6 +3182,7 @@ private List<String> fetchValuesOfTransaction(List<String> header, GetLoansLoanI

private List<String> fetchValuesOfRepaymentSchedule(List<String> header, GetLoansLoanIdRepaymentPeriod repaymentPeriod) {
List<String> actualValues = new ArrayList<>();

for (String headerName : header) {
switch (headerName) {
case "Nr" -> actualValues.add(repaymentPeriod.getPeriod() == null ? null : String.valueOf(repaymentPeriod.getPeriod()));
Expand All @@ -3196,12 +3198,12 @@ private List<String> fetchValuesOfRepaymentSchedule(List<String> header, GetLoan
actualValues.add(repaymentPeriod.getPrincipalDue() == null ? null : String.valueOf(repaymentPeriod.getPrincipalDue()));
case "Interest" ->
actualValues.add(repaymentPeriod.getInterestDue() == null ? null : String.valueOf(repaymentPeriod.getInterestDue()));
case "Fees" -> actualValues
.add(repaymentPeriod.getFeeChargesDue() == null ? null : String.valueOf(repaymentPeriod.getFeeChargesDue()));
case "Penalties" -> actualValues.add(
repaymentPeriod.getPenaltyChargesDue() == null ? null : String.valueOf(repaymentPeriod.getPenaltyChargesDue()));
case "Due" -> actualValues.add(
repaymentPeriod.getTotalDueForPeriod() == null ? null : String.valueOf(repaymentPeriod.getTotalDueForPeriod()));
case "Fees" -> actualValues.add(repaymentPeriod.getFeeChargesDue() == null ? null
: String.valueOf(new Utils.DoubleFormatter(repaymentPeriod.getFeeChargesDue()).format()));
case "Penalties" -> actualValues.add(repaymentPeriod.getPenaltyChargesDue() == null ? null
: String.valueOf(new Utils.DoubleFormatter(repaymentPeriod.getPenaltyChargesDue()).format()));
case "Due" -> actualValues.add(repaymentPeriod.getTotalDueForPeriod() == null ? null
: String.valueOf(new Utils.DoubleFormatter(repaymentPeriod.getTotalDueForPeriod()).format()));
case "Paid" -> actualValues.add(
repaymentPeriod.getTotalPaidForPeriod() == null ? null : String.valueOf(repaymentPeriod.getTotalPaidForPeriod()));
case "In advance" -> actualValues.add(repaymentPeriod.getTotalPaidInAdvanceForPeriod() == null ? null
Expand All @@ -3211,7 +3213,7 @@ private List<String> fetchValuesOfRepaymentSchedule(List<String> header, GetLoan
case "Waived" -> actualValues.add(repaymentPeriod.getTotalWaivedForPeriod() == null ? null
: String.valueOf(repaymentPeriod.getTotalWaivedForPeriod()));
case "Outstanding" -> actualValues.add(repaymentPeriod.getTotalOutstandingForPeriod() == null ? null
: String.valueOf(repaymentPeriod.getTotalOutstandingForPeriod()));
: String.valueOf(new Utils.DoubleFormatter(repaymentPeriod.getTotalOutstandingForPeriod()).format()));
default -> throw new IllegalStateException(String.format("Header name %s cannot be found", headerName));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2546,7 +2546,7 @@ Feature: LoanCharge
| 01 January 2024 | Repayment | 60.0 | 60.0 | 0.0 | 0.0 | 0.0 | 40.0 |
Then Loan Charges tab has a given charge with the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| NSF fee | true | Specified due date | 01 February 2024 | Flat | 20.0 | 0.0 | 0.0 | 20.0 |
| NSF fee | true | Specified due date | 01 February 2024 | Flat | 20.0 | 0.0 | 0.0 | 20.0 |
When Admin makes a charge adjustment for the last "LOAN_NSF_FEE" type charge which is due on "01 February 2024" with 20 EUR transaction amount and externalId ""
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 |
Expand All @@ -2564,3 +2564,93 @@ Feature: LoanCharge
| 01 January 2024 | Repayment | 60.0 | 60.0 | 0.0 | 0.0 | 0.0 | 40.0 |
| 01 February 2024 | Charge Adjustment | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | 40.0 |
And LoanChargeAdjustmentPostBusinessEvent is raised on "01 February 2024"

@TestRailId:C3501
Scenario: Verify repayment schedule amounts after large charge amount added - UC1
When Admin sets the business date to "20 February 2025"
And Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 20 December 2024 | 800 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 4 | MONTHS | 1 | MONTHS | 4 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "20 December 2024" with "800" amount and expected disbursement date on "20 December 2024"
When Admin successfully disburse the loan on "20 December 2024" with "800" EUR transaction amount
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 |
| | | 20 December 2024 | | 800.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 20 January 2025 | | 600.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 2 | 31 | 20 February 2025 | | 400.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 3 | 28 | 20 March 2025 | | 200.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 4 | 31 | 20 April 2025 | | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
And Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 800.0 | 0.0 | 0.0 | 0.0 | 800.0 | 0.0 | 0.0 | 0.0 | 800.0 |
And Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 20 December 2024 | Disbursement | 800.0 | 0.0 | 0.0 | 0.0 | 0.0 | 800.0 | false | false |
And Admin adds "LOAN_NSF_FEE" due date charge with "25 December 2024" due date and 123456789012.12 EUR transaction amount
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 |
| | | 20 December 2024 | | 800.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 20 January 2025 | | 600.0 | 200.0 | 0.0 | 0.0 | 123456789012.12 | 123456789212.12 | 0.0 | 0.0 | 0.0 | 123456789212.12 |
| 2 | 31 | 20 February 2025 | | 400.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 3 | 28 | 20 March 2025 | | 200.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 4 | 31 | 20 April 2025 | | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
And Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 800.0 | 0.0 | 0.0 | 123456789012.12 | 123456789812.12 | 0.0 | 0.0 | 0.0 | 123456789812.12 |
And Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 20 December 2024 | Disbursement | 800.0 | 0.0 | 0.0 | 0.0 | 0.0 | 800.0 | false | false |
Then Loan Charges tab has a given charge with the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| NSF fee | true | Specified due date | 25 December 2024 | Flat | 123456789012.12 | 0.0 | 0.0 | 123456789012.12 |

@TestRailId:C3502
Scenario: Verify repayment schedule amounts after a few large charges amount added - UC2
When Admin sets the business date to "20 February 2025"
And Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 20 December 2024 | 800 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 4 | MONTHS | 1 | MONTHS | 4 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "20 December 2024" with "800" amount and expected disbursement date on "20 December 2024"
When Admin successfully disburse the loan on "20 December 2024" with "800" EUR transaction amount
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 |
| | | 20 December 2024 | | 800.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 20 January 2025 | | 600.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 2 | 31 | 20 February 2025 | | 400.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 3 | 28 | 20 March 2025 | | 200.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
| 4 | 31 | 20 April 2025 | | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 | 0.0 | 0.0 | 0.0 | 200.0 |
And Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 800.0 | 0.0 | 0.0 | 0.0 | 800.0 | 0.0 | 0.0 | 0.0 | 800.0 |
And Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 20 December 2024 | Disbursement | 800.0 | 0.0 | 0.0 | 0.0 | 0.0 | 800.0 | false | false |
And Admin adds "LOAN_NSF_FEE" due date charge with "25 December 2024" due date and 123456789012.12 EUR transaction amount
When Admin adds "LOAN_SNOOZE_FEE" due date charge with "28 December 2024" due date and 1003456789012.12 EUR transaction amount
When Admin adds "LOAN_NSF_FEE" due date charge with "31 January 2025" due date and 5503456789012.12 EUR transaction amount
When Admin adds "LOAN_NSF_FEE" due date charge with "23 February 2025" due date and 1003456789012.12 EUR transaction amount
When Admin adds "LOAN_NSF_FEE" due date charge with "03 April 2025" due date and 1503456789012.12 EUR transaction amount
When Admin adds "LOAN_SNOOZE_FEE" due date charge with "09 April 2025" due date and 103456789037.12 EUR transaction amount
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 |
| | | 20 December 2024 | | 800.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 20 January 2025 | | 600.0 | 200.0 | 0.0 | 1003456789012.12 | 123456789012.12 | 1126913578224.24 | 0.0 | 0.0 | 0.0 | 1126913578224.24 |
| 2 | 31 | 20 February 2025 | | 400.0 | 200.0 | 0.0 | 0.0 | 5503456789012.12 | 5503456789212.12 | 0.0 | 0.0 | 0.0 | 5503456789212.12 |
| 3 | 28 | 20 March 2025 | | 200.0 | 200.0 | 0.0 | 0.0 | 1003456789012.12 | 1003456789212.12 | 0.0 | 0.0 | 0.0 | 1003456789212.12 |
| 4 | 31 | 20 April 2025 | | 0.0 | 200.0 | 0.0 | 103456789037.12 | 1503456789012.12 | 1606913578249.24 | 0.0 | 0.0 | 0.0 | 1606913578249.24 |
And Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 800.0 | 0.0 | 1106913578049.24 | 8133827156048.48 | 9240740734897.72 | 0.0 | 0.0 | 0.0 | 9240740734897.72 |
And Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 20 December 2024 | Disbursement | 800.0 | 0.0 | 0.0 | 0.0 | 0.0 | 800.0 | false | false |
Then Loan Charges tab has a given charge with the following data:
| Name | isPenalty | Payment due at | Due as of | Calculation type | Due | Paid | Waived | Outstanding |
| NSF fee | true | Specified due date | 25 December 2024 | Flat | 123456789012.12 | 0.0 | 0.0 | 123456789012.12 |
| Snooze fee | false | Specified due date | 28 December 2024 | Flat | 1003456789012.12 | 0.0 | 0.0 | 1003456789012.12 |
| NSF fee | true | Specified due date | 31 January 2025 | Flat | 5503456789012.12 | 0.0 | 0.0 | 5503456789012.12 |
| NSF fee | true | Specified due date | 23 February 2025 | Flat | 1003456789012.12 | 0.0 | 0.0 | 1003456789012.12 |
| NSF fee | true | Specified due date | 03 April 2025 | Flat | 1503456789012.12 | 0.0 | 0.0 | 1503456789012.12 |
| Snooze fee | false | Specified due date | 09 April 2025 | Flat | 103456789037.12 | 0.0 | 0.0 | 103456789037.12 |
Loading