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 b108ca92a FINERACT-1971: Enhance validation for installment level 
delinquency for loan product
b108ca92a is described below

commit b108ca92a67269cd578bfe823d9f4d45a54e43c9
Author: Ruchi Dhamankar <[email protected]>
AuthorDate: Mon May 13 16:30:33 2024 +0530

    FINERACT-1971: Enhance validation for installment level delinquency for 
loan product
---
 .../serialization/LoanProductDataValidator.java    | 22 ++++++++--
 .../CustomSnapshotEventIntegrationTest.java        |  5 ---
 ...allmentLevelDelinquencyAPIIntegrationTests.java | 50 ++++++++++++++++++++++
 3 files changed, 68 insertions(+), 9 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
index 433fcf630..9fbd578f1 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/serialization/LoanProductDataValidator.java
@@ -342,9 +342,9 @@ public final class LoanProductDataValidator {
         // Validating whether the processor is existing
         
loanRepaymentScheduleTransactionProcessorFactory.determineProcessor(transactionProcessingStrategyCode);
 
+        Long delinquencyBucketId = null;
         if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
 element)) {
-            final Long delinquencyBucketId = 
this.fromApiJsonHelper.extractLongNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
-                    element);
+            delinquencyBucketId = 
this.fromApiJsonHelper.extractLongNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
 element);
             
baseDataValidator.reset().parameter(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME).value(delinquencyBucketId)
                     .ignoreIfNull().integerGreaterThanZero();
         }
@@ -785,6 +785,13 @@ public final class LoanProductDataValidator {
                     
.extractBooleanNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, 
element);
             
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY)
                     
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
+            if (delinquencyBucketId == null) {
+                if (enableInstallmentLevelDelinquency) {
+                    
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY).failWithCode(
+                            
"can.be.enabled.for.loan.product.having.valid.delinquency.bucket",
+                            "Installment level delinquency cannot be enabled 
if Delinquency bucket is not configured for loan product");
+                }
+            }
         }
 
         String loanScheduleType = LoanScheduleType.CUMULATIVE.name();
@@ -1301,9 +1308,9 @@ public final class LoanProductDataValidator {
                     .integerZeroOrGreater();
         }
 
+        Long delinquencyBucketId = null;
         if 
(this.fromApiJsonHelper.parameterExists(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
 element)) {
-            final Long delinquencyBucketId = 
this.fromApiJsonHelper.extractLongNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
-                    element);
+            delinquencyBucketId = 
this.fromApiJsonHelper.extractLongNamed(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME,
 element);
             
baseDataValidator.reset().parameter(LoanProductConstants.DELINQUENCY_BUCKET_PARAM_NAME).value(delinquencyBucketId)
                     .ignoreIfNull().integerGreaterThanZero();
         }
@@ -1770,6 +1777,13 @@ public final class LoanProductDataValidator {
                     
.extractBooleanNamed(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY, 
element);
             
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY)
                     
.value(enableInstallmentLevelDelinquency).ignoreIfNull().validateForBooleanValue();
+            if (delinquencyBucketId == null) {
+                if (enableInstallmentLevelDelinquency) {
+                    
baseDataValidator.reset().parameter(LoanProductConstants.ENABLE_INSTALLMENT_LEVEL_DELINQUENCY).failWithCode(
+                            
"can.be.enabled.for.loan.product.having.valid.delinquency.bucket",
+                            "Installment level delinquency cannot be enabled 
if Delinquency bucket is not configured for loan product");
+                }
+            }
         }
 
         String loanScheduleType = 
loanProduct.getLoanProductRelatedDetail().getLoanScheduleType().name();
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java
index e8b9e3359..bfbb3242d 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/CustomSnapshotEventIntegrationTest.java
@@ -64,7 +64,6 @@ public class CustomSnapshotEventIntegrationTest extends 
BaseLoanIntegrationTest
             // Create Loan Product
             PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
                     InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
-            loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
             PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(loanProductsRequest);
 
             // Apply and Approve Loan
@@ -112,7 +111,6 @@ public class CustomSnapshotEventIntegrationTest extends 
BaseLoanIntegrationTest
             // Create Loan Product
             PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
                     InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
-            loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
             PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(loanProductsRequest);
 
             // Apply and Approve Loan
@@ -169,7 +167,6 @@ public class CustomSnapshotEventIntegrationTest extends 
BaseLoanIntegrationTest
             // Create Loan Product
             PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
                     InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
-            loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
             PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(loanProductsRequest);
 
             // Apply and Approve Loan
@@ -215,7 +212,6 @@ public class CustomSnapshotEventIntegrationTest extends 
BaseLoanIntegrationTest
             // Create Loan Product
             PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
                     InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
-            loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
             PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(loanProductsRequest);
 
             // Apply and Approve Loan
@@ -259,7 +255,6 @@ public class CustomSnapshotEventIntegrationTest extends 
BaseLoanIntegrationTest
             // Create Loan Product
             PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
                     InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
-            loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
             PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(loanProductsRequest);
 
             // Apply and Approve Loan
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java
index d6ed9adc7..19a8e9c34 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/InstallmentLevelDelinquencyAPIIntegrationTests.java
@@ -31,6 +31,7 @@ import 
org.apache.fineract.client.models.GetLoansLoanIdLoanInstallmentLevelDelin
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
 import org.apache.fineract.client.models.PostLoanProductsResponse;
+import org.apache.fineract.client.models.PutLoanProductsProductIdRequest;
 import org.apache.fineract.client.util.CallFailedRuntimeException;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
@@ -410,6 +411,55 @@ public class 
InstallmentLevelDelinquencyAPIIntegrationTests extends BaseLoanInte
 
     }
 
+    @Test
+    public void 
tesInstallmentLevelSettingForLoanProductWithoutDelinquencyBucketValidation() {
+
+        runAt("31 May 2023", () -> {
+            // Create Client
+            Long clientId = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+
+            // Create Loan Product without delinquency bucket
+            PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
+                    InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
+            // set installment level delinquency as true
+            loanProductsRequest.setEnableInstallmentLevelDelinquency(true);
+
+            // Create loan product with installment level delinquency setting
+            CallFailedRuntimeException callFailedRuntimeException = 
Assertions.assertThrows(CallFailedRuntimeException.class,
+                    () -> 
loanProductHelper.createLoanProduct(loanProductsRequest));
+
+            Assertions.assertTrue(callFailedRuntimeException.getMessage()
+                    .contains("Installment level delinquency cannot be enabled 
if Delinquency bucket is not configured for loan product"));
+
+        });
+
+    }
+
+    @Test
+    public void 
tesUpdateInstallmentLevelSettingForLoanProductWithoutDelinquencyBucketValidation()
 {
+
+        runAt("31 May 2023", () -> {
+            // Create Client
+            Long clientId = 
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+
+            // Create Loan Product without delinquency bucket
+            PostLoanProductsRequest loanProductsRequest = 
create1InstallmentAmountInMultiplesOf4Period1MonthLongWithInterestAndAmortizationProduct(
+                    InterestType.FLAT, AmortizationType.EQUAL_INSTALLMENTS);
+
+            PostLoanProductsResponse loanProductResponse = 
loanProductHelper.createLoanProduct(loanProductsRequest);
+
+            // Update loan product with installment level delinquency setting
+            CallFailedRuntimeException callFailedRuntimeException = 
Assertions.assertThrows(CallFailedRuntimeException.class,
+                    () -> 
loanProductHelper.updateLoanProductById(loanProductResponse.getResourceId(),
+                            new 
PutLoanProductsProductIdRequest().enableInstallmentLevelDelinquency(true).locale("en")));
+
+            Assertions.assertTrue(callFailedRuntimeException.getMessage()
+                    .contains("Installment level delinquency cannot be enabled 
if Delinquency bucket is not configured for loan product"));
+
+        });
+
+    }
+
     private void updateBusinessDateAndExecuteCOBJob(String date) {
         businessDateHelper.updateBusinessDate(
                 new 
BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));

Reply via email to