You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@fineract.apache.org by ad...@apache.org on 2026/03/10 11:30:56 UTC
(fineract) branch develop updated (242cea39f4 -> c06317b690)
This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a change to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
from 242cea39f4 FINERACT-2421: Update actions/upload-artifact digest to ea165f8
new 45dbe77fe3 FINERACT-2522: Max disb amount validation issue in case multidisb loan with expected tranches and overApplied enabled
new c06317b690 FINERACT-2522: added e2e tests for max disb that expects tranches amount validation with approved over applied setting
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../fineract/test/helper/ErrorMessageHelper.java | 4 +
.../fineract/test/stepdef/loan/LoanStepDef.java | 13 ++
.../test/resources/features/EMICalculation.feature | 4 +-
.../src/test/resources/features/Loan.feature | 179 ++++++++++++++++++++-
.../serialization/LoanDisbursementValidator.java | 20 +--
.../LoanTransactionValidatorImpl.java | 11 +-
.../service/LoanDisbursementService.java | 2 +-
.../ClientLoanIntegrationTest.java | 4 +-
8 files changed, 212 insertions(+), 25 deletions(-)
(fineract) 02/02: FINERACT-2522: added e2e tests for max disb that expects tranches amount validation with approved over applied setting
Posted by ad...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
commit c06317b690ec511bb0235fb3e7717000def2c015
Author: MarianaDmytrivBinariks <md...@binariks.com>
AuthorDate: Fri Mar 6 19:01:50 2026 +0200
FINERACT-2522: added e2e tests for max disb that expects tranches amount validation with approved over applied setting
---
.../src/test/resources/features/Loan.feature | 109 +++++++++++++++++++++
1 file changed, 109 insertions(+)
diff --git a/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature b/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature
index 9b03c69436..d6147dfc09 100644
--- a/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature
+++ b/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature
@@ -9105,10 +9105,35 @@ Feature: Loan
And Admin successfully approves the loan on "1 January 2024" with "1200" amount and expected disbursement date on "1 January 2024"
Then Loan has availableDisbursementAmountWithOverApplied field with value: 500
Then Loan status will be "APPROVED"
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1000.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 01 February 2024 | | 835.74 | 164.26 | 5.83 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 2 | 29 | 01 March 2024 | | 670.53 | 165.21 | 4.88 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 3 | 31 | 01 April 2024 | | 504.35 | 166.18 | 3.91 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 4 | 30 | 01 May 2024 | | 337.2 | 167.15 | 2.94 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 5 | 31 | 01 June 2024 | | 169.08 | 168.12 | 1.97 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 6 | 30 | 01 July 2024 | | 0.0 | 169.08 | 0.99 | 0.0 | 0.0 | 170.07 | 0.0 | 0.0 | 0.0 | 170.07 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1000.0 | 20.52 | 0.0 | 0.0 | 1020.52 | 0.0 | 0.0 | 0.0 | 1020.52 |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2024 | | 1000.0 | |
And Admin successfully add disbursement detail to the loan on "5 January 2024" with 200 EUR transaction amount
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1000.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | | | 05 January 2024 | | 200.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 01 February 2024 | | 1002.77 | 197.23 | 6.85 | 0.0 | 0.0 | 204.08 | 0.0 | 0.0 | 0.0 | 204.08 |
+ | 2 | 29 | 01 March 2024 | | 804.54 | 198.23 | 5.85 | 0.0 | 0.0 | 204.08 | 0.0 | 0.0 | 0.0 | 204.08 |
+ | 3 | 31 | 01 April 2024 | | 605.15 | 199.39 | 4.69 | 0.0 | 0.0 | 204.08 | 0.0 | 0.0 | 0.0 | 204.08 |
+ | 4 | 30 | 01 May 2024 | | 404.6 | 200.55 | 3.53 | 0.0 | 0.0 | 204.08 | 0.0 | 0.0 | 0.0 | 204.08 |
+ | 5 | 31 | 01 June 2024 | | 202.88 | 201.72 | 2.36 | 0.0 | 0.0 | 204.08 | 0.0 | 0.0 | 0.0 | 204.08 |
+ | 6 | 30 | 01 July 2024 | | 0.0 | 202.88 | 1.18 | 0.0 | 0.0 | 204.06 | 0.0 | 0.0 | 0.0 | 204.06 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1200.0 | 24.46 | 0.0 | 0.0 | 1224.46 | 0.0 | 0.0 | 0.0 | 1224.46 |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2024 | | 1000.0 | |
@@ -9119,6 +9144,22 @@ Feature: Loan
And Admin successfully disburse the loan on "1 January 2024" with "1300" EUR transaction amount
Then Loan has availableDisbursementAmountWithOverApplied field with value: 0
Then Loan status will be "ACTIVE"
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1300.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | | | 05 January 2024 | | 200.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 01 February 2024 | | 1286.47 | 213.53 | 7.58 | 0.0 | 0.0 | 221.11 | 0.0 | 0.0 | 0.0 | 221.11 |
+ | 2 | 29 | 01 March 2024 | | 1071.7 | 214.77 | 6.34 | 0.0 | 0.0 | 221.11 | 0.0 | 0.0 | 0.0 | 221.11 |
+ | 3 | 31 | 01 April 2024 | | 855.67 | 216.03 | 5.08 | 0.0 | 0.0 | 221.11 | 0.0 | 0.0 | 0.0 | 221.11 |
+ | 4 | 30 | 01 May 2024 | | 638.38 | 217.29 | 3.82 | 0.0 | 0.0 | 221.11 | 0.0 | 0.0 | 0.0 | 221.11 |
+ | 5 | 31 | 01 June 2024 | | 419.83 | 218.55 | 2.56 | 0.0 | 0.0 | 221.11 | 0.0 | 0.0 | 0.0 | 221.11 |
+ | 6 | 30 | 01 July 2024 | | 200.0 | 219.83 | 1.28 | 0.0 | 0.0 | 221.11 | 0.0 | 0.0 | 0.0 | 221.11 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1300.0 | 26.66 | 0.0 | 0.0 | 1326.66 | 0.0 | 0.0 | 0.0 | 1326.66 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 01 January 2024 | Disbursement | 1300.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1300.0 | false | false |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2024 | 01 January 2024 | 1300.0 | |
@@ -9126,6 +9167,26 @@ Feature: Loan
When Admin sets the business date to "5 January 2024"
Then Admin fails to disburse the loan on "5 January 2024" with "300" EUR transaction amount because of wrong amount
And Admin successfully disburse the loan on "5 January 2024" with "200" EUR transaction amount
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1300.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | | | 05 January 2024 | | 200.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2024 | | 1253.5 | 246.5 | 8.6 | 0.0 | 0.0 | 255.1 | 0.0 | 0.0 | 0.0 | 255.1 |
+ | 2 | 29 | 01 March 2024 | | 1005.71 | 247.79 | 7.31 | 0.0 | 0.0 | 255.1 | 0.0 | 0.0 | 0.0 | 255.1 |
+ | 3 | 31 | 01 April 2024 | | 756.48 | 249.23 | 5.87 | 0.0 | 0.0 | 255.1 | 0.0 | 0.0 | 0.0 | 255.1 |
+ | 4 | 30 | 01 May 2024 | | 505.79 | 250.69 | 4.41 | 0.0 | 0.0 | 255.1 | 0.0 | 0.0 | 0.0 | 255.1 |
+ | 5 | 31 | 01 June 2024 | | 253.64 | 252.15 | 2.95 | 0.0 | 0.0 | 255.1 | 0.0 | 0.0 | 0.0 | 255.1 |
+ | 6 | 30 | 01 July 2024 | | 0.0 | 253.64 | 1.48 | 0.0 | 0.0 | 255.12 | 0.0 | 0.0 | 0.0 | 255.12 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1500.0 | 30.62 | 0.0 | 0.0 | 1530.62 | 0.0 | 0.0 | 0.0 | 1530.62 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 01 January 2024 | Disbursement | 1300.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1300.0 | false | false |
+ | 05 January 2024 | Disbursement | 200.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
+ # --- close loan --- #
+ When Loan Pay-off is made on "5 January 2024"
+ Then Loan is closed with zero outstanding balance and it's all installments have obligations met
@TestRailId:C70225
Scenario: Verify max disb amount validation in case multidisb loan that expect tranches with overapplied setting enabled - UC2
@@ -9137,6 +9198,18 @@ Feature: Loan
And Admin successfully approves the loan on "1 January 2024" with "1200" amount and expected disbursement date on "1 January 2024"
Then Loan has availableDisbursementAmountWithOverApplied field with value: 500
Then Loan status will be "APPROVED"
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1000.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 01 February 2024 | | 835.74 | 164.26 | 5.83 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 2 | 29 | 01 March 2024 | | 670.53 | 165.21 | 4.88 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 3 | 31 | 01 April 2024 | | 504.35 | 166.18 | 3.91 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 4 | 30 | 01 May 2024 | | 337.2 | 167.15 | 2.94 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 5 | 31 | 01 June 2024 | | 169.08 | 168.12 | 1.97 | 0.0 | 0.0 | 170.09 | 0.0 | 0.0 | 0.0 | 170.09 |
+ | 6 | 30 | 01 July 2024 | | 0.0 | 169.08 | 0.99 | 0.0 | 0.0 | 170.07 | 0.0 | 0.0 | 0.0 | 170.07 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1000.0 | 20.52 | 0.0 | 0.0 | 1020.52 | 0.0 | 0.0 | 0.0 | 1020.52 |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2024 | | 1000.0 | |
@@ -9151,6 +9224,22 @@ Feature: Loan
And Admin successfully disburse the loan on "1 January 2024" with "1100" EUR transaction amount
Then Loan status will be "ACTIVE"
Then Loan has availableDisbursementAmountWithOverApplied field with value: 200
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | | | 05 January 2024 | | 200.0 | | | 0.0 | | 0.0 | | | | 0.0 |
+ | 1 | 31 | 01 February 2024 | | 1119.33 | 180.67 | 6.42 | 0.0 | 0.0 | 187.09 | 0.0 | 0.0 | 0.0 | 187.09 |
+ | 2 | 29 | 01 March 2024 | | 937.6 | 181.73 | 5.36 | 0.0 | 0.0 | 187.09 | 0.0 | 0.0 | 0.0 | 187.09 |
+ | 3 | 31 | 01 April 2024 | | 754.81 | 182.79 | 4.3 | 0.0 | 0.0 | 187.09 | 0.0 | 0.0 | 0.0 | 187.09 |
+ | 4 | 30 | 01 May 2024 | | 570.96 | 183.85 | 3.24 | 0.0 | 0.0 | 187.09 | 0.0 | 0.0 | 0.0 | 187.09 |
+ | 5 | 31 | 01 June 2024 | | 386.03 | 184.93 | 2.16 | 0.0 | 0.0 | 187.09 | 0.0 | 0.0 | 0.0 | 187.09 |
+ | 6 | 30 | 01 July 2024 | | 200.0 | 186.03 | 1.09 | 0.0 | 0.0 | 187.12 | 0.0 | 0.0 | 0.0 | 187.12 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1100.0 | 22.57 | 0.0 | 0.0 | 1122.57 | 0.0 | 0.0 | 0.0 | 1122.57 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 01 January 2024 | Disbursement | 1100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1100.0 | false | false |
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
| 01 January 2024 | 01 January 2024 | 1100.0 | |
@@ -9158,3 +9247,23 @@ Feature: Loan
When Admin sets the business date to "5 January 2024"
Then Admin fails to disburse the loan on "5 January 2024" with "800" EUR transaction amount because of wrong amount
And Admin successfully disburse the loan on "5 January 2024" with "400" EUR transaction amount
+ Then Loan Repayment schedule has 6 periods, with the following data for periods:
+ | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | | | 01 January 2024 | | 1100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | | | 05 January 2024 | | 400.0 | | | 0.0 | | 0.0 | 0.0 | | | |
+ | 1 | 31 | 01 February 2024 | | 1253.37 | 246.63 | 8.45 | 0.0 | 0.0 | 255.08 | 0.0 | 0.0 | 0.0 | 255.08 |
+ | 2 | 29 | 01 March 2024 | | 1005.6 | 247.77 | 7.31 | 0.0 | 0.0 | 255.08 | 0.0 | 0.0 | 0.0 | 255.08 |
+ | 3 | 31 | 01 April 2024 | | 756.39 | 249.21 | 5.87 | 0.0 | 0.0 | 255.08 | 0.0 | 0.0 | 0.0 | 255.08 |
+ | 4 | 30 | 01 May 2024 | | 505.72 | 250.67 | 4.41 | 0.0 | 0.0 | 255.08 | 0.0 | 0.0 | 0.0 | 255.08 |
+ | 5 | 31 | 01 June 2024 | | 253.59 | 252.13 | 2.95 | 0.0 | 0.0 | 255.08 | 0.0 | 0.0 | 0.0 | 255.08 |
+ | 6 | 30 | 01 July 2024 | | 0.0 | 253.59 | 1.48 | 0.0 | 0.0 | 255.07 | 0.0 | 0.0 | 0.0 | 255.07 |
+ Then Loan Repayment schedule has the following data in Total row:
+ | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
+ | 1500.0 | 30.47 | 0.0 | 0.0 | 1530.47 | 0.0 | 0.0 | 0.0 | 1530.47 |
+ Then Loan Transactions tab has the following data:
+ | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
+ | 01 January 2024 | Disbursement | 1100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1100.0 | false | false |
+ | 05 January 2024 | Disbursement | 400.0 | 0.0 | 0.0 | 0.0 | 0.0 | 1500.0 | false | false |
+ # --- close loan --- #
+ When Loan Pay-off is made on "5 January 2024"
+ Then Loan is closed with zero outstanding balance and it's all installments have obligations met
(fineract) 01/02: FINERACT-2522: Max disb amount validation issue in case multidisb loan with expected tranches and overApplied enabled
Posted by ad...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
commit 45dbe77fe3af8bb432b8cc928552c2647fada33f
Author: mariiaKraievska <ri...@gmail.com>
AuthorDate: Fri Mar 6 10:20:04 2026 +0200
FINERACT-2522: Max disb amount validation issue in case multidisb loan with expected tranches and overApplied enabled
---
.../fineract/test/helper/ErrorMessageHelper.java | 4 ++
.../fineract/test/stepdef/loan/LoanStepDef.java | 13 ++++
.../test/resources/features/EMICalculation.feature | 4 +-
.../src/test/resources/features/Loan.feature | 70 +++++++++++++++++++++-
.../serialization/LoanDisbursementValidator.java | 20 +++----
.../LoanTransactionValidatorImpl.java | 11 ++--
.../service/LoanDisbursementService.java | 2 +-
.../ClientLoanIntegrationTest.java | 4 +-
8 files changed, 103 insertions(+), 25 deletions(-)
diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java
index d689a359f2..387d57bcff 100644
--- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java
+++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java
@@ -128,6 +128,10 @@ public final class ErrorMessageHelper {
return "Loan Disbursal is not allowed. Loan Account is not in approved and not disbursed state.";
}
+ public static String disburseIsNotAllowedExceedApprovedAmountFailure() {
+ return "Loan can't be disbursed, disburse amount is exceeding approved principal.";
+ }
+
public static String loanSubmitDateInFutureFailureMsg() {
return "The date on which a loan is submitted cannot be in the future.";
}
diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
index b682f3ea69..ca3bd43b50 100644
--- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
+++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java
@@ -1863,6 +1863,19 @@ public class LoanStepDef extends AbstractStepDef {
assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.disburseIsNotAllowedFailure());
}
+ @Then("Admin fails to disburse the loan on {string} with {string} amount due to exceed approved amount")
+ public void disburseIsNotAllowedExceedApprovedAmountFailure(String disbursementDate, String disbursementAmount) {
+ final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
+ final long loanId = loanResponse.getLoanId();
+ final PostLoansLoanIdRequest disburseRequest = LoanRequestFactory.defaultLoanDisburseRequest()
+ .actualDisbursementDate(disbursementDate).transactionAmount(new BigDecimal(disbursementAmount));
+
+ final CallFailedRuntimeException exception = fail(
+ () -> fineractClient.loans().stateTransitions(loanId, disburseRequest, Map.of("command", "disburse")));
+ assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403);
+ assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.disburseIsNotAllowedExceedApprovedAmountFailure());
+ }
+
@Then("Admin fails to disburse the loan on {string} with {string} EUR transaction amount because of charge-off that was performed for the loan")
public void disburseChargedOffLoanFailure(String actualDisbursementDate, String transactionAmount) {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
diff --git a/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature b/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature
index e50ec3ada9..cf3a1e160c 100644
--- a/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature
+++ b/fineract-e2e-tests-runner/src/test/resources/features/EMICalculation.feature
@@ -7950,7 +7950,7 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 30 January 2025 | Accrual | 0.11 | 0.0 | 0.11 | 0.0 | 0.0 | 0.0 | false | false |
| 31 January 2025 | Accrual | 0.11 | 0.0 | 0.11 | 0.0 | 0.0 | 0.0 | false | false |
| 01 February 2025 | Disbursement | 300.0 | 0.0 | 0.0 | 0.0 | 0.0 | 882.78 | false | false |
- Then Admin fails to disburse the loan on "01 February 2025" with "100" amount
+ Then Admin fails to disburse the loan on "01 February 2025" with "100" amount due to exceed approved amount
# --- undo last disbursement --- #
When Admin successfully undo last disbursal
Then Loan Tranche Details tab has the following data:
@@ -8141,7 +8141,7 @@ Feature: EMI calculation and repayment schedule checks for interest bearing loan
| 31 January 2025 | Repayment | 117.86 | 116.16 | 1.7 | 0.0 | 0.0 | 468.02 | false | false |
| 31 January 2025 | Accrual | 0.11 | 0.0 | 0.11 | 0.0 | 0.0 | 0.0 | false | false |
| 01 February 2025 | Disbursement | 300.0 | 0.0 | 0.0 | 0.0 | 0.0 | 768.02 | false | false |
- Then Admin fails to disburse the loan on "01 February 2025" with "100" amount
+ Then Admin fails to disburse the loan on "01 February 2025" with "100" amount due to exceed approved amount
# --- undo disbursement --- #
When Admin sets the business date to "02 February 2025"
When Admin runs inline COB job for Loan
diff --git a/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature b/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature
index fbcc73ade9..9b03c69436 100644
--- a/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature
+++ b/fineract-e2e-tests-runner/src/test/resources/features/Loan.feature
@@ -151,13 +151,13 @@ Feature: Loan
And Admin checks available disbursement amount 0.0 EUR
Then Loan has availableDisbursementAmountWithOverApplied field with value: 300
Then Admin fails to disburse the loan on "2 January 2024" with "1600" EUR transaction amount because of wrong amount
- And Admin successfully disburse the loan on "2 January 2024" with "1500" EUR transaction amount
+ And Admin successfully disburse the loan on "2 January 2024" with "1300" EUR transaction amount
Then Loan has availableDisbursementAmountWithOverApplied field with value: 0
Then Loan status will be "ACTIVE"
And Admin checks available disbursement amount 0.0 EUR
Then Loan Tranche Details tab has the following data:
| Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
- | 01 January 2024 | 02 January 2024 | 1500.0 | |
+ | 01 January 2024 | 02 January 2024 | 1300.0 | |
| 05 January 2024 | | 200.0 | 1200.0 |
When Loan Pay-off is made on "2 January 2024"
@@ -8335,7 +8335,7 @@ Feature: Loan
| 01 January 2025 | Disbursement | 700.0 | 0.0 | 0.0 | 0.0 | 0.0 | 700.0 | false | false |
| 01 January 2025 | Repayment | 117.86 | 117.86 | 0.0 | 0.0 | 0.0 | 582.14 | false | false |
| 01 January 2025 | Disbursement | 300.0 | 0.0 | 0.0 | 0.0 | 0.0 | 882.14 | false | false |
- Then Admin fails to disburse the loan on "01 January 2025" with "100" amount
+ Then Admin fails to disburse the loan on "01 January 2025" with "100" amount due to exceed approved amount
# --- undo disbursement --- #
When Admin successfully undo last disbursal
Then Loan Tranche Details tab has the following data:
@@ -9094,3 +9094,67 @@ Feature: Loan
Then LoanDisbursalTransactionBusinessEvent has changedTerms "false"
When Loan Pay-off is made on "08 January 2024"
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
+
+ @TestRailId:C70224
+ Scenario: Verify max disb amount validation in case multidisb loan that expect tranches with overapplied setting enabled - UC1
+ When Admin sets the business date to "1 January 2024"
+ And Admin creates a client with random data
+ When Admin creates a fully customized loan with disbursement details 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 | 1st_tranche_disb_expected_date |1st_tranche_disb [...]
+ | LP2_PROGRESSIVE_ADV_PYMNT_INTEREST_RECALC_360_30_MULTIDISB_OVER_APPLIED_EXPECTED_TRANCHES | 01 January 2024 | 1000 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | 01 January 2024 | 1000.0 [...]
+ And Admin successfully approves the loan on "1 January 2024" with "1200" amount and expected disbursement date on "1 January 2024"
+ Then Loan has availableDisbursementAmountWithOverApplied field with value: 500
+ Then Loan status will be "APPROVED"
+ Then Loan Tranche Details tab has the following data:
+ | Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
+ | 01 January 2024 | | 1000.0 | |
+ And Admin successfully add disbursement detail to the loan on "5 January 2024" with 200 EUR transaction amount
+ Then Loan Tranche Details tab has the following data:
+ | Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
+ | 01 January 2024 | | 1000.0 | |
+ | 05 January 2024 | | 200.0 | 1200.0 |
+ Then Loan has availableDisbursementAmountWithOverApplied field with value: 300
+ Then Admin fails to disburse the loan on "1 January 2024" with "1600" EUR transaction amount because of wrong amount
+ Then Admin fails to disburse the loan on "1 January 2024" with "1500" EUR transaction amount because of wrong amount
+ And Admin successfully disburse the loan on "1 January 2024" with "1300" EUR transaction amount
+ Then Loan has availableDisbursementAmountWithOverApplied field with value: 0
+ Then Loan status will be "ACTIVE"
+ Then Loan Tranche Details tab has the following data:
+ | Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
+ | 01 January 2024 | 01 January 2024 | 1300.0 | |
+ | 05 January 2024 | | 200.0 | 1200.0 |
+ When Admin sets the business date to "5 January 2024"
+ Then Admin fails to disburse the loan on "5 January 2024" with "300" EUR transaction amount because of wrong amount
+ And Admin successfully disburse the loan on "5 January 2024" with "200" EUR transaction amount
+
+ @TestRailId:C70225
+ Scenario: Verify max disb amount validation in case multidisb loan that expect tranches with overapplied setting enabled - UC2
+ When Admin sets the business date to "1 January 2024"
+ And Admin creates a client with random data
+ When Admin creates a fully customized loan with disbursement details 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 | 1st_tranche_disb_expected_date |1st_tranche_disb [...]
+ | LP2_PROGRESSIVE_ADV_PYMNT_INTEREST_RECALC_360_30_MULTIDISB_OVER_APPLIED_EXPECTED_TRANCHES | 01 January 2024 | 1000 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | 01 January 2024 | 1000.0 [...]
+ And Admin successfully approves the loan on "1 January 2024" with "1200" amount and expected disbursement date on "1 January 2024"
+ Then Loan has availableDisbursementAmountWithOverApplied field with value: 500
+ Then Loan status will be "APPROVED"
+ Then Loan Tranche Details tab has the following data:
+ | Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
+ | 01 January 2024 | | 1000.0 | |
+ And Admin successfully add disbursement detail to the loan on "5 January 2024" with 200 EUR transaction amount
+ Then Loan Tranche Details tab has the following data:
+ | Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
+ | 01 January 2024 | | 1000.0 | |
+ | 05 January 2024 | | 200.0 | 1200.0 |
+ And Admin checks available disbursement amount 0.0 EUR
+ Then Loan has availableDisbursementAmountWithOverApplied field with value: 300
+ Then Admin fails to disburse the loan on "1 January 2024" with "1600" EUR transaction amount because of wrong amount
+ And Admin successfully disburse the loan on "1 January 2024" with "1100" EUR transaction amount
+ Then Loan status will be "ACTIVE"
+ Then Loan has availableDisbursementAmountWithOverApplied field with value: 200
+ Then Loan Tranche Details tab has the following data:
+ | Expected Disbursement On | Disbursed On | Principal | Net Disbursal Amount |
+ | 01 January 2024 | 01 January 2024 | 1100.0 | |
+ | 05 January 2024 | | 200.0 | 1200.0 |
+ When Admin sets the business date to "5 January 2024"
+ Then Admin fails to disburse the loan on "5 January 2024" with "800" EUR transaction amount because of wrong amount
+ And Admin successfully disburse the loan on "5 January 2024" with "400" EUR transaction amount
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanDisbursementValidator.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanDisbursementValidator.java
index fe2fa363e7..df3f4558a7 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanDisbursementValidator.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanDisbursementValidator.java
@@ -34,24 +34,20 @@ public final class LoanDisbursementValidator {
private final LoanApplicationValidator loanApplicationValidator;
- public void compareDisbursedToApprovedOrProposedPrincipal(final Loan loan, final BigDecimal disbursedAmount,
- final BigDecimal totalDisbursed) {
+ public void compareDisbursedToApprovedOrProposedPrincipal(final Loan loan, final BigDecimal totalDisbursed) {
final BigDecimal totalCapitalizedIncome = loan.getSummary().getTotalCapitalizedIncome();
final BigDecimal totalCapitalizedIncomeAdjustment = MathUtil.nullToZero(loan.getSummary().getTotalCapitalizedIncomeAdjustment());
final BigDecimal netCapitalizedIncome = totalCapitalizedIncome.subtract(totalCapitalizedIncomeAdjustment);
- if (loan.loanProduct().isDisallowExpectedDisbursements() && loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
+ if (loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
+ // Validate total disbursed amount (after this transaction) against max allowed
validateOverMaximumAmount(loan, totalDisbursed, netCapitalizedIncome);
} else {
- if (loan.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
- validateOverMaximumAmount(loan, disbursedAmount, netCapitalizedIncome);
- } else {
- if ((totalDisbursed.compareTo(loan.getApprovedPrincipal()) > 0)
- || (totalDisbursed.add(netCapitalizedIncome).compareTo(loan.getApprovedPrincipal()) > 0)) {
- final String errorMsg = "Loan can't be disbursed, disburse amount is exceeding approved principal.";
- throw new LoanDisbursalException(errorMsg, "disburse.amount.must.be.less.than.approved.principal", totalDisbursed,
- loan.getApprovedPrincipal());
- }
+ if ((totalDisbursed.compareTo(loan.getApprovedPrincipal()) > 0)
+ || (totalDisbursed.add(netCapitalizedIncome).compareTo(loan.getApprovedPrincipal()) > 0)) {
+ final String errorMsg = "Loan can't be disbursed, disburse amount is exceeding approved principal.";
+ throw new LoanDisbursalException(errorMsg, "disburse.amount.must.be.less.than.approved.principal", totalDisbursed,
+ loan.getApprovedPrincipal());
}
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
index 65c55ee8c4..43132cc328 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanTransactionValidatorImpl.java
@@ -162,8 +162,9 @@ public class LoanTransactionValidatorImpl implements LoanTransactionValidator {
validateLoanClientIsActive(loan);
validateLoanGroupIsActive(loan);
- final BigDecimal disbursedAmount = loan.getSummary().getTotalPrincipalDisbursed();
- loanDisbursementValidator.compareDisbursedToApprovedOrProposedPrincipal(loan, principal, disbursedAmount);
+ final BigDecimal totalDisbursedAmount = principal != null ? loan.getDisbursedAmount().add(principal)
+ : loan.getDisbursedAmount();
+ loanDisbursementValidator.compareDisbursedToApprovedOrProposedPrincipal(loan, totalDisbursedAmount);
if (loan.isChargedOff()) {
throw new GeneralPlatformDomainRuleException("error.msg.loan.disbursal.not.allowed.on.charged.off",
@@ -186,9 +187,9 @@ public class LoanTransactionValidatorImpl implements LoanTransactionValidator {
if ((loanCollateralManagements != null && !loanCollateralManagements.isEmpty()) && loan.getLoanType().isIndividualAccount()) {
BigDecimal totalCollateral = collectTotalCollateral(loanCollateralManagements);
- // Validate the loan collateral value against the disbursedAmount
- if (disbursedAmount.compareTo(totalCollateral) > 0) {
- throw new LoanCollateralAmountNotSufficientException(disbursedAmount);
+ // Validate the loan collateral value against the total disbursed amount after this transaction
+ if (totalDisbursedAmount.compareTo(totalCollateral) > 0) {
+ throw new LoanCollateralAmountNotSufficientException(totalDisbursedAmount);
}
}
diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java
index b8fe98fa56..0d6d0296aa 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanDisbursementService.java
@@ -208,7 +208,7 @@ public class LoanDisbursementService {
.setPrincipal(loan.getLoanRepaymentScheduleDetail().getPrincipal().minus(diff).getAmount());
totalAmount = loan.getLoanRepaymentScheduleDetail().getPrincipal().getAmount();
}
- loanDisbursementValidator.compareDisbursedToApprovedOrProposedPrincipal(loan, disburseAmount.getAmount(), totalAmount);
+ loanDisbursementValidator.compareDisbursedToApprovedOrProposedPrincipal(loan, totalAmount);
}
return disburseAmount;
}
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
index fa6e570489..c8208b4cb1 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java
@@ -6413,7 +6413,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
.locale("en").dateFormat(DATETIME_PATTERN));
});
assertEquals(403, exception.getResponse().code());
- assertTrue(exception.getMessage().contains("error.msg.loan.disbursal.not.allowed.on.charged.off"));
+ assertTrue(exception.getMessage().contains("amount.can't.be.greater.than.maximum.applied.loan.amount.calculation"));
exception = assertThrows(CallFailedRuntimeException.class, () -> {
errorLoanTransactionHelper.disburseLoan((long) loanID,
@@ -6421,7 +6421,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest {
.locale("en").dateFormat(DATETIME_PATTERN));
});
assertEquals(403, exception.getResponse().code());
- assertTrue(exception.getMessage().contains("error.msg.loan.disbursal.not.allowed.on.charged.off"));
+ assertTrue(exception.getMessage().contains("amount.can't.be.greater.than.maximum.applied.loan.amount.calculation"));
LOAN_TRANSACTION_HELPER.makeLoanRepayment((long) loanID, new PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN)
.transactionDate("07 September 2022").locale("en").transactionAmount(5000.0));