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 f981ffe51 FINERACT-1971: Loan transaction processing strategy validation fix f981ffe51 is described below commit f981ffe519b6d821332970dd7c386344051ff55f Author: taskain7 <task...@gmail.com> AuthorDate: Fri Dec 15 12:03:28 2023 +0100 FINERACT-1971: Loan transaction processing strategy validation fix --- .../LoanApplicationCommandFromApiJsonHelper.java | 16 +++++++ .../LoanApplicationApprovalTest.java | 49 ++++++++++++++++------ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java index ca34c369d..37e39e9e0 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/serialization/LoanApplicationCommandFromApiJsonHelper.java @@ -396,6 +396,14 @@ public final class LoanApplicationCommandFromApiJsonHelper { .extractStringNamed(LoanApiConstants.transactionProcessingStrategyCodeParameterName, element); baseDataValidator.reset().parameter(LoanApiConstants.transactionProcessingStrategyCodeParameterName) .value(transactionProcessingStrategy).notNull(); + + if (!AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY + .equals(loanProduct.getTransactionProcessingStrategyCode()) + && AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY.equals(transactionProcessingStrategy)) { + baseDataValidator.reset().parameter(LoanApiConstants.transactionProcessingStrategyCodeParameterName).failWithCode( + "strategy.cannot.be.advanced.payment.allocation.if.not.configured", + "Loan transaction processing strategy cannot be Advanced Payment Allocation Strategy if it's not configured on loan product"); + } // Validating whether the processor is existing loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(transactionProcessingStrategy); @@ -670,6 +678,14 @@ public final class LoanApplicationCommandFromApiJsonHelper { loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(transactionProcessingStrategy); } + if (!AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY + .equals(loanProduct.getTransactionProcessingStrategyCode()) + && AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY.equals(transactionProcessingStrategy)) { + baseDataValidator.reset().parameter(LoanApiConstants.transactionProcessingStrategyCodeParameterName).failWithCode( + "strategy.cannot.be.advanced.payment.allocation.if.not.configured", + "Loan transaction processing strategy cannot be Advanced Payment Allocation Strategy if it's not configured on loan product"); + } + BigDecimal principal = null; if (this.fromApiJsonHelper.parameterExists(LoanApiConstants.principalParameterName, element)) { atLeastOneParameterPassedForUpdate = true; diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java index 3e3a32a4c..7a667bb77 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanApplicationApprovalTest.java @@ -29,6 +29,7 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import lombok.extern.slf4j.Slf4j; import org.apache.fineract.integrationtests.common.ClientHelper; import org.apache.fineract.integrationtests.common.CollateralManagementHelper; import org.apache.fineract.integrationtests.common.CommonConstants; @@ -38,18 +39,18 @@ import org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder; import org.apache.fineract.integrationtests.common.loans.LoanStatusChecker; import org.apache.fineract.integrationtests.common.loans.LoanTestLifecycleExtension; import org.apache.fineract.integrationtests.common.loans.LoanTransactionHelper; +import org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; @SuppressWarnings("rawtypes") @ExtendWith(LoanTestLifecycleExtension.class) +@Slf4j public class LoanApplicationApprovalTest { - private static final Logger LOG = LoggerFactory.getLogger(LoanApplicationApprovalTest.class); + private static final String DATETIME_PATTERN = "dd MMMM yyyy"; private ResponseSpecification responseSpec; private ResponseSpecification responseSpecForStatusCode403; private ResponseSpecification responseSpecForStatusCode400; @@ -136,16 +137,41 @@ public class LoanApplicationApprovalTest { createTranches.add(createTrancheDetail("23 March 2014", "4000")); final Integer clientID = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014"); - LOG.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientID); + log.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientID); final Integer loanProductID = this.loanTransactionHelper .getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withTranches(true) .withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null)); - LOG.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}", + log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}", loanProductID); this.trancheLoansApprovedAmountLesserThanProposedAmount(clientID, loanProductID, createTranches); this.trancheLoansApprovalValidation(clientID, loanProductID, createTranches); + } + + @Test + public void loanApplicationShouldFailIfTransactionProcessingStrategyIsAdvancedPaymentAllocationButItIsNotConfiguredOnProduct() { + final Integer clientId = ClientHelper.createClient(this.requestSpec, this.responseSpec, "01 January 2014"); + log.info("---------------------------------CLIENT CREATED WITH ID--------------------------------------------------- {}", clientId); + + final Integer loanProductId = this.loanTransactionHelper + .getLoanProductId(new LoanProductTestBuilder().withInterestTypeAsDecliningBalance().withTranches(true) + .withInterestCalculationPeriodTypeAsRepaymentPeriod(true).build(null)); + log.info("----------------------------------LOAN PRODUCT CREATED WITH ID------------------------------------------- {}", + loanProductId); + + loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode400); + final String loanApplicationJSON = new LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1") + .withLoanTermFrequencyAsMonths().withNumberOfRepayments("1").withRepaymentEveryAfter("1") + .withRepaymentFrequencyTypeAsMonths().withInterestRatePerPeriod("0").withInterestTypeAsFlatBalance() + .withAmortizationTypeAsEqualPrincipalPayments().withInterestCalculationPeriodTypeSameAsRepaymentPeriod() + .withExpectedDisbursementDate("01 March 2022").withSubmittedOnDate("01 March 2022").withLoanType("individual") + .withRepaymentStrategy(AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY) + .build(clientId.toString(), loanProductId.toString(), null); + List<HashMap> error = (List<HashMap>) loanTransactionHelper.createLoanAccount(loanApplicationJSON, CommonConstants.RESPONSE_ERROR); + assertEquals( + "validation.msg.loan.transactionProcessingStrategyCode.strategy.cannot.be.advanced.payment.allocation.if.not.configured", + error.get(0).get(CommonConstants.RESPONSE_ERROR_MESSAGE_CODE)); } @@ -160,17 +186,17 @@ public class LoanApplicationApprovalTest { approveTranches.add(createTrancheDetail("23 March 2014", "1000")); final Integer loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches); - LOG.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanID); + log.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanID); HashMap loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); - LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------"); + log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------"); loanStatusHashMap = this.loanTransactionHelper.approveLoanWithApproveAmount(approveDate, expectedDisbursementDate, approvalAmount, loanID, approveTranches); LoanStatusChecker.verifyLoanIsApproved(loanStatusHashMap); LoanStatusChecker.verifyLoanIsWaitingForDisbursal(loanStatusHashMap); - LOG.info("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------"); + log.info("-----------------------------------MULTI DISBURSAL LOAN APPROVED SUCCESSFULLY---------------------------------------"); } @@ -205,12 +231,12 @@ public class LoanApplicationApprovalTest { approveTranche4.add(createTrancheDetail("24 March 2014", "100")); final Integer loanID = applyForLoanApplicationWithTranches(clientID, loanProductID, proposedAmount, createTranches); - LOG.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanID); + log.info("-----------------------------------LOAN CREATED WITH LOANID------------------------------------------------- {}", loanID); HashMap<String, Object> loanStatusHashMap = LoanStatusChecker.getStatusOfLoan(this.requestSpec, this.responseSpec, loanID); LoanStatusChecker.verifyLoanIsPending(loanStatusHashMap); - LOG.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------"); + log.info("-----------------------------------APPROVE LOAN-----------------------------------------------------------"); this.loanTransactionHelper = new LoanTransactionHelper(this.requestSpec, this.responseSpecForStatusCode400); /* Tranches with same expected disbursement date */ @@ -278,7 +304,7 @@ public class LoanApplicationApprovalTest { public Integer applyForLoanApplicationWithTranches(final Integer clientID, final Integer loanProductID, String principal, List<HashMap> tranches) { - LOG.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); + log.info("--------------------------------APPLYING FOR LOAN APPLICATION--------------------------------"); List<HashMap> collaterals = new ArrayList<>(); final Integer collateralId = CollateralManagementHelper.createCollateralProduct(this.requestSpec, this.responseSpec); Assertions.assertNotNull(collateralId); @@ -304,5 +330,4 @@ public class LoanApplicationApprovalTest { return this.loanTransactionHelper.getLoanId(loanApplicationJSON); } - }