Merge pull request #5824
FINERACT-2421: reschedule after reage schedule and balance fix
diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
index ba11f3a..965b314 100644
--- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
+++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/LoanProductsRequestFactory.java
@@ -1053,7 +1053,7 @@
.maxPrincipal(10000.0)//
.minNumberOfRepayments(1)//
.numberOfRepayments(4)//
- .maxNumberOfRepayments(30)//
+ .maxNumberOfRepayments(100)//
.isLinkedToFloatingInterestRates(false)//
.minInterestRatePerPeriod((double) 0)//
.interestRatePerPeriod((double) 12)//
diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment-Part4.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment-Part4.feature
index 8c09d32..0d32cd3 100644
--- a/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment-Part4.feature
+++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment-Part4.feature
@@ -6,40 +6,40 @@
When Admin sets the business date to "26 October 2025"
When Admin creates a client with random data
When Admin creates a fully customized loan with loan product`s charges and 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_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 26 October 2025 | 1 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 1 | MONTHS | 1 | MONTHS | 1 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
+ | 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_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 26 October 2025 | 1 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 1 | MONTHS | 1 | MONTHS | 1 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "26 October 2025" with "1" amount and expected disbursement date on "26 October 2025"
Then Loan Repayment schedule has 1 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 |
- | | | 26 October 2025 | | 1.0 | | | 0.0 | | 0.0 | | | | 0.0 |
- | 1 | 31 | 26 November 2025 | | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 26 October 2025 | | 1.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 26 November 2025 | | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
When Admin successfully disburse the loan on "26 October 2025" with "0.4" EUR transaction amount
Then Loan Repayment schedule has 1 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 |
- | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 26 November 2025 | | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 26 November 2025 | | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
- | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
When Admin sets the business date to "27 October 2025"
When Loan Pay-off is made on "27 October 2025"
Then Loan Repayment schedule has 1 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 |
- | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 26 November 2025 | 27 October 2025 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 26 November 2025 | 27 October 2025 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
- | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
- | 27 October 2025 | Repayment | 0.4 | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
+ | 27 October 2025 | Repayment | 0.4 | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
@TestRailId:C4354
@@ -47,43 +47,43 @@
When Admin sets the business date to "26 October 2025"
When Admin creates a client with random data
When Admin creates a fully customized loan with loan product`s charges and 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_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 26 October 2025 | 1 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 2 | MONTHS | 1 | MONTHS | 2 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
+ | 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_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 26 October 2025 | 1 | 0 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 2 | MONTHS | 1 | MONTHS | 2 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "26 October 2025" with "1" amount and expected disbursement date on "26 October 2025"
Then Loan Repayment schedule has 2 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 |
- | | | 26 October 2025 | | 1.0 | | | 0.0 | | 0.0 | | | | 0.0 |
- | 1 | 31 | 26 November 2025 | | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
- | 2 | 30 | 26 December 2025 | | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 26 October 2025 | | 1.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 26 November 2025 | | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
+ | 2 | 30 | 26 December 2025 | | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 1.0 |
When Admin successfully disburse the loan on "26 October 2025" with "0.4" EUR transaction amount
Then Loan Repayment schedule has 2 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 |
- | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 26 November 2025 | | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
- | 2 | 30 | 26 December 2025 | 26 October 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 26 November 2025 | | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
+ | 2 | 30 | 26 December 2025 | 26 October 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
- | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
When Admin sets the business date to "27 October 2025"
When Loan Pay-off is made on "27 October 2025"
Then Loan Repayment schedule has 2 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 |
- | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 26 November 2025 | 27 October 2025 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
- | 2 | 30 | 26 December 2025 | 26 October 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 26 October 2025 | | 0.4 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 26 November 2025 | 27 October 2025 | 0.0 | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
+ | 2 | 30 | 26 December 2025 | 26 October 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 0.4 | 0.0 | 0.0 | 0.0 | 0.4 | 0.4 | 0.4 | 0.0 | 0.0 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
- | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
- | 27 October 2025 | Repayment | 0.4 | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 26 October 2025 | Disbursement | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | 0.4 | false | false |
+ | 27 October 2025 | Repayment | 0.4 | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
@TestRailId:C4648
@@ -135,176 +135,176 @@
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
@TestRailId:C4683 @AdvancedPaymentAllocation @ProgressiveLoanSchedule
- Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical, prepayment with NEXT_INSTALLMENT strategy
+ Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical prepayment with NEXT_INSTALLMENT strategy
When Admin sets the business date to "23 February 2026"
When Admin creates a client with random data
When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
When Admin creates a fully customized loan with the following data:
- | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
- | LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 01 January 2026 | 25000000 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
+ | 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_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 01 January 2026 | 25000000 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2026" with "25000000" amount and expected disbursement date on "01 January 2026"
When Admin successfully disburse the loan on "01 January 2026" with "25000000" EUR transaction 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 |
- | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 01 February 2026 | | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 2 | 28 | 01 March 2026 | | 21039772.25 | 1994381.56 | 226259.15 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 3 | 31 | 01 April 2026 | | 19033564.29 | 2006207.96 | 214432.75 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 4 | 30 | 01 May 2026 | | 17000651.89 | 2032912.4 | 187728.31 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 5 | 31 | 01 June 2026 | | 14953278.1 | 2047373.79 | 173266.92 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 6 | 30 | 01 July 2026 | | 12880121.78 | 2073156.32 | 147484.39 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 7 | 31 | 01 August 2026 | | 10790752.45 | 2089369.33 | 131271.38 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 8 | 31 | 01 September 2026 | | 8680088.72 | 2110663.73 | 109976.98 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 9 | 30 | 01 October 2026 | | 6545059.84 | 2135028.88 | 85611.83 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 10 | 31 | 01 November 2026 | | 4391124.95 | 2153934.89 | 66705.82 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 11 | 30 | 01 December 2026 | | 2213793.97 | 2177330.98 | 43309.73 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 12 | 31 | 01 January 2027 | | 0.0 | 2213793.97 | 22562.5 | 0.0 | 0.0 | 2236356.47 | 0.0 | 0.0 | 0.0 | 2236356.47 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2026 | | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 2 | 28 | 01 March 2026 | | 21039772.25 | 1994381.56 | 226259.15 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 3 | 31 | 01 April 2026 | | 19033564.29 | 2006207.96 | 214432.75 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 4 | 30 | 01 May 2026 | | 17000651.89 | 2032912.4 | 187728.31 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 5 | 31 | 01 June 2026 | | 14953278.1 | 2047373.79 | 173266.92 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 6 | 30 | 01 July 2026 | | 12880121.78 | 2073156.32 | 147484.39 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 7 | 31 | 01 August 2026 | | 10790752.45 | 2089369.33 | 131271.38 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 8 | 31 | 01 September 2026 | | 8680088.72 | 2110663.73 | 109976.98 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 9 | 30 | 01 October 2026 | | 6545059.84 | 2135028.88 | 85611.83 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 10 | 31 | 01 November 2026 | | 4391124.95 | 2153934.89 | 66705.82 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 11 | 30 | 01 December 2026 | | 2213793.97 | 2177330.98 | 43309.73 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 12 | 31 | 01 January 2027 | | 0.0 | 2213793.97 | 22562.5 | 0.0 | 0.0 | 2236356.47 | 0.0 | 0.0 | 0.0 | 2236356.47 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 25000000.0 | 1663404.28 | 0.0 | 0.0 | 26663404.28 | 0.0 | 0.0 | 0.0 | 26663404.28 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 25000000.0 | 1663404.28 | 0.0 | 0.0 | 26663404.28 | 0.0 | 0.0 | 0.0 | 26663404.28 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
- | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
When Loan Pay-off is made on "23 February 2026"
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 |
- | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 01 February 2026 | 23 February 2026 | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 0.0 | 2220640.71 | 0.0 |
- | 2 | 28 | 01 March 2026 | 23 February 2026 | 20813513.1 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 3 | 31 | 01 April 2026 | 23 February 2026 | 18592872.39 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 4 | 30 | 01 May 2026 | 23 February 2026 | 16372231.68 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 5 | 31 | 01 June 2026 | 23 February 2026 | 14151590.97 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 6 | 30 | 01 July 2026 | 23 February 2026 | 11930950.26 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 7 | 31 | 01 August 2026 | 23 February 2026 | 9710309.55 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 8 | 31 | 01 September 2026 | 23 February 2026 | 7489668.84 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 9 | 30 | 01 October 2026 | 23 February 2026 | 5269028.13 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 10 | 31 | 01 November 2026 | 23 February 2026 | 3048387.42 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 11 | 30 | 01 December 2026 | 23 February 2026 | 827746.71 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 12 | 31 | 01 January 2027 | 23 February 2026 | 0.0 | 827746.71 | 180821.92 | 0.0 | 0.0 | 1008568.63 | 1008568.63 | 1008568.63 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2026 | 23 February 2026 | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 0.0 | 2220640.71 | 0.0 |
+ | 2 | 28 | 01 March 2026 | 23 February 2026 | 20813513.1 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 3 | 31 | 01 April 2026 | 23 February 2026 | 18592872.39 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 4 | 30 | 01 May 2026 | 23 February 2026 | 16372231.68 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 5 | 31 | 01 June 2026 | 23 February 2026 | 14151590.97 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 6 | 30 | 01 July 2026 | 23 February 2026 | 11930950.26 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 7 | 31 | 01 August 2026 | 23 February 2026 | 9710309.55 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 8 | 31 | 01 September 2026 | 23 February 2026 | 7489668.84 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 9 | 30 | 01 October 2026 | 23 February 2026 | 5269028.13 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 10 | 31 | 01 November 2026 | 23 February 2026 | 3048387.42 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 11 | 30 | 01 December 2026 | 23 February 2026 | 827746.71 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 12 | 31 | 01 January 2027 | 23 February 2026 | 0.0 | 827746.71 | 180821.92 | 0.0 | 0.0 | 1008568.63 | 1008568.63 | 1008568.63 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 25000000.0 | 435616.44 | 0.0 | 0.0 | 25435616.44 | 25435616.44 | 23214975.73 | 2220640.71 | 0.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 25000000.0 | 435616.44 | 0.0 | 0.0 | 25435616.44 | 25435616.44 | 23214975.73 | 2220640.71 | 0.0 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
- | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
- | 23 February 2026 | Repayment | 25435616.44 | 25000000.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
- | 23 February 2026 | Accrual | 435616.44 | 0.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
+ | 23 February 2026 | Repayment | 25435616.44 | 25000000.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
+ | 23 February 2026 | Accrual | 435616.44 | 0.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
@TestRailId:C4684 @AdvancedPaymentAllocation @ProgressiveLoanSchedule
- Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical, prepayment with LAST_INSTALLMENT strategy
+ Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical prepayment with LAST_INSTALLMENT strategy
When Admin sets the business date to "23 February 2026"
When Admin creates a client with random data
When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "LAST_INSTALLMENT" future installment allocation rule
When Admin creates a fully customized loan with the following data:
- | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
- | LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 01 January 2026 | 25000000 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
+ | 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_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 01 January 2026 | 25000000 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2026" with "25000000" amount and expected disbursement date on "01 January 2026"
When Admin successfully disburse the loan on "01 January 2026" with "25000000" EUR transaction 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 |
- | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 01 February 2026 | | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 2 | 28 | 01 March 2026 | | 21039772.25 | 1994381.56 | 226259.15 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 3 | 31 | 01 April 2026 | | 19033564.29 | 2006207.96 | 214432.75 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 4 | 30 | 01 May 2026 | | 17000651.89 | 2032912.4 | 187728.31 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 5 | 31 | 01 June 2026 | | 14953278.1 | 2047373.79 | 173266.92 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 6 | 30 | 01 July 2026 | | 12880121.78 | 2073156.32 | 147484.39 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 7 | 31 | 01 August 2026 | | 10790752.45 | 2089369.33 | 131271.38 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 8 | 31 | 01 September 2026 | | 8680088.72 | 2110663.73 | 109976.98 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 9 | 30 | 01 October 2026 | | 6545059.84 | 2135028.88 | 85611.83 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 10 | 31 | 01 November 2026 | | 4391124.95 | 2153934.89 | 66705.82 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 11 | 30 | 01 December 2026 | | 2213793.97 | 2177330.98 | 43309.73 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 12 | 31 | 01 January 2027 | | 0.0 | 2213793.97 | 22562.5 | 0.0 | 0.0 | 2236356.47 | 0.0 | 0.0 | 0.0 | 2236356.47 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2026 | | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 2 | 28 | 01 March 2026 | | 21039772.25 | 1994381.56 | 226259.15 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 3 | 31 | 01 April 2026 | | 19033564.29 | 2006207.96 | 214432.75 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 4 | 30 | 01 May 2026 | | 17000651.89 | 2032912.4 | 187728.31 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 5 | 31 | 01 June 2026 | | 14953278.1 | 2047373.79 | 173266.92 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 6 | 30 | 01 July 2026 | | 12880121.78 | 2073156.32 | 147484.39 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 7 | 31 | 01 August 2026 | | 10790752.45 | 2089369.33 | 131271.38 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 8 | 31 | 01 September 2026 | | 8680088.72 | 2110663.73 | 109976.98 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 9 | 30 | 01 October 2026 | | 6545059.84 | 2135028.88 | 85611.83 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 10 | 31 | 01 November 2026 | | 4391124.95 | 2153934.89 | 66705.82 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 11 | 30 | 01 December 2026 | | 2213793.97 | 2177330.98 | 43309.73 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 12 | 31 | 01 January 2027 | | 0.0 | 2213793.97 | 22562.5 | 0.0 | 0.0 | 2236356.47 | 0.0 | 0.0 | 0.0 | 2236356.47 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 25000000.0 | 1663404.28 | 0.0 | 0.0 | 26663404.28 | 0.0 | 0.0 | 0.0 | 26663404.28 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 25000000.0 | 1663404.28 | 0.0 | 0.0 | 26663404.28 | 0.0 | 0.0 | 0.0 | 26663404.28 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
- | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
When Loan Pay-off is made on "23 February 2026"
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 |
- | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 01 February 2026 | 23 February 2026 | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 0.0 | 2220640.71 | 0.0 |
- | 2 | 28 | 01 March 2026 | 23 February 2026 | 22206407.14 | 827746.67 | 180821.92 | 0.0 | 0.0 | 1008568.59 | 1008568.59 | 1008568.59 | 0.0 | 0.0 |
- | 3 | 31 | 01 April 2026 | 23 February 2026 | 19985766.43 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 4 | 30 | 01 May 2026 | 23 February 2026 | 17765125.72 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 5 | 31 | 01 June 2026 | 23 February 2026 | 15544485.01 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 6 | 30 | 01 July 2026 | 23 February 2026 | 13323844.3 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 7 | 31 | 01 August 2026 | 23 February 2026 | 11103203.59 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 8 | 31 | 01 September 2026 | 23 February 2026 | 8882562.88 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 9 | 30 | 01 October 2026 | 23 February 2026 | 6661922.17 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 10 | 31 | 01 November 2026 | 23 February 2026 | 4441281.46 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 11 | 30 | 01 December 2026 | 23 February 2026 | 2220640.75 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 12 | 31 | 01 January 2027 | 23 February 2026 | 0.0 | 2220640.75 | 0.0 | 0.0 | 0.0 | 2220640.75 | 2220640.75 | 2220640.75 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2026 | 23 February 2026 | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 0.0 | 2220640.71 | 0.0 |
+ | 2 | 28 | 01 March 2026 | 23 February 2026 | 22206407.14 | 827746.67 | 180821.92 | 0.0 | 0.0 | 1008568.59 | 1008568.59 | 1008568.59 | 0.0 | 0.0 |
+ | 3 | 31 | 01 April 2026 | 23 February 2026 | 19985766.43 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 4 | 30 | 01 May 2026 | 23 February 2026 | 17765125.72 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 5 | 31 | 01 June 2026 | 23 February 2026 | 15544485.01 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 6 | 30 | 01 July 2026 | 23 February 2026 | 13323844.3 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 7 | 31 | 01 August 2026 | 23 February 2026 | 11103203.59 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 8 | 31 | 01 September 2026 | 23 February 2026 | 8882562.88 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 9 | 30 | 01 October 2026 | 23 February 2026 | 6661922.17 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 10 | 31 | 01 November 2026 | 23 February 2026 | 4441281.46 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 11 | 30 | 01 December 2026 | 23 February 2026 | 2220640.75 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 12 | 31 | 01 January 2027 | 23 February 2026 | 0.0 | 2220640.75 | 0.0 | 0.0 | 0.0 | 2220640.75 | 2220640.75 | 2220640.75 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 25000000.0 | 435616.44 | 0.0 | 0.0 | 25435616.44 | 25435616.44 | 23214975.73 | 2220640.71 | 0.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 25000000.0 | 435616.44 | 0.0 | 0.0 | 25435616.44 | 25435616.44 | 23214975.73 | 2220640.71 | 0.0 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
- | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
- | 23 February 2026 | Repayment | 25435616.44 | 25000000.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
- | 23 February 2026 | Accrual | 435616.44 | 0.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
+ | 23 February 2026 | Repayment | 25435616.44 | 25000000.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
+ | 23 February 2026 | Accrual | 435616.44 | 0.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
@TestRailId:C4685 @AdvancedPaymentAllocation @ProgressiveLoanSchedule
- Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical, prepayment with NEXT_LAST_INSTALLMENT strategy
+ Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical prepayment with NEXT_LAST_INSTALLMENT strategy
When Admin sets the business date to "23 February 2026"
When Admin creates a client with random data
When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_LAST_INSTALLMENT" future installment allocation rule
When Admin creates a fully customized loan with the following data:
- | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
- | LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 01 January 2026 | 25000000 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
+ | 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_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 01 January 2026 | 25000000 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 12 | MONTHS | 1 | MONTHS | 12 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 January 2026" with "25000000" amount and expected disbursement date on "01 January 2026"
When Admin successfully disburse the loan on "01 January 2026" with "25000000" EUR transaction 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 |
- | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 01 February 2026 | | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 2 | 28 | 01 March 2026 | | 21039772.25 | 1994381.56 | 226259.15 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 3 | 31 | 01 April 2026 | | 19033564.29 | 2006207.96 | 214432.75 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 4 | 30 | 01 May 2026 | | 17000651.89 | 2032912.4 | 187728.31 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 5 | 31 | 01 June 2026 | | 14953278.1 | 2047373.79 | 173266.92 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 6 | 30 | 01 July 2026 | | 12880121.78 | 2073156.32 | 147484.39 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 7 | 31 | 01 August 2026 | | 10790752.45 | 2089369.33 | 131271.38 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 8 | 31 | 01 September 2026 | | 8680088.72 | 2110663.73 | 109976.98 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 9 | 30 | 01 October 2026 | | 6545059.84 | 2135028.88 | 85611.83 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 10 | 31 | 01 November 2026 | | 4391124.95 | 2153934.89 | 66705.82 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 11 | 30 | 01 December 2026 | | 2213793.97 | 2177330.98 | 43309.73 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
- | 12 | 31 | 01 January 2027 | | 0.0 | 2213793.97 | 22562.5 | 0.0 | 0.0 | 2236356.47 | 0.0 | 0.0 | 0.0 | 2236356.47 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2026 | | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 2 | 28 | 01 March 2026 | | 21039772.25 | 1994381.56 | 226259.15 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 3 | 31 | 01 April 2026 | | 19033564.29 | 2006207.96 | 214432.75 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 4 | 30 | 01 May 2026 | | 17000651.89 | 2032912.4 | 187728.31 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 5 | 31 | 01 June 2026 | | 14953278.1 | 2047373.79 | 173266.92 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 6 | 30 | 01 July 2026 | | 12880121.78 | 2073156.32 | 147484.39 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 7 | 31 | 01 August 2026 | | 10790752.45 | 2089369.33 | 131271.38 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 8 | 31 | 01 September 2026 | | 8680088.72 | 2110663.73 | 109976.98 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 9 | 30 | 01 October 2026 | | 6545059.84 | 2135028.88 | 85611.83 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 10 | 31 | 01 November 2026 | | 4391124.95 | 2153934.89 | 66705.82 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 11 | 30 | 01 December 2026 | | 2213793.97 | 2177330.98 | 43309.73 | 0.0 | 0.0 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 |
+ | 12 | 31 | 01 January 2027 | | 0.0 | 2213793.97 | 22562.5 | 0.0 | 0.0 | 2236356.47 | 0.0 | 0.0 | 0.0 | 2236356.47 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 25000000.0 | 1663404.28 | 0.0 | 0.0 | 26663404.28 | 0.0 | 0.0 | 0.0 | 26663404.28 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 25000000.0 | 1663404.28 | 0.0 | 0.0 | 26663404.28 | 0.0 | 0.0 | 0.0 | 26663404.28 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
- | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
When Loan Pay-off is made on "23 February 2026"
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 |
- | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 31 | 01 February 2026 | 23 February 2026 | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 0.0 | 2220640.71 | 0.0 |
- | 2 | 28 | 01 March 2026 | 23 February 2026 | 20813513.1 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 3 | 31 | 01 April 2026 | 23 February 2026 | 19985766.43 | 827746.67 | 180821.92 | 0.0 | 0.0 | 1008568.59 | 1008568.59 | 1008568.59 | 0.0 | 0.0 |
- | 4 | 30 | 01 May 2026 | 23 February 2026 | 17765125.72 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 5 | 31 | 01 June 2026 | 23 February 2026 | 15544485.01 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 6 | 30 | 01 July 2026 | 23 February 2026 | 13323844.3 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 7 | 31 | 01 August 2026 | 23 February 2026 | 11103203.59 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 8 | 31 | 01 September 2026 | 23 February 2026 | 8882562.88 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 9 | 30 | 01 October 2026 | 23 February 2026 | 6661922.17 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 10 | 31 | 01 November 2026 | 23 February 2026 | 4441281.46 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 11 | 30 | 01 December 2026 | 23 February 2026 | 2220640.75 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
- | 12 | 31 | 01 January 2027 | 23 February 2026 | 0.0 | 2220640.75 | 0.0 | 0.0 | 0.0 | 2220640.75 | 2220640.75 | 2220640.75 | 0.0 | 0.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2026 | | 25000000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2026 | 23 February 2026 | 23034153.81 | 1965846.19 | 254794.52 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 0.0 | 2220640.71 | 0.0 |
+ | 2 | 28 | 01 March 2026 | 23 February 2026 | 20813513.1 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 3 | 31 | 01 April 2026 | 23 February 2026 | 19985766.43 | 827746.67 | 180821.92 | 0.0 | 0.0 | 1008568.59 | 1008568.59 | 1008568.59 | 0.0 | 0.0 |
+ | 4 | 30 | 01 May 2026 | 23 February 2026 | 17765125.72 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 5 | 31 | 01 June 2026 | 23 February 2026 | 15544485.01 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 6 | 30 | 01 July 2026 | 23 February 2026 | 13323844.3 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 7 | 31 | 01 August 2026 | 23 February 2026 | 11103203.59 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 8 | 31 | 01 September 2026 | 23 February 2026 | 8882562.88 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 9 | 30 | 01 October 2026 | 23 February 2026 | 6661922.17 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 10 | 31 | 01 November 2026 | 23 February 2026 | 4441281.46 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 11 | 30 | 01 December 2026 | 23 February 2026 | 2220640.75 | 2220640.71 | 0.0 | 0.0 | 0.0 | 2220640.71 | 2220640.71 | 2220640.71 | 0.0 | 0.0 |
+ | 12 | 31 | 01 January 2027 | 23 February 2026 | 0.0 | 2220640.75 | 0.0 | 0.0 | 0.0 | 2220640.75 | 2220640.75 | 2220640.75 | 0.0 | 0.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 25000000.0 | 435616.44 | 0.0 | 0.0 | 25435616.44 | 25435616.44 | 23214975.73 | 2220640.71 | 0.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 25000000.0 | 435616.44 | 0.0 | 0.0 | 25435616.44 | 25435616.44 | 23214975.73 | 2220640.71 | 0.0 |
Then Loan Transactions tab has the following data:
- | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
- | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
- | 23 February 2026 | Repayment | 25435616.44 | 25000000.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
- | 23 February 2026 | Accrual | 435616.44 | 0.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 01 January 2026 | Disbursement | 25000000.0 | 0.0 | 0.0 | 0.0 | 0.0 | 25000000.0 |
+ | 23 February 2026 | Repayment | 25435616.44 | 25000000.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
+ | 23 February 2026 | Accrual | 435616.44 | 0.0 | 435616.44 | 0.0 | 0.0 | 0.0 |
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
@@ -346,7 +346,7 @@
| 3 | 30 | 30 April 2024 | | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 |
| 4 | 31 | 31 May 2024 | | 0.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 |
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 | 0.0 | 0.0 | 0.0 | 1000.0 | 0.0 | 0.0 | 0.0 | 1000.0 |
@TestRailId:C78845 @AdvancedPaymentAllocation
@@ -382,13 +382,216 @@
When Admin sets the business date to "12 February 2024"
When Admin successfully disburse the loan on "12 February 2024" with "1000" EUR transaction amount
Then Loan Repayment schedule has 5 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 |
- | | | 12 February 2024 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
- | 1 | 0 | 12 February 2024 | 12 February 2024 | 750.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 |
- | 2 | 29 | 12 March 2024 | | 562.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 |
- | 3 | 31 | 12 April 2024 | | 374.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 |
- | 4 | 30 | 12 May 2024 | | 186.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 |
- | 5 | 31 | 12 June 2024 | | 0.0 | 186.0 | 0.0 | 0.0 | 0.0 | 186.0 | 0.0 | 0.0 | 0.0 | 186.0 |
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 12 February 2024 | | 1000.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 0 | 12 February 2024 | 12 February 2024 | 750.0 | 250.0 | 0.0 | 0.0 | 0.0 | 250.0 | 250.0 | 0.0 | 0.0 | 0.0 |
+ | 2 | 29 | 12 March 2024 | | 562.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 |
+ | 3 | 31 | 12 April 2024 | | 374.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 |
+ | 4 | 30 | 12 May 2024 | | 186.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 | 0.0 | 0.0 | 0.0 | 188.0 |
+ | 5 | 31 | 12 June 2024 | | 0.0 | 186.0 | 0.0 | 0.0 | 0.0 | 186.0 | 0.0 | 0.0 | 0.0 | 186.0 |
Then Loan Repayment schedule has the following data in Total row:
- | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
- | 1000.0 | 0.0 | 0.0 | 0.0 | 1000.0 | 250.0 | 0.0 | 0.0 | 750.0 |
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1000.0 | 0.0 | 0.0 | 0.0 | 1000.0 | 250.0 | 0.0 | 0.0 | 750.0 |
+
+ @TestRailId:CXXXX @AdvancedPaymentAllocation @ProgressiveLoanSchedule
+ Scenario: Verify AdvancedPaymentAllocation behaviour: loanScheduleProcessingType-vertical two repayment and prepayment with NEXT_INSTALLMENT strategy
+ When Admin sets the business date to "23 February 2026"
+ When Admin creates a client with random data
+ When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
+ When Admin creates a fully customized loan with the following data:
+ | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
+ | LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC | 31 December 2024 | 424036.08 | 12 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 36 | MONTHS | 1 | MONTHS | 36 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
+ And Admin successfully approves the loan on "31 December 2024" with "424036.08" amount and expected disbursement date on "31 December 2024"
+ When Admin successfully disburse the loan on "31 December 2024" with "424036.08" EUR transaction amount
+ Then Loan Repayment schedule has 36 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 |
+ | | | 31 December 2024 | | 424036.08 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 31 January 2025 | | 414277.37 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 2 | 28 | 28 February 2025 | | 404100.44 | 10176.93 | 3903.46 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 3 | 31 | 31 March 2025 | | 394341.73 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 4 | 30 | 30 April 2025 | | 384443.61 | 9898.12 | 4182.27 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 5 | 31 | 31 May 2025 | | 374684.9 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 6 | 30 | 30 June 2025 | | 364786.78 | 9898.12 | 4182.27 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 7 | 31 | 31 July 2025 | | 355028.07 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 8 | 31 | 31 August 2025 | | 345269.36 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 9 | 30 | 30 September 2025 | | 335371.24 | 9898.12 | 4182.27 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 10 | 31 | 31 October 2025 | | 325612.53 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 11 | 30 | 30 November 2025 | | 315714.41 | 9898.12 | 4182.27 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 12 | 31 | 31 December 2025 | | 305955.7 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 13 | 31 | 31 January 2026 | | 296196.99 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 14 | 28 | 28 February 2026 | | 285809.91 | 10387.08 | 3693.31 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 15 | 31 | 31 March 2026 | | 274642.43 | 11167.48 | 2912.91 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 16 | 30 | 30 April 2026 | | 263270.84 | 11371.59 | 2708.8 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 17 | 31 | 31 May 2026 | | 251873.65 | 11397.19 | 2683.2 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 18 | 30 | 30 June 2026 | | 240277.49 | 11596.16 | 2484.23 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 19 | 31 | 31 July 2026 | | 228645.96 | 11631.53 | 2448.86 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 20 | 31 | 31 August 2026 | | 216895.88 | 11750.08 | 2330.31 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 21 | 30 | 30 September 2026 | | 204954.74 | 11941.14 | 2139.25 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 22 | 31 | 31 October 2026 | | 192963.2 | 11991.54 | 2088.85 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 23 | 30 | 30 November 2026 | | 180786.01 | 12177.19 | 1903.2 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 24 | 31 | 31 December 2026 | | 168548.15 | 12237.86 | 1842.53 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 25 | 31 | 31 January 2027 | | 156185.57 | 12362.58 | 1717.81 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 26 | 28 | 28 February 2027 | | 143542.94 | 12642.63 | 1437.76 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 27 | 31 | 31 March 2027 | | 130925.51 | 12617.43 | 1462.96 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 28 | 30 | 30 April 2027 | | 118136.44 | 12789.07 | 1291.32 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 29 | 31 | 31 May 2027 | | 105260.07 | 12876.37 | 1204.02 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 30 | 30 | 30 June 2027 | | 92217.86 | 13042.21 | 1038.18 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 31 | 31 | 31 July 2027 | | 79077.33 | 13140.53 | 939.86 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 32 | 31 | 31 August 2027 | | 65802.88 | 13274.45 | 805.94 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 33 | 30 | 30 September 2027 | | 52371.5 | 13431.38 | 649.01 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 34 | 31 | 31 October 2027 | | 38824.87 | 13546.63 | 533.76 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 35 | 30 | 30 November 2027 | | 25127.41 | 13697.46 | 382.93 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 36 | 31 | 31 December 2027 | | 0.0 | 25127.41 | 256.09 | 0.0 | 0.0 | 25383.5 | 0.0 | 0.0 | 0.0 | 25383.5 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 424036.08 | 94161.07 | 0.0 | 0.0 | 518197.15 | 0.0 | 0.0 | 0.0 | 518197.15 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 31 December 2024 | Disbursement | 424036.08 | 0.0 | 0.0 | 0.0 | 0.0 | 424036.08 |
+ And Customer makes "AUTOPAY" repayment on "12 February 2025" with 55284.0 EUR transaction amount
+ Then Loan Repayment schedule has 36 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 |
+ | | | 31 December 2024 | | 424036.08 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 31 January 2025 | 12 February 2025 | 414277.37 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 14080.39 | 0.0 | 14080.39 | 0.0 |
+ | 2 | 28 | 28 February 2025 | 12 February 2025 | 400196.98 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 3 | 31 | 31 March 2025 | 12 February 2025 | 386116.59 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 4 | 30 | 30 April 2025 | | 372036.2 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 13042.83 | 13042.83 | 0.0 | 1037.56 |
+ | 5 | 31 | 31 May 2025 | | 372036.2 | 0.0 | 14080.39 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 6 | 30 | 30 June 2025 | | 362474.64 | 9561.56 | 4518.83 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 7 | 31 | 31 July 2025 | | 352196.54 | 10278.1 | 3802.29 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 8 | 31 | 31 August 2025 | | 341918.44 | 10278.1 | 3802.29 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 9 | 30 | 30 September 2025 | | 331517.68 | 10400.76 | 3679.63 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 10 | 31 | 31 October 2025 | | 321239.58 | 10278.1 | 3802.29 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 11 | 30 | 30 November 2025 | | 310838.82 | 10400.76 | 3679.63 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 12 | 31 | 31 December 2025 | | 300560.72 | 10278.1 | 3802.29 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 13 | 31 | 31 January 2026 | | 290282.62 | 10278.1 | 3802.29 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 14 | 28 | 28 February 2026 | | 279500.46 | 10782.16 | 3298.23 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 15 | 31 | 31 March 2026 | | 268268.68 | 11231.78 | 2848.61 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 16 | 30 | 30 April 2026 | | 256834.23 | 11434.45 | 2645.94 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 17 | 31 | 31 May 2026 | | 245371.44 | 11462.79 | 2617.6 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 18 | 30 | 30 June 2026 | | 233711.15 | 11660.29 | 2420.1 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 19 | 31 | 31 July 2026 | | 222012.69 | 11698.46 | 2381.93 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 20 | 31 | 31 August 2026 | | 210195.0 | 11817.69 | 2262.7 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 21 | 30 | 30 September 2026 | | 198187.77 | 12007.23 | 2073.16 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 22 | 31 | 31 October 2026 | | 186127.27 | 12060.5 | 2019.89 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 23 | 30 | 30 November 2026 | | 173882.66 | 12244.61 | 1835.78 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 24 | 31 | 31 December 2026 | | 161574.44 | 12308.22 | 1772.17 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 25 | 31 | 31 January 2027 | | 149140.78 | 12433.66 | 1646.73 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 26 | 28 | 28 February 2027 | | 136433.3 | 12707.48 | 1372.91 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 27 | 31 | 31 March 2027 | | 123743.41 | 12689.89 | 1390.5 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 28 | 30 | 30 April 2027 | | 110883.5 | 12859.91 | 1220.48 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 29 | 31 | 31 May 2027 | | 97933.21 | 12950.29 | 1130.1 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 30 | 30 | 30 June 2027 | | 84818.74 | 13114.47 | 965.92 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 31 | 31 | 31 July 2027 | | 71602.8 | 13215.94 | 864.45 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 32 | 31 | 31 August 2027 | | 58252.17 | 13350.63 | 729.76 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 33 | 30 | 30 September 2027 | | 44746.32 | 13505.85 | 574.54 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 34 | 31 | 31 October 2027 | | 31121.97 | 13624.35 | 456.04 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 35 | 30 | 30 November 2027 | | 17348.54 | 13773.43 | 306.96 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 36 | 31 | 31 December 2027 | | 0.0 | 17348.54 | 176.81 | 0.0 | 0.0 | 17525.35 | 0.0 | 0.0 | 0.0 | 17525.35 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 424036.08 | 86302.92 | 0.0 | 0.0 | 510339.0 | 55284.0 | 41203.61 | 14080.39 | 455055.0 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 31 December 2024 | Disbursement | 424036.08 | 0.0 | 0.0 | 0.0 | 0.0 | 424036.08 |
+ | 12 February 2025 | Repayment | 55284.0 | 50962.32 | 4321.68 | 0.0 | 0.0 | 373073.76 |
+ And Customer makes "AUTOPAY" repayment on "27 June 2025" with 66605.0 EUR transaction amount
+ Then Loan Repayment schedule has 36 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 |
+ | | | 31 December 2024 | | 424036.08 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 31 January 2025 | 12 February 2025 | 414277.37 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 14080.39 | 0.0 | 14080.39 | 0.0 |
+ | 2 | 28 | 28 February 2025 | 12 February 2025 | 400196.98 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 3 | 31 | 31 March 2025 | 12 February 2025 | 386116.59 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 4 | 30 | 30 April 2025 | 27 June 2025 | 372036.2 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 13042.83 | 1037.56 | 0.0 |
+ | 5 | 31 | 31 May 2025 | 27 June 2025 | 372036.2 | 0.0 | 14080.39 | 0.0 | 0.0 | 14080.39 | 14080.39 | 0.0 | 14080.39 | 0.0 |
+ | 6 | 30 | 30 June 2025 | 27 June 2025 | 357955.81 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 7 | 31 | 31 July 2025 | 27 June 2025 | 343875.42 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 8 | 31 | 31 August 2025 | 27 June 2025 | 329795.03 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 9 | 30 | 30 September 2025 | | 329795.03 | 0.0 | 14080.39 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 10 | 31 | 31 October 2025 | | 319063.77 | 10731.26 | 3349.13 | 0.0 | 0.0 | 14080.39 | 9245.88 | 9245.88 | 0.0 | 4834.51 |
+ | 11 | 30 | 30 November 2025 | | 308144.96 | 10918.81 | 3161.58 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 12 | 31 | 31 December 2025 | | 297331.54 | 10813.42 | 3266.97 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 13 | 31 | 31 January 2026 | | 286518.12 | 10813.42 | 3266.97 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 14 | 28 | 28 February 2026 | | 275332.6 | 11185.52 | 2894.87 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 15 | 31 | 31 March 2026 | | 264058.34 | 11274.26 | 2806.13 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 16 | 30 | 30 April 2026 | | 252582.36 | 11475.98 | 2604.41 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 17 | 31 | 31 May 2026 | | 241076.23 | 11506.13 | 2574.26 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 18 | 30 | 30 June 2026 | | 229373.58 | 11702.65 | 2377.74 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 19 | 31 | 31 July 2026 | | 217630.92 | 11742.66 | 2337.73 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 20 | 31 | 31 August 2026 | | 205768.58 | 11862.34 | 2218.05 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 21 | 30 | 30 September 2026 | | 193717.69 | 12050.89 | 2029.5 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 22 | 31 | 31 October 2026 | | 181611.63 | 12106.06 | 1974.33 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 23 | 30 | 30 November 2026 | | 169322.48 | 12289.15 | 1791.24 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 24 | 31 | 31 December 2026 | | 156967.79 | 12354.69 | 1725.7 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 25 | 31 | 31 January 2027 | | 144487.18 | 12480.61 | 1599.78 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 26 | 28 | 28 February 2027 | | 131736.86 | 12750.32 | 1330.07 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 27 | 31 | 31 March 2027 | | 118999.1 | 12737.76 | 1342.63 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 28 | 30 | 30 April 2027 | | 106092.4 | 12906.7 | 1173.69 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 29 | 31 | 31 May 2027 | | 93093.28 | 12999.12 | 1081.27 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 30 | 30 | 30 June 2027 | | 79931.07 | 13162.21 | 918.18 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 31 | 31 | 31 July 2027 | | 66665.32 | 13265.75 | 814.64 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 32 | 31 | 31 August 2027 | | 53264.37 | 13400.95 | 679.44 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 33 | 30 | 30 September 2027 | | 39709.33 | 13555.04 | 525.35 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 34 | 31 | 31 October 2027 | | 26033.65 | 13675.68 | 404.71 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 35 | 30 | 30 November 2027 | | 12210.03 | 13823.62 | 256.77 | 0.0 | 0.0 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 |
+ | 36 | 31 | 31 December 2027 | | 0.0 | 12210.03 | 124.44 | 0.0 | 0.0 | 12334.47 | 0.0 | 0.0 | 0.0 | 12334.47 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 424036.08 | 81112.04 | 0.0 | 0.0 | 505148.12 | 121889.0 | 92690.66 | 29198.34 | 383259.12 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 31 December 2024 | Disbursement | 424036.08 | 0.0 | 0.0 | 0.0 | 0.0 | 424036.08 |
+ | 12 February 2025 | Repayment | 55284.0 | 50962.32 | 4321.68 | 0.0 | 0.0 | 373073.76 |
+ | 27 June 2025 | Repayment | 66605.0 | 52524.61 | 14080.39 | 0.0 | 0.0 | 320549.15 |
+ When Loan Pay-off is made on "20 August 2025"
+ Then Loan Repayment schedule has 36 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 |
+ | | | 31 December 2024 | | 424036.08 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 31 January 2025 | 12 February 2025 | 414277.37 | 9758.71 | 4321.68 | 0.0 | 0.0 | 14080.39 | 14080.39 | 0.0 | 14080.39 | 0.0 |
+ | 2 | 28 | 28 February 2025 | 12 February 2025 | 400196.98 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 3 | 31 | 31 March 2025 | 12 February 2025 | 386116.59 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 4 | 30 | 30 April 2025 | 27 June 2025 | 372036.2 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 13042.83 | 1037.56 | 0.0 |
+ | 5 | 31 | 31 May 2025 | 27 June 2025 | 372036.2 | 0.0 | 14080.39 | 0.0 | 0.0 | 14080.39 | 14080.39 | 0.0 | 14080.39 | 0.0 |
+ | 6 | 30 | 30 June 2025 | 27 June 2025 | 357955.81 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 7 | 31 | 31 July 2025 | 27 June 2025 | 343875.42 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 8 | 31 | 31 August 2025 | 27 June 2025 | 329795.03 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 9 | 30 | 30 September 2025 | 20 August 2025 | 315714.64 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 10 | 31 | 31 October 2025 | 20 August 2025 | 301634.25 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 11 | 30 | 30 November 2025 | 20 August 2025 | 287553.86 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 12 | 31 | 31 December 2025 | 20 August 2025 | 273473.47 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 13 | 31 | 31 January 2026 | 20 August 2025 | 259393.08 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 14 | 28 | 28 February 2026 | 20 August 2025 | 245312.69 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 15 | 31 | 31 March 2026 | 20 August 2025 | 231232.3 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 16 | 30 | 30 April 2026 | 20 August 2025 | 217151.91 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 17 | 31 | 31 May 2026 | 20 August 2025 | 203071.52 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 18 | 30 | 30 June 2026 | 20 August 2025 | 188991.13 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 19 | 31 | 31 July 2026 | 20 August 2025 | 174910.74 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 20 | 31 | 31 August 2026 | 20 August 2025 | 160830.35 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 21 | 30 | 30 September 2026 | 20 August 2025 | 146749.96 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 22 | 31 | 31 October 2026 | 20 August 2025 | 132669.57 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 23 | 30 | 30 November 2026 | 20 August 2025 | 118589.18 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 24 | 31 | 31 December 2026 | 20 August 2025 | 104508.79 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 25 | 31 | 31 January 2027 | 20 August 2025 | 90428.4 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 26 | 28 | 28 February 2027 | 20 August 2025 | 76348.01 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 27 | 31 | 31 March 2027 | 20 August 2025 | 62267.62 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 28 | 30 | 30 April 2027 | 20 August 2025 | 48187.23 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 29 | 31 | 31 May 2027 | 20 August 2025 | 34106.84 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 30 | 30 | 30 June 2027 | 20 August 2025 | 20026.45 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 31 | 31 | 31 July 2027 | 20 August 2025 | 5946.06 | 14080.39 | 0.0 | 0.0 | 0.0 | 14080.39 | 14080.39 | 14080.39 | 0.0 | 0.0 |
+ | 32 | 31 | 31 August 2027 | 20 August 2025 | 0.0 | 5946.06 | 0.0 | 0.0 | 0.0 | 5946.06 | 5946.06 | 5946.06 | 0.0 | 0.0 |
+ | 33 | 30 | 30 September 2027 | 20 August 2025 | 0.0 | 0.0 | 9841.72 | 0.0 | 0.0 | 9841.72 | 9841.72 | 9841.72 | 0.0 | 0.0 |
+ | 34 | 31 | 31 October 2027 | 20 August 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
+ | 35 | 30 | 30 November 2027 | 20 August 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
+ | 36 | 31 | 31 December 2027 | 20 August 2025 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 424036.08 | 28243.79 | 0.0 | 0.0 | 452279.87 | 452279.87 | 423081.53 | 29198.34 | 0.0 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
+ | 31 December 2024 | Disbursement | 424036.08 | 0.0 | 0.0 | 0.0 | 0.0 | 424036.08 |
+ | 12 February 2025 | Repayment | 55284.0 | 50962.32 | 4321.68 | 0.0 | 0.0 | 373073.76 |
+ | 27 June 2025 | Repayment | 66605.0 | 52524.61 | 14080.39 | 0.0 | 0.0 | 320549.15 |
+ | 20 August 2025 | Repayment | 330390.87 | 320549.15 | 9841.72 | 0.0 | 0.0 | 0.0 |
+ | 23 February 2026 | Accrual | 28243.79 | 0.0 | 28243.79 | 0.0 | 0.0 | 0.0 |
+ Then Loan is closed with zero outstanding balance and it's all installments have obligations met
+ When Admin set "LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_VERTICAL_INTEREST_RECALC" loan product "REPAYMENT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule
diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
index c7376b9..74cc8a3 100644
--- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
+++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/calc/ProgressiveEMICalculator.java
@@ -392,8 +392,14 @@
calculateUnrecognizedInterestTillDateOnScheduleModelCopyAndDefer(scheduleModel,
latestNotLastOpenRepaymentPeriodBeforeDate.get(), transactionDate);
}
+ // Amend payment amount if outstanding is lower
+ Money amendedInterestAmount = null;
+ if (scheduleModel.getTotalPaidInterest().plus(interestAmount).isGreaterThan(scheduleModel.getTotalDueInterest())) {
+ amendedInterestAmount = scheduleModel.getTotalDueInterest().minus(scheduleModel.getTotalPaidInterest());
+ }
+ Money finalInterestAmount = amendedInterestAmount != null ? amendedInterestAmount : interestAmount;
- repaymentPeriod.ifPresent(rp -> rp.addPaidInterestAmount(interestAmount));
+ repaymentPeriod.ifPresent(rp -> rp.addPaidInterestAmount(finalInterestAmount));
calculateOutstandingBalance(scheduleModel);
calculateLastUnpaidRepaymentPeriodEMI(scheduleModel, transactionDate);
}
@@ -405,7 +411,14 @@
return;
}
Optional<RepaymentPeriod> repaymentPeriod = findRepaymentPeriod(scheduleModel, repaymentPeriodFromDate, repaymentPeriodDueDate);
- repaymentPeriod.ifPresent(rp -> rp.addPaidPrincipalAmount(principalAmount));
+ // Amend payment amount if outstanding is lower
+ Money amendedPrincipalAmount = null;
+ if (scheduleModel.getTotalPaidPrincipal().plus(principalAmount)
+ .isGreaterThan(scheduleModel.getTotalDuePrincipal().plus(scheduleModel.getTotalCreditedPrincipal()))) {
+ amendedPrincipalAmount = scheduleModel.getTotalDuePrincipal().minus(scheduleModel.getTotalPaidPrincipal());
+ }
+ Money finalPrincipalAmount = amendedPrincipalAmount != null ? amendedPrincipalAmount : principalAmount;
+ repaymentPeriod.ifPresent(rp -> rp.addPaidPrincipalAmount(finalPrincipalAmount));
// If it is paid late, we need to calculate with the period due date
LocalDate balanceCorrectionDate = DateUtils.isBefore(repaymentPeriodDueDate, transactionDate) ? repaymentPeriodDueDate
: transactionDate;
@@ -500,40 +513,72 @@
@NotNull
public PeriodDueDetails getDueAmounts(@NotNull ProgressiveLoanInterestScheduleModel scheduleModel, @NotNull LocalDate periodFromDate,
@NotNull LocalDate periodDueDate, @NotNull LocalDate targetDate) {
+
ProgressiveLoanInterestScheduleModel recalculatedScheduleModelTillDate = recalculateScheduleModelTillDate(scheduleModel,
targetDate);
+
RepaymentPeriod repaymentPeriod = recalculatedScheduleModelTillDate
.findRepaymentPeriodByFromAndDueDate(periodFromDate, periodDueDate).orElseThrow();
+
long notFullyRepaidRepaymentPeriodCount = recalculatedScheduleModelTillDate.repaymentPeriods().stream()
.filter(rp -> !rp.isFullyPaid()).count();
- boolean multiplePeriodIsUnpaid = notFullyRepaidRepaymentPeriodCount > 1L;
- boolean onePeriodIsUnpaid = notFullyRepaidRepaymentPeriodCount == 1L;
- if (!targetDate.isAfter(repaymentPeriod.getFromDate())) {
- if (multiplePeriodIsUnpaid) {
- repaymentPeriod.setEmi(repaymentPeriod.getOriginalEmi());
- Money totalOutstandingPrincipal = recalculatedScheduleModelTillDate.getTotalOutstandingPrincipal();
- Money outstandingPrincipal = repaymentPeriod.getOutstandingPrincipal();
- // If there are less outstanding principal than anticipated
- Money emiAdjustment = MathUtil.negativeToZero(outstandingPrincipal.minus(totalOutstandingPrincipal));
- repaymentPeriod.setEmi(repaymentPeriod.getEmi().minus(emiAdjustment));
- } else if (repaymentPeriod.isFullyPaid() && onePeriodIsUnpaid) {
- repaymentPeriod.setEmi(MathUtil.min(repaymentPeriod.getOriginalEmi(), //
- recalculatedScheduleModelTillDate.getTotalDuePrincipal() //
- .minus(recalculatedScheduleModelTillDate.getTotalPaidPrincipal()) //
- .add(repaymentPeriod.getPaidPrincipal()) //
- .add(repaymentPeriod.getDueInterest()),
- false)); //
- }
- }
- Money duePrincipal = repaymentPeriod.getDuePrincipal();
+
+ boolean isVertical = scheduleModel.loanProductRelatedDetail()
+ .getLoanScheduleProcessingType() == LoanScheduleProcessingType.VERTICAL;
+
+ adjustEmiIfRequired(repaymentPeriod, recalculatedScheduleModelTillDate, targetDate, notFullyRepaidRepaymentPeriodCount);
+
+ Money duePrincipal = isVertical && notFullyRepaidRepaymentPeriodCount > 1
+ ? repaymentPeriod.getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest()
+ : repaymentPeriod.getDuePrincipal();
+
Money dueInterest = repaymentPeriod.getDueInterest();
- if (scheduleModel.loanProductRelatedDetail().getLoanScheduleProcessingType() == LoanScheduleProcessingType.VERTICAL
- && notFullyRepaidRepaymentPeriodCount > 1) {
- duePrincipal = repaymentPeriod.getEmiPlusCreditedAmountsPlusFutureUnrecognizedInterest();
+
+ if (!isVertical) {
+ return new PeriodDueDetails(repaymentPeriod.getEmi(), duePrincipal, dueInterest);
}
- return new PeriodDueDetails(repaymentPeriod.getEmi(), //
- duePrincipal, //
- dueInterest); //
+
+ Money calculatedDuePrincipal = capDueAmount(duePrincipal, recalculatedScheduleModelTillDate.getTotalDuePrincipal(),
+ recalculatedScheduleModelTillDate.getTotalPaidPrincipal(), repaymentPeriod.getPaidPrincipal());
+
+ Money calculatedDueInterest = capDueAmount(dueInterest, recalculatedScheduleModelTillDate.getTotalDueInterest(),
+ recalculatedScheduleModelTillDate.getTotalPaidInterest(), repaymentPeriod.getPaidInterest());
+
+ return new PeriodDueDetails(repaymentPeriod.getEmi(), calculatedDuePrincipal, calculatedDueInterest);
+ }
+
+ private void adjustEmiIfRequired(RepaymentPeriod repaymentPeriod,
+ ProgressiveLoanInterestScheduleModel recalculatedScheduleModelTillDate, LocalDate targetDate,
+ long notFullyRepaidRepaymentPeriodCount) {
+
+ if (targetDate.isAfter(repaymentPeriod.getFromDate())) {
+ return;
+ }
+
+ if (notFullyRepaidRepaymentPeriodCount > 1L) {
+ repaymentPeriod.setEmi(repaymentPeriod.getOriginalEmi());
+
+ Money emiAdjustment = MathUtil.negativeToZero(
+ repaymentPeriod.getOutstandingPrincipal().minus(recalculatedScheduleModelTillDate.getTotalOutstandingPrincipal()));
+
+ repaymentPeriod.setEmi(repaymentPeriod.getEmi().minus(emiAdjustment));
+ return;
+ }
+
+ if (repaymentPeriod.isFullyPaid() && notFullyRepaidRepaymentPeriodCount == 1L) {
+ repaymentPeriod.setEmi(MathUtil.min(repaymentPeriod.getOriginalEmi(),
+ recalculatedScheduleModelTillDate.getTotalDuePrincipal()
+ .minus(recalculatedScheduleModelTillDate.getTotalPaidPrincipal()).add(repaymentPeriod.getPaidPrincipal())
+ .add(repaymentPeriod.getDueInterest()),
+ false));
+ }
+ }
+
+ private Money capDueAmount(Money dueAmount, Money totalDueAmount, Money totalPaidAmount, Money paidAmount) {
+ Money maximumAmount = totalDueAmount.minus(totalPaidAmount);
+ maximumAmount = maximumAmount.isLessThan(paidAmount) ? paidAmount : maximumAmount;
+
+ return maximumAmount.isLessThan(dueAmount) ? maximumAmount : dueAmount;
}
@Override
@@ -1268,7 +1313,6 @@
*
* @param interestRate
* Interest Rate in Percentage
- *
* @return Rate Interest Rate in fraction format
*/
private BigDecimal calcNominalInterestRatePercentage(final BigDecimal interestRate, MathContext mc) {
@@ -1815,19 +1859,14 @@
*
* @param interestRate
* Rate of Interest
- *
* @param repaymentEvery
* Repaid Every
- *
* @param daysInYear
* Days is Year based on DaysInYear enum
- *
* @param actualDaysInPeriod
* Always the actual number of days in the actual period
- *
* @param calculatedDaysInPeriod
* Calculated days in Period (It has importance related to Reschedule)
- *
* @return Rate Factor for period
*/
private BigDecimal rateFactorByRepaymentEveryDay(final BigDecimal interestRate, final BigDecimal repaymentEvery,
@@ -1845,19 +1884,14 @@
*
* @param interestRate
* Rate of Interest
- *
* @param repaymentEvery
* Repaid Every
- *
* @param daysInYear
* Days is Year based on DaysInYear enum
- *
* @param actualDaysInPeriod
* Always the actual number of days in the actual period
- *
* @param calculatedDaysInPeriod
* Calculated days in Period (It has importance related to Reschedule)
- *
* @return Rate Factor for period
*/
private BigDecimal rateFactorByRepaymentEveryWeek(final BigDecimal interestRate, final BigDecimal repaymentEvery,
@@ -1875,22 +1909,16 @@
*
* @param interestRate
* Rate of Interest
- *
* @param repaymentEvery
* Repaid Every
- *
* @param daysInMonth
* Days in Month based on DaysInMonth enum
- *
* @param daysInYear
* Days is Year based on DaysInYear enum
- *
* @param actualDaysInPeriod
* Always the actual number of days in the actual period
- *
* @param calculatedDaysInPeriod
* Calculated days in Period (It has importance related to Reschedule)
- *
* @return Rate Factor for period
*/
BigDecimal rateFactorByRepaymentEveryMonth(final BigDecimal interestRate, final BigDecimal repaymentEvery, final BigDecimal daysInMonth,
@@ -1909,22 +1937,16 @@
*
* @param interestRate
* Rate of Interest
- *
* @param repaymentPeriodMultiplierInDays
* Multiplier number in days of the repayment every parameter
- *
* @param repaymentEvery
* Repaid Every
- *
* @param daysInYear
* Days is Year based on DaysInYear enum
- *
* @param actualDaysInPeriod
* Always the actual number of days in the actual period
- *
* @param calculatedDaysInPeriod
* Calculated days in Period (It has importance related to Reschedule)
- *
* @return Rate Factor for period
*/
private BigDecimal rateFactorByRepaymentPeriod(final BigDecimal interestRate, final BigDecimal repaymentPeriodMultiplierInDays,
@@ -1965,7 +1987,6 @@
* fn = 1 + fnValueFrom * rateFactorEnd
*
* @param previousFnValue
- *
* @param currentRateFactor
*
*/
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
index 8216d59..acffc2c 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java
@@ -21,6 +21,7 @@
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -52,10 +53,12 @@
@Override
public void createJournalEntriesForLoan(final LoanDTO loanDTO) {
- final Long officeId = loanDTO.getOfficeId();
- final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(officeId);
- final Office office = this.helper.getOfficeById(officeId);
+ final Map<Long, GLClosure> latestGLClosureByOfficeId = new HashMap<>();
+ final Map<Long, Office> officeById = new HashMap<>();
for (final LoanTransactionDTO loanTransactionDTO : loanDTO.getNewLoanTransactions()) {
+ final Long officeId = loanTransactionDTO.getOfficeId() == null ? loanDTO.getOfficeId() : loanTransactionDTO.getOfficeId();
+ final GLClosure latestGLClosure = latestGLClosureByOfficeId.computeIfAbsent(officeId, this.helper::getLatestClosureByBranch);
+ final Office office = officeById.computeIfAbsent(officeId, this.helper::getOfficeById);
final LocalDate transactionDate = loanTransactionDTO.getTransactionDate();
this.helper.checkForBranchClosures(latestGLClosure, transactionDate);
final LoanTransactionEnumData transactionType = loanTransactionDTO.getTransactionType();
@@ -104,6 +107,11 @@
createJournalEntriesForWriteOffs(loanDTO, loanTransactionDTO, office);
}
+ // Handle Transfers
+ else if (transactionType.isInitiateTransfer() || transactionType.isApproveTransfer() || transactionType.isWithdrawTransfer()) {
+ createJournalEntriesForTransfers(loanDTO, loanTransactionDTO, office);
+ }
+
// Logic for Refunds of Active Loans
else if (transactionType.isRefundForActiveLoans()) {
createJournalEntriesForRefundForActiveLoan(loanDTO, loanTransactionDTO, office);
@@ -159,6 +167,29 @@
}
}
+ private void createJournalEntriesForTransfers(final LoanDTO loanDTO, final LoanTransactionDTO loanTransactionDTO, final Office office) {
+ final Long loanProductId = loanDTO.getLoanProductId();
+ final Long loanId = loanDTO.getLoanId();
+ final String currencyCode = loanDTO.getCurrencyCode();
+
+ final String transactionId = loanTransactionDTO.getTransactionId();
+ final LocalDate transactionDate = loanTransactionDTO.getTransactionDate();
+ final BigDecimal principalAmount = loanTransactionDTO.getPrincipal();
+
+ if (!MathUtil.isGreaterThanZero(principalAmount)) {
+ return;
+ }
+
+ final boolean isInitiateTransfer = loanTransactionDTO.getTransactionType().isInitiateTransfer();
+ final Integer debitAccount = isInitiateTransfer ? AccrualAccountsForLoan.TRANSFERS_SUSPENSE.getValue()
+ : AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue();
+ final Integer creditAccount = isInitiateTransfer ? AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue()
+ : AccrualAccountsForLoan.TRANSFERS_SUSPENSE.getValue();
+
+ this.helper.createJournalEntriesForLoan(office, currencyCode, debitAccount, creditAccount, loanProductId, null, loanId,
+ transactionId, transactionDate, principalAmount);
+ }
+
private void createJournalEntriesForCapitalizedIncome(final LoanDTO loanDTO, final LoanTransactionDTO loanTransactionDTO,
final Office office) {
// loan properties
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
index 6081ab9..cb81686 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
@@ -21,6 +21,7 @@
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -47,12 +48,14 @@
@Override
public void createJournalEntriesForLoan(final LoanDTO loanDTO) {
- final Long officeId = loanDTO.getOfficeId();
- final GLClosure latestGLClosure = this.helper.getLatestClosureByBranch(officeId);
final Long loanProductId = loanDTO.getLoanProductId();
final String currencyCode = loanDTO.getCurrencyCode();
- final Office office = this.helper.getOfficeById(officeId);
+ final Map<Long, GLClosure> latestGLClosureByOfficeId = new HashMap<>();
+ final Map<Long, Office> officeById = new HashMap<>();
for (final LoanTransactionDTO loanTransactionDTO : loanDTO.getNewLoanTransactions()) {
+ final Long officeId = loanTransactionDTO.getOfficeId() == null ? loanDTO.getOfficeId() : loanTransactionDTO.getOfficeId();
+ final GLClosure latestGLClosure = latestGLClosureByOfficeId.computeIfAbsent(officeId, this.helper::getLatestClosureByBranch);
+ final Office office = officeById.computeIfAbsent(officeId, this.helper::getOfficeById);
final LocalDate transactionDate = loanTransactionDTO.getTransactionDate();
final String transactionId = loanTransactionDTO.getTransactionId();
final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
diff --git a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
index a87fc12..3862ee6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/infrastructure/jobs/service/SchedulerJobListener.java
@@ -42,7 +42,6 @@
private final SchedularWritePlatformService schedularService;
private final TenantDetailsService tenantDetailsService;
- private int stackTraceLevel = 0;
@Override
public String getName() {
@@ -79,9 +78,7 @@
String errorLog = null;
if (jobException != null) {
status = SchedulerServiceConstants.STATUS_FAILED;
- this.stackTraceLevel = 0;
- final Throwable throwable = getCauseFromException(jobException);
- this.stackTraceLevel = 0;
+ final Throwable throwable = getCauseFromException(jobException, 0);
StackTraceElement[] stackTraceElements = null;
errorMessage = throwable.getMessage();
stackTraceElements = throwable.getStackTrace();
@@ -117,13 +114,12 @@
}
}
- private Throwable getCauseFromException(final Throwable exception) {
- if (this.stackTraceLevel <= SchedulerServiceConstants.STACK_TRACE_LEVEL && exception.getCause() != null
+ private Throwable getCauseFromException(final Throwable exception, final int stackTraceLevel) {
+ if (stackTraceLevel <= SchedulerServiceConstants.STACK_TRACE_LEVEL && exception.getCause() != null
&& (exception.getCause().toString().contains(SchedulerServiceConstants.SCHEDULER_EXCEPTION)
|| exception.getCause().toString().contains(SchedulerServiceConstants.JOB_EXECUTION_EXCEPTION)
|| exception.getCause().toString().contains(SchedulerServiceConstants.JOB_METHOD_INVOCATION_FAILED_EXCEPTION))) {
- this.stackTraceLevel++;
- return getCauseFromException(exception.getCause());
+ return getCauseFromException(exception.getCause(), stackTraceLevel + 1);
} else if (exception.getCause() != null) {
return exception.getCause();
}
diff --git a/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForTransferLoanTest.java b/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForTransferLoanTest.java
new file mode 100644
index 0000000..a36df46
--- /dev/null
+++ b/fineract-provider/src/test/java/org/apache/fineract/accounting/journalentry/CreateJournalEntriesForTransferLoanTest.java
@@ -0,0 +1,135 @@
+/**
+ * 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.accounting.journalentry;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.math.BigDecimal;
+import java.time.LocalDate;
+import java.util.Collections;
+import java.util.List;
+import org.apache.fineract.accounting.closure.domain.GLClosure;
+import org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
+import org.apache.fineract.accounting.journalentry.data.LoanDTO;
+import org.apache.fineract.accounting.journalentry.data.LoanTransactionDTO;
+import org.apache.fineract.accounting.journalentry.service.AccountingProcessorHelper;
+import org.apache.fineract.accounting.journalentry.service.AccrualBasedAccountingProcessorForLoan;
+import org.apache.fineract.organisation.office.domain.Office;
+import org.apache.fineract.portfolio.loanaccount.data.LoanTransactionEnumData;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+class CreateJournalEntriesForTransferLoanTest {
+
+ private static final Long LOAN_ID = 1L;
+ private static final Long LOAN_PRODUCT_ID = 1L;
+ private static final Long LOAN_OFFICE_ID = 1L;
+ private static final Long TRANSACTION_OFFICE_ID = 2L;
+ private static final String CURRENCY_CODE = "USD";
+ private static final String TRANSACTION_ID = "txn-transfer";
+ private static final LocalDate TRANSACTION_DATE = LocalDate.of(2021, 2, 11);
+ private static final BigDecimal TRANSACTION_AMOUNT = new BigDecimal("600.00");
+ private static final BigDecimal PRINCIPAL_AMOUNT = new BigDecimal("500.00");
+
+ @Mock
+ private AccountingProcessorHelper helper;
+ @InjectMocks
+ private AccrualBasedAccountingProcessorForLoan processor;
+ private Office office;
+
+ @BeforeEach
+ void setUp() {
+ office = Office.headOffice("Transaction Office", TRANSACTION_DATE, null);
+ when(helper.getOfficeById(TRANSACTION_OFFICE_ID)).thenReturn(office);
+
+ GLClosure mockClosure = mock(GLClosure.class);
+ when(helper.getLatestClosureByBranch(TRANSACTION_OFFICE_ID)).thenReturn(mockClosure);
+ }
+
+ @Test
+ void shouldCreateJournalEntriesForTransferInitiation() {
+ LoanTransactionEnumData transactionType = mock(LoanTransactionEnumData.class);
+ when(transactionType.isInitiateTransfer()).thenReturn(true);
+
+ processor.createJournalEntriesForLoan(createLoanDTO(transactionType));
+
+ verify(helper).createJournalEntriesForLoan(office, CURRENCY_CODE, AccrualAccountsForLoan.TRANSFERS_SUSPENSE.getValue(),
+ AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), LOAN_PRODUCT_ID, null, LOAN_ID, TRANSACTION_ID, TRANSACTION_DATE,
+ PRINCIPAL_AMOUNT);
+ }
+
+ @Test
+ void shouldCreateJournalEntriesForTransferApproval() {
+ LoanTransactionEnumData transactionType = mock(LoanTransactionEnumData.class);
+ when(transactionType.isApproveTransfer()).thenReturn(true);
+
+ processor.createJournalEntriesForLoan(createLoanDTO(transactionType));
+
+ verify(helper).createJournalEntriesForLoan(office, CURRENCY_CODE, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+ AccrualAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), LOAN_PRODUCT_ID, null, LOAN_ID, TRANSACTION_ID, TRANSACTION_DATE,
+ PRINCIPAL_AMOUNT);
+ }
+
+ @Test
+ void shouldCreateJournalEntriesForTransferWithdrawal() {
+ LoanTransactionEnumData transactionType = mock(LoanTransactionEnumData.class);
+ when(transactionType.isWithdrawTransfer()).thenReturn(true);
+
+ processor.createJournalEntriesForLoan(createLoanDTO(transactionType));
+
+ verify(helper).createJournalEntriesForLoan(office, CURRENCY_CODE, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+ AccrualAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), LOAN_PRODUCT_ID, null, LOAN_ID, TRANSACTION_ID, TRANSACTION_DATE,
+ PRINCIPAL_AMOUNT);
+ }
+
+ @Test
+ void shouldNotCreateJournalEntriesForTransferWithoutPrincipalAmount() {
+ LoanTransactionEnumData transactionType = mock(LoanTransactionEnumData.class);
+ when(transactionType.isInitiateTransfer()).thenReturn(true);
+
+ processor.createJournalEntriesForLoan(createLoanDTO(transactionType, null));
+
+ verify(helper, never()).createJournalEntriesForLoan(any(Office.class), anyString(), any(Integer.class), any(Integer.class),
+ any(Long.class), isNull(), any(Long.class), anyString(), any(LocalDate.class), any(BigDecimal.class));
+ }
+
+ private LoanDTO createLoanDTO(final LoanTransactionEnumData transactionType) {
+ return createLoanDTO(transactionType, PRINCIPAL_AMOUNT);
+ }
+
+ private LoanDTO createLoanDTO(final LoanTransactionEnumData transactionType, final BigDecimal principalAmount) {
+ LoanTransactionDTO loanTransactionDTO = new LoanTransactionDTO(TRANSACTION_OFFICE_ID, null, TRANSACTION_ID, TRANSACTION_DATE,
+ transactionType, TRANSACTION_AMOUNT, principalAmount, null, null, null, null, false, Collections.emptyList(),
+ Collections.emptyList(), false, "", null, null, null, null);
+
+ return new LoanDTO(LOAN_ID, LOAN_PRODUCT_ID, LOAN_OFFICE_ID, CURRENCY_CODE, false, true, true, List.of(loanTransactionDTO), false,
+ false, null, false, false, null, null, null);
+ }
+}