FINERACT-1981: Fix interest calculation when applies multi disbursement
This commit is contained in:
committed by
Adam Saghy
parent
6e6ac8ffd6
commit
8ab9c9ea9a
@@ -4082,10 +4082,10 @@ 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 |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 22 January 2024 | 750.54 | 249.46 | 5.68 | 0.0 | 0.0 | 255.14 | 255.14 | 255.14 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 22 January 2024 | 750.53 | 249.47 | 5.68 | 0.0 | 0.0 | 255.15 | 255.15 | 255.15 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | 22 January 2024 | 495.4 | 255.14 | 0.0 | 0.0 | 0.0 | 255.14 | 255.14 | 255.14 | 0.0 | 0.0 |
|
| 2 | 29 | 01 March 2024 | 22 January 2024 | 495.38 | 255.15 | 0.0 | 0.0 | 0.0 | 255.15 | 255.15 | 255.15 | 0.0 | 0.0 |
|
||||||
| 3 | 31 | 01 April 2024 | 22 January 2024 | 240.26 | 255.14 | 0.0 | 0.0 | 0.0 | 255.14 | 255.14 | 255.14 | 0.0 | 0.0 |
|
| 3 | 31 | 01 April 2024 | 22 January 2024 | 240.23 | 255.15 | 0.0 | 0.0 | 0.0 | 255.15 | 255.15 | 255.15 | 0.0 | 0.0 |
|
||||||
| 4 | 30 | 01 May 2024 | 22 January 2024 | 0.0 | 240.26 | 0.0 | 0.0 | 0.0 | 240.26 | 240.26 | 240.26 | 0.0 | 0.0 |
|
| 4 | 30 | 01 May 2024 | 22 January 2024 | 0.0 | 240.23 | 0.0 | 0.0 | 0.0 | 240.23 | 240.23 | 240.23 | 0.0 | 0.0 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 5.68 | 0.0 | 0.0 | 1005.68 | 1005.68 | 1005.68 | 0.0 | 0.0 |
|
| 1000.0 | 5.68 | 0.0 | 0.0 | 1005.68 | 1005.68 | 1005.68 | 0.0 | 0.0 |
|
||||||
@@ -4354,10 +4354,10 @@ 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 |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | | 753.25 | 246.75 | 8.39 | 0.0 | 0.0 | 255.14 | 0.0 | 0.0 | 0.0 | 255.14 |
|
| 1 | 31 | 01 February 2024 | | 753.24 | 246.76 | 8.39 | 0.0 | 0.0 | 255.15 | 0.0 | 0.0 | 0.0 | 255.15 |
|
||||||
| 2 | 29 | 01 March 2024 | | 504.02 | 249.23 | 5.91 | 0.0 | 0.0 | 255.14 | 0.0 | 0.0 | 0.0 | 255.14 |
|
| 2 | 29 | 01 March 2024 | | 504.0 | 249.24 | 5.91 | 0.0 | 0.0 | 255.15 | 0.0 | 0.0 | 0.0 | 255.15 |
|
||||||
| 3 | 31 | 01 April 2024 | | 253.11 | 250.91 | 4.23 | 0.0 | 0.0 | 255.14 | 0.0 | 0.0 | 0.0 | 255.14 |
|
| 3 | 31 | 01 April 2024 | | 253.08 | 250.92 | 4.23 | 0.0 | 0.0 | 255.15 | 0.0 | 0.0 | 0.0 | 255.15 |
|
||||||
| 4 | 30 | 01 May 2024 | | 0.0 | 253.11 | 2.05 | 0.0 | 0.0 | 255.16 | 0.0 | 0.0 | 0.0 | 255.16 |
|
| 4 | 30 | 01 May 2024 | | 0.0 | 253.08 | 2.05 | 0.0 | 0.0 | 255.13 | 0.0 | 0.0 | 0.0 | 255.13 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 20.58 | 0.0 | 0.0 | 1020.58 | 0.0 | 0.0 | 0.0 | 1020.58 |
|
| 1000.0 | 20.58 | 0.0 | 0.0 | 1020.58 | 0.0 | 0.0 | 0.0 | 1020.58 |
|
||||||
@@ -4371,10 +4371,10 @@ 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 |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 22 January 2024 | 750.54 | 249.46 | 5.68 | 0.0 | 0.0 | 255.14 | 255.14 | 255.14 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 22 January 2024 | 750.53 | 249.47 | 5.68 | 0.0 | 0.0 | 255.15 | 255.15 | 255.15 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | | 500.7 | 249.84 | 5.3 | 0.0 | 0.0 | 255.14 | 247.7 | 247.7 | 0.0 | 7.44 |
|
| 2 | 29 | 01 March 2024 | | 500.68 | 249.85 | 5.3 | 0.0 | 0.0 | 255.15 | 247.69 | 247.69 | 0.0 | 7.46 |
|
||||||
| 3 | 31 | 01 April 2024 | | 249.76 | 250.94 | 4.2 | 0.0 | 0.0 | 255.14 | 0.0 | 0.0 | 0.0 | 255.14 |
|
| 3 | 31 | 01 April 2024 | | 249.73 | 250.95 | 4.2 | 0.0 | 0.0 | 255.15 | 0.0 | 0.0 | 0.0 | 255.15 |
|
||||||
| 4 | 30 | 01 May 2024 | | 0.0 | 249.76 | 2.03 | 0.0 | 0.0 | 251.79 | 0.0 | 0.0 | 0.0 | 251.79 |
|
| 4 | 30 | 01 May 2024 | | 0.0 | 249.73 | 2.03 | 0.0 | 0.0 | 251.76 | 0.0 | 0.0 | 0.0 | 251.76 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 17.21 | 0.0 | 0.0 | 1017.21 | 502.84 | 502.84 | 0.0 | 514.37 |
|
| 1000.0 | 17.21 | 0.0 | 0.0 | 1017.21 | 502.84 | 502.84 | 0.0 | 514.37 |
|
||||||
@@ -4385,19 +4385,19 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| 22 January 2024 | Payout Refund | 500.0 | 494.32 | 5.68 | 0.0 | 0.0 | 505.68 | false | false |
|
| 22 January 2024 | Payout Refund | 500.0 | 494.32 | 5.68 | 0.0 | 0.0 | 505.68 | false | false |
|
||||||
| 22 January 2024 | Interest Refund | 2.84 | 2.84 | 0.0 | 0.0 | 0.0 | 502.84 | false | false |
|
| 22 January 2024 | Interest Refund | 2.84 | 2.84 | 0.0 | 0.0 | 0.0 | 502.84 | false | false |
|
||||||
When Admin sets the business date to "01 March 2024"
|
When Admin sets the business date to "01 March 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 7.44 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 7.46 EUR transaction amount
|
||||||
When Admin sets the business date to "01 April 2024"
|
When Admin sets the business date to "01 April 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 April 2024" with 255.14 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 April 2024" with 255.15 EUR transaction amount
|
||||||
When Admin sets the business date to "01 May 2024"
|
When Admin sets the business date to "01 May 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 May 2024" with 251.79 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 May 2024" with 251.76 EUR transaction amount
|
||||||
Then Loan Repayment schedule has 4 periods, with the following data for periods:
|
Then Loan Repayment schedule has 4 periods, with the following data for periods:
|
||||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 22 January 2024 | 750.54 | 249.46 | 5.68 | 0.0 | 0.0 | 255.14 | 255.14 | 255.14 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 22 January 2024 | 750.53 | 249.47 | 5.68 | 0.0 | 0.0 | 255.15 | 255.15 | 255.15 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | 01 March 2024 | 500.7 | 249.84 | 5.3 | 0.0 | 0.0 | 255.14 | 255.14 | 247.7 | 0.0 | 0.0 |
|
| 2 | 29 | 01 March 2024 | 01 March 2024 | 500.68 | 249.85 | 5.3 | 0.0 | 0.0 | 255.15 | 255.15 | 247.69 | 0.0 | 0.0 |
|
||||||
| 3 | 31 | 01 April 2024 | 01 April 2024 | 249.76 | 250.94 | 4.2 | 0.0 | 0.0 | 255.14 | 255.14 | 0.0 | 0.0 | 0.0 |
|
| 3 | 31 | 01 April 2024 | 01 April 2024 | 249.73 | 250.95 | 4.2 | 0.0 | 0.0 | 255.15 | 255.15 | 0.0 | 0.0 | 0.0 |
|
||||||
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 249.76 | 2.03 | 0.0 | 0.0 | 251.79 | 251.79 | 0.0 | 0.0 | 0.0 |
|
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 249.73 | 2.03 | 0.0 | 0.0 | 251.76 | 251.76 | 0.0 | 0.0 | 0.0 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 17.21 | 0.0 | 0.0 | 1017.21 | 1017.21 | 502.84 | 0.0 | 0.0 |
|
| 1000.0 | 17.21 | 0.0 | 0.0 | 1017.21 | 1017.21 | 502.84 | 0.0 | 0.0 |
|
||||||
@@ -4407,9 +4407,9 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| 01 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
| 01 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
||||||
| 22 January 2024 | Payout Refund | 500.0 | 494.32 | 5.68 | 0.0 | 0.0 | 505.68 | false | false |
|
| 22 January 2024 | Payout Refund | 500.0 | 494.32 | 5.68 | 0.0 | 0.0 | 505.68 | false | false |
|
||||||
| 22 January 2024 | Interest Refund | 2.84 | 2.84 | 0.0 | 0.0 | 0.0 | 502.84 | false | false |
|
| 22 January 2024 | Interest Refund | 2.84 | 2.84 | 0.0 | 0.0 | 0.0 | 502.84 | false | false |
|
||||||
| 01 March 2024 | Repayment | 7.44 | 2.14 | 5.3 | 0.0 | 0.0 | 500.7 | false | false |
|
| 01 March 2024 | Repayment | 7.46 | 2.16 | 5.3 | 0.0 | 0.0 | 500.68 | false | false |
|
||||||
| 01 April 2024 | Repayment | 255.14 | 250.94 | 4.2 | 0.0 | 0.0 | 249.76 | false | false |
|
| 01 April 2024 | Repayment | 255.15 | 250.95 | 4.2 | 0.0 | 0.0 | 249.73 | false | false |
|
||||||
| 01 May 2024 | Repayment | 251.79 | 249.76 | 2.03 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Repayment | 251.76 | 249.73 | 2.03 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 01 May 2024 | Accrual | 17.21 | 0.0 | 17.21 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Accrual | 17.21 | 0.0 | 17.21 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
||||||
|
|
||||||
@@ -4430,10 +4430,10 @@ 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 |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 22 January 2024 | 749.64 | 250.36 | 4.47 | 0.0 | 0.0 | 254.83 | 254.83 | 254.83 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 22 January 2024 | 749.63 | 250.37 | 4.47 | 0.0 | 0.0 | 254.84 | 254.84 | 254.84 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | | 500.11 | 249.53 | 5.3 | 0.0 | 0.0 | 254.83 | 247.61 | 247.61 | 0.0 | 7.22 |
|
| 2 | 29 | 01 March 2024 | | 500.09 | 249.54 | 5.3 | 0.0 | 0.0 | 254.84 | 247.6 | 247.6 | 0.0 | 7.24 |
|
||||||
| 3 | 31 | 01 April 2024 | | 249.47 | 250.64 | 4.19 | 0.0 | 0.0 | 254.83 | 0.0 | 0.0 | 0.0 | 254.83 |
|
| 3 | 31 | 01 April 2024 | | 249.44 | 250.65 | 4.19 | 0.0 | 0.0 | 254.84 | 0.0 | 0.0 | 0.0 | 254.84 |
|
||||||
| 4 | 30 | 01 May 2024 | | 0.0 | 249.47 | 2.02 | 0.0 | 0.0 | 251.49 | 0.0 | 0.0 | 0.0 | 251.49 |
|
| 4 | 30 | 01 May 2024 | | 0.0 | 249.44 | 2.02 | 0.0 | 0.0 | 251.46 | 0.0 | 0.0 | 0.0 | 251.46 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 15.98 | 0.0 | 0.0 | 1015.98 | 502.44 | 502.44 | 0.0 | 513.54 |
|
| 1000.0 | 15.98 | 0.0 | 0.0 | 1015.98 | 502.44 | 502.44 | 0.0 | 513.54 |
|
||||||
@@ -4444,19 +4444,19 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| 22 January 2024 | Merchant Issued Refund | 500.0 | 495.53 | 4.47 | 0.0 | 0.0 | 504.47 | false | false |
|
| 22 January 2024 | Merchant Issued Refund | 500.0 | 495.53 | 4.47 | 0.0 | 0.0 | 504.47 | false | false |
|
||||||
| 22 January 2024 | Interest Refund | 2.44 | 2.44 | 0.0 | 0.0 | 0.0 | 502.03 | false | false |
|
| 22 January 2024 | Interest Refund | 2.44 | 2.44 | 0.0 | 0.0 | 0.0 | 502.03 | false | false |
|
||||||
When Admin sets the business date to "01 March 2024"
|
When Admin sets the business date to "01 March 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 7.22 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 7.24 EUR transaction amount
|
||||||
When Admin sets the business date to "01 April 2024"
|
When Admin sets the business date to "01 April 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 April 2024" with 254.83 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 April 2024" with 254.84 EUR transaction amount
|
||||||
When Admin sets the business date to "01 May 2024"
|
When Admin sets the business date to "01 May 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 May 2024" with 251.49 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 May 2024" with 251.46 EUR transaction amount
|
||||||
Then Loan Repayment schedule has 4 periods, with the following data for periods:
|
Then Loan Repayment schedule has 4 periods, with the following data for periods:
|
||||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 22 January 2024 | 749.64 | 250.36 | 4.47 | 0.0 | 0.0 | 254.83 | 254.83 | 254.83 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 22 January 2024 | 749.63 | 250.37 | 4.47 | 0.0 | 0.0 | 254.84 | 254.84 | 254.84 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | 01 March 2024 | 500.11 | 249.53 | 5.3 | 0.0 | 0.0 | 254.83 | 254.83 | 247.61 | 0.0 | 0.0 |
|
| 2 | 29 | 01 March 2024 | 01 March 2024 | 500.09 | 249.54 | 5.3 | 0.0 | 0.0 | 254.84 | 254.84 | 247.6 | 0.0 | 0.0 |
|
||||||
| 3 | 31 | 01 April 2024 | 01 April 2024 | 249.47 | 250.64 | 4.19 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 3 | 31 | 01 April 2024 | 01 April 2024 | 249.44 | 250.65 | 4.19 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 249.47 | 2.02 | 0.0 | 0.0 | 251.49 | 251.49 | 0.0 | 0.0 | 0.0 |
|
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 249.44 | 2.02 | 0.0 | 0.0 | 251.46 | 251.46 | 0.0 | 0.0 | 0.0 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 15.98 | 0.0 | 0.0 | 1015.98 | 1015.98 | 502.44 | 0.0 | 0.0 |
|
| 1000.0 | 15.98 | 0.0 | 0.0 | 1015.98 | 1015.98 | 502.44 | 0.0 | 0.0 |
|
||||||
@@ -4466,9 +4466,9 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
||||||
| 22 January 2024 | Merchant Issued Refund | 500.0 | 495.53 | 4.47 | 0.0 | 0.0 | 504.47 | false | false |
|
| 22 January 2024 | Merchant Issued Refund | 500.0 | 495.53 | 4.47 | 0.0 | 0.0 | 504.47 | false | false |
|
||||||
| 22 January 2024 | Interest Refund | 2.44 | 2.44 | 0.0 | 0.0 | 0.0 | 502.03 | false | false |
|
| 22 January 2024 | Interest Refund | 2.44 | 2.44 | 0.0 | 0.0 | 0.0 | 502.03 | false | false |
|
||||||
| 01 March 2024 | Repayment | 7.22 | 1.92 | 5.3 | 0.0 | 0.0 | 500.11 | false | false |
|
| 01 March 2024 | Repayment | 7.24 | 1.94 | 5.3 | 0.0 | 0.0 | 500.09 | false | false |
|
||||||
| 01 April 2024 | Repayment | 254.83 | 250.64 | 4.19 | 0.0 | 0.0 | 249.47 | false | false |
|
| 01 April 2024 | Repayment | 254.84 | 250.65 | 4.19 | 0.0 | 0.0 | 249.44 | false | false |
|
||||||
| 01 May 2024 | Repayment | 251.49 | 249.47 | 2.02 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Repayment | 251.46 | 249.44 | 2.02 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 01 May 2024 | Accrual | 15.98 | 0.0 | 15.98 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Accrual | 15.98 | 0.0 | 15.98 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
||||||
|
|
||||||
@@ -4487,10 +4487,10 @@ 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 |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | | 752.34 | 247.66 | 7.17 | 0.0 | 0.0 | 254.83 | 0.0 | 0.0 | 0.0 | 254.83 |
|
| 1 | 31 | 01 February 2024 | | 752.33 | 247.67 | 7.17 | 0.0 | 0.0 | 254.84 | 0.0 | 0.0 | 0.0 | 254.84 |
|
||||||
| 2 | 29 | 01 March 2024 | | 503.41 | 248.93 | 5.9 | 0.0 | 0.0 | 254.83 | 0.0 | 0.0 | 0.0 | 254.83 |
|
| 2 | 29 | 01 March 2024 | | 503.39 | 248.94 | 5.9 | 0.0 | 0.0 | 254.84 | 0.0 | 0.0 | 0.0 | 254.84 |
|
||||||
| 3 | 31 | 01 April 2024 | | 252.8 | 250.61 | 4.22 | 0.0 | 0.0 | 254.83 | 0.0 | 0.0 | 0.0 | 254.83 |
|
| 3 | 31 | 01 April 2024 | | 252.77 | 250.62 | 4.22 | 0.0 | 0.0 | 254.84 | 0.0 | 0.0 | 0.0 | 254.84 |
|
||||||
| 4 | 30 | 01 May 2024 | | 0.0 | 252.8 | 2.05 | 0.0 | 0.0 | 254.85 | 0.0 | 0.0 | 0.0 | 254.85 |
|
| 4 | 30 | 01 May 2024 | | 0.0 | 252.77 | 2.05 | 0.0 | 0.0 | 254.82 | 0.0 | 0.0 | 0.0 | 254.82 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 19.34 | 0.0 | 0.0 | 1019.34 | 0.0 | 0.0 | 0.0 | 1019.34 |
|
| 1000.0 | 19.34 | 0.0 | 0.0 | 1019.34 | 0.0 | 0.0 | 0.0 | 1019.34 |
|
||||||
@@ -4499,23 +4499,23 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| 01 January 2024 | Disbursement | 250.0 | 0.0 | 0.0 | 0.0 | 0.0 | 250.0 | false | false |
|
| 01 January 2024 | Disbursement | 250.0 | 0.0 | 0.0 | 0.0 | 0.0 | 250.0 | false | false |
|
||||||
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
||||||
When Admin sets the business date to "01 February 2024"
|
When Admin sets the business date to "01 February 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 254.83 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 254.84 EUR transaction amount
|
||||||
When Admin sets the business date to "01 March 2024"
|
When Admin sets the business date to "01 March 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 254.83 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 March 2024" with 254.84 EUR transaction amount
|
||||||
When Admin sets the business date to "01 April 2024"
|
When Admin sets the business date to "01 April 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 April 2024" with 254.83 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 April 2024" with 254.84 EUR transaction amount
|
||||||
When Admin sets the business date to "01 May 2024"
|
When Admin sets the business date to "01 May 2024"
|
||||||
And Customer makes "AUTOPAY" repayment on "01 May 2024" with 254.85 EUR transaction amount
|
And Customer makes "AUTOPAY" repayment on "01 May 2024" with 254.82 EUR transaction amount
|
||||||
When Admin sets the business date to "10 May 2024"
|
When Admin sets the business date to "10 May 2024"
|
||||||
When Customer makes "PAYOUT_REFUND" transaction with "AUTOPAY" payment type on "10 May 2024" with 500 EUR transaction amount and system-generated Idempotency key
|
When Customer makes "PAYOUT_REFUND" transaction with "AUTOPAY" payment type on "10 May 2024" with 500 EUR transaction amount and system-generated Idempotency key
|
||||||
Then Loan Repayment schedule has 4 periods, with the following data for periods:
|
Then Loan Repayment schedule has 4 periods, with the following data for periods:
|
||||||
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 01 February 2024 | 752.34 | 247.66 | 7.17 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 01 February 2024 | 752.33 | 247.67 | 7.17 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | 01 March 2024 | 503.41 | 248.93 | 5.9 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 2 | 29 | 01 March 2024 | 01 March 2024 | 503.39 | 248.94 | 5.9 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 3 | 31 | 01 April 2024 | 01 April 2024 | 252.8 | 250.61 | 4.22 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 3 | 31 | 01 April 2024 | 01 April 2024 | 252.77 | 250.62 | 4.22 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 252.8 | 2.05 | 0.0 | 0.0 | 254.85 | 254.85 | 0.0 | 0.0 | 0.0 |
|
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 252.77 | 2.05 | 0.0 | 0.0 | 254.82 | 254.82 | 0.0 | 0.0 | 0.0 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 19.34 | 0.0 | 0.0 | 1019.34 | 1019.34 | 0.0 | 0.0 | 0.0 |
|
| 1000.0 | 19.34 | 0.0 | 0.0 | 1019.34 | 1019.34 | 0.0 | 0.0 | 0.0 |
|
||||||
@@ -4523,10 +4523,10 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||||
| 01 January 2024 | Disbursement | 250.0 | 0.0 | 0.0 | 0.0 | 0.0 | 250.0 | false | false |
|
| 01 January 2024 | Disbursement | 250.0 | 0.0 | 0.0 | 0.0 | 0.0 | 250.0 | false | false |
|
||||||
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
||||||
| 01 February 2024 | Repayment | 254.83 | 247.66 | 7.17 | 0.0 | 0.0 | 752.34 | false | false |
|
| 01 February 2024 | Repayment | 254.84 | 247.67 | 7.17 | 0.0 | 0.0 | 752.33 | false | false |
|
||||||
| 01 March 2024 | Repayment | 254.83 | 248.93 | 5.9 | 0.0 | 0.0 | 503.41 | false | false |
|
| 01 March 2024 | Repayment | 254.84 | 248.94 | 5.9 | 0.0 | 0.0 | 503.39 | false | false |
|
||||||
| 01 April 2024 | Repayment | 254.83 | 250.61 | 4.22 | 0.0 | 0.0 | 252.8 | false | false |
|
| 01 April 2024 | Repayment | 254.84 | 250.62 | 4.22 | 0.0 | 0.0 | 252.77 | false | false |
|
||||||
| 01 May 2024 | Repayment | 254.85 | 252.8 | 2.05 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Repayment | 254.82 | 252.77 | 2.05 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 01 May 2024 | Accrual | 19.34 | 0.0 | 19.34 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Accrual | 19.34 | 0.0 | 19.34 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 10 May 2024 | Payout Refund | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
| 10 May 2024 | Payout Refund | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 10 May 2024 | Interest Refund | 14.01 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
| 10 May 2024 | Interest Refund | 14.01 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
@@ -4536,10 +4536,10 @@ 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 |
|
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 01 January 2024 | | 250.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
| | | 07 January 2024 | | 750.0 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||||
| 1 | 31 | 01 February 2024 | 01 February 2024 | 752.34 | 247.66 | 7.17 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 1 | 31 | 01 February 2024 | 01 February 2024 | 752.33 | 247.67 | 7.17 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 2 | 29 | 01 March 2024 | 01 March 2024 | 503.41 | 248.93 | 5.9 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 2 | 29 | 01 March 2024 | 01 March 2024 | 503.39 | 248.94 | 5.9 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 3 | 31 | 01 April 2024 | 01 April 2024 | 252.8 | 250.61 | 4.22 | 0.0 | 0.0 | 254.83 | 254.83 | 0.0 | 0.0 | 0.0 |
|
| 3 | 31 | 01 April 2024 | 01 April 2024 | 252.77 | 250.62 | 4.22 | 0.0 | 0.0 | 254.84 | 254.84 | 0.0 | 0.0 | 0.0 |
|
||||||
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 252.8 | 2.05 | 0.0 | 0.0 | 254.85 | 254.85 | 0.0 | 0.0 | 0.0 |
|
| 4 | 30 | 01 May 2024 | 01 May 2024 | 0.0 | 252.77 | 2.05 | 0.0 | 0.0 | 254.82 | 254.82 | 0.0 | 0.0 | 0.0 |
|
||||||
Then Loan Repayment schedule has the following data in Total row:
|
Then Loan Repayment schedule has the following data in Total row:
|
||||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||||
| 1000.0 | 19.34 | 0.0 | 0.0 | 1019.34 | 1019.34 | 0.0 | 0.0 | 0.0 |
|
| 1000.0 | 19.34 | 0.0 | 0.0 | 1019.34 | 1019.34 | 0.0 | 0.0 | 0.0 |
|
||||||
@@ -4547,10 +4547,10 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
|
|||||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||||
| 01 January 2024 | Disbursement | 250.0 | 0.0 | 0.0 | 0.0 | 0.0 | 250.0 | false | false |
|
| 01 January 2024 | Disbursement | 250.0 | 0.0 | 0.0 | 0.0 | 0.0 | 250.0 | false | false |
|
||||||
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
| 07 January 2024 | Disbursement | 750.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1000.0 | false | false |
|
||||||
| 01 February 2024 | Repayment | 254.83 | 247.66 | 7.17 | 0.0 | 0.0 | 752.34 | false | false |
|
| 01 February 2024 | Repayment | 254.84 | 247.67 | 7.17 | 0.0 | 0.0 | 752.33 | false | false |
|
||||||
| 01 March 2024 | Repayment | 254.83 | 248.93 | 5.9 | 0.0 | 0.0 | 503.41 | false | false |
|
| 01 March 2024 | Repayment | 254.84 | 248.94 | 5.9 | 0.0 | 0.0 | 503.39 | false | false |
|
||||||
| 01 April 2024 | Repayment | 254.83 | 250.61 | 4.22 | 0.0 | 0.0 | 252.8 | false | false |
|
| 01 April 2024 | Repayment | 254.84 | 250.62 | 4.22 | 0.0 | 0.0 | 252.77 | false | false |
|
||||||
| 01 May 2024 | Repayment | 254.85 | 252.8 | 2.05 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Repayment | 254.82 | 252.77 | 2.05 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 01 May 2024 | Accrual | 19.34 | 0.0 | 19.34 | 0.0 | 0.0 | 0.0 | false | false |
|
| 01 May 2024 | Accrual | 19.34 | 0.0 | 19.34 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 10 May 2024 | Payout Refund | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
| 10 May 2024 | Payout Refund | 500.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
| 10 May 2024 | Interest Refund | 14.01 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
| 10 May 2024 | Interest Refund | 14.01 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||||
|
|||||||
+52
-3
@@ -26,9 +26,12 @@ import java.math.MathContext;
|
|||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
import java.util.function.BiConsumer;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
@@ -62,7 +65,8 @@ public class ProgressiveLoanInterestScheduleModel {
|
|||||||
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, final Integer installmentAmountInMultiplesOf,
|
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail, final Integer installmentAmountInMultiplesOf,
|
||||||
final MathContext mc) {
|
final MathContext mc) {
|
||||||
this.mc = mc;
|
this.mc = mc;
|
||||||
this.repaymentPeriods = copyRepaymentPeriods(repaymentPeriods);
|
this.repaymentPeriods = copyRepaymentPeriods(repaymentPeriods,
|
||||||
|
(previousPeriod, repaymentPeriod) -> new RepaymentPeriod(previousPeriod, repaymentPeriod, mc));
|
||||||
this.interestRates = new TreeSet<>(interestRates);
|
this.interestRates = new TreeSet<>(interestRates);
|
||||||
this.loanProductRelatedDetail = loanProductRelatedDetail;
|
this.loanProductRelatedDetail = loanProductRelatedDetail;
|
||||||
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
|
this.installmentAmountInMultiplesOf = installmentAmountInMultiplesOf;
|
||||||
@@ -74,11 +78,20 @@ public class ProgressiveLoanInterestScheduleModel {
|
|||||||
installmentAmountInMultiplesOf, mc);
|
installmentAmountInMultiplesOf, mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<RepaymentPeriod> copyRepaymentPeriods(final List<RepaymentPeriod> repaymentPeriods) {
|
public ProgressiveLoanInterestScheduleModel emptyCopy() {
|
||||||
|
final List<RepaymentPeriod> repaymentPeriodCopies = copyRepaymentPeriods(repaymentPeriods,
|
||||||
|
(previousPeriod, repaymentPeriod) -> new RepaymentPeriod(previousPeriod, repaymentPeriod.getFromDate(),
|
||||||
|
repaymentPeriod.getDueDate(), repaymentPeriod.getEmi().zero(), mc));
|
||||||
|
return new ProgressiveLoanInterestScheduleModel(repaymentPeriodCopies, interestRates, loanProductRelatedDetail,
|
||||||
|
installmentAmountInMultiplesOf, mc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<RepaymentPeriod> copyRepaymentPeriods(final List<RepaymentPeriod> repaymentPeriods,
|
||||||
|
final BiFunction<RepaymentPeriod, RepaymentPeriod, RepaymentPeriod> repaymentCopyFunction) {
|
||||||
final List<RepaymentPeriod> repaymentCopies = new ArrayList<>(repaymentPeriods.size());
|
final List<RepaymentPeriod> repaymentCopies = new ArrayList<>(repaymentPeriods.size());
|
||||||
RepaymentPeriod previousPeriod = null;
|
RepaymentPeriod previousPeriod = null;
|
||||||
for (RepaymentPeriod repaymentPeriod : repaymentPeriods) {
|
for (RepaymentPeriod repaymentPeriod : repaymentPeriods) {
|
||||||
RepaymentPeriod currentPeriod = new RepaymentPeriod(previousPeriod, repaymentPeriod, mc);
|
RepaymentPeriod currentPeriod = repaymentCopyFunction.apply(previousPeriod, repaymentPeriod);
|
||||||
previousPeriod = currentPeriod;
|
previousPeriod = currentPeriod;
|
||||||
repaymentCopies.add(currentPeriod);
|
repaymentCopies.add(currentPeriod);
|
||||||
}
|
}
|
||||||
@@ -229,4 +242,40 @@ public class ProgressiveLoanInterestScheduleModel {
|
|||||||
.filter(period -> isInPeriod(transactionDate, period.getFromDate(), period.getDueDate(), period.isFirstRepaymentPeriod()))//
|
.filter(period -> isInPeriod(transactionDate, period.getFromDate(), period.getDueDate(), period.isFirstRepaymentPeriod()))//
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return repaymentPeriods.stream() //
|
||||||
|
.filter(rp -> !rp.getEmi().isZero()) //
|
||||||
|
.findFirst() //
|
||||||
|
.isEmpty(); //
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gives you repayment pairs to copy attributes.
|
||||||
|
*
|
||||||
|
* @param periodFromDueDate
|
||||||
|
* Copy from this due periods.
|
||||||
|
* @param copyFromPeriods
|
||||||
|
* Copy source
|
||||||
|
* @param copyConsumer
|
||||||
|
* Consumer to copy attributes. Params: (from, to)
|
||||||
|
*/
|
||||||
|
public void copyPeriodsFrom(final LocalDate periodFromDueDate, List<RepaymentPeriod> copyFromPeriods,
|
||||||
|
BiConsumer<RepaymentPeriod, RepaymentPeriod> copyConsumer) {
|
||||||
|
if (copyFromPeriods.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Iterator<RepaymentPeriod> actualIterator = repaymentPeriods.iterator();
|
||||||
|
final Iterator<RepaymentPeriod> copyFromIterator = copyFromPeriods.iterator();
|
||||||
|
while (actualIterator.hasNext()) {
|
||||||
|
final RepaymentPeriod copyFromPeriod = copyFromIterator.next();
|
||||||
|
RepaymentPeriod actualPeriod = actualIterator.next();
|
||||||
|
while (actualIterator.hasNext() && !copyFromPeriod.getDueDate().isEqual(actualPeriod.getDueDate())) {
|
||||||
|
actualPeriod = actualIterator.next();
|
||||||
|
}
|
||||||
|
if (!actualPeriod.getDueDate().isBefore(periodFromDueDate)) {
|
||||||
|
copyConsumer.accept(copyFromPeriod, actualPeriod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+49
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing,
|
||||||
|
* software distributed under the License is distributed on an
|
||||||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
* KIND, either express or implied. See the License for the
|
||||||
|
* specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.fineract.portfolio.loanproduct.calc;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.apache.fineract.organisation.monetary.domain.Money;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class EmiChangeOperation {
|
||||||
|
|
||||||
|
public enum Action {
|
||||||
|
DISBURSEMENT, INTEREST_RATE_CHANGE
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Action action;
|
||||||
|
private final LocalDate submittedOnDate;
|
||||||
|
|
||||||
|
private final Money amount;
|
||||||
|
private final BigDecimal interestRate;
|
||||||
|
|
||||||
|
public static EmiChangeOperation disburse(final LocalDate disbursementDueDate, final Money disbursedAmount) {
|
||||||
|
return new EmiChangeOperation(EmiChangeOperation.Action.DISBURSEMENT, disbursementDueDate, disbursedAmount, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EmiChangeOperation changeInterestRate(final LocalDate newInterestSubmittedOnDate, final BigDecimal newInterestRate) {
|
||||||
|
return new EmiChangeOperation(EmiChangeOperation.Action.INTEREST_RATE_CHANGE, newInterestSubmittedOnDate, null, newInterestRate);
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
-29
@@ -102,9 +102,16 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
@Override
|
@Override
|
||||||
public void addDisbursement(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate disbursementDueDate,
|
public void addDisbursement(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate disbursementDueDate,
|
||||||
final Money disbursedAmount) {
|
final Money disbursedAmount) {
|
||||||
scheduleModel.changeOutstandingBalanceAndUpdateInterestPeriods(disbursementDueDate, disbursedAmount, scheduleModel.zero())
|
addDisbursement(scheduleModel, EmiChangeOperation.disburse(disbursementDueDate, disbursedAmount));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDisbursement(final ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||||
|
scheduleModel
|
||||||
|
.changeOutstandingBalanceAndUpdateInterestPeriods(operation.getSubmittedOnDate(), operation.getAmount(),
|
||||||
|
scheduleModel.zero())
|
||||||
.ifPresent((repaymentPeriod) -> calculateEMIValueAndRateFactors(
|
.ifPresent((repaymentPeriod) -> calculateEMIValueAndRateFactors(
|
||||||
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, disbursementDueDate), scheduleModel));
|
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, operation.getSubmittedOnDate()), scheduleModel,
|
||||||
|
operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
private LocalDate getEffectiveRepaymentDueDate(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
private LocalDate getEffectiveRepaymentDueDate(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||||
@@ -125,13 +132,18 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
@Override
|
@Override
|
||||||
public void changeInterestRate(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate newInterestSubmittedOnDate,
|
public void changeInterestRate(final ProgressiveLoanInterestScheduleModel scheduleModel, final LocalDate newInterestSubmittedOnDate,
|
||||||
final BigDecimal newInterestRate) {
|
final BigDecimal newInterestRate) {
|
||||||
final LocalDate interestRateChangeEffectiveDate = newInterestSubmittedOnDate.minusDays(1);
|
changeInterestRate(scheduleModel, EmiChangeOperation.changeInterestRate(newInterestSubmittedOnDate, newInterestRate));
|
||||||
scheduleModel.addInterestRate(interestRateChangeEffectiveDate, newInterestRate);
|
}
|
||||||
|
|
||||||
|
private void changeInterestRate(final ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||||
|
final LocalDate interestRateChangeEffectiveDate = operation.getSubmittedOnDate().minusDays(1);
|
||||||
|
scheduleModel.addInterestRate(interestRateChangeEffectiveDate, operation.getInterestRate());
|
||||||
scheduleModel
|
scheduleModel
|
||||||
.changeOutstandingBalanceAndUpdateInterestPeriods(interestRateChangeEffectiveDate, scheduleModel.zero(),
|
.changeOutstandingBalanceAndUpdateInterestPeriods(interestRateChangeEffectiveDate, scheduleModel.zero(),
|
||||||
scheduleModel.zero())
|
scheduleModel.zero())
|
||||||
.ifPresent(repaymentPeriod -> calculateEMIValueAndRateFactors(
|
.ifPresent(repaymentPeriod -> calculateEMIValueAndRateFactors(
|
||||||
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, interestRateChangeEffectiveDate), scheduleModel));
|
getEffectiveRepaymentDueDate(scheduleModel, repaymentPeriod, interestRateChangeEffectiveDate), scheduleModel,
|
||||||
|
operation));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -283,15 +295,24 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
/**
|
/**
|
||||||
* Calculate Equal Monthly Installment value and Rate Factor -1 values for calculate Interest
|
* Calculate Equal Monthly Installment value and Rate Factor -1 values for calculate Interest
|
||||||
*/
|
*/
|
||||||
void calculateEMIValueAndRateFactors(final LocalDate calculateFromRepaymentPeriodDueDate,
|
private void calculateEMIValueAndRateFactors(final LocalDate calculateFromRepaymentPeriodDueDate,
|
||||||
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
final ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||||
final List<RepaymentPeriod> relatedRepaymentPeriods = scheduleModel.getRelatedRepaymentPeriods(calculateFromRepaymentPeriodDueDate);
|
final List<RepaymentPeriod> relatedRepaymentPeriods = scheduleModel.getRelatedRepaymentPeriods(calculateFromRepaymentPeriodDueDate);
|
||||||
|
final boolean onlyOnActualModelShouldApply = scheduleModel.isEmpty()
|
||||||
|
|| operation.getAction() == EmiChangeOperation.Action.INTEREST_RATE_CHANGE;
|
||||||
|
|
||||||
calculateRateFactorForPeriods(relatedRepaymentPeriods, scheduleModel);
|
calculateRateFactorForPeriods(relatedRepaymentPeriods, scheduleModel);
|
||||||
calculateOutstandingBalance(scheduleModel);
|
calculateOutstandingBalance(scheduleModel);
|
||||||
calculateEMIOnPeriods(relatedRepaymentPeriods, scheduleModel);
|
if (onlyOnActualModelShouldApply) {
|
||||||
|
calculateEMIOnActualModel(relatedRepaymentPeriods, scheduleModel);
|
||||||
|
} else {
|
||||||
|
calculateEMIOnNewEmptyModelAndMerge(relatedRepaymentPeriods, scheduleModel, operation);
|
||||||
|
}
|
||||||
calculateOutstandingBalance(scheduleModel);
|
calculateOutstandingBalance(scheduleModel);
|
||||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||||
checkAndAdjustEmiIfNeededOnRelatedRepaymentPeriods(scheduleModel, relatedRepaymentPeriods);
|
if (onlyOnActualModelShouldApply) {
|
||||||
|
checkAndAdjustEmiIfNeededOnRelatedRepaymentPeriods(scheduleModel, relatedRepaymentPeriods);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestScheduleModel scheduleModel) {
|
private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||||
@@ -378,19 +399,19 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
*
|
*
|
||||||
* @return Rate Interest Rate in fraction format
|
* @return Rate Interest Rate in fraction format
|
||||||
*/
|
*/
|
||||||
BigDecimal calcNominalInterestRatePercentage(final BigDecimal interestRate, MathContext mc) {
|
private BigDecimal calcNominalInterestRatePercentage(final BigDecimal interestRate, MathContext mc) {
|
||||||
return MathUtil.nullToZero(interestRate).divide(DIVISOR_100, mc);
|
return MathUtil.nullToZero(interestRate).divide(DIVISOR_100, mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * Calculate rate factors from ONLY repayment periods
|
* * Calculate rate factors from ONLY repayment periods
|
||||||
*/
|
*/
|
||||||
void calculateRateFactorForPeriods(final List<RepaymentPeriod> repaymentPeriods,
|
private void calculateRateFactorForPeriods(final List<RepaymentPeriod> repaymentPeriods,
|
||||||
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||||
repaymentPeriods.forEach(repaymentPeriod -> calculateRateFactorForRepaymentPeriod(repaymentPeriod, scheduleModel));
|
repaymentPeriods.forEach(repaymentPeriod -> calculateRateFactorForRepaymentPeriod(repaymentPeriod, scheduleModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateRateFactorForRepaymentPeriod(final RepaymentPeriod repaymentPeriod,
|
private void calculateRateFactorForRepaymentPeriod(final RepaymentPeriod repaymentPeriod,
|
||||||
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||||
repaymentPeriod.getInterestPeriods().forEach(interestPeriod -> {
|
repaymentPeriod.getInterestPeriods().forEach(interestPeriod -> {
|
||||||
interestPeriod.setRateFactor(calculateRateFactorPerPeriod(scheduleModel, repaymentPeriod, interestPeriod.getFromDate(),
|
interestPeriod.setRateFactor(calculateRateFactorPerPeriod(scheduleModel, repaymentPeriod, interestPeriod.getFromDate(),
|
||||||
@@ -403,8 +424,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
/**
|
/**
|
||||||
* Calculate Rate Factor for an exact Period
|
* Calculate Rate Factor for an exact Period
|
||||||
*/
|
*/
|
||||||
BigDecimal calculateRateFactorPerPeriod(final ProgressiveLoanInterestScheduleModel scheduleModel, final RepaymentPeriod repaymentPeriod,
|
private BigDecimal calculateRateFactorPerPeriod(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||||
final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate) {
|
final RepaymentPeriod repaymentPeriod, final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate) {
|
||||||
final MathContext mc = scheduleModel.mc();
|
final MathContext mc = scheduleModel.mc();
|
||||||
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail = scheduleModel.loanProductRelatedDetail();
|
final LoanProductMinimumRepaymentScheduleRelatedDetail loanProductRelatedDetail = scheduleModel.loanProductRelatedDetail();
|
||||||
final BigDecimal interestRate = calcNominalInterestRatePercentage(scheduleModel.getInterestRate(interestPeriodFromDate),
|
final BigDecimal interestRate = calcNominalInterestRatePercentage(scheduleModel.getInterestRate(interestPeriodFromDate),
|
||||||
@@ -443,7 +464,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
* @param interestPeriodDueDate
|
* @param interestPeriodDueDate
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
BigDecimal calculatePeriodFractions(final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate, MathContext mc) {
|
private BigDecimal calculatePeriodFractions(final LocalDate interestPeriodFromDate, final LocalDate interestPeriodDueDate,
|
||||||
|
MathContext mc) {
|
||||||
BigDecimal cumulatedRateFactor = BigDecimal.ZERO;
|
BigDecimal cumulatedRateFactor = BigDecimal.ZERO;
|
||||||
int actualYear = interestPeriodFromDate.getYear();
|
int actualYear = interestPeriodFromDate.getYear();
|
||||||
int endYear = interestPeriodDueDate.getYear();
|
int endYear = interestPeriodDueDate.getYear();
|
||||||
@@ -473,7 +495,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
* @param calculatedDaysInPeriod
|
* @param calculatedDaysInPeriod
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
BigDecimal calculateRateFactorPerPeriodBasedOnRepaymentFrequency(final BigDecimal interestRate,
|
private BigDecimal calculateRateFactorPerPeriodBasedOnRepaymentFrequency(final BigDecimal interestRate,
|
||||||
final PeriodFrequencyType repaymentFrequency, final BigDecimal repaymentEvery, final BigDecimal daysInMonth,
|
final PeriodFrequencyType repaymentFrequency, final BigDecimal repaymentEvery, final BigDecimal daysInMonth,
|
||||||
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod,
|
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod,
|
||||||
final MathContext mc) {
|
final MathContext mc) {
|
||||||
@@ -488,7 +510,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateEMIOnPeriods(final List<RepaymentPeriod> repaymentPeriods, final ProgressiveLoanInterestScheduleModel scheduleModel) {
|
private void calculateEMIOnActualModel(List<RepaymentPeriod> repaymentPeriods, ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||||
if (repaymentPeriods.isEmpty()) {
|
if (repaymentPeriods.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -496,7 +518,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
final BigDecimal rateFactorN = MathUtil.stripTrailingZeros(calculateRateFactorPlus1N(repaymentPeriods, mc));
|
final BigDecimal rateFactorN = MathUtil.stripTrailingZeros(calculateRateFactorPlus1N(repaymentPeriods, mc));
|
||||||
final BigDecimal fnResult = MathUtil.stripTrailingZeros(calculateFnResult(repaymentPeriods, mc));
|
final BigDecimal fnResult = MathUtil.stripTrailingZeros(calculateFnResult(repaymentPeriods, mc));
|
||||||
final RepaymentPeriod startPeriod = repaymentPeriods.get(0);
|
final RepaymentPeriod startPeriod = repaymentPeriods.get(0);
|
||||||
// TODO: double check
|
|
||||||
final Money outstandingBalance = startPeriod.getInitialBalanceForEmiRecalculation();
|
final Money outstandingBalance = startPeriod.getInitialBalanceForEmiRecalculation();
|
||||||
|
|
||||||
final Money equalMonthlyInstallment = Money.of(outstandingBalance.getCurrencyData(),
|
final Money equalMonthlyInstallment = Money.of(outstandingBalance.getCurrencyData(),
|
||||||
@@ -511,7 +533,22 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Money applyInstallmentAmountInMultiplesOf(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
private void calculateEMIOnNewEmptyModelAndMerge(List<RepaymentPeriod> repaymentPeriods,
|
||||||
|
ProgressiveLoanInterestScheduleModel scheduleModel, final EmiChangeOperation operation) {
|
||||||
|
if (repaymentPeriods.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final ProgressiveLoanInterestScheduleModel scheduleModelCopy = scheduleModel.emptyCopy();
|
||||||
|
addDisbursement(scheduleModelCopy, operation);
|
||||||
|
|
||||||
|
final LocalDate firstDueDate = repaymentPeriods.get(0).getDueDate();
|
||||||
|
scheduleModel.copyPeriodsFrom(firstDueDate, scheduleModelCopy.repaymentPeriods(), (newRepaymentPeriod, actualRepaymentPeriod) -> {
|
||||||
|
actualRepaymentPeriod.setEmi(actualRepaymentPeriod.getEmi().plus(newRepaymentPeriod.getEmi()));
|
||||||
|
actualRepaymentPeriod.setOriginalEmi(actualRepaymentPeriod.getOriginalEmi().plus(newRepaymentPeriod.getOriginalEmi()));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Money applyInstallmentAmountInMultiplesOf(final ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||||
final Money equalMonthlyInstallment) {
|
final Money equalMonthlyInstallment) {
|
||||||
return scheduleModel.installmentAmountInMultiplesOf() != null
|
return scheduleModel.installmentAmountInMultiplesOf() != null
|
||||||
? Money.roundToMultiplesOf(equalMonthlyInstallment, scheduleModel.installmentAmountInMultiplesOf())
|
? Money.roundToMultiplesOf(equalMonthlyInstallment, scheduleModel.installmentAmountInMultiplesOf())
|
||||||
@@ -534,7 +571,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
/**
|
/**
|
||||||
* Calculate Rate Factor Product from rate factors
|
* Calculate Rate Factor Product from rate factors
|
||||||
*/
|
*/
|
||||||
BigDecimal calculateRateFactorPlus1N(final List<RepaymentPeriod> periods, MathContext mc) {
|
private BigDecimal calculateRateFactorPlus1N(final List<RepaymentPeriod> periods, MathContext mc) {
|
||||||
return periods.stream().map(RepaymentPeriod::getRateFactorPlus1).reduce(BigDecimal.ONE,
|
return periods.stream().map(RepaymentPeriod::getRateFactorPlus1).reduce(BigDecimal.ONE,
|
||||||
(BigDecimal acc, BigDecimal value) -> acc.multiply(value, mc));
|
(BigDecimal acc, BigDecimal value) -> acc.multiply(value, mc));
|
||||||
}
|
}
|
||||||
@@ -542,7 +579,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
/**
|
/**
|
||||||
* Summarize Fn values
|
* Summarize Fn values
|
||||||
*/
|
*/
|
||||||
BigDecimal calculateFnResult(final List<RepaymentPeriod> periods, final MathContext mc) {
|
private BigDecimal calculateFnResult(final List<RepaymentPeriod> periods, final MathContext mc) {
|
||||||
return periods.stream()//
|
return periods.stream()//
|
||||||
.skip(1)//
|
.skip(1)//
|
||||||
.map(RepaymentPeriod::getRateFactorPlus1)//
|
.map(RepaymentPeriod::getRateFactorPlus1)//
|
||||||
@@ -552,8 +589,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
/**
|
/**
|
||||||
* Calculate the EMI (Equal Monthly Installment) value
|
* Calculate the EMI (Equal Monthly Installment) value
|
||||||
*/
|
*/
|
||||||
BigDecimal calculateEMIValue(final BigDecimal rateFactorPlus1N, final BigDecimal outstandingBalanceForRest, final BigDecimal fnResult,
|
private BigDecimal calculateEMIValue(final BigDecimal rateFactorPlus1N, final BigDecimal outstandingBalanceForRest,
|
||||||
MathContext mc) {
|
final BigDecimal fnResult, MathContext mc) {
|
||||||
return rateFactorPlus1N.multiply(outstandingBalanceForRest, mc).divide(fnResult, mc);
|
return rateFactorPlus1N.multiply(outstandingBalanceForRest, mc).divide(fnResult, mc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,8 +618,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
*
|
*
|
||||||
* @return Rate Factor for period
|
* @return Rate Factor for period
|
||||||
*/
|
*/
|
||||||
BigDecimal rateFactorByRepaymentEveryDay(final BigDecimal interestRate, final BigDecimal repaymentEvery, final BigDecimal daysInYear,
|
private BigDecimal rateFactorByRepaymentEveryDay(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||||
final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
||||||
return rateFactorByRepaymentPeriod(interestRate, BigDecimal.ONE, repaymentEvery, daysInYear, actualDaysInPeriod,
|
return rateFactorByRepaymentPeriod(interestRate, BigDecimal.ONE, repaymentEvery, daysInYear, actualDaysInPeriod,
|
||||||
calculatedDaysInPeriod, mc);
|
calculatedDaysInPeriod, mc);
|
||||||
}
|
}
|
||||||
@@ -611,8 +648,8 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
*
|
*
|
||||||
* @return Rate Factor for period
|
* @return Rate Factor for period
|
||||||
*/
|
*/
|
||||||
BigDecimal rateFactorByRepaymentEveryWeek(final BigDecimal interestRate, final BigDecimal repaymentEvery, final BigDecimal daysInYear,
|
private BigDecimal rateFactorByRepaymentEveryWeek(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||||
final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod, MathContext mc) {
|
||||||
return rateFactorByRepaymentPeriod(interestRate, ONE_WEEK_IN_DAYS, repaymentEvery, daysInYear, actualDaysInPeriod,
|
return rateFactorByRepaymentPeriod(interestRate, ONE_WEEK_IN_DAYS, repaymentEvery, daysInYear, actualDaysInPeriod,
|
||||||
calculatedDaysInPeriod, mc);
|
calculatedDaysInPeriod, mc);
|
||||||
}
|
}
|
||||||
@@ -678,7 +715,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
*
|
*
|
||||||
* @return Rate Factor for period
|
* @return Rate Factor for period
|
||||||
*/
|
*/
|
||||||
BigDecimal rateFactorByRepaymentPeriod(final BigDecimal interestRate, final BigDecimal repaymentPeriodMultiplierInDays,
|
private BigDecimal rateFactorByRepaymentPeriod(final BigDecimal interestRate, final BigDecimal repaymentPeriodMultiplierInDays,
|
||||||
final BigDecimal repaymentEvery, final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod,
|
final BigDecimal repaymentEvery, final BigDecimal daysInYear, final BigDecimal actualDaysInPeriod,
|
||||||
final BigDecimal calculatedDaysInPeriod, final MathContext mc) {
|
final BigDecimal calculatedDaysInPeriod, final MathContext mc) {
|
||||||
if (MathUtil.isZero(calculatedDaysInPeriod)) {
|
if (MathUtil.isZero(calculatedDaysInPeriod)) {
|
||||||
@@ -697,7 +734,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
|||||||
* Calculate Rate Factor based on Partial Period
|
* Calculate Rate Factor based on Partial Period
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
BigDecimal rateFactorByRepaymentPartialPeriod(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
private BigDecimal rateFactorByRepaymentPartialPeriod(final BigDecimal interestRate, final BigDecimal repaymentEvery,
|
||||||
final BigDecimal cumulatedPeriodRatio, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod,
|
final BigDecimal cumulatedPeriodRatio, final BigDecimal actualDaysInPeriod, final BigDecimal calculatedDaysInPeriod,
|
||||||
final MathContext mc) {
|
final MathContext mc) {
|
||||||
if (MathUtil.isZero(calculatedDaysInPeriod)) {
|
if (MathUtil.isZero(calculatedDaysInPeriod)) {
|
||||||
|
|||||||
+19
-12
@@ -953,14 +953,16 @@ class ProgressiveEMICalculatorTest {
|
|||||||
disbursedAmount = toMoney(25.0);
|
disbursedAmount = toMoney(25.0);
|
||||||
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 8), disbursedAmount);
|
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 8), disbursedAmount);
|
||||||
|
|
||||||
checkPeriod(interestSchedule, 0, 0, 29.94, 0.001019591398, 0.00, 1.15, 28.79, 146.21);
|
checkTotalInterestDue(interestSchedule, 4.65);
|
||||||
checkPeriod(interestSchedule, 0, 1, 29.94, 0.000764693548, 0.08, 1.15, 28.79, 146.21);
|
|
||||||
checkPeriod(interestSchedule, 0, 2, 29.94, 0.006117548387, 1.07, 1.15, 28.79, 146.21);
|
checkPeriod(interestSchedule, 0, 0, 29.93, 0.001019591398, 0.00, 1.15, 28.78, 146.22);
|
||||||
checkPeriod(interestSchedule, 1, 0, 29.94, 0.007901833333, 1.16, 28.78, 117.43);
|
checkPeriod(interestSchedule, 0, 1, 29.93, 0.000764693548, 0.08, 1.15, 28.78, 146.22);
|
||||||
checkPeriod(interestSchedule, 2, 0, 29.94, 0.007901833333, 0.93, 29.01, 88.42);
|
checkPeriod(interestSchedule, 0, 2, 29.93, 0.006117548387, 1.07, 1.15, 28.78, 146.22);
|
||||||
checkPeriod(interestSchedule, 3, 0, 29.94, 0.007901833333, 0.70, 29.24, 59.18);
|
checkPeriod(interestSchedule, 1, 0, 29.93, 0.007901833333, 1.16, 28.77, 117.45);
|
||||||
checkPeriod(interestSchedule, 4, 0, 29.94, 0.007901833333, 0.47, 29.47, 29.71);
|
checkPeriod(interestSchedule, 2, 0, 29.93, 0.007901833333, 0.93, 29.00, 88.45);
|
||||||
checkPeriod(interestSchedule, 5, 0, 29.94, 0.007901833333, 0.23, 29.71, 0.0);
|
checkPeriod(interestSchedule, 3, 0, 29.93, 0.007901833333, 0.70, 29.23, 59.22);
|
||||||
|
checkPeriod(interestSchedule, 4, 0, 29.93, 0.007901833333, 0.47, 29.46, 29.76);
|
||||||
|
checkPeriod(interestSchedule, 5, 0, 30.0, 0.007901833333, 0.24, 29.76, 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1034,13 +1036,13 @@ class ProgressiveEMICalculatorTest {
|
|||||||
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 6, 1), LocalDate.of(2024, 1, 1), toMoney(51.03));
|
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 6, 1), LocalDate.of(2024, 1, 1), toMoney(51.03));
|
||||||
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 7, 1), LocalDate.of(2024, 1, 1), toMoney(44.85));
|
emiCalculator.payPrincipal(interestSchedule, LocalDate.of(2024, 7, 1), LocalDate.of(2024, 1, 1), toMoney(44.85));
|
||||||
|
|
||||||
Assertions.assertEquals(0.0, toDouble(interestSchedule.getTotalDueInterest()));
|
checkTotalInterestDue(interestSchedule, 0.0);
|
||||||
|
|
||||||
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 1), toMoney(200.0));
|
emiCalculator.addDisbursement(interestSchedule, LocalDate.of(2024, 1, 1), toMoney(200.0));
|
||||||
Assertions.assertEquals(4.20, toDouble(interestSchedule.getTotalDueInterest()));
|
checkTotalInterestDue(interestSchedule, 4.11);
|
||||||
|
|
||||||
checkEmi(interestSchedule, 4, 84.03);
|
checkEmi(interestSchedule, 4, 85.05);
|
||||||
checkEmi(interestSchedule, 5, 84.05);
|
checkEmi(interestSchedule, 5, 78.86);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -1398,6 +1400,11 @@ class ProgressiveEMICalculatorTest {
|
|||||||
Assertions.assertEquals(emiValue, toDouble(interestScheduleModel.repaymentPeriods().get(repaymentIdx).getEmi()));
|
Assertions.assertEquals(emiValue, toDouble(interestScheduleModel.repaymentPeriods().get(repaymentIdx).getEmi()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void checkTotalInterestDue(final ProgressiveLoanInterestScheduleModel interestScheduleModel,
|
||||||
|
final double totalInterestDue) {
|
||||||
|
Assertions.assertEquals(totalInterestDue, toDouble(interestScheduleModel.getTotalDueInterest()));
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkPeriod(final ProgressiveLoanInterestScheduleModel interestScheduleModel, final int repaymentIdx,
|
private static void checkPeriod(final ProgressiveLoanInterestScheduleModel interestScheduleModel, final int repaymentIdx,
|
||||||
final int interestIdx, final double emiValue, final double rateFactor, final double interestDue, final double principalDue,
|
final int interestIdx, final double emiValue, final double rateFactor, final double interestDue, final double principalDue,
|
||||||
final double remaingBalance) {
|
final double remaingBalance) {
|
||||||
|
|||||||
+3
-3
@@ -889,7 +889,7 @@ public class LoanInterestRefundTest extends BaseLoanIntegrationTest {
|
|||||||
transaction(171.29, "Repayment", "01 May 2021"), //
|
transaction(171.29, "Repayment", "01 May 2021"), //
|
||||||
transaction(171.29, "Repayment", "01 June 2021"), //
|
transaction(171.29, "Repayment", "01 June 2021"), //
|
||||||
transaction(171.32, "Repayment", "01 July 2021"), //
|
transaction(171.32, "Repayment", "01 July 2021"), //
|
||||||
transaction(27.77, "Accrual", "01 July 2021") //
|
transaction(27.76, "Accrual", "01 July 2021") //
|
||||||
); //
|
); //
|
||||||
});
|
});
|
||||||
runAt("11 July 2021", () -> {
|
runAt("11 July 2021", () -> {
|
||||||
@@ -909,8 +909,8 @@ public class LoanInterestRefundTest extends BaseLoanIntegrationTest {
|
|||||||
transaction(171.29, "Repayment", "01 June 2021"), //
|
transaction(171.29, "Repayment", "01 June 2021"), //
|
||||||
transaction(171.32, "Repayment", "01 July 2021"), //
|
transaction(171.32, "Repayment", "01 July 2021"), //
|
||||||
transaction(500.0, "Payout Refund", "11 July 2021"), //
|
transaction(500.0, "Payout Refund", "11 July 2021"), //
|
||||||
transaction(20.41, "Interest Refund", "11 July 2021"), //
|
transaction(20.40, "Interest Refund", "11 July 2021"), //
|
||||||
transaction(27.77, "Accrual", "01 July 2021") //
|
transaction(27.76, "Accrual", "01 July 2021") //
|
||||||
); //
|
); //
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user