FINERACT-2181: Fix for certain interest recalculation settings making prepay api and payment allocation inconsistent

This commit is contained in:
mark.vituska
2025-07-07 17:04:17 +02:00
committed by Adam Saghy
parent 01f850aecc
commit df995bc932
11 changed files with 332 additions and 146 deletions
@@ -1440,24 +1440,24 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
# --- Pay-off between 1st and 2nd installment, 1st installment is overdue ---
When Admin sets the business date to "15 February 2024"
And Customer makes "AUTOPAY" repayment on "15 February 2024" with 101.11 EUR transaction amount
And Customer makes "AUTOPAY" repayment on "15 February 2024" with 101.16 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 | 15 February 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 | 15 February 2024 | 67.09 | 16.48 | 0.53 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2024 | 15 February 2024 | 50.08 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 15 February 2024 | 33.07 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 15 February 2024 | 16.06 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 15 February 2024 | 0.0 | 16.06 | 0.0 | 0.0 | 0.0 | 16.06 | 16.06 | 16.06 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | 15 February 2024 | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2024 | 15 February 2024 | 50.13 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 15 February 2024 | 33.12 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 15 February 2024 | 16.11 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 15 February 2024 | 0.0 | 16.11 | 0.0 | 0.0 | 0.0 | 16.11 | 16.11 | 16.11 | 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.11 | 0.0 | 0.0 | 101.11 | 101.11 | 84.1 | 17.01 | 0.0 |
| 100.0 | 1.16 | 0.0 | 0.0 | 101.16 | 101.16 | 84.15 | 17.01 | 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 |
| 15 February 2024 | Repayment | 101.11 | 100.0 | 1.11 | 0.0 | 0.0 | 0.0 | false | false |
| 15 February 2024 | Accrual | 1.11 | 0.0 | 1.11 | 0.0 | 0.0 | 0.0 | false | false |
| 15 February 2024 | Repayment | 101.16 | 100.0 | 1.16 | 0.0 | 0.0 | 0.0 | false | false |
| 15 February 2024 | Accrual | 1.16 | 0.0 | 1.16 | 0.0 | 0.0 | 0.0 | false | false |
Then Loan's all installments have obligations met
@TestRailId:C3215
@@ -1989,14 +1989,14 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 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 | 31 | 01 April 2024 | | 50.52 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.8 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.99 | 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.99 | 0.1 | 0.0 | 0.0 | 17.09 | 0.0 | 0.0 | 0.0 | 17.09 |
| 2 | 29 | 01 March 2024 | | 67.09 | 16.48 | 0.53 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.47 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.75 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.94 | 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.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 |
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.14 | 0.0 | 0.0 | 102.14 | 0.0 | 0.0 | 0.0 | 102.14 |
| 100.0 | 2.09 | 0.0 | 0.0 | 102.09 | 0.0 | 0.0 | 0.0 | 102.09 |
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 |
@@ -2252,13 +2252,13 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| | | 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 | 31 | 01 April 2024 | | 50.71 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 34.0 | 16.71 | 0.3 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.19 | 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 | 17.19 | 0.1 | 0.0 | 0.0 | 17.29 | 0.0 | 0.0 | 0.0 | 17.29 |
| 3 | 31 | 01 April 2024 | | 50.58 | 16.56 | 0.45 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.87 | 16.71 | 0.3 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.06 | 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 | 17.06 | 0.1 | 0.0 | 0.0 | 17.16 | 0.0 | 0.0 | 0.0 | 17.16 |
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.34 | 0.0 | 0.0 | 102.34 | 0.0 | 0.0 | 0.0 | 102.34 |
| 100.0 | 2.21 | 0.0 | 0.0 | 102.21 | 0.0 | 0.0 | 0.0 | 102.21 |
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 |
@@ -2565,13 +2565,13 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| | | 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.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 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 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
| 3 | 31 | 01 April 2024 | | 50.46 | 16.59 | 0.42 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.74 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.93 | 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.93 | 0.1 | 0.0 | 0.0 | 17.03 | 0.0 | 0.0 | 0.0 | 17.03 |
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.15 | 0.0 | 0.0 | 102.15 | 17.01 | 0.0 | 0.0 | 85.14 |
| 100.0 | 2.08 | 0.0 | 0.0 | 102.08 | 17.01 | 0.0 | 0.0 | 85.07 |
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 |
@@ -2863,13 +2863,13 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| | | 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 | 10.0 | 0.0 | 10.0 | 7.01 |
| 3 | 31 | 01 April 2024 | | 50.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 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 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
| 3 | 31 | 01 April 2024 | | 50.44 | 16.61 | 0.4 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.72 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.91 | 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.91 | 0.1 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
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.15 | 0.0 | 0.0 | 102.15 | 27.01 | 0.0 | 10.0 | 75.14 |
| 100.0 | 2.06 | 0.0 | 0.0 | 102.06 | 27.01 | 0.0 | 10.0 | 75.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 |
@@ -2883,19 +2883,19 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| | | 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 | 10.0 | 0.0 | 10.0 | 7.01 |
| 3 | 31 | 01 April 2024 | | 50.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 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 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
| 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.41 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.73 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.92 | 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.92 | 0.1 | 0.0 | 0.0 | 17.02 | 0.0 | 0.0 | 0.0 | 17.02 |
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.15 | 0.0 | 0.0 | 102.15 | 27.01 | 0.0 | 10.0 | 75.14 |
| 100.0 | 2.07 | 0.0 | 0.0 | 102.07 | 27.01 | 0.0 | 10.0 | 75.06 |
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 |
| 05 March 2024 | Repayment | 10.0 | 10.0 | 0.0 | 0.0 | 0.0 | 73.57 | false | false |
| 09 March 2024 | Accrual | 1.2 | 0.0 | 1.2 | 0.0 | 0.0 | 0.0 | false | false |
| 09 March 2024 | Accrual | 1.19 | 0.0 | 1.19 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3241
Scenario: Verify interest recalculation in case of overdue installments: UC16 - 1st installment paid on due date, 2nd installment overdue, interest recalculation: same as repayment period, till rest frequency date
@@ -2949,12 +2949,12 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 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 | 10.0 | 0.0 | 10.0 | 7.01 |
| 3 | 31 | 01 April 2024 | | 50.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 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 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
| 4 | 30 | 01 May 2024 | | 33.91 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.19 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 17.19 | 0.2 | 0.0 | 0.0 | 17.39 | 0.0 | 0.0 | 0.0 | 17.39 |
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.15 | 0.0 | 0.0 | 102.15 | 27.01 | 0.0 | 10.0 | 75.14 |
| 100.0 | 2.44 | 0.0 | 0.0 | 102.44 | 27.01 | 0.0 | 10.0 | 75.43 |
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 |
@@ -2969,12 +2969,12 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 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 | 10.0 | 0.0 | 10.0 | 7.01 |
| 3 | 31 | 01 April 2024 | | 50.53 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.81 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.0 | 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 | 17.0 | 0.1 | 0.0 | 0.0 | 17.1 | 0.0 | 0.0 | 0.0 | 17.1 |
| 4 | 30 | 01 May 2024 | | 33.95 | 16.58 | 0.43 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.27 | 16.68 | 0.33 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 6 | 30 | 01 July 2024 | | 0.0 | 17.27 | 0.24 | 0.0 | 0.0 | 17.51 | 0.0 | 0.0 | 0.0 | 17.51 |
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.15 | 0.0 | 0.0 | 102.15 | 27.01 | 0.0 | 10.0 | 75.14 |
| 100.0 | 2.56 | 0.0 | 0.0 | 102.56 | 27.01 | 0.0 | 10.0 | 75.55 |
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 |
@@ -3154,24 +3154,24 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
# --- Fully repaid between 1st and 2nd installment, 1st installment is overdue ---
When Admin sets the business date to "15 February 2024"
And Customer makes "AUTOPAY" repayment on "15 February 2024" with 101.11 EUR transaction amount
And Customer makes "AUTOPAY" repayment on "15 February 2024" with 101.16 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 | 15 February 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 | 15 February 2024 | 67.09 | 16.48 | 0.53 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2024 | 15 February 2024 | 50.08 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 15 February 2024 | 33.07 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 15 February 2024 | 16.06 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 15 February 2024 | 0.0 | 16.06 | 0.0 | 0.0 | 0.0 | 16.06 | 16.06 | 16.06 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | 15 February 2024 | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 3 | 31 | 01 April 2024 | 15 February 2024 | 50.13 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 15 February 2024 | 33.12 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 15 February 2024 | 16.11 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 15 February 2024 | 0.0 | 16.11 | 0.0 | 0.0 | 0.0 | 16.11 | 16.11 | 16.11 | 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.11 | 0.0 | 0.0 | 101.11 | 101.11 | 84.1 | 17.01 | 0.0 |
| 100.0 | 1.16 | 0.0 | 0.0 | 101.16 | 101.16 | 84.15 | 17.01 | 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 |
| 15 February 2024 | Repayment | 101.11 | 100.0 | 1.11 | 0.0 | 0.0 | 0.0 | false | false |
| 15 February 2024 | Accrual | 1.11 | 0.0 | 1.11 | 0.0 | 0.0 | 0.0 | false | false |
| 15 February 2024 | Repayment | 101.16 | 100.0 | 1.16 | 0.0 | 0.0 | 0.0 | false | false |
| 15 February 2024 | Accrual | 1.16 | 0.0 | 1.16 | 0.0 | 0.0 | 0.0 | false | false |
Then Loan's all installments have obligations met
@TestRailId:C3248
@@ -7890,10 +7890,10 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 3 | 31 | 01 April 2025 | | 4661.9 | 1112.7 | 576.13 | 0.0 | 0.0 | 1688.83 | 0.0 | 0.0 | 0.0 | 1688.83 |
| 4 | 30 | 01 May 2025 | | 3549.2 | 1112.7 | 576.13 | 0.0 | 0.0 | 1688.83 | 0.0 | 0.0 | 0.0 | 1688.83 |
| 5 | 31 | 01 June 2025 | | 2436.5 | 1112.7 | 576.13 | 0.0 | 0.0 | 1688.83 | 0.0 | 0.0 | 0.0 | 1688.83 |
| 6 | 30 | 01 July 2025 | | 0.0 | 2436.5 | 576.13 | 0.0 | 0.0 | 3012.63 | 0.0 | 0.0 | 0.0 | 3012.63 |
| 6 | 30 | 01 July 2025 | | 0.0 | 2436.5 | 896.66 | 0.0 | 0.0 | 3333.16 | 0.0 | 0.0 | 0.0 | 3333.16 |
And Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 8000.0 | 3456.78 | 0.0 | 0.0 | 11456.78 | 0.05 | 0.0 | 0.04 | 11456.73 |
| 8000.0 | 3777.31 | 0.0 | 0.0 | 11777.31 | 0.05 | 0.0 | 0.04 | 11777.26 |
@TestRailId:C3657
Scenario: Verify tranche interest bearing progressive loan that expects two tranches with repayment and undo last disbursement - UC1
@@ -8707,3 +8707,120 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 06 April 2025 | Accrual | 0.17 | 0.0 | 0.17 | 0.0 | 0.0 | 0.0 | false | false |
| 07 April 2025 | Merchant Issued Refund | 1.99 | 1.99 | 0.0 | 0.0 | 0.0 | 279.61 | false | false |
| 07 April 2025 | Accrual | 0.16 | 0.0 | 0.16 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3783
Scenario: Verify that remaining repayment periods are correctly calculated when early repayment is made on till rest frequency type loan
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_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_REST_FREQUENCY_DATE | 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 runs inline COB job for Loan
When Admin sets the business date to "7 January 2024"
And Customer makes "AUTOPAY" repayment on "7 January 2024" with 17.01 EUR transaction amount
When Admin runs inline COB job for Loan
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 | 07 January 2024 | 83.1 | 16.9 | 0.11 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 66.96 | 16.14 | 0.87 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.34 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 33.62 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 16.81 | 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.81 | 0.1 | 0.0 | 0.0 | 16.91 | 0.0 | 0.0 | 0.0 | 16.91 |
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.96 | 0.0 | 0.0 | 101.96 | 17.01 | 17.01 | 0.0 | 84.95 |
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 |
| 02 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false | false |
| 03 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false | false |
| 04 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false | false |
| 05 January 2024 | Accrual | 0.02 | 0.0 | 0.02 | 0.0 | 0.0 | 0.0 | false | false |
| 06 January 2024 | Accrual | 0.01 | 0.0 | 0.01 | 0.0 | 0.0 | 0.0 | false | false |
| 07 January 2024 | Repayment | 17.01 | 16.9 | 0.11 | 0.0 | 0.0 | 83.1 | false | false |
@TestRailId:C3798
Scenario: Verify prepayment on daily interest recalculation loan with preClosureInterestCalculationStrategy = till rest frequency date
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_EMI_360_30_INTEREST_RECALCULATION_DAILY_TILL_REST_FREQUENCY_DATE | 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 "02 April 2024"
And Customer makes "AUTOPAY" repayment on "12 March 2024" with 101.74 EUR transaction amount
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
Then Loan has 0 outstanding 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 | 12 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 | 12 March 2024 | 67.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 17.01 | 0.0 |
| 3 | 31 | 01 April 2024 | 12 March 2024 | 50.71 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 4 | 30 | 01 May 2024 | 12 March 2024 | 33.7 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 5 | 31 | 01 June 2024 | 12 March 2024 | 16.69 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 17.01 | 17.01 | 0.0 | 0.0 |
| 6 | 30 | 01 July 2024 | 12 March 2024 | 0.0 | 16.69 | 0.0 | 0.0 | 0.0 | 16.69 | 16.69 | 16.69 | 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.74 | 0.0 | 0.0 | 101.74 | 101.74 | 67.72 | 34.02 | 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 |
| 12 March 2024 | Repayment | 101.74 | 100.0 | 1.74 | 0.0 | 0.0 | 0.0 | false | false |
| 02 April 2024 | Accrual | 1.74 | 0.0 | 1.74 | 0.0 | 0.0 | 0.0 | false | false |
When Customer undo "1"th "Repayment" transaction made on "12 March 2024"
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.14 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 3 | 31 | 01 April 2024 | | 50.71 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 4 | 30 | 01 May 2024 | | 34.01 | 16.7 | 0.31 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 |
| 5 | 31 | 01 June 2024 | | 17.2 | 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 | 17.2 | 0.1 | 0.0 | 0.0 | 17.3 | 0.0 | 0.0 | 0.0 | 17.3 |
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.35 | 0.0 | 0.0 | 102.35 | 0.0 | 0.0 | 0.0 | 102.35 |
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 |
| 12 March 2024 | Repayment | 101.74 | 100.0 | 1.74 | 0.0 | 0.0 | 0.0 | true | false |
| 02 April 2024 | Accrual | 1.74 | 0.0 | 1.74 | 0.0 | 0.0 | 0.0 | false | false |
And Customer makes "AUTOPAY" repayment on "22 March 2024" with 101.74 EUR transaction amount
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
Then Loan has 0 outstanding amount
@@ -3901,18 +3901,18 @@ Feature: Charge-off
| 1 | 31 | 01 February 2024 | 01 February 2024 | 86.02 | 13.98 | 7.0 | 0.0 | 0.0 | 20.98 | 20.98 | 0.0 | 0.0 | 0.0 |
| 2 | 29 | 01 March 2024 | | 71.06 | 14.96 | 6.02 | 0.0 | 0.0 | 20.98 | 0.0 | 0.0 | 0.0 | 20.98 |
| 3 | 31 | 01 April 2024 | | 56.1 | 14.96 | 6.02 | 0.0 | 0.0 | 20.98 | 0.0 | 0.0 | 0.0 | 20.98 |
| 4 | 30 | 01 May 2024 | | 41.14 | 14.96 | 6.02 | 0.0 | 0.0 | 20.98 | 0.0 | 0.0 | 0.0 | 20.98 |
| 5 | 31 | 01 June 2024 | | 23.04 | 18.1 | 2.88 | 0.0 | 0.0 | 20.98 | 0.0 | 0.0 | 0.0 | 20.98 |
| 6 | 30 | 01 July 2024 | | 0.0 | 23.04 | 1.61 | 0.0 | 0.0 | 24.65 | 0.0 | 0.0 | 0.0 | 24.65 |
| 4 | 30 | 01 May 2024 | | 39.12 | 16.98 | 4.0 | 0.0 | 0.0 | 20.98 | 0.0 | 0.0 | 0.0 | 20.98 |
| 5 | 31 | 01 June 2024 | | 20.88 | 18.24 | 2.74 | 0.0 | 0.0 | 20.98 | 0.0 | 0.0 | 0.0 | 20.98 |
| 6 | 30 | 01 July 2024 | | 0.0 | 20.88 | 1.46 | 0.0 | 0.0 | 22.34 | 0.0 | 0.0 | 0.0 | 22.34 |
Then Loan Repayment schedule has the following data in Total row:
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
| 100.0 | 29.55 | 0.0 | 0.0 | 129.55 | 20.98 | 0.0 | 0.0 | 108.57 |
| 100.0 | 27.24 | 0.0 | 0.0 | 127.24 | 20.98 | 0.0 | 0.0 | 106.26 |
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 | 20.98 | 13.98 | 7.0 | 0.0 | 0.0 | 86.02 | false | false |
| 02 April 2024 | Accrual | 19.24 | 0.0 | 19.24 | 0.0 | 0.0 | 0.0 | false | false |
| 02 April 2024 | Charge-off | 108.57 | 86.02 | 22.55 | 0.0 | 0.0 | 0.0 | false | false |
| 02 April 2024 | Charge-off | 106.26 | 86.02 | 20.24 | 0.0 | 0.0 | 0.0 | false | false |
@TestRailId:C3363
Scenario: Charge-off on due date when loan behavior is zero-interest with interestRecalculation disabled - UC1
@@ -6006,17 +6006,17 @@ Feature: Charge-off
| | | 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 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.18 | 0.0 | 0.0 | 67.23 | 35.98 | 35.98 | 0.0 | 31.25 |
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 |
| 100.0 | 1.25 | 0.0 | 0.0 | 101.25 | 70.0 | 35.98 | 17.01 | 31.25 |
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 |
| 31 March 2024 | Accrual Adjustment | 0.47 | 0.0 | 0.47 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Charge-off | 31.25 | 31.07 | 0.18 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3499 @AdvancedPaymentAllocation
@@ -9585,4 +9585,4 @@ Feature: Charge-off
And Loan Details response does not contain chargedOff flag and chargedOffOnDate field after repayment and reverted charge off
And Loan has 0.0 outstanding amount
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@@ -1036,17 +1036,17 @@ Feature: Contract Termination
| | | 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 |
| 3 | 30 | 31 March 2024 | | 0.0 | 67.05 | 0.18 | 0.0 | 0.0 | 67.23 | 35.98 | 35.98 | 0.0 | 31.25 |
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 |
| 100.0 | 1.25 | 0.0 | 0.0 | 101.25 | 70.0 | 35.98 | 17.01 | 31.25 |
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 |
| 31 March 2024 | Accrual Adjustment | 0.47 | 0.0 | 0.47 | 0.0 | 0.0 | 0.0 | false | false |
| 31 March 2024 | Contract Termination | 31.25 | 31.07 | 0.18 | 0.0 | 0.0 | 0.0 | false | true |
And Global configuration "is-principal-compounding-disabled-for-overdue-loans" is disabled
@TestRailId:C3738
@@ -639,21 +639,21 @@ Feature: Loan interest pause on repayment schedule
And Customer makes "PAYOUT_REFUND" transaction with "AUTOPAY" payment type on "22 April 2025" with 400 EUR transaction amount and self-generated Idempotency key
When Admin sets the business date to "23 April 2025"
And Admin runs inline COB job for Loan
And Admin makes Credit Balance Refund transaction on "23 April 2025" with 160.75 EUR transaction amount
And Admin makes Credit Balance Refund transaction on "23 April 2025" with 165.25 EUR transaction amount
When Admin sets the business date to "01 May 2025"
And Admin runs inline COB job for Loan
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 April 2025 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
| 1 | 30 | 01 May 2025 | 21 April 2025 | 834.21 | 165.79 | 14.25 | 0.0 | 25.0 | 205.04 | 205.04 | 205.04 | 0.0 | 0.0 |
| 2 | 31 | 01 June 2025 | 21 April 2025 | 654.17 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 3 | 30 | 01 July 2025 | 21 April 2025 | 474.13 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 4 | 31 | 01 August 2025 | 21 April 2025 | 294.09 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 5 | 31 | 01 September 2025 | 22 April 2025 | 114.05 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 6 | 30 | 01 October 2025 | 22 April 2025 | 0.0 | 114.05 | 0.0 | 0.0 | 0.0 | 114.05 | 114.05 | 114.05 | 0.0 | 0.0 |
| 1 | 30 | 01 May 2025 | 21 April 2025 | 829.71 | 170.29 | 9.75 | 0.0 | 25.0 | 205.04 | 205.04 | 205.04 | 0.0 | 0.0 |
| 2 | 31 | 01 June 2025 | 21 April 2025 | 649.67 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 3 | 30 | 01 July 2025 | 21 April 2025 | 469.63 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 4 | 31 | 01 August 2025 | 21 April 2025 | 289.59 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 5 | 31 | 01 September 2025 | 22 April 2025 | 109.55 | 180.04 | 0.0 | 0.0 | 0.0 | 180.04 | 180.04 | 180.04 | 0.0 | 0.0 |
| 6 | 30 | 01 October 2025 | 22 April 2025 | 0.0 | 109.55 | 0.0 | 0.0 | 0.0 | 109.55 | 109.55 | 109.55 | 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 |
| 1000.0 | 14.25 | 0.0 | 25.0 | 1039.25 | 1039.25 | 1039.25 | 0.0 | 0.0 |
| 1000.0 | 9.75 | 0.0 | 25.0 | 1034.75 | 1034.75 | 1034.75 | 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 April 2025 | Disbursement | 1000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
@@ -671,10 +671,9 @@ Feature: Loan interest pause on repayment schedule
| 13 April 2025 | Accrual | 0.75 | 0.0 | 0.75 | 0.0 | 0.0 | 0.0 | false | false |
| 14 April 2025 | Accrual | 0.75 | 0.0 | 0.75 | 0.0 | 0.0 | 0.0 | false | false |
| 20 April 2025 | Accrual | 25.0 | 0.0 | 0.0 | 0.0 | 25.0 | 0.0 | false | false |
| 21 April 2025 | Repayment | 800.0 | 760.75 | 14.25 | 0.0 | 25.0 | 239.25 | false | false |
| 22 April 2025 | Payout Refund | 400.0 | 239.25 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
| 22 April 2025 | Accrual | 4.5 | 0.0 | 4.5 | 0.0 | 0.0 | 0.0 | false | false |
| 23 April 2025 | Credit Balance Refund | 160.75 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
| 21 April 2025 | Repayment | 800.0 | 765.25 | 9.75 | 0.0 | 25.0 | 234.75 | false | false |
| 22 April 2025 | Payout Refund | 400.0 | 234.75 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
| 23 April 2025 | Credit Balance Refund | 165.25 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
@TestRailId:C3627
@@ -5405,4 +5405,4 @@ Feature: LoanRepayment
| 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 | 40.0 | 39.42 | 0.58 | 0.0 | 0.0 | 60.58 | false | false |
When Admin set "LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
When Admin set "LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
@@ -21,6 +21,7 @@ package org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.im
import static java.math.BigDecimal.ZERO;
import static java.util.stream.Collectors.mapping;
import static java.util.stream.Collectors.toList;
import static org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper.isInPeriod;
import static org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction.accrualAdjustment;
import static org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction.accrueTransaction;
import static org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionRelationTypeEnum.CHARGEBACK;
@@ -67,6 +68,7 @@ import org.apache.fineract.organisation.monetary.domain.MonetaryCurrency;
import org.apache.fineract.organisation.monetary.domain.Money;
import org.apache.fineract.organisation.monetary.domain.MoneyHelper;
import org.apache.fineract.portfolio.loanaccount.data.LoanTermVariationsData;
import org.apache.fineract.portfolio.loanaccount.data.OutstandingAmountsDTO;
import org.apache.fineract.portfolio.loanaccount.data.TransactionChangeData;
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
@@ -74,6 +76,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargeOffBehaviour;
import org.apache.fineract.portfolio.loanaccount.domain.LoanChargePaidBy;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCreditAllocationRule;
import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalculationDetails;
import org.apache.fineract.portfolio.loanaccount.domain.LoanPaymentAllocationRule;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleProcessingWrapper;
@@ -96,6 +99,7 @@ import org.apache.fineract.portfolio.loanaccount.service.InterestRefundService;
import org.apache.fineract.portfolio.loanaccount.service.LoanBalanceService;
import org.apache.fineract.portfolio.loanaccount.service.schedule.LoanScheduleComponent;
import org.apache.fineract.portfolio.loanproduct.calc.EMICalculator;
import org.apache.fineract.portfolio.loanproduct.calc.data.OutstandingDetails;
import org.apache.fineract.portfolio.loanproduct.calc.data.PeriodDueDetails;
import org.apache.fineract.portfolio.loanproduct.calc.data.ProgressiveLoanInterestScheduleModel;
import org.apache.fineract.portfolio.loanproduct.calc.data.RepaymentPeriod;
@@ -103,7 +107,6 @@ import org.apache.fineract.portfolio.loanproduct.domain.AllocationType;
import org.apache.fineract.portfolio.loanproduct.domain.CreditAllocationTransactionType;
import org.apache.fineract.portfolio.loanproduct.domain.DueType;
import org.apache.fineract.portfolio.loanproduct.domain.FutureInstallmentAllocationRule;
import org.apache.fineract.portfolio.loanproduct.domain.LoanPreCloseInterestCalculationStrategy;
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductRelatedDetail;
import org.apache.fineract.portfolio.loanproduct.domain.PaymentAllocationType;
import org.apache.fineract.util.LoopContext;
@@ -326,6 +329,9 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
public ChangedTransactionDetail processLatestTransaction(LoanTransaction loanTransaction, TransactionCtx ctx) {
// If we are behind, we might need to first recalculate interest
if (ctx instanceof ProgressiveTransactionCtx progressiveTransactionCtx) {
if (loanTransaction.isRepaymentLikeType() && loanTransaction.isNotReversed()) {
progressiveTransactionCtx.setPrepayAttempt(calculateIsPrepayAttempt(loanTransaction, progressiveTransactionCtx));
}
recalculateInterestForDate(loanTransaction.getTransactionDate(), progressiveTransactionCtx);
}
switch (loanTransaction.getTypeOf()) {
@@ -1523,13 +1529,16 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
if (currentDate.isAfter(fromDate) && !currentDate.isAfter(toDate)) {
LocalDate lastOverdueBalanceChange;
if (currentInstallment.getLoan().getLoanInterestRecalculationDetails().getRestFrequencyType().isSameAsRepayment()) {
if (shouldRecalculateTillInstallmentDueDate(currentInstallment.getLoan().getLoanInterestRecalculationDetails(),
ctx.isPrepayAttempt())) {
lastOverdueBalanceChange = toDate;
} else {
lastOverdueBalanceChange = currentDate;
}
emiCalculator.addBalanceCorrection(ctx.getModel(), lastOverdueBalanceChange, aggregatedOverDuePrincipal.negated());
ctx.getModel().lastOverdueBalanceChange(lastOverdueBalanceChange);
if (DateUtils.isBefore(ctx.getModel().lastOverdueBalanceChange(), toDate)) {
emiCalculator.addBalanceCorrection(ctx.getModel(), lastOverdueBalanceChange, aggregatedOverDuePrincipal.negated());
ctx.getModel().lastOverdueBalanceChange(lastOverdueBalanceChange);
}
}
}
@@ -2419,7 +2428,7 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
if (DueType.IN_ADVANCE.equals(paymentAllocationType.getDueType())) {
payDate = calculateNewPayDateInCaseOfInAdvancePayment(loanTransaction, installment);
payDate = calculateNewPayDateInCaseOfInAdvancePayment(loanTransaction, installment, ctx.isPrepayAttempt());
updateRepaymentPeriodBalances(paymentAllocationType, installment, ctx, payDate);
}
@@ -2465,19 +2474,54 @@ public class AdvancedPaymentScheduleTransactionProcessor extends AbstractLoanRep
}
}
private LocalDate calculateNewPayDateInCaseOfInAdvancePayment(LoanTransaction loanTransaction,
LoanRepaymentScheduleInstallment inAdvanceInstallment) {
LoanPreCloseInterestCalculationStrategy strategy = loanTransaction.getLoan().getLoanInterestRecalculationDetails()
.getPreCloseInterestCalculationStrategy();
private boolean calculateIsPrepayAttempt(LoanTransaction loanTransaction, ProgressiveTransactionCtx progressiveTransactionCtx) {
Loan loan = loanTransaction.getLoan();
LoanRepaymentScheduleInstallment installment = loan.getRelatedRepaymentScheduleInstallment(loanTransaction.getTransactionDate());
if (installment == null) {
return false;
}
if (loan.getLoanInterestRecalculationDetails() == null) {
return false;
}
OutstandingDetails outstandingAmounts = emiCalculator.getOutstandingAmountsTillDate(progressiveTransactionCtx.getModel(),
installment.getDueDate());
OutstandingAmountsDTO result = new OutstandingAmountsDTO(progressiveTransactionCtx.getCurrency()) //
.principal(outstandingAmounts.getOutstandingPrincipal()) //
.interest(outstandingAmounts.getOutstandingInterest());//
return switch (strategy) {
case TILL_PRE_CLOSURE_DATE -> loanTransaction.getTransactionDate();
// TODO use isInPeriod
case TILL_REST_FREQUENCY_DATE -> loanTransaction.getTransactionDate().isAfter(inAdvanceInstallment.getFromDate()) //
&& !loanTransaction.getTransactionDate().isAfter(inAdvanceInstallment.getDueDate()) //
? inAdvanceInstallment.getDueDate() //
: loanTransaction.getTransactionDate(); //
case NONE -> throw new IllegalStateException("Unexpected PreClosureInterestCalculationStrategy: NONE");
return loanTransaction.getAmount(progressiveTransactionCtx.getCurrency()).isGreaterThanOrEqualTo(result.getTotalOutstanding());
}
private LocalDate calculateNewPayDateInCaseOfInAdvancePayment(LoanTransaction loanTransaction,
LoanRepaymentScheduleInstallment inAdvanceInstallment, boolean prepayAttempt) {
if (shouldRecalculateTillInstallmentDueDate(loanTransaction.getLoan().getLoanInterestRecalculationDetails(), prepayAttempt)) {
return isInPeriod(loanTransaction.getTransactionDate(), inAdvanceInstallment, false) ? inAdvanceInstallment.getDueDate()
: loanTransaction.getTransactionDate();
} else {
return loanTransaction.getTransactionDate();
}
}
private boolean shouldRecalculateTillInstallmentDueDate(LoanInterestRecalculationDetails recalculationDetails,
boolean isPrepayAttempt) {
// Rest frequency type and pre close interest calculation strategy can be controversial
// if restFrequencyType == DAILY and preCloseInterestCalculationStrategy == TILL_PRE_CLOSURE_DATE
// no problem. Calculate till transaction date
// if restFrequencyType == SAME_AS_REPAYMENT_PERIOD and preCloseInterestCalculationStrategy ==
// TILL_REST_FREQUENCY_DATE
// again, no problem. Calculate till due date of current installment
// if restFrequencyType == DAILY and preCloseInterestCalculationStrategy == TILL_REST_FREQUENCY_DATE
// or restFrequencyType == SAME_AS_REPAYMENT_PERIOD and preCloseInterestCalculationStrategy ==
// TILL_PRE_CLOSURE_DATE
// we cannot harmonize the two configs. Behaviour should mimic prepay api.
return switch (recalculationDetails.getRestFrequencyType()) {
case DAILY ->
isPrepayAttempt && recalculationDetails.getPreCloseInterestCalculationStrategy().calculateTillRestFrequencyEnabled();
case SAME_AS_REPAYMENT_PERIOD ->
recalculationDetails.getPreCloseInterestCalculationStrategy().calculateTillRestFrequencyEnabled();
case WEEKLY -> throw new IllegalStateException("Unexpected RecalculationFrequencyType: WEEKLY");
case MONTHLY -> throw new IllegalStateException("Unexpected RecalculationFrequencyType: MONTHLY");
case INVALID -> throw new IllegalStateException("Unexpected RecalculationFrequencyType: INVALID");
};
}
@@ -44,6 +44,8 @@ public class ProgressiveTransactionCtx extends TransactionCtx {
private boolean isChargedOff = false;
@Setter
private boolean isContractTerminated = false;
@Setter
private boolean isPrepayAttempt = false;
private List<LoanRepaymentScheduleInstallment> skipRepaymentScheduleInstallments = new ArrayList<>();
public ProgressiveTransactionCtx(MonetaryCurrency currency, List<LoanRepaymentScheduleInstallment> installments,
@@ -203,7 +203,7 @@ public class ProgressiveLoanScheduleGenerator implements LoanScheduleGenerator {
Optional<ProgressiveLoanInterestScheduleModel> savedModel = interestScheduleModelRepositoryWrapper.getSavedModel(loan,
transactionDate);
ProgressiveLoanInterestScheduleModel model = savedModel
.orElseGet(() -> processor.calculateInterestScheduleModel(loan.getId(), onDate));
.orElseGet(() -> processor.calculateInterestScheduleModel(loan.getId(), transactionDate));
OutstandingDetails outstandingAmounts = emiCalculator.getOutstandingAmountsTillDate(model, transactionDate);
// TODO: We should add all the past due outstanding amounts as well
OutstandingAmountsDTO result = new OutstandingAmountsDTO(currency) //
@@ -35,6 +35,7 @@ import org.apache.fineract.portfolio.loanaccount.data.ScheduleGeneratorDTO;
import org.apache.fineract.portfolio.loanaccount.domain.ChangedTransactionDetail;
import org.apache.fineract.portfolio.loanaccount.domain.Loan;
import org.apache.fineract.portfolio.loanaccount.domain.LoanCharge;
import org.apache.fineract.portfolio.loanaccount.domain.LoanInterestRecalculationDetails;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleInstallment;
import org.apache.fineract.portfolio.loanaccount.domain.LoanRepaymentScheduleTransactionProcessorFactory;
import org.apache.fineract.portfolio.loanaccount.domain.LoanTransaction;
@@ -73,6 +74,13 @@ public class LoanTransactionProcessingServiceImpl implements LoanTransactionProc
if (!DateUtils.isEqualBusinessDate(loanTransaction.getTransactionDate())) {
return false;
}
LoanInterestRecalculationDetails interestRecalculationDetails = loan.getLoanInterestRecalculationDetails();
if (interestRecalculationDetails != null && ((interestRecalculationDetails.getRestFrequencyType().isSameAsRepayment()
&& interestRecalculationDetails.getPreCloseInterestCalculationStrategy().calculateTillPreClosureDateEnabled())
|| (interestRecalculationDetails.getRestFrequencyType().isDaily()
&& interestRecalculationDetails.getPreCloseInterestCalculationStrategy().calculateTillRestFrequencyEnabled()))) {
return false;
}
if (loan.isProgressiveSchedule()) {
return modelRepository.hasValidModelForDate(loan.getId(), loanTransaction.getTransactionDate());
}
@@ -1246,6 +1246,22 @@ public final class LoanProductDataValidator {
baseDataValidator.reset().parameter(LoanProductConstants.preClosureInterestCalculationStrategyParamName)
.value(preCloseInterestCalculationStrategy).ignoreIfNull().inMinMaxRange(
LoanPreCloseInterestCalculationStrategy.getMinValue(), LoanPreCloseInterestCalculationStrategy.getMaxValue());
String loanScheduleType = LoanScheduleType.CUMULATIVE.toString();
if (fromApiJsonHelper.parameterExists(LoanProductConstants.LOAN_SCHEDULE_TYPE, element)) {
loanScheduleType = fromApiJsonHelper.extractStringNamed(LoanProductConstants.LOAN_SCHEDULE_TYPE, element);
}
if (LoanScheduleType.PROGRESSIVE.equals(LoanScheduleType.valueOf(loanScheduleType))
&& preCloseInterestCalculationStrategy != null) {
LoanPreCloseInterestCalculationStrategy preCloseStrategy = LoanPreCloseInterestCalculationStrategy
.fromInt(preCloseInterestCalculationStrategy);
if (preCloseStrategy.calculateTillRestFrequencyEnabled() && !frequencyType.isSameAsRepayment() && !frequencyType.isDaily()) {
baseDataValidator.reset().failWithCodeNoParameterAddedToErrorCode(
"when.preclose.strategy.is.till.rest.frequency.then.frequency.type.is.daily.or.same.as.repayment",
"When the pre-close interest calculation strategy is set to `Till Rest Frequency Date` "
+ "the frequency of outstanding principal calculation must be `Daily` or `Same as repayment period`.");
}
}
}
public void validateForUpdate(final JsonCommand command, final LoanProduct loanProduct) {
@@ -135,7 +135,7 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
installment(1112.7, 576.13, 1688.83, false, "01 April 2023"), //
installment(1112.7, 576.13, 1688.83, false, "01 May 2023"), //
installment(1112.7, 576.13, 1688.83, false, "01 June 2023"), //
installment(2436.5, 576.13, 3012.63, false, "01 July 2023") //
installment(2436.5, 389.15, 2825.65, false, "01 July 2023") //
);
});
}
@@ -496,9 +496,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1991.05, 0.0, 0.0, 50.79);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.23, 0.0, 0.0, 33.61);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2025.55, 0.0, 0.0, 16.88);
});
runAt("20 February 2023", () -> {
Long loanId = loanIdRef.get();
@@ -509,9 +509,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1980.46, 0.0, 0.0, 61.38);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.14, 0.0, 0.0, 33.7);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2036.23, 0.0, 0.0, 16.97);
});
runAt("2 March 2023", () -> {
Long loanId = loanIdRef.get();
@@ -523,8 +523,8 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2074.49, 0.0, 0.0, 17.29);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2007.03, 0.0, 0.0, 34.81);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2042.63, 0.0, 0.0, 17.02);
});
payoffOnDateAndVerifyStatus("1 February 2023", loanIdRef.get());
}
@@ -561,9 +561,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1991.05, 0.0, 0.0, 50.79);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.23, 0.0, 0.0, 33.61);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2025.55, 0.0, 0.0, 16.88);
});
runAt("15 February 2023", () -> {
Long loanId = loanIdRef.get();
@@ -572,9 +572,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1983.4, 0.0, 0.0, 58.44);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.16, 0.0, 0.0, 33.68);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2033.27, 0.0, 0.0, 16.94);
loanTransactionHelper.makeLoanRepayment("15 February 2023", 500.0F, loanId.intValue());
@@ -583,9 +583,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 2, 1), 1975.17, 500, 1475.17, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 66.67, 0,
66.67, 0, 500);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1983.4, 0.0, 0.0, 58.44);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.16, 0.0, 0.0, 33.68);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2033.27, 0.0, 0.0, 16.94);
loanTransactionHelper.makeLoanRepayment("15 February 2023", 500f, loanId.intValue());
@@ -594,9 +594,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 2, 1), 1975.17, 1000, 975.17, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 66.67, 0,
66.67, 0, 1000);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1983.4, 0.0, 0.0, 58.44);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.16, 0.0, 0.0, 33.68);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2033.27, 0.0, 0.0, 16.94);
});
runAt("20 February 2023", () -> {
@@ -608,9 +608,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyPaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67, 2041.84);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1981.95, 0.0, 0.0, 59.89);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.15, 0.0, 0.0, 33.69);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2034.73, 0.0, 0.0, 16.96);
});
runAt("1 March 2023", () -> {
@@ -624,9 +624,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyPaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67, 2041.84);
validateFullyPaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyPaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1981.95, 0.0, 0.0, 59.89);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.15, 0.0, 0.0, 33.69);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2034.73, 0.0, 0.0, 16.96);
});
runAt("2 April 2023", () -> {
Long loanId = loanIdRef.get();
@@ -638,9 +638,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 2, 1), 1975.17, 1975.17, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 66.67,
66.67, 0, 0, 2041.84);
validateFullyPaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 33.75);
validateFullyPaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1981.95, 0.0, 0.0, 59.89);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.15, 0.0, 0.0, 33.69);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2034.73, 0.0, 0.0, 17.51);
});
runAt("1 May 2023", () -> {
Long loanId = loanIdRef.get();
@@ -655,10 +655,10 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 2, 1), 1975.17, 1975.17, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 66.67,
66.67, 0, 0, 2041.84);
validateFullyPaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 4, 1), 2008.09, 2008.09, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 33.75,
33.75, 0, 0, 2041.84);
validateFullyPaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 33.75);
validateFullyPaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1981.95, 0.0, 0.0, 59.89);
validateRepaymentPeriod(loanDetails, 3, LocalDate.of(2023, 4, 1), 2008.15, 2008.15, 0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 33.69,
33.69, 0, 0, 2041.84);
validateFullyPaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2034.73, 0.0, 0.0, 24.77);
});
}
@@ -934,8 +934,8 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateFullyPaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1991.63, 0.0, 0.0, 50.21);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 1991.63, 0.0, 0.0, 50.21);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2007.69, 0.0, 0.0, 34.15);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2025.51, 0.0, 0.0, 16.88);
});
runAt("20 March 2023", () -> {
Long loanId = loanIdRef.get();
@@ -947,8 +947,8 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateFullyPaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1991.63, 0.0, 0.0, 50.21);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 1991.63, 0.0, 0.0, 50.21);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 1998.06, 0.0, 0.0, 43.78);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2035.14, 0.0, 0.0, 16.96);
});
payoffOnDateAndVerifyStatus("1 March 2023", loanIdRef.get());
}
@@ -1043,9 +1043,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1991.05, 0.0, 0.0, 50.79);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.23, 0.0, 0.0, 33.61);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2025.55, 0.0, 0.0, 16.88);
});
runAt("20 February 2023", () -> {
Long loanId = loanIdRef.get();
@@ -1057,9 +1057,9 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
logLoanDetails(loanDetails);
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.09, 0.0, 0.0, 33.75);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2041.57, 0.0, 0.0, 17.01);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1980.46, 0.0, 0.0, 61.38);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2008.14, 0.0, 0.0, 33.7);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2036.23, 0.0, 0.0, 16.97);
});
runAt("2 March 2023", () -> {
Long loanId = loanIdRef.get();
@@ -1072,8 +1072,8 @@ public class LoanInterestRecalculationCOBTest extends BaseLoanIntegrationTest {
validateFullyUnpaidRepaymentPeriod(loanDetails, 1, "01 February 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 2, "01 March 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 1975.17, 0.0, 0.0, 66.67);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2074.49, 0.0, 0.0, 17.29);
validateFullyUnpaidRepaymentPeriod(loanDetails, 3, "01 April 2023", 2007.03, 0.0, 0.0, 34.81);
validateFullyUnpaidRepaymentPeriod(loanDetails, 4, "01 May 2023", 2042.63, 0.0, 0.0, 17.02);
});
payoffOnDateAndVerifyStatus("1 February 2023", loanIdRef.get());
}