FINERACT-2553: Fix repayment schedule during accelerate maturity date charge off/contract termination when full backdated repayment occurs after it

This commit is contained in:
mariiaKraievska
2025-06-05 14:58:20 +02:00
committed by Adam Saghy
parent 57ef4a2771
commit 71a4d08849
9 changed files with 569 additions and 62 deletions
@@ -5890,6 +5890,228 @@ Feature: Charge-off
| 29 February 2024 | Accrual | 1.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | false | false |
| 29 February 2024 | Charge-off | 66.98 | 66.8 | 0.18 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3727
Scenario: As a user I want to perform accelerate maturity to charge-off date with interest recalculation when backdated full repayment occurs after - S12
Given Global configuration "is-principal-compounding-disabled-for-overdue-loans" is enabled
When Admin sets the business date to "01 January 2024"
When 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_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
When Admin sets the business date to "01 February 2024"
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
When Admin sets the business date to "31 March 2024"
And Admin does charge-off the loan on "31 March 2024"
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.47 | 0.0 | 0.0 | 67.52 | 0.0 | 0.0 | 0.0 | 67.52 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.54 | 0.0 | 0.0 | 101.54 | 17.01 | 0.0 | 0.0 | 84.53 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 84.53 | 83.57 | 0.96 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 84.06 EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2024 | 01 March 2024 | 50.04 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 01 March 2024 | 33.03 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 01 March 2024 | 16.02 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 01 March 2024 | 0.0 | 16.02 | 0.0 | 0.0 | 0.0 | 16.02 | 16.02 | 16.02 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.07 | 0.0 | 0.0 | 101.07 | 101.07 | 67.05 | 0.0 | 0.0 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 01 March 2024 | Repayment | 84.06 | 83.57 | 0.49 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.47 | 0.0 | 0.47 | 0.0 | 0.0 | 0.0 | false | false |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3728
Scenario: As a user I want to perform accelerate maturity to charge-off date with interest recalculation when backdated repayment with excess amount occurs after - S13
Given Global configuration "is-principal-compounding-disabled-for-overdue-loans" is enabled
When Admin sets the business date to "01 January 2024"
When 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_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
When Admin sets the business date to "01 February 2024"
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
When Admin sets the business date to "31 March 2024"
And Admin does charge-off the loan on "31 March 2024"
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.47 | 0.0 | 0.0 | 67.52 | 0.0 | 0.0 | 0.0 | 67.52 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.54 | 0.0 | 0.0 | 101.54 | 17.01 | 0.0 | 0.0 | 84.53 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 84.53 | 83.57 | 0.96 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 27.01 EUR transaction amount
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.32 | 0.0 | 0.0 | 67.37 | 10.0 | 10.0 | 0.0 | 57.37 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.39 | 0.0 | 0.0 | 101.39 | 44.02 | 10.0 | 0.0 | 57.37 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 01 March 2024 | Repayment | 27.01 | 26.52 | 0.49 | 0.0 | 0.0 | 57.05 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.15 | 0.0 | 0.15 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 57.37 | 57.05 | 0.32 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3729
Scenario: As a user I want to perform accelerate maturity to charge-off date with interest recalculation when backdated first repayment with excess amount occurs after
Given Global configuration "is-principal-compounding-disabled-for-overdue-loans" is enabled
When Admin sets the business date to "01 January 2024"
When 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_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ACCELERATE_MATURITY_CHARGE_OFF_BEHAVIOUR | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
When Admin sets the business date to "31 March 2024"
And Admin does charge-off the loan on "31 March 2024"
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.14 | 0.56 | 0.0 | 0.0 | 67.7 | 0.0 | 0.0 | 0.0 | 67.7 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.72 | 0.0 | 0.0 | 101.72 | 0.0 | 0.0 | 0.0 | 101.72 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 31 March 2024 | Accrual | 1.72 | 0.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 101.72 | 100.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 70.00 EUR transaction amount
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 March 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 17.01 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.08 | 0.0 | 0.0 | 67.13 | 35.98 | 35.98 | 0.0 | 31.15 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.15 | 0.0 | 0.0 | 101.15 | 70.0 | 35.98 | 17.01 | 31.15 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 March 2024 | Repayment | 70.0 | 68.93 | 1.07 | 0.0 | 0.0 | 31.07 | false | false |
| 31 March 2024 | Accrual | 1.72 | 0.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.57 | 0.0 | 0.57 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 31.15 | 31.07 | 0.08 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3499 @AdvancedPaymentAllocation
Scenario: Verify accelerate maturity to charge-off date when interest recalculation is disabled - case when charge-off occurs with adjustment to last installment
When Admin sets the business date to "01 January 2024"
@@ -8298,6 +8520,7 @@ Feature: Charge-off
| 13 April 2025 | Merchant Issued Refund | 500.0 | 9.81 | 0.5 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual Adjustment | 0.24 | 0.0 | 0.24 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 7.34 | 0.0 | 7.34 | 0.0 | 0.0 | 0.0 | false | false |
When Customer makes "GOODWILL_CREDIT" transaction with "AUTOPAY" payment type on "13 April 2025" with 500 EUR transaction amount and system-generated Idempotency key
Then Loan Repayment schedule has 6 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 | Waived | Outstanding |
@@ -8319,6 +8542,7 @@ Feature: Charge-off
| 13 April 2025 | Goodwill Credit | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual Adjustment | 0.24 | 0.0 | 0.24 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 7.34 | 0.0 | 7.34 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3612
Scenario: As a user I want to verify that backdated transactions are allowed after charge-off and backdated full repayment, interestRecalculation = true
@@ -9172,6 +9396,7 @@ Feature: Charge-off
| 13 April 2025 | Merchant Issued Refund | 500.0 | 9.81 | 0.5 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 3.21 | 0.0 | 3.21 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual Adjustment | 0.24 | 0.0 | 0.24 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 7.34 | 0.0 | 7.34 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3644
Scenario: As a user I want to verify that charge-off transaction if the amount balance becomes zero is reversed after backdated full repayment and MIR, interestRecalculation = true
@@ -825,4 +825,226 @@ Feature: Contract Termination
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 15 February 2024 | Repayment | 17.01 | 16.77 | 0.24 | 0.0 | 0.0 | 66.8 | false | true |
| 29 February 2024 | Accrual | 1.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | false | false |
| 29 February 2024 | Contract Termination | 66.98 | 66.8 | 0.18 | 0.0 | 0.0 | 0.0 | false | false |
| 29 February 2024 | Contract Termination | 66.98 | 66.8 | 0.18 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3724
Scenario: As a user I want to perform contract termination to a progressive loan with interest recalculation when backdated full repayment occurs after - S12
Given Global configuration "is-principal-compounding-disabled-for-overdue-loans" is enabled
When Admin sets the business date to "01 January 2024"
When 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_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_CONTRACT_TERMINATION | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
When Admin sets the business date to "01 February 2024"
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
When Admin sets the business date to "31 March 2024"
And Admin successfully terminates loan contract
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.47 | 0.0 | 0.0 | 67.52 | 0.0 | 0.0 | 0.0 | 67.52 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.54 | 0.0 | 0.0 | 101.54 | 17.01 | 0.0 | 0.0 | 84.53 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 84.53 | 83.57 | 0.96 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 84.06 EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2024 | 01 March 2024 | 50.04 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 01 March 2024 | 33.03 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 01 March 2024 | 16.02 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 01 March 2024 | 0.0 | 16.02 | 0.0 | 0.0 | 0.0 | 16.02 | 16.02 | 16.02 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.07 | 0.0 | 0.0 | 101.07 | 101.07 | 67.05 | 0.0 | 0.0 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 01 March 2024 | Repayment | 84.06 | 83.57 | 0.49 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.47 | 0.0 | 0.47 | 0.0 | 0.0 | 0.0 | false | false |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3725
Scenario: As a user I want to perform contract termination to a progressive loan with interest recalculation when backdated repayment with excess amount occurs after - S13
Given Global configuration "is-principal-compounding-disabled-for-overdue-loans" is enabled
When Admin sets the business date to "01 January 2024"
When 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_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_CONTRACT_TERMINATION | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
When Admin sets the business date to "01 February 2024"
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
When Admin sets the business date to "31 March 2024"
And Admin successfully terminates loan contract
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.47 | 0.0 | 0.0 | 67.52 | 0.0 | 0.0 | 0.0 | 67.52 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.54 | 0.0 | 0.0 | 101.54 | 17.01 | 0.0 | 0.0 | 84.53 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 84.53 | 83.57 | 0.96 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 27.01 EUR transaction amount
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.32 | 0.0 | 0.0 | 67.37 | 10.0 | 10.0 | 0.0 | 57.37 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.39 | 0.0 | 0.0 | 101.39 | 44.02 | 10.0 | 0.0 | 57.37 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
| 01 March 2024 | Repayment | 27.01 | 26.52 | 0.49 | 0.0 | 0.0 | 57.05 | false | false |
| 31 March 2024 | Accrual | 1.54 | 0.0 | 1.54 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.15 | 0.0 | 0.15 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 57.37 | 57.05 | 0.32 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3726
Scenario: As a user I want to perform contract termination to a progressive loan with interest recalculation when backdated first repayment with excess amount occurs after
Given Global configuration "is-principal-compounding-disabled-for-overdue-loans" is enabled
When Admin sets the business date to "01 January 2024"
When 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_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_CONTRACT_TERMINATION | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
Then Loan Repayment schedule has 6 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
When Admin sets the business date to "31 March 2024"
And Admin successfully terminates loan contract
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 2 | 29 | 01 March 2024 | | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.14 | 0.56 | 0.0 | 0.0 | 67.7 | 0.0 | 0.0 | 0.0 | 67.7 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.72 | 0.0 | 0.0 | 101.72 | 0.0 | 0.0 | 0.0 | 101.72 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 31 March 2024 | Accrual | 1.72 | 0.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 101.72 | 100.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 70.00 EUR transaction amount
Then Loan Repayment schedule has 3 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 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 31 | 01 February 2024 | 01 March 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 17.01 | 0.0 |
| 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.08 | 0.0 | 0.0 | 67.13 | 35.98 | 35.98 | 0.0 | 31.15 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 1.15 | 0.0 | 0.0 | 101.15 | 70.0 | 35.98 | 17.01 | 31.15 |
Then Loan Transactions tab has the following data:
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
| 01 March 2024 | Repayment | 70.0 | 68.93 | 1.07 | 0.0 | 0.0 | 31.07 | false | false |
| 31 March 2024 | Accrual | 1.72 | 0.0 | 1.72 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Accrual Adjustment | 0.57 | 0.0 | 0.57 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 31.15 | 31.07 | 0.08 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@@ -1655,6 +1655,12 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom<Long> {
return false;
}
public void liftContractTerminationSubStatus() {
if (this.loanSubStatus.isContractTermination()) {
this.loanSubStatus = null;
}
}
public List<LoanTermVariations> getActiveLoanTermVariations() {
if (this.loanTermVariations == null) {
return new ArrayList<>();
@@ -353,32 +353,47 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
private void handleContractTermination(final LoanTransaction loanTransaction, final TransactionCtx transactionCtx) {
handleAccelerateMaturityDate(loanTransaction, transactionCtx);
final BigDecimal newInterest = getInterestTillChargeOffForPeriod(loanTransaction.getLoan(), loanTransaction.getTransactionDate(),
transactionCtx);
createMissingAccrualTransactionDuringChargeOffIfNeeded(newInterest, loanTransaction, loanTransaction.getTransactionDate(),
transactionCtx);
loanTransaction.resetDerivedComponents();
// determine how much is outstanding total and breakdown for principal, interest and charges
Money principalPortion = Money.zero(transactionCtx.getCurrency());
Money interestPortion = Money.zero(transactionCtx.getCurrency());
Money feeChargesPortion = Money.zero(transactionCtx.getCurrency());
Money penaltyChargesPortion = Money.zero(transactionCtx.getCurrency());
for (final LoanRepaymentScheduleInstallment currentInstallment : transactionCtx.getInstallments()) {
principalPortion = principalPortion.plus(currentInstallment.getPrincipalOutstanding(transactionCtx.getCurrency()));
interestPortion = interestPortion.plus(currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()));
feeChargesPortion = feeChargesPortion.plus(currentInstallment.getFeeChargesOutstanding(transactionCtx.getCurrency()));
penaltyChargesPortion = penaltyChargesPortion
.plus(currentInstallment.getPenaltyChargesOutstanding(transactionCtx.getCurrency()));
if (transactionCtx.getInstallments().stream().anyMatch(this::isNotObligationsMet)) {
handleAccelerateMaturityDate(loanTransaction, transactionCtx);
final BigDecimal newInterest = getInterestTillChargeOffForPeriod(loanTransaction.getLoan(),
loanTransaction.getTransactionDate(), transactionCtx);
createMissingAccrualTransactionDuringChargeOffIfNeeded(newInterest, loanTransaction, loanTransaction.getTransactionDate(),
transactionCtx);
loanTransaction.resetDerivedComponents();
// determine how much is outstanding total and breakdown for principal, interest and charges
for (final LoanRepaymentScheduleInstallment currentInstallment : transactionCtx.getInstallments()) {
principalPortion = principalPortion.plus(currentInstallment.getPrincipalOutstanding(transactionCtx.getCurrency()));
interestPortion = interestPortion.plus(currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()));
feeChargesPortion = feeChargesPortion.plus(currentInstallment.getFeeChargesOutstanding(transactionCtx.getCurrency()));
penaltyChargesPortion = penaltyChargesPortion
.plus(currentInstallment.getPenaltyChargesOutstanding(transactionCtx.getCurrency()));
}
loanTransaction.updateComponentsAndTotal(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
} else {
loanTransaction.resetDerivedComponents();
loanTransaction.updateComponentsAndTotal(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
}
loanTransaction.updateComponentsAndTotal(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx) {
progressiveTransactionCtx.setContractTerminated(true);
}
if (isAllComponentsZero(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion)
&& loanTransaction.isNotReversed()) {
loanTransaction.reverse();
loanTransaction.getLoan().liftContractTerminationSubStatus();
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveCtx) {
progressiveCtx.setContractTerminated(false);
}
}
}
@@ -1381,7 +1396,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
public void recalculateInterestForDate(LocalDate targetDate, ProgressiveTransactionCtx ctx) {
if (ctx.getInstallments() != null && !ctx.getInstallments().isEmpty()) {
Loan loan = ctx.getInstallments().get(0).getLoan();
if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.isNpa() && !ctx.isChargedOff()) {
if (loan.isInterestBearingAndInterestRecalculationEnabled() && !loan.isNpa() && !ctx.isChargedOff()
&& !ctx.isContractTerminated()) {
List<LoanRepaymentScheduleInstallment> overdueInstallmentsSortedByInstallmentNumber = findOverdueInstallmentsBeforeDateSortedByInstallmentNumber(
targetDate, ctx);
@@ -1572,36 +1588,42 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
private void handleChargeOff(final LoanTransaction loanTransaction, final TransactionCtx transactionCtx) {
if (loanTransaction.getLoan().isProgressiveSchedule()) {
if (LoanChargeOffBehaviour.ZERO_INTEREST
.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
handleZeroInterestChargeOff(loanTransaction, transactionCtx);
} else if (LoanChargeOffBehaviour.ACCELERATE_MATURITY
.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
handleAccelerateMaturityDate(loanTransaction, transactionCtx);
}
}
final BigDecimal newInterest = getInterestTillChargeOffForPeriod(loanTransaction.getLoan(), loanTransaction.getTransactionDate(),
transactionCtx);
createMissingAccrualTransactionDuringChargeOffIfNeeded(newInterest, loanTransaction, loanTransaction.getTransactionDate(),
transactionCtx);
loanTransaction.resetDerivedComponents();
// determine how much is outstanding total and breakdown for principal, interest and charges
Money principalPortion = Money.zero(transactionCtx.getCurrency());
Money interestPortion = Money.zero(transactionCtx.getCurrency());
Money feeChargesPortion = Money.zero(transactionCtx.getCurrency());
Money penaltyChargesPortion = Money.zero(transactionCtx.getCurrency());
for (final LoanRepaymentScheduleInstallment currentInstallment : transactionCtx.getInstallments()) {
principalPortion = principalPortion.plus(currentInstallment.getPrincipalOutstanding(transactionCtx.getCurrency()));
interestPortion = interestPortion.plus(currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()));
feeChargesPortion = feeChargesPortion.plus(currentInstallment.getFeeChargesOutstanding(transactionCtx.getCurrency()));
penaltyChargesPortion = penaltyChargesPortion
.plus(currentInstallment.getPenaltyChargesOutstanding(transactionCtx.getCurrency()));
}
loanTransaction.updateComponentsAndTotal(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
if (transactionCtx.getInstallments().stream().anyMatch(this::isNotObligationsMet)) {
if (loanTransaction.getLoan().isProgressiveSchedule()) {
if (LoanChargeOffBehaviour.ZERO_INTEREST
.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
handleZeroInterestChargeOff(loanTransaction, transactionCtx);
} else if (LoanChargeOffBehaviour.ACCELERATE_MATURITY
.equals(loanTransaction.getLoan().getLoanProductRelatedDetail().getChargeOffBehaviour())) {
handleAccelerateMaturityDate(loanTransaction, transactionCtx);
}
}
final BigDecimal newInterest = getInterestTillChargeOffForPeriod(loanTransaction.getLoan(),
loanTransaction.getTransactionDate(), transactionCtx);
createMissingAccrualTransactionDuringChargeOffIfNeeded(newInterest, loanTransaction, loanTransaction.getTransactionDate(),
transactionCtx);
loanTransaction.resetDerivedComponents();
// determine how much is outstanding total and breakdown for principal, interest and charges
for (final LoanRepaymentScheduleInstallment currentInstallment : transactionCtx.getInstallments()) {
principalPortion = principalPortion.plus(currentInstallment.getPrincipalOutstanding(transactionCtx.getCurrency()));
interestPortion = interestPortion.plus(currentInstallment.getInterestOutstanding(transactionCtx.getCurrency()));
feeChargesPortion = feeChargesPortion.plus(currentInstallment.getFeeChargesOutstanding(transactionCtx.getCurrency()));
penaltyChargesPortion = penaltyChargesPortion
.plus(currentInstallment.getPenaltyChargesOutstanding(transactionCtx.getCurrency()));
}
loanTransaction.updateComponentsAndTotal(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
} else {
loanTransaction.resetDerivedComponents();
loanTransaction.updateComponentsAndTotal(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion);
}
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx) {
progressiveTransactionCtx.setChargedOff(true);
@@ -1610,6 +1632,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
if (isAllComponentsZero(principalPortion, interestPortion, feeChargesPortion, penaltyChargesPortion)
&& loanTransaction.isNotReversed()) {
loanTransaction.reverse();
loanTransaction.getLoan().liftChargeOff();
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveCtx) {
progressiveCtx.setChargedOff(false);
@@ -1671,11 +1694,13 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
.filter(installment -> transactionDate.isAfter(installment.getFromDate()))
.collect(Collectors.toCollection(ArrayList::new));
final List<LoanTransaction> transactionsToBeReprocessed = installments.stream()
.filter(installment -> transactionDate.isBefore(installment.getFromDate())
&& !installment.getLoanTransactionToRepaymentScheduleMappings().isEmpty())
.flatMap(installment -> installment.getLoanTransactionToRepaymentScheduleMappings().stream())
.map(LoanTransactionToRepaymentScheduleMapping::getLoanTransaction).toList();
final List<LoanTransaction> transactionsToBeReprocessed = loan.getLoanTransactions().stream()
.filter(transaction -> transaction.getTransactionDate().isBefore(transactionDate))
.filter(transaction -> transaction.getLoanTransactionToRepaymentScheduleMappings().stream().anyMatch(mapping -> {
final LoanRepaymentScheduleInstallment installment = mapping.getInstallment();
return transactionDate.isBefore(installment.getFromDate())
&& installments.stream().anyMatch(i -> i.getInstallmentNumber().equals(installment.getInstallmentNumber()));
})).toList();
if (futureFee.compareTo(BigDecimal.ZERO) > 0 || futurePenalty.compareTo(BigDecimal.ZERO) > 0) {
final Optional<LocalDate> latestDueDate = loan.getCharges().stream()
@@ -1693,6 +1718,12 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
}
transactionCtx.getInstallments().stream().filter(installment -> installment.getFromDate().isBefore(transactionDate))
.filter(installment -> transactionsToBeReprocessed.stream()
.anyMatch(transaction -> transaction.getLoanTransactionToRepaymentScheduleMappings().stream().anyMatch(
mapping -> mapping.getInstallment().getInstallmentNumber().equals(installment.getInstallmentNumber()))))
.forEach(LoanRepaymentScheduleInstallment::resetDerivedComponents);
loanSchedule.updateLoanSchedule(loan, installmentsUpToTransactionDate);
if (transactionCtx instanceof ProgressiveTransactionCtx progressiveTransactionCtx && loan.isInterestRecalculationEnabled()) {
@@ -2209,7 +2240,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
Loan loan = context.getLoanTransaction().getLoan();
if (context.getCtx() instanceof ProgressiveTransactionCtx progressiveTransactionCtx
&& loan.isInterestBearingAndInterestRecalculationEnabled()
&& !progressiveTransactionCtx.isChargedOff()) {
&& !progressiveTransactionCtx.isChargedOff()
&& !progressiveTransactionCtx.isContractTerminated()) {
context.setAllocatedAmount(
handlingPaymentAllocationForInterestBearingProgressiveLoan(context.getLoanTransaction(),
context.getTransactionAmountUnprocessed(), context.getBalances(),
@@ -2237,7 +2269,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
Loan loan = context.getLoanTransaction().getLoan();
if (context.getCtx() instanceof ProgressiveTransactionCtx progressiveTransactionCtx
&& loan.isInterestBearingAndInterestRecalculationEnabled()
&& !progressiveTransactionCtx.isChargedOff()) {
&& !progressiveTransactionCtx.isChargedOff()
&& !progressiveTransactionCtx.isContractTerminated()) {
context.setAllocatedAmount(handlingPaymentAllocationForInterestBearingProgressiveLoan(
context.getLoanTransaction(), context.getTransactionAmountUnprocessed(),
context.getBalances(), paymentAllocationType, dueInstallment, progressiveTransactionCtx,
@@ -2290,7 +2323,8 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
if (context.getCtx() instanceof ProgressiveTransactionCtx progressiveTransactionCtx
&& loan.isInterestBearingAndInterestRecalculationEnabled()
&& !progressiveTransactionCtx.isChargedOff()) {
&& !progressiveTransactionCtx.isChargedOff()
&& !progressiveTransactionCtx.isContractTerminated()) {
context.setAllocatedAmount(handlingPaymentAllocationForInterestBearingProgressiveLoan(
context.getLoanTransaction(), evenPortion, context.getBalances(), paymentAllocationType,
inAdvanceInstallment, progressiveTransactionCtx,
@@ -2650,27 +2684,33 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
private void updateRepaymentPeriodsAfterAccelerateMaturityDate(final ProgressiveTransactionCtx transactionCtx,
final LocalDate chargeOffDate, final List<LoanTransaction> transactionsToBeReprocessed) {
final LocalDate transactionDate, final List<LoanTransaction> transactionsToBeReprocessed) {
final List<LoanRepaymentScheduleInstallment> previousInstallmentsMapping = new ArrayList<>();
transactionsToBeReprocessed.forEach(t -> {
previousInstallmentsMapping.addAll(t.getLoanTransactionToRepaymentScheduleMappings().stream()
.map(LoanTransactionToRepaymentScheduleMapping::getInstallment).toList());
t.getLoanTransactionToRepaymentScheduleMappings().clear();
});
final List<RepaymentPeriod> repaymentPeriods = transactionCtx.getModel().repaymentPeriods();
if (repaymentPeriods.isEmpty()) {
return;
}
final List<RepaymentPeriod> periodsBeforeChargeOff = repaymentPeriods.stream()
.filter(rp -> rp.getFromDate().isBefore(chargeOffDate)).toList();
final List<RepaymentPeriod> periodsBeforeAccelerateMaturity = repaymentPeriods.stream()
.filter(rp -> rp.getFromDate().isBefore(transactionDate)).toList();
if (periodsBeforeChargeOff.isEmpty()) {
if (periodsBeforeAccelerateMaturity.isEmpty()) {
return;
}
final RepaymentPeriod lastPeriod = periodsBeforeChargeOff.get(periodsBeforeChargeOff.size() - 1);
final RepaymentPeriod lastPeriod = periodsBeforeAccelerateMaturity.getLast();
final List<RepaymentPeriod> periodsToRemove = repaymentPeriods.stream().filter(rp -> rp.getFromDate().isAfter(chargeOffDate))
final List<RepaymentPeriod> periodsToRemove = repaymentPeriods.stream().filter(rp -> rp.getFromDate().isAfter(transactionDate))
.toList();
lastPeriod.setDueDate(chargeOffDate);
lastPeriod.getInterestPeriods().removeIf(interestPeriod -> !interestPeriod.getFromDate().isBefore(chargeOffDate));
lastPeriod.setDueDate(transactionDate);
lastPeriod.getInterestPeriods().removeIf(interestPeriod -> !interestPeriod.getFromDate().isBefore(transactionDate));
transactionCtx.getModel().repaymentPeriods().removeAll(periodsToRemove);
@@ -2678,7 +2718,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
BigDecimal::add);
final BigDecimal newInterest = emiCalculator
.getPeriodInterestTillDate(transactionCtx.getModel(), lastPeriod.getDueDate(), chargeOffDate, false).getAmount();
.getPeriodInterestTillDate(transactionCtx.getModel(), lastPeriod.getDueDate(), transactionDate, false).getAmount();
lastPeriod.setEmi(lastPeriod.getDuePrincipal().add(totalPrincipal).add(newInterest));
@@ -2686,6 +2726,11 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
transactionCtx.getModel().disableEMIRecalculation();
for (LoanTransaction processTransaction : transactionsToBeReprocessed) {
transactionCtx.getModel().repaymentPeriods().stream()
.filter(repaymentPeriod -> repaymentPeriod.getFromDate().isBefore(transactionDate))
.filter(repaymentPeriod -> previousInstallmentsMapping.stream()
.anyMatch(installment -> installment.getFromDate().equals(repaymentPeriod.getFromDate())))
.forEach(RepaymentPeriod::resetDerivedComponents);
emiCalculator.addBalanceCorrection(transactionCtx.getModel(), processTransaction.getTransactionDate(),
processTransaction.getPrincipalPortion(transactionCtx.getCurrency()));
processSingleTransaction(processTransaction, transactionCtx);
@@ -42,6 +42,8 @@ public class ProgressiveTransactionCtx extends TransactionCtx {
private Money sumOfInterestRefundAmount;
@Setter
private boolean isChargedOff = false;
@Setter
private boolean isContractTerminated = false;
private List<LoanRepaymentScheduleInstallment> skipRepaymentScheduleInstallments = new ArrayList<>();
public ProgressiveTransactionCtx(MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
@@ -103,6 +103,7 @@ public class InterestScheduleModelRepositoryWrapperImpl implements InterestSched
ProgressiveTransactionCtx ctx = new ProgressiveTransactionCtx(loan.getCurrency(), loan.getRepaymentScheduleInstallments(),
Set.of(), new MoneyHolder(loan.getTotalOverpaidAsMoney()), new ChangedTransactionDetail(), savedModel.get());
ctx.setChargedOff(loan.isChargedOff());
ctx.setContractTerminated(loan.isContractTermination());
advancedPaymentScheduleTransactionProcessor.recalculateInterestForDate(businessDate, ctx);
}
} else {
@@ -351,4 +351,9 @@ public final class RepaymentPeriod {
public Money getOutstandingPrincipal() {
return MathUtil.negativeToZero(getDuePrincipal().minus(getPaidPrincipal()), mc);
}
public void resetDerivedComponents() {
this.paidInterest = paidInterest.zero();
this.paidPrincipal = paidPrincipal.zero();
}
}
@@ -335,8 +335,8 @@ public class LoanAccrualsProcessingServiceImpl implements LoanAccrualsProcessing
private void addAccruals(@NotNull final Loan loan, @NotNull LocalDate tillDate, final boolean periodic, final boolean isFinal,
final boolean addJournal, final boolean chargeOnDueDate) {
if ((!isFinal && !loan.isOpen()) || loan.isNpa() || loan.isChargedOff()
|| !loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()) {
if ((!isFinal && !loan.isOpen()) || loan.isNpa() || loan.isChargedOff() || !loan.isPeriodicAccrualAccountingEnabledOnLoanProduct()
|| loan.isContractTermination()) {
return;
}
@@ -90,6 +90,7 @@ public class LoanTransactionProcessingServiceImpl implements LoanTransactionProc
new ChangedTransactionDetail(), savedModel.orElse(null), getTotalRefundInterestAmount(loan));
progressiveContext.getAlreadyProcessedTransactions().addAll(loanTransactionService.retrieveListOfTransactionsForReprocessing(loan));
progressiveContext.setChargedOff(loan.isChargedOff());
progressiveContext.setContractTerminated(loan.isContractTermination());
ChangedTransactionDetail result = advancedProcessor.processLatestTransaction(loanTransaction, progressiveContext);
if (savedModel.isPresent() && !TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
modelRepository.writeInterestScheduleModel(loan, savedModel.get());