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
The following commit(s) were added to refs/heads/develop by this push:
new 28747fecd FINERACT-1724: Approval limit calculation modification
28747fecd is described below
commit 28747fecd15935f0f71c580174d0cef80113569f
Author: abraham.menyhart <[email protected]>
AuthorDate: Tue Jul 4 13:07:20 2023 +0200
FINERACT-1724: Approval limit calculation modification
---
.../portfolio/loanaccount/domain/Loan.java | 7 +-
.../LoanDisbursementDetailsIntegrationTest.java | 93 ++++++++++++++++++++++
.../common/loans/LoanProductTestBuilder.java | 4 +-
.../common/loans/LoanTransactionHelper.java | 6 ++
4 files changed, 106 insertions(+), 4 deletions(-)
diff --git
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
index d69e1149f..dd9cd2bd1 100644
---
a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
+++
b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java
@@ -2668,8 +2668,11 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom {
if (this.loanProduct().isDisallowExpectedDisbursements() &&
this.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
BigDecimal maxDisbursedAmount = getOverAppliedMax();
- if (disbursedAmount.compareTo(maxDisbursedAmount) > 0) {
- final String errorMessage = "Loan disbursal amount can't be
greater than maximum applied loan amount calculation.";
+ if (totalDisbursed.compareTo(maxDisbursedAmount) > 0) {
+ final String errorMessage = String.format(
+ "Loan disbursal amount can't be greater than maximum
applied loan amount calculation. "
+ + "Total disbursed amount: %s Maximum
disbursal amount: %s",
+ totalDisbursed.stripTrailingZeros().toPlainString(),
maxDisbursedAmount.stripTrailingZeros().toPlainString());
throw new InvalidLoanStateTransitionException("disbursal",
"amount.can't.be.greater.than.maximum.applied.loan.amount.calculation",
errorMessage, disbursedAmount,
maxDisbursedAmount);
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
index 3d6cdbe5b..6ce5f9937 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDisbursementDetailsIntegrationTest.java
@@ -18,6 +18,8 @@
*/
package org.apache.fineract.integrationtests;
+import static java.lang.Double.parseDouble;
+import static org.hamcrest.Matchers.equalTo;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -36,6 +38,7 @@ import java.util.List;
import java.util.Locale;
import lombok.extern.slf4j.Slf4j;
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
+import org.apache.fineract.client.models.GetLoansLoanIdDisbursementDetails;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
@@ -316,6 +319,89 @@ public class LoanDisbursementDetailsIntegrationTest {
log.info("-----------MULTI DISBURSAL LOAN EQUAL INSTALLMENTS
SUCCESSFULLY-------");
}
+ @Test
+ public void disburseLoanWithExceededOverAppliedAmountFails() {
+ final String operationDate = "01 January 2014";
+ final String principal = "1000";
+ final String firstDisbursedPrincipal = "900";
+ final String secondDisbursedPrincipal = "1101";
+
+ final Integer clientId = ClientHelper.createClient(this.requestSpec,
this.responseSpec, operationDate);
+ log.info("-----------------CLIENT CREATED WITH ID-------------------
{}", clientId);
+
+ final String loanProductJSON = new
LoanProductTestBuilder().withAmortizationTypeAsEqualInstallments() //
+ .withInterestTypeAsDecliningBalance().withMoratorium("",
"").withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+ .withInterestTypeAsDecliningBalance() //
+ .withMultiDisburse() //
+ .withDisallowExpectedDisbursements(true) //
+ .build(null);
+ log.info("Product {}", loanProductJSON);
+ final Integer loanProductId =
this.loanTransactionHelper.getLoanProductId(loanProductJSON);
+ log.info("------------------LOAN PRODUCT CREATED WITH ID-----------
{}", loanProductId);
+
+ final Integer loanId =
applyForMultiTrancheLoanApplication(clientId.toString(),
loanProductId.toString(), principal, operationDate);
+
+ log.info("-------------------LOAN CREATED WITH loanId-----------------
{}", loanId);
+
+ this.loanTransactionHelper.approveLoanWithApproveAmount(operationDate,
expectedDisbursementDate, principal, loanId, null);
+ log.info("-------------------MULTI DISBURSAL LOAN APPROVED
SUCCESSFULLY-------");
+
+ GetLoansLoanIdResponse getLoansLoanIdResponse =
this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
+ assertNotNull(getLoansLoanIdResponse);
+
+
this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
+
+ loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate,
loanId, firstDisbursedPrincipal);
+ log.info("-------------------MULTI DISBURSAL LOAN DISBURSED
SUCCESSFULLY-------");
+
+ loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate,
loanId, secondDisbursedPrincipal,
+ overAppliedAmountFailedResponseSpec());
+ log.info("-------------------MULTI DISBURSAL LOAN DISBURSEMENT
FAILED-------");
+ }
+
+ @Test
+ public void disburseLoanWithExceededOverAppliedAmountSucceed() {
+ final String operationDate = "01 January 2014";
+ final String principal = "1000";
+ final String firstDisbursedPrincipal = "900";
+ final String secondDisbursedPrincipal = "1100";
+
+ final Integer clientId = ClientHelper.createClient(this.requestSpec,
this.responseSpec, operationDate);
+ log.info("-----------------CLIENT CREATED WITH ID-------------------
{}", clientId);
+
+ final String loanProductJSON = new
LoanProductTestBuilder().withAmortizationTypeAsEqualInstallments() //
+ .withInterestTypeAsDecliningBalance().withMoratorium("",
"").withInterestCalculationPeriodTypeAsRepaymentPeriod(true)
+ .withInterestTypeAsDecliningBalance() //
+ .withMultiDisburse() //
+ .withDisallowExpectedDisbursements(true) //
+ .build(null);
+ log.info("Product {}", loanProductJSON);
+ final Integer loanProductId =
this.loanTransactionHelper.getLoanProductId(loanProductJSON);
+ log.info("------------------LOAN PRODUCT CREATED WITH ID-----------
{}", loanProductId);
+
+ final Integer loanId =
applyForMultiTrancheLoanApplication(clientId.toString(),
loanProductId.toString(), principal, operationDate);
+
+ log.info("-------------------LOAN CREATED WITH loanId-----------------
{}", loanId);
+
+ this.loanTransactionHelper.approveLoanWithApproveAmount(operationDate,
expectedDisbursementDate, principal, loanId, null);
+ log.info("-------------------MULTI DISBURSAL LOAN APPROVED
SUCCESSFULLY-------");
+
+ GetLoansLoanIdResponse getLoansLoanIdResponse =
this.loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
+ assertNotNull(getLoansLoanIdResponse);
+
+
this.loanTransactionHelper.printRepaymentSchedule(getLoansLoanIdResponse);
+
+ loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate,
loanId, firstDisbursedPrincipal);
+ log.info("-------------------MULTI DISBURSAL LOAN DISBURSED
SUCCESSFULLY-FIRST-------");
+
+ loanTransactionHelper.disburseLoanWithTransactionAmount(operationDate,
loanId, secondDisbursedPrincipal);
+ log.info("-------------------MULTI DISBURSAL LOAN DISBURSED
SUCCESSFULLY-SECOND-------");
+
+ double disbursementPrincipalSum =
this.loanTransactionHelper.getLoan(requestSpec, responseSpec,
loanId).getDisbursementDetails()
+
.stream().map(GetLoansLoanIdDisbursementDetails::getPrincipal).mapToDouble(p ->
p).sum();
+ assertEquals(parseDouble(firstDisbursedPrincipal) +
parseDouble(secondDisbursedPrincipal), disbursementPrincipalSum);
+ }
+
@Test
public void createApproveAndValidateMultiDisburseLoan() throws
ParseException {
@@ -599,4 +685,11 @@ public class LoanDisbursementDetailsIntegrationTest {
}
}
}
+
+ private ResponseSpecification overAppliedAmountFailedResponseSpec() {
+ return new
ResponseSpecBuilder().expectBody("userMessageGlobalisationCode",
equalTo("validation.msg.domain.rule.violation"))
+ .expectBody("errors[0].userMessageGlobalisationCode",
+
equalTo("error.msg.loan.disbursal.amount.can't.be.greater.than.maximum.applied.loan.amount.calculation"))
+ .expectStatusCode(403).build();
+ }
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index d06dbd24d..a13b01e6c 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -435,8 +435,8 @@ public class LoanProductTestBuilder {
return this;
}
- public LoanProductTestBuilder withDisallowExpectedDisbursements(boolean
disallowExpectectedDisbursements) {
- this.disallowExpectedDisbursements = disallowExpectectedDisbursements;
+ public LoanProductTestBuilder withDisallowExpectedDisbursements(boolean
disallowExpectedDisbursements) {
+ this.disallowExpectedDisbursements = disallowExpectedDisbursements;
if (this.disallowExpectedDisbursements) {
this.allowApprovedDisbursedAmountsOverApplied = true;
this.overAppliedCalculationType = "percentage";
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
index 16c1a1708..b162694cd 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanTransactionHelper.java
@@ -356,6 +356,12 @@ public class LoanTransactionHelper extends IntegrationTest
{
getDisburseLoanAsJSON(date, transactionAmount, null,
externalId), "");
}
+ public Object disburseLoanWithTransactionAmount(final String date, final
Integer loanID, final String transactionAmount,
+ ResponseSpecification responseSpec) {
+ return
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
+ getDisburseLoanAsJSON(date, transactionAmount, null),
responseSpec);
+ }
+
public HashMap disburseLoanWithTransactionAmount(final String date, final
Integer loanID, final String transactionAmount) {
return
performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
getDisburseLoanAsJSON(date, transactionAmount, null));