FINERACT-2281: fix unrecognized interest handling when first period is unpaid
This commit is contained in:
+229
-11
@@ -6195,7 +6195,7 @@ Feature: LoanAccrualActivity
|
||||
Then Loan Repayment schedule has 12 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 31 | 21 April 2025 | | 218.82 | 123.64 | 0.77 | 0.0 | 0.0 | 124.41 | 83.64 | 83.64 | 0.0 | 40.77 |
|
||||
| 1 | 31 | 21 April 2025 | | 218.82 | 123.64 | 0.84 | 0.0 | 0.0 | 124.48 | 83.64 | 83.64 | 0.0 | 40.84 |
|
||||
| 2 | 30 | 21 May 2025 | 21 March 2025 | 195.18 | 23.64 | 0.0 | 0.0 | 0.0 | 23.64 | 23.64 | 23.64 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 21 June 2025 | 21 March 2025 | 171.54 | 23.64 | 0.0 | 0.0 | 0.0 | 23.64 | 23.64 | 23.64 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 21 July 2025 | 21 March 2025 | 147.9 | 23.64 | 0.0 | 0.0 | 0.0 | 23.64 | 23.64 | 23.64 | 0.0 | 0.0 |
|
||||
@@ -6209,7 +6209,7 @@ Feature: LoanAccrualActivity
|
||||
| 12 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 0.77 | 0.0 | 0.0 | 343.23 | 302.46 | 302.46 | 0.0 | 40.77 |
|
||||
| 342.46 | 0.84 | 0.0 | 0.0 | 343.3 | 302.46 | 302.46 | 0.0 | 40.84 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
@@ -6759,11 +6759,11 @@ Feature: LoanAccrualActivity
|
||||
When Admin sets the business date to "29 April 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
And Customer makes "AUTOPAY" repayment on "29 April 2025" with 100 EUR transaction amount
|
||||
Then Loan has 1.93 outstanding amount
|
||||
Then Loan has 2.6 outstanding amount
|
||||
Then Loan Repayment schedule has 12 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 31 | 21 April 2025 | | 222.26 | 120.2 | 1.93 | 0.0 | 0.0 | 122.13 |120.2 | 20.2 | 100.0| 1.93 |
|
||||
| 1 | 31 | 21 April 2025 | | 222.26 | 120.2 | 2.6 | 0.0 | 0.0 | 122.8 |120.2 | 20.2 | 100.0| 2.6 |
|
||||
| 2 | 30 | 21 May 2025 | 21 March 2025 | 202.06 | 20.2 | 0.0 | 0.0 | 0.0 | 20.2 | 20.2 | 20.2 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 21 June 2025 | 21 March 2025 | 181.86 | 20.2 | 0.0 | 0.0 | 0.0 | 20.2 | 20.2 | 20.2 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 21 July 2025 | 21 March 2025 | 161.66 | 20.2 | 0.0 | 0.0 | 0.0 | 20.2 | 20.2 | 20.2 | 0.0 | 0.0 |
|
||||
@@ -6777,7 +6777,7 @@ Feature: LoanAccrualActivity
|
||||
| 12 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 20.26 | 0.0 | 0.0 | 0.0 | 20.26 | 20.26 | 20.26 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 1.93 | 0.0 | 0.0 | 344.39 | 342.46 | 242.46 | 100.0 | 1.93 |
|
||||
| 342.46 | 2.6 | 0.0 | 0.0 | 345.06 | 342.46 | 242.46 | 100.0 | 2.6 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
@@ -6798,13 +6798,13 @@ Feature: LoanAccrualActivity
|
||||
Then Credit Balance Refund transaction on active loan "29 April 2025" with 100 EUR transaction amount will result an error
|
||||
When Admin sets the business date to "06 May 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
And Customer makes "AUTOPAY" repayment on "06 May 2025" with 1.93 EUR transaction amount
|
||||
And Customer makes "AUTOPAY" repayment on "06 May 2025" with 2.6 EUR transaction amount
|
||||
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
||||
Then Loan has 0 outstanding amount
|
||||
Then Loan Repayment schedule has 12 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 31 | 21 April 2025 | 06 May 2025 | 222.26 | 120.2 | 1.93 | 0.0 | 0.0 | 122.13 |122.13 | 20.2 | 101.93 | 0.0 |
|
||||
| 1 | 31 | 21 April 2025 | 06 May 2025 | 222.26 | 120.2 | 2.6 | 0.0 | 0.0 | 122.8 |122.8 | 20.2 | 102.6 | 0.0 |
|
||||
| 2 | 30 | 21 May 2025 | 21 March 2025 | 202.06 | 20.2 | 0.0 | 0.0 | 0.0 | 20.2 | 20.2 | 20.2 | 0.0 | 0.0 |
|
||||
| 3 | 31 | 21 June 2025 | 21 March 2025 | 181.86 | 20.2 | 0.0 | 0.0 | 0.0 | 20.2 | 20.2 | 20.2 | 0.0 | 0.0 |
|
||||
| 4 | 30 | 21 July 2025 | 21 March 2025 | 161.66 | 20.2 | 0.0 | 0.0 | 0.0 | 20.2 | 20.2 | 20.2 | 0.0 | 0.0 |
|
||||
@@ -6818,7 +6818,7 @@ Feature: LoanAccrualActivity
|
||||
| 12 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 20.26 | 0.0 | 0.0 | 0.0 | 20.26 | 20.26 | 20.26 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 1.93 | 0.0 | 0.0 | 344.39 | 344.39 | 242.46 | 101.93 | 0.0 |
|
||||
| 342.46 | 2.6 | 0.0 | 0.0 | 345.06 | 345.06 | 242.46 | 102.6 | 0.0 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
@@ -6836,8 +6836,7 @@ Feature: LoanAccrualActivity
|
||||
| 28 April 2025 | Accrual | 0.08 | 0.0 | 0.08 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 29 April 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 29 April 2025 | Accrual | 0.09 | 0.0 | 0.09 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 06 May 2025 | Repayment | 1.93 | 0.0 | 1.93 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 06 May 2025 | Accrual Adjustment | 0.67 | 0.0 | 0.67 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 06 May 2025 | Repayment | 2.6 | 0.0 | 2.6 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
# - CBR on closed loan is forbidden - #
|
||||
Then Credit Balance Refund transaction on active loan "06 May 2025" with 100 EUR transaction amount will result an error
|
||||
|
||||
@@ -7157,4 +7156,223 @@ Feature: LoanAccrualActivity
|
||||
| 07 May 2025 | Accrual | 0.05 | 0.0 | 0.05 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 07 May 2025 | Accrual Activity | 1.18 | 0.0 | 1.18 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
# - CBR on closed loan is forbidden - #
|
||||
Then Credit Balance Refund transaction on active loan "07 May 2025" with 72.35 EUR transaction amount will result an error
|
||||
Then Credit Balance Refund transaction on active loan "07 May 2025" with 72.35 EUR transaction amount will result an error
|
||||
|
||||
@TestRailId:C3736
|
||||
Scenario: Verify that interest is calculated after last unpaid period in case of reversed repayment made before MIR and CBR for progressive loan with downpayment
|
||||
When Admin sets the business date to "21 March 2025"
|
||||
And Admin creates a client with random data
|
||||
And 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_RECALCULATION_DAILY_EMI_360_30_MULTIDISBURSE_DOWNPAYMENT | 21 March 2025 | 242.46 | 29.99 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
|
||||
And Admin successfully approves the loan on "21 March 2025" with "242.46" amount and expected disbursement date on "21 March 2025"
|
||||
And Admin successfully disburse the loan on "21 March 2025" with "242.46" EUR transaction amount
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 |
|
||||
| 2 | 31 | 21 April 2025 | | 168.65 | 13.19 | 4.54 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 3 | 30 | 21 May 2025 | | 155.13 | 13.52 | 4.21 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 4 | 31 | 21 June 2025 | | 141.28 | 13.85 | 3.88 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 5 | 30 | 21 July 2025 | | 127.08 | 14.2 | 3.53 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 6 | 31 | 21 August 2025 | | 112.53 | 14.55 | 3.18 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 7 | 31 | 21 September 2025 | | 97.61 | 14.92 | 2.81 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 8 | 30 | 21 October 2025 | | 82.32 | 15.29 | 2.44 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 9 | 31 | 21 November 2025 | | 66.65 | 15.67 | 2.06 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 10 | 30 | 21 December 2025 | | 50.59 | 16.06 | 1.67 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 11 | 31 | 21 January 2026 | | 34.12 | 16.47 | 1.26 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 12 | 31 | 21 February 2026 | | 17.24 | 16.88 | 0.85 | 0.0 | 0.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 |
|
||||
| 13 | 28 | 21 March 2026 | | 0.0 | 17.24 | 0.43 | 0.0 | 0.0 | 17.67 | 0.0 | 0.0 | 0.0 | 17.67 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 242.46 | 30.86 | 0.0 | 0.0 | 273.32 | 0.0 | 0.0 | 0.0 | 273.32 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
And Customer makes "AUTOPAY" repayment on "21 March 2025" with 100 EUR transaction amount
|
||||
And Customer makes "MERCHANT_ISSUED_REFUND" transaction with "AUTOPAY" payment type on "21 March 2025" with 242.46 EUR transaction amount and system-generated Idempotency key
|
||||
Then Loan status will be "OVERPAID"
|
||||
Then Loan has 100 overpaid amount
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | 21 March 2025 | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 60.62 | 0.0 | 0.0 | 0.0 |
|
||||
| 2 | 31 | 21 April 2025 | 21 March 2025 | 164.11 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 3 | 30 | 21 May 2025 | 21 March 2025 | 146.38 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 4 | 31 | 21 June 2025 | 21 March 2025 | 128.65 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 5 | 30 | 21 July 2025 | 21 March 2025 | 110.92 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 21 August 2025 | 21 March 2025 | 93.19 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 7 | 31 | 21 September 2025 | 21 March 2025 | 75.46 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 8 | 30 | 21 October 2025 | 21 March 2025 | 57.73 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 9 | 31 | 21 November 2025 | 21 March 2025 | 40.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 10 | 30 | 21 December 2025 | 21 March 2025 | 22.27 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 11 | 31 | 21 January 2026 | 21 March 2025 | 4.54 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 12 | 31 | 21 February 2026 | 21 March 2025 | 0.0 | 4.54 | 0.0 | 0.0 | 0.0 | 4.54 | 4.54 | 4.54 | 0.0 | 0.0 |
|
||||
| 13 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 242.46 | 0.0 | 0.0 | 0.0 | 242.46 | 242.46 | 181.84 | 0.0 | 0.0 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | false | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 142.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
When Admin sets the business date to "28 March 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
When Admin makes Credit Balance Refund transaction on "28 March 2025" with 100 EUR transaction amount
|
||||
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
||||
Then Loan has 0 outstanding amount
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | 21 March 2025 | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 60.62 | 0.0 | 0.0 | 0.0 |
|
||||
| 2 | 31 | 21 April 2025 | 21 March 2025 | 164.11 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 3 | 30 | 21 May 2025 | 21 March 2025 | 146.38 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 4 | 31 | 21 June 2025 | 21 March 2025 | 128.65 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 5 | 30 | 21 July 2025 | 21 March 2025 | 110.92 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 21 August 2025 | 21 March 2025 | 93.19 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 7 | 31 | 21 September 2025 | 21 March 2025 | 75.46 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 8 | 30 | 21 October 2025 | 21 March 2025 | 57.73 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 9 | 31 | 21 November 2025 | 21 March 2025 | 40.0 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 10 | 30 | 21 December 2025 | 21 March 2025 | 22.27 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 11 | 31 | 21 January 2026 | 21 March 2025 | 4.54 | 17.73 | 0.0 | 0.0 | 0.0 | 17.73 | 17.73 | 17.73 | 0.0 | 0.0 |
|
||||
| 12 | 31 | 21 February 2026 | 21 March 2025 | 0.0 | 4.54 | 0.0 | 0.0 | 0.0 | 4.54 | 4.54 | 4.54 | 0.0 | 0.0 |
|
||||
| 13 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 242.46 | 0.0 | 0.0 | 0.0 | 242.46 | 242.46 | 181.84 | 0.0 | 0.0 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | false | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 142.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 28 March 2025 | Credit Balance Refund | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
When Admin sets the business date to "02 April 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
When Customer undo "1"th "Repayment" transaction made on "21 March 2025"
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | 21 March 2025 | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 60.62 | 0.0 | 0.0 | 0.0 |
|
||||
| 2 | 31 | 21 April 2025 | | 166.69 | 115.15 | 1.93 | 0.0 | 0.0 | 117.08 | 15.15 | 15.15 | 0.0 | 101.93 |
|
||||
| 3 | 30 | 21 May 2025 | 21 March 2025 | 151.54 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 4 | 31 | 21 June 2025 | 21 March 2025 | 136.39 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 5 | 30 | 21 July 2025 | 21 March 2025 | 121.24 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 21 August 2025 | 21 March 2025 | 106.09 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 7 | 31 | 21 September 2025 | 21 March 2025 | 90.94 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 8 | 30 | 21 October 2025 | 21 March 2025 | 75.79 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 9 | 31 | 21 November 2025 | 21 March 2025 | 60.64 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 10 | 30 | 21 December 2025 | 21 March 2025 | 45.49 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 11 | 31 | 21 January 2026 | 21 March 2025 | 30.34 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 12 | 31 | 21 February 2026 | 21 March 2025 | 15.19 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 13 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 15.19 | 0.0 | 0.0 | 0.0 | 15.19 | 15.19 | 15.19 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 1.93 | 0.0 | 0.0 | 344.39 | 242.46 | 181.84 | 0.0 | 101.93 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | true | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
| 28 March 2025 | Credit Balance Refund | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | true |
|
||||
When Admin sets the business date to "21 April 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | 21 March 2025 | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 60.62 | 0.0 | 0.0 | 0.0 |
|
||||
| 2 | 31 | 21 April 2025 | | 166.69 | 115.15 | 1.93 | 0.0 | 0.0 | 117.08 | 15.15 | 15.15 | 0.0 | 101.93 |
|
||||
| 3 | 30 | 21 May 2025 | 21 March 2025 | 151.54 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 4 | 31 | 21 June 2025 | 21 March 2025 | 136.39 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 5 | 30 | 21 July 2025 | 21 March 2025 | 121.24 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 21 August 2025 | 21 March 2025 | 106.09 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 7 | 31 | 21 September 2025 | 21 March 2025 | 90.94 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 8 | 30 | 21 October 2025 | 21 March 2025 | 75.79 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 9 | 31 | 21 November 2025 | 21 March 2025 | 60.64 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 10 | 30 | 21 December 2025 | 21 March 2025 | 45.49 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 11 | 31 | 21 January 2026 | 21 March 2025 | 30.34 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 12 | 31 | 21 February 2026 | 21 March 2025 | 15.19 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 13 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 15.19 | 0.0 | 0.0 | 0.0 | 15.19 | 15.19 | 15.19 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 1.93 | 0.0 | 0.0 | 344.39 | 242.46 | 181.84 | 0.0 | 101.93 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | true | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
| 28 March 2025 | Credit Balance Refund | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | true |
|
||||
| 20 April 2025 | Accrual | 1.85 | 0.0 | 1.85 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
When Admin sets the business date to "22 April 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | 21 March 2025 | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 60.62 | 0.0 | 0.0 | 0.0 |
|
||||
| 2 | 31 | 21 April 2025 | | 166.69 | 115.15 | 2.01 | 0.0 | 0.0 | 117.16 | 15.15 | 15.15 | 0.0 | 102.01 |
|
||||
| 3 | 30 | 21 May 2025 | 21 March 2025 | 151.54 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 4 | 31 | 21 June 2025 | 21 March 2025 | 136.39 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 5 | 30 | 21 July 2025 | 21 March 2025 | 121.24 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 21 August 2025 | 21 March 2025 | 106.09 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 7 | 31 | 21 September 2025 | 21 March 2025 | 90.94 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 8 | 30 | 21 October 2025 | 21 March 2025 | 75.79 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 9 | 31 | 21 November 2025 | 21 March 2025 | 60.64 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 10 | 30 | 21 December 2025 | 21 March 2025 | 45.49 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 11 | 31 | 21 January 2026 | 21 March 2025 | 30.34 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 12 | 31 | 21 February 2026 | 21 March 2025 | 15.19 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 13 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 15.19 | 0.0 | 0.0 | 0.0 | 15.19 | 15.19 | 15.19 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 2.01 | 0.0 | 0.0 | 344.47 | 242.46 | 181.84 | 0.0 | 102.01 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | true | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
| 28 March 2025 | Credit Balance Refund | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | true |
|
||||
| 20 April 2025 | Accrual | 1.85 | 0.0 | 1.85 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 21 April 2025 | Accrual | 0.08 | 0.0 | 0.08 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
When Admin sets the business date to "23 April 2025"
|
||||
And Admin runs inline COB job for Loan
|
||||
Then Loan Repayment schedule has 13 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 |
|
||||
| | | 21 March 2025 | | 242.46 | | | 0.0 | | 0.0 | 0.0 | | | |
|
||||
| 1 | 0 | 21 March 2025 | 21 March 2025 | 181.84 | 60.62 | 0.0 | 0.0 | 0.0 | 60.62 | 60.62 | 0.0 | 0.0 | 0.0 |
|
||||
| 2 | 31 | 21 April 2025 | | 166.69 | 115.15 | 2.1 | 0.0 | 0.0 | 117.25 | 15.15 | 15.15 | 0.0 | 102.1 |
|
||||
| 3 | 30 | 21 May 2025 | 21 March 2025 | 151.54 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 4 | 31 | 21 June 2025 | 21 March 2025 | 136.39 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 5 | 30 | 21 July 2025 | 21 March 2025 | 121.24 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 6 | 31 | 21 August 2025 | 21 March 2025 | 106.09 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 7 | 31 | 21 September 2025 | 21 March 2025 | 90.94 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 8 | 30 | 21 October 2025 | 21 March 2025 | 75.79 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 9 | 31 | 21 November 2025 | 21 March 2025 | 60.64 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 10 | 30 | 21 December 2025 | 21 March 2025 | 45.49 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 11 | 31 | 21 January 2026 | 21 March 2025 | 30.34 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 12 | 31 | 21 February 2026 | 21 March 2025 | 15.19 | 15.15 | 0.0 | 0.0 | 0.0 | 15.15 | 15.15 | 15.15 | 0.0 | 0.0 |
|
||||
| 13 | 28 | 21 March 2026 | 21 March 2025 | 0.0 | 15.19 | 0.0 | 0.0 | 0.0 | 15.19 | 15.19 | 15.19 | 0.0 | 0.0 |
|
||||
And Loan Repayment schedule has the following data in Total row:
|
||||
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
|
||||
| 342.46 | 2.1 | 0.0 | 0.0 | 344.56 | 242.46 | 181.84 | 0.0 | 102.1 |
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | true | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
| 28 March 2025 | Credit Balance Refund | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | true |
|
||||
| 20 April 2025 | Accrual | 1.85 | 0.0 | 1.85 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 21 April 2025 | Accrual | 0.08 | 0.0 | 0.08 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 22 April 2025 | Accrual | 0.08 | 0.0 | 0.08 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
And Customer makes "AUTOPAY" repayment on "23 April 2025" with 102.1 EUR transaction amount
|
||||
Then Loan status will be "CLOSED_OBLIGATIONS_MET"
|
||||
Then Loan has 0 outstanding amount
|
||||
And Loan Transactions tab has the following data:
|
||||
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
|
||||
| 21 March 2025 | Disbursement | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | 242.46 | false | false |
|
||||
| 21 March 2025 | Repayment | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 142.46 | true | false |
|
||||
| 21 March 2025 | Merchant Issued Refund | 242.46 | 242.46 | 0.0 | 0.0 | 0.0 | 0.0 | false | true |
|
||||
| 28 March 2025 | Credit Balance Refund | 100.0 | 100.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | true |
|
||||
| 20 April 2025 | Accrual | 1.85 | 0.0 | 1.85 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 21 April 2025 | Accrual | 0.08 | 0.0 | 0.08 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 22 April 2025 | Accrual | 0.08 | 0.0 | 0.08 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 23 April 2025 | Repayment | 102.1 | 100.0 | 2.1 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
| 23 April 2025 | Accrual | 0.09 | 0.0 | 0.09 | 0.0 | 0.0 | 0.0 | false | false |
|
||||
|
||||
+110
-41
@@ -53,6 +53,7 @@ import org.apache.fineract.portfolio.loanproduct.calc.data.ProgressiveLoanIntere
|
||||
import org.apache.fineract.portfolio.loanproduct.calc.data.RepaymentPeriod;
|
||||
import org.apache.fineract.portfolio.loanproduct.domain.LoanProductMinimumRepaymentScheduleRelatedDetail;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@@ -182,16 +183,25 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
scheduleModel.zero()).ifPresent(repaymentPeriod -> {
|
||||
calculateRateFactorForRepaymentPeriod(repaymentPeriod, scheduleModel);
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, balanceCorrectionDate);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void payInterest(ProgressiveLoanInterestScheduleModel scheduleModel, LocalDate repaymentPeriodDueDate, LocalDate transactionDate,
|
||||
Money interestAmount) {
|
||||
findRepaymentPeriod(scheduleModel, repaymentPeriodDueDate).ifPresent(rp -> rp.addPaidInterestAmount(interestAmount));
|
||||
Optional<RepaymentPeriod> repaymentPeriod = findRepaymentPeriod(scheduleModel, repaymentPeriodDueDate);
|
||||
|
||||
Optional<RepaymentPeriod> latestNotLastOpenRepaymentPeriodBeforeDate = getLatestNotLastOpenRepaymentPeriodBeforeDate(scheduleModel,
|
||||
transactionDate);
|
||||
if (latestNotLastOpenRepaymentPeriodBeforeDate.isPresent() && repaymentPeriod.equals(latestNotLastOpenRepaymentPeriodBeforeDate)) {
|
||||
calculateUnrecognizedInterestTillDateOnScheduleModelCopyAndDefer(scheduleModel,
|
||||
latestNotLastOpenRepaymentPeriodBeforeDate.get(), transactionDate);
|
||||
}
|
||||
|
||||
repaymentPeriod.ifPresent(rp -> rp.addPaidInterestAmount(interestAmount));
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, transactionDate);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,17 +221,38 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
repaymentPeriod.ifPresent(rp -> {
|
||||
// If any period total paid > calculated EMI, then set EMI to total paid -> effectively it is marked as
|
||||
// fully paid
|
||||
if (transactionDateIsBefore && rp.getTotalPaidAmount().isGreaterThan(rp.getEmiPlusCreditedAmounts())) {
|
||||
if (transactionDateIsBefore
|
||||
&& rp.getTotalPaidAmount().isGreaterThan(rp.getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest())) {
|
||||
rp.setEmi(rp.getTotalPaidAmount().minus(rp.getTotalCreditedAmount()));
|
||||
} else if (transactionDateIsBefore
|
||||
&& rp.getTotalPaidAmount().isEqualTo(rp.getOriginalEmi().add(rp.getTotalCreditedAmount()))) {
|
||||
rp.setEmi(rp.getTotalPaidAmount().minus(rp.getTotalCreditedAmount()));
|
||||
}
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, balanceCorrectionDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<RepaymentPeriod> getLatestNotLastOpenRepaymentPeriodBeforeDate(ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||
LocalDate transactionDate) {
|
||||
List<RepaymentPeriod> unpaidRepaymentPeriods = scheduleModel.repaymentPeriods() //
|
||||
.stream() //
|
||||
.filter(rp -> !rp.isFullyPaid()) //
|
||||
.toList(); //
|
||||
|
||||
if (CollectionUtils.isEmpty(unpaidRepaymentPeriods)
|
||||
|| unpaidRepaymentPeriods.getLast().equals(scheduleModel.repaymentPeriods().getLast())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
RepaymentPeriod latestNotLastOpenRepaymentPeriod = unpaidRepaymentPeriods.getLast();
|
||||
if (DateUtils.isBefore(transactionDate, latestNotLastOpenRepaymentPeriod.getDueDate())) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return Optional.of(latestNotLastOpenRepaymentPeriod);
|
||||
}
|
||||
|
||||
private void addCreditedAmountsToInterestPeriod(ProgressiveLoanInterestScheduleModel scheduleModel, LocalDate transactionDate,
|
||||
Money creditedPrincipalAmount, Money creditedInterestAmount) {
|
||||
scheduleModel.repaymentPeriods().stream().filter(checkRepaymentPeriodIsInCreditRange(scheduleModel, transactionDate)).findFirst()
|
||||
@@ -260,7 +291,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
addCreditedAmountsToInterestPeriod(scheduleModel, transactionDate, creditedPrincipalAmount, creditedInterestAmount);
|
||||
calculateRateFactorForRepaymentPeriod(repaymentPeriod, scheduleModel);
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, transactionDate);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -334,22 +365,9 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
public OutstandingDetails getOutstandingAmountsTillDate(ProgressiveLoanInterestScheduleModel scheduleModel, LocalDate targetDate) {
|
||||
MathContext mc = scheduleModel.mc();
|
||||
ProgressiveLoanInterestScheduleModel scheduleModelCopy = scheduleModel.deepCopy(mc);
|
||||
// TODO use findInterestPeriod
|
||||
scheduleModelCopy.repaymentPeriods().stream()//
|
||||
.filter(rp -> targetDate.isAfter(rp.getFromDate()) && !targetDate.isAfter(rp.getDueDate())).findFirst()//
|
||||
.flatMap(rp -> rp.getInterestPeriods().stream()//
|
||||
.filter(ip -> targetDate.isAfter(ip.getFromDate()) && !targetDate.isAfter(ip.getDueDate())) //
|
||||
.reduce((one, two) -> two))
|
||||
.ifPresent(ip -> ip.setDueDate(targetDate)); //
|
||||
|
||||
calculateRateFactorForPeriods(scheduleModelCopy.repaymentPeriods(), scheduleModelCopy);
|
||||
scheduleModelCopy.repaymentPeriods()
|
||||
.forEach(rp -> rp.getInterestPeriods().stream().filter(ip -> targetDate.isBefore(ip.getDueDate())).forEach(ip -> {
|
||||
ip.setRateFactor(BigDecimal.ZERO);
|
||||
ip.setRateFactorTillPeriodDueDate(BigDecimal.ZERO);
|
||||
}));
|
||||
calculateRateFactorForScheduleTillDateInclusive(scheduleModelCopy, targetDate);
|
||||
calculateOutstandingBalance(scheduleModelCopy);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModelCopy);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModelCopy, targetDate);
|
||||
|
||||
Money totalOutstandingPrincipal = MathUtil
|
||||
.negativeToZero(scheduleModelCopy.getTotalDuePrincipal().minus(scheduleModelCopy.getTotalPaidPrincipal()));
|
||||
@@ -421,7 +439,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
});
|
||||
calculateRateFactorForPeriods(scheduleModelCopy.repaymentPeriods(), scheduleModelCopy);
|
||||
calculateOutstandingBalance(scheduleModelCopy);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModelCopy);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModelCopy, targetDate);
|
||||
}
|
||||
return scheduleModelCopy;
|
||||
}
|
||||
@@ -443,37 +461,63 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
calculateEMIOnNewModelAndMerge(relatedRepaymentPeriods, scheduleModel, operation);
|
||||
}
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, calculateFromRepaymentPeriodDueDate);
|
||||
if (onlyOnActualModelShouldApply && (scheduleModel.loanTermVariations() == null
|
||||
|| scheduleModel.loanTermVariations().get(LoanTermVariationType.DUE_DATE) == null)) {
|
||||
checkAndAdjustEmiIfNeededOnRelatedRepaymentPeriods(scheduleModel, relatedRepaymentPeriods);
|
||||
}
|
||||
}
|
||||
|
||||
private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestScheduleModel scheduleModel) {
|
||||
MathContext mc = scheduleModel.mc();
|
||||
Money totalDueInterest = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getDueInterest).reduce(scheduleModel.zero(),
|
||||
(m1, m2) -> m1.plus(m2, mc)); // 1.46
|
||||
Money totalEMI = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getEmiPlusCreditedAmounts)
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 101.48
|
||||
Money totalDisbursedAmount = scheduleModel.repaymentPeriods().stream()
|
||||
.flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getDisbursementAmount))
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 100
|
||||
Money totalCapitalizedIncome = scheduleModel.repaymentPeriods().stream()
|
||||
.flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getCapitalizedIncomePrincipal))
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 100
|
||||
|
||||
Money diff = totalDisbursedAmount.plus(totalCapitalizedIncome, mc).plus(scheduleModel.getTotalCreditedPrincipal(), mc)
|
||||
.plus(totalDueInterest, mc).minus(totalEMI, mc);
|
||||
private void calculateLastUnpaidRepaymentPeriodEMI(ProgressiveLoanInterestScheduleModel scheduleModel, LocalDate tillDate) {
|
||||
Optional<RepaymentPeriod> findLastUnpaidRepaymentPeriod = scheduleModel.repaymentPeriods().stream().filter(rp -> !rp.isFullyPaid())
|
||||
.reduce((first, second) -> second);
|
||||
|
||||
findLastUnpaidRepaymentPeriod.ifPresent(repaymentPeriod -> {
|
||||
repaymentPeriod.setFutureUnrecognizedInterest(scheduleModel.zero());
|
||||
scheduleModel.repaymentPeriods().forEach(rp -> {
|
||||
rp.setInterestMoved(false);
|
||||
});
|
||||
|
||||
MathContext mc = scheduleModel.mc();
|
||||
Money totalDueInterest = scheduleModel.repaymentPeriods().stream().map(RepaymentPeriod::getDueInterest)
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 1.46
|
||||
Money totalEMI = scheduleModel.repaymentPeriods().stream()
|
||||
.map(RepaymentPeriod::getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest)
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 101.48
|
||||
Money totalDisbursedAmount = scheduleModel.repaymentPeriods().stream()
|
||||
.flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getDisbursementAmount))
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 100
|
||||
Money totalCapitalizedIncome = scheduleModel.repaymentPeriods().stream()
|
||||
.flatMap(rp -> rp.getInterestPeriods().stream().map(InterestPeriod::getCapitalizedIncomePrincipal))
|
||||
.reduce(scheduleModel.zero(), (m1, m2) -> m1.plus(m2, mc)); // 100
|
||||
|
||||
Money diff = totalDisbursedAmount.plus(totalCapitalizedIncome, mc).plus(scheduleModel.getTotalCreditedPrincipal(), mc)
|
||||
.plus(totalDueInterest, mc).minus(totalEMI, mc);
|
||||
|
||||
repaymentPeriod.setEmi(repaymentPeriod.getEmi().add(diff, mc));
|
||||
if (repaymentPeriod.getEmi()
|
||||
.isLessThan(repaymentPeriod.getTotalPaidAmount().minus(repaymentPeriod.getTotalCreditedAmount(), mc))) {
|
||||
repaymentPeriod.setEmi(repaymentPeriod.getTotalPaidAmount().minus(repaymentPeriod.getTotalCreditedAmount(), mc));
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, tillDate);
|
||||
}
|
||||
|
||||
calculateUnrecognizedInterestTillDateOnScheduleModelCopyAndDefer(scheduleModel, repaymentPeriod, tillDate);
|
||||
});
|
||||
}
|
||||
|
||||
private void calculateUnrecognizedInterestTillDateOnScheduleModelCopyAndDefer(ProgressiveLoanInterestScheduleModel scheduleModel,
|
||||
RepaymentPeriod repaymentPeriod, LocalDate tillDate) {
|
||||
MathContext mc = scheduleModel.mc();
|
||||
ProgressiveLoanInterestScheduleModel scheduleModelCopy = scheduleModel.deepCopy(mc);
|
||||
calculateRateFactorForScheduleTillDateInclusive(scheduleModelCopy, tillDate);
|
||||
Optional<RepaymentPeriod> futureUnrecognizedInterestPeriod = getPeriodWithUnrecognizedInterest(repaymentPeriod, scheduleModelCopy);
|
||||
|
||||
futureUnrecognizedInterestPeriod.ifPresent(period -> {
|
||||
repaymentPeriod.setFutureUnrecognizedInterest(period.getUnrecognizedInterest());
|
||||
scheduleModel.repaymentPeriods().stream().filter(rp -> rp.getDueDate().isAfter(repaymentPeriod.getDueDate())) //
|
||||
.forEach(rp -> {
|
||||
rp.setInterestMoved(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -509,7 +553,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
}
|
||||
});
|
||||
calculateOutstandingBalance(newScheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(newScheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(newScheduleModel, relatedPeriodsFirstDueDate);
|
||||
if (!getEmiAdjustment(newScheduleModel.repaymentPeriods()).hasLessEmiDifference(emiAdjustment)) {
|
||||
break;
|
||||
}
|
||||
@@ -861,6 +905,31 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
return new EmiAdjustment(repaymentPeriods.get(0).getEmi(), repaymentPeriods.get(0).getEmi().copy(0.0), repaymentPeriods, 0);
|
||||
}
|
||||
|
||||
private void calculateRateFactorForScheduleTillDateInclusive(ProgressiveLoanInterestScheduleModel scheduleModelCopy,
|
||||
LocalDate targetDate) {
|
||||
scheduleModelCopy.findRepaymentPeriod(targetDate).flatMap(rp -> rp.findInterestPeriod(targetDate))
|
||||
.ifPresent(ip -> ip.setDueDate(targetDate));
|
||||
|
||||
calculateRateFactorForPeriods(scheduleModelCopy.repaymentPeriods(), scheduleModelCopy);
|
||||
|
||||
scheduleModelCopy.repaymentPeriods()
|
||||
.forEach(rp -> rp.getInterestPeriods().stream().filter(ip -> targetDate.isBefore(ip.getDueDate())).forEach(ip -> {
|
||||
ip.setRateFactor(BigDecimal.ZERO);
|
||||
ip.setRateFactorTillPeriodDueDate(BigDecimal.ZERO);
|
||||
}));
|
||||
}
|
||||
|
||||
private Optional<RepaymentPeriod> getPeriodWithUnrecognizedInterest(RepaymentPeriod lastUnpaidRepaymentPeriod,
|
||||
ProgressiveLoanInterestScheduleModel scheduleModelCopy) {
|
||||
for (RepaymentPeriod period : scheduleModelCopy.repaymentPeriods().reversed()) {
|
||||
if (MathUtil.isGreaterThanZero(period.getUnrecognizedInterest())
|
||||
&& period.getDueDate().isAfter(lastUnpaidRepaymentPeriod.getDueDate())) {
|
||||
return Optional.of(period);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Rate Factor Product from rate factors
|
||||
*/
|
||||
@@ -1082,7 +1151,7 @@ public final class ProgressiveEMICalculator implements EMICalculator {
|
||||
final List<RepaymentPeriod> relatedRepaymentPeriods = scheduleModel.getRelatedRepaymentPeriods(startDate);
|
||||
calculateRateFactorForPeriods(relatedRepaymentPeriods, scheduleModel);
|
||||
calculateOutstandingBalance(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel);
|
||||
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, startDate);
|
||||
}
|
||||
|
||||
private long getUncountablePeriods(final List<RepaymentPeriod> relatedRepaymentPeriods, final Money originalEmi) {
|
||||
|
||||
+1
-1
@@ -145,7 +145,7 @@ public class InterestPeriod implements Comparable<InterestPeriod> {
|
||||
.multiply(getRateFactorTillPeriodDueDate(), mc) //
|
||||
.divide(BigDecimal.valueOf(lengthTillPeriodDueDate), mc) //
|
||||
.multiply(BigDecimal.valueOf(getLength()), mc); //
|
||||
return MathUtil.negativeToZero(MathUtil.add(creditedInterest.getAmount(), interestDueTillRepaymentDueDate, mc));
|
||||
return MathUtil.negativeToZero(MathUtil.add(mc, creditedInterest.getAmount(), interestDueTillRepaymentDueDate));
|
||||
}
|
||||
|
||||
public long getLength() {
|
||||
|
||||
+33
-20
@@ -60,6 +60,9 @@ public final class RepaymentPeriod {
|
||||
private Money paidPrincipal;
|
||||
@Getter
|
||||
private Money paidInterest;
|
||||
@Setter
|
||||
@Getter
|
||||
private Money futureUnrecognizedInterest;
|
||||
|
||||
@JsonExclude
|
||||
private final MathContext mc;
|
||||
@@ -72,9 +75,12 @@ public final class RepaymentPeriod {
|
||||
private Memo<Money> dueInterestCalculation;
|
||||
@JsonExclude
|
||||
private Memo<Money> outstandingBalanceCalculation;
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean isInterestMoved = false;
|
||||
|
||||
private RepaymentPeriod(RepaymentPeriod previous, LocalDate fromDate, LocalDate dueDate, List<InterestPeriod> interestPeriods,
|
||||
Money emi, Money originalEmi, Money paidPrincipal, Money paidInterest, MathContext mc) {
|
||||
Money emi, Money originalEmi, Money paidPrincipal, Money paidInterest, Money futureUnrecognizedInterest, MathContext mc) {
|
||||
this.previous = previous;
|
||||
this.fromDate = fromDate;
|
||||
this.dueDate = dueDate;
|
||||
@@ -83,17 +89,18 @@ public final class RepaymentPeriod {
|
||||
this.originalEmi = originalEmi;
|
||||
this.paidPrincipal = paidPrincipal;
|
||||
this.paidInterest = paidInterest;
|
||||
this.futureUnrecognizedInterest = futureUnrecognizedInterest;
|
||||
this.mc = mc;
|
||||
}
|
||||
|
||||
public static RepaymentPeriod empty(RepaymentPeriod previous, MathContext mc) {
|
||||
return new RepaymentPeriod(previous, null, null, new ArrayList<>(), null, null, null, null, mc);
|
||||
return new RepaymentPeriod(previous, null, null, new ArrayList<>(), null, null, null, null, null, mc);
|
||||
}
|
||||
|
||||
public static RepaymentPeriod create(RepaymentPeriod previous, LocalDate fromDate, LocalDate dueDate, Money emi, MathContext mc) {
|
||||
final Money zero = emi.zero();
|
||||
final RepaymentPeriod newRepaymentPeriod = new RepaymentPeriod(previous, fromDate, dueDate, new ArrayList<>(), emi, emi, zero, zero,
|
||||
mc);
|
||||
zero, mc);
|
||||
// There is always at least 1 interest period, by default with same from-due date as repayment period
|
||||
newRepaymentPeriod.interestPeriods.add(InterestPeriod.withEmptyAmounts(newRepaymentPeriod, fromDate, dueDate));
|
||||
return newRepaymentPeriod;
|
||||
@@ -102,7 +109,7 @@ public final class RepaymentPeriod {
|
||||
public static RepaymentPeriod copy(RepaymentPeriod previous, RepaymentPeriod repaymentPeriod, MathContext mc) {
|
||||
final RepaymentPeriod newRepaymentPeriod = new RepaymentPeriod(previous, repaymentPeriod.fromDate, repaymentPeriod.dueDate,
|
||||
new ArrayList<>(), repaymentPeriod.emi, repaymentPeriod.originalEmi, repaymentPeriod.paidPrincipal,
|
||||
repaymentPeriod.paidInterest, mc);
|
||||
repaymentPeriod.paidInterest, repaymentPeriod.futureUnrecognizedInterest, mc);
|
||||
// There is always at least 1 interest period, by default with same from-due date as repayment period
|
||||
for (InterestPeriod interestPeriod : repaymentPeriod.interestPeriods) {
|
||||
newRepaymentPeriod.interestPeriods.add(InterestPeriod.copy(newRepaymentPeriod, interestPeriod, mc));
|
||||
@@ -113,7 +120,7 @@ public final class RepaymentPeriod {
|
||||
public static RepaymentPeriod copyWithoutPaidAmounts(RepaymentPeriod previous, RepaymentPeriod repaymentPeriod, MathContext mc) {
|
||||
final Money zero = repaymentPeriod.emi.zero();
|
||||
final RepaymentPeriod newRepaymentPeriod = new RepaymentPeriod(previous, repaymentPeriod.fromDate, repaymentPeriod.dueDate,
|
||||
new ArrayList<>(), repaymentPeriod.emi, repaymentPeriod.originalEmi, zero, zero, mc);
|
||||
new ArrayList<>(), repaymentPeriod.emi, repaymentPeriod.originalEmi, zero, zero, zero, mc);
|
||||
// There is always at least 1 interest period, by default with same from-due date as repayment period
|
||||
for (InterestPeriod interestPeriod : repaymentPeriod.interestPeriods) {
|
||||
var interestPeriodCopy = InterestPeriod.copy(newRepaymentPeriod, interestPeriod);
|
||||
@@ -154,14 +161,19 @@ public final class RepaymentPeriod {
|
||||
public Money getCalculatedDueInterest() {
|
||||
if (calculatedDueInterestCalculation == null) {
|
||||
calculatedDueInterestCalculation = Memo.of(this::calculateCalculatedDueInterest,
|
||||
() -> new Object[] { this.previous, this.interestPeriods });
|
||||
() -> new Object[] { this.previous, this.interestPeriods, this.futureUnrecognizedInterest, this.isInterestMoved });
|
||||
}
|
||||
return calculatedDueInterestCalculation.get();
|
||||
}
|
||||
|
||||
private Money calculateCalculatedDueInterest() {
|
||||
Money calculatedDueInterest = Money.of(emi.getCurrencyData(),
|
||||
getInterestPeriods().stream().map(InterestPeriod::getCalculatedDueInterest).reduce(BigDecimal.ZERO, BigDecimal::add), mc);
|
||||
Money calculatedDueInterest = getZero(mc);
|
||||
if (!isInterestMoved) {
|
||||
calculatedDueInterest = Money.of(emi.getCurrencyData(),
|
||||
getInterestPeriods().stream().map(InterestPeriod::getCalculatedDueInterest).reduce(BigDecimal.ZERO, BigDecimal::add),
|
||||
mc);
|
||||
}
|
||||
calculatedDueInterest = calculatedDueInterest.add(getFutureUnrecognizedInterest(), mc);
|
||||
if (getPrevious().isPresent()) {
|
||||
calculatedDueInterest = calculatedDueInterest.add(getPrevious().get().getUnrecognizedInterest(), mc);
|
||||
}
|
||||
@@ -176,22 +188,22 @@ public final class RepaymentPeriod {
|
||||
public Money getDueInterest() {
|
||||
if (dueInterestCalculation == null) {
|
||||
// Due interest might be the maximum paid if there is pay-off or early repayment
|
||||
dueInterestCalculation = Memo
|
||||
.of(() -> MathUtil.max(
|
||||
getPaidPrincipal().isGreaterThan(getCalculatedDuePrincipal()) ? getPaidInterest()
|
||||
: MathUtil.min(getCalculatedDueInterest(), getEmiPlusCreditedAmounts(), false),
|
||||
getPaidInterest(), false), () -> new Object[] { paidPrincipal, paidInterest, interestPeriods });
|
||||
dueInterestCalculation = Memo.of(
|
||||
() -> MathUtil.max(getPaidPrincipal().isGreaterThan(getCalculatedDuePrincipal()) ? getPaidInterest()
|
||||
: MathUtil.min(getCalculatedDueInterest(), getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest(), false),
|
||||
getPaidInterest(), false),
|
||||
() -> new Object[] { paidPrincipal, paidInterest, interestPeriods, futureUnrecognizedInterest });
|
||||
}
|
||||
return dueInterestCalculation.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives back an EMI amount which includes credited amounts as well
|
||||
* Gives back an EMI amount which includes credited amounts and future unrecognized interest as well
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Money getEmiPlusCreditedAmounts() {
|
||||
return getEmi().plus(getTotalCreditedAmount(), mc); //
|
||||
public Money getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest() {
|
||||
return getEmi().plus(getTotalCreditedAmount(), mc).plus(getFutureUnrecognizedInterest(), mc); //
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +212,7 @@ public final class RepaymentPeriod {
|
||||
* @return
|
||||
*/
|
||||
public Money getCalculatedDuePrincipal() {
|
||||
return MathUtil.negativeToZero(getEmiPlusCreditedAmounts().minus(getCalculatedDueInterest(), mc), mc);
|
||||
return MathUtil.negativeToZero(getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest().minus(getCalculatedDueInterest(), mc), mc);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,8 +255,9 @@ public final class RepaymentPeriod {
|
||||
*/
|
||||
public Money getDuePrincipal() {
|
||||
// Due principal might be the maximum paid if there is pay-off or early repayment
|
||||
return MathUtil.max(MathUtil.negativeToZero(getEmiPlusCreditedAmounts().minus(getDueInterest(), mc), mc), getPaidPrincipal(),
|
||||
false);
|
||||
return MathUtil.max(
|
||||
MathUtil.negativeToZero(getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest().minus(getDueInterest(), mc), mc),
|
||||
getPaidPrincipal(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,7 +279,7 @@ public final class RepaymentPeriod {
|
||||
}
|
||||
|
||||
public boolean isFullyPaid() {
|
||||
return getEmiPlusCreditedAmounts().isEqualTo(getTotalPaidAmount());
|
||||
return getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest().isEqualTo(getTotalPaidAmount());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user