FINERACT-1724: Approval limit calculation modification
This commit is contained in:
committed by
Adam Saghy
parent
1cb1372e68
commit
28747fecd1
+5
-2
@@ -2668,8 +2668,11 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom {
|
|||||||
|
|
||||||
if (this.loanProduct().isDisallowExpectedDisbursements() && this.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
|
if (this.loanProduct().isDisallowExpectedDisbursements() && this.loanProduct().isAllowApprovedDisbursedAmountsOverApplied()) {
|
||||||
BigDecimal maxDisbursedAmount = getOverAppliedMax();
|
BigDecimal maxDisbursedAmount = getOverAppliedMax();
|
||||||
if (disbursedAmount.compareTo(maxDisbursedAmount) > 0) {
|
if (totalDisbursed.compareTo(maxDisbursedAmount) > 0) {
|
||||||
final String errorMessage = "Loan disbursal amount can't be greater than maximum applied loan amount calculation.";
|
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",
|
throw new InvalidLoanStateTransitionException("disbursal",
|
||||||
"amount.can't.be.greater.than.maximum.applied.loan.amount.calculation", errorMessage, disbursedAmount,
|
"amount.can't.be.greater.than.maximum.applied.loan.amount.calculation", errorMessage, disbursedAmount,
|
||||||
maxDisbursedAmount);
|
maxDisbursedAmount);
|
||||||
|
|||||||
+93
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.fineract.integrationtests;
|
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.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@@ -36,6 +38,7 @@ import java.util.List;
|
|||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
|
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.GetLoansLoanIdRepaymentPeriod;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
|
import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
|
||||||
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
import org.apache.fineract.client.models.GetLoansLoanIdResponse;
|
||||||
@@ -316,6 +319,89 @@ public class LoanDisbursementDetailsIntegrationTest {
|
|||||||
log.info("-----------MULTI DISBURSAL LOAN EQUAL INSTALLMENTS SUCCESSFULLY-------");
|
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
|
@Test
|
||||||
public void createApproveAndValidateMultiDisburseLoan() throws ParseException {
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -435,8 +435,8 @@ public class LoanProductTestBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LoanProductTestBuilder withDisallowExpectedDisbursements(boolean disallowExpectectedDisbursements) {
|
public LoanProductTestBuilder withDisallowExpectedDisbursements(boolean disallowExpectedDisbursements) {
|
||||||
this.disallowExpectedDisbursements = disallowExpectectedDisbursements;
|
this.disallowExpectedDisbursements = disallowExpectedDisbursements;
|
||||||
if (this.disallowExpectedDisbursements) {
|
if (this.disallowExpectedDisbursements) {
|
||||||
this.allowApprovedDisbursedAmountsOverApplied = true;
|
this.allowApprovedDisbursedAmountsOverApplied = true;
|
||||||
this.overAppliedCalculationType = "percentage";
|
this.overAppliedCalculationType = "percentage";
|
||||||
|
|||||||
+6
@@ -356,6 +356,12 @@ public class LoanTransactionHelper extends IntegrationTest {
|
|||||||
getDisburseLoanAsJSON(date, transactionAmount, null, externalId), "");
|
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) {
|
public HashMap disburseLoanWithTransactionAmount(final String date, final Integer loanID, final String transactionAmount) {
|
||||||
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
|
return performLoanTransaction(createLoanOperationURL(DISBURSE_LOAN_COMMAND, loanID),
|
||||||
getDisburseLoanAsJSON(date, transactionAmount, null));
|
getDisburseLoanAsJSON(date, transactionAmount, null));
|
||||||
|
|||||||
Reference in New Issue
Block a user