This is an automated email from the ASF dual-hosted git repository.

arnold 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 66aab8d15 Fix Delinquency Classification for scenario
66aab8d15 is described below

commit 66aab8d157c6fb2e7c0cda29d2d8887330fd6c56
Author: Jose Alberto Hernandez <[email protected]>
AuthorDate: Tue Nov 22 19:41:01 2022 -0600

    Fix Delinquency Classification for scenario
---
 .../service/LoanDelinquencyDomainServiceImpl.java  |   4 +-
 .../DelinquencyAndChargebackIntegrationTest.java   | 110 ++++++++++++++++++++-
 2 files changed, 108 insertions(+), 6 deletions(-)

diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/LoanDelinquencyDomainServiceImpl.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/LoanDelinquencyDomainServiceImpl.java
index 26ddea7a8..1d569c90b 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/LoanDelinquencyDomainServiceImpl.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/delinquency/service/LoanDelinquencyDomainServiceImpl.java
@@ -116,13 +116,13 @@ public class LoanDelinquencyDomainServiceImpl implements 
LoanDelinquencyDomainSe
 
         Long overdueDays = 0L;
         if (overdueSinceDate != null) {
-            overdueSinceDate = 
overdueSinceDate.plusDays(graceDays.longValue());
-            collectionData.setDelinquentDate(overdueSinceDate);
             overdueDays = DateUtils.getDifferenceInDays(overdueSinceDate, 
businessDate);
             if (overdueDays < 0) {
                 overdueDays = 0L;
             }
             collectionData.setPastDueDays(overdueDays);
+            overdueSinceDate = 
overdueSinceDate.plusDays(graceDays.longValue());
+            collectionData.setDelinquentDate(overdueSinceDate);
         }
         collectionData.setDelinquentAmount(outstandingAmount);
 
diff --git 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
index 191728fb4..361aaf096 100644
--- 
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
+++ 
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/DelinquencyAndChargebackIntegrationTest.java
@@ -34,6 +34,7 @@ import 
org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdResponse;
 import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse;
 import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
+import org.apache.fineract.infrastructure.core.service.DateUtils;
 import org.apache.fineract.integrationtests.common.BusinessDateHelper;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
@@ -93,7 +94,7 @@ public class DelinquencyAndChargebackIntegrationTest {
 
         // Create Loan Account
         final Integer loanId = createLoanAccount(loanTransactionHelper, 
clientId.toString(),
-                getLoanProductsProductResponse.getId().toString(), 
operationDate);
+                getLoanProductsProductResponse.getId().toString(), 
operationDate, "12");
 
         // Move the Business date 1 month to apply the first repayment
         businessDate = businessDate.plusMonths(1);
@@ -182,6 +183,107 @@ public class DelinquencyAndChargebackIntegrationTest {
         GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.FALSE);
     }
 
+    @Test
+    public void testLoanClassificationStepAsPartOfCOBRepeated() {
+        GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.TRUE);
+
+        LocalDate businessDate = LocalDate.parse("2022-01-01", 
DateUtils.DEFAULT_DATE_FORMATTER);
+        log.info("Current Business date {}", businessDate);
+        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, businessDate);
+
+        final SchedulerJobHelper schedulerJobHelper = new 
SchedulerJobHelper(requestSpec);
+        // Delinquency Bucket
+        final Integer delinquencyBucketId = 
DelinquencyBucketsHelper.createDelinquencyBucket(requestSpec, responseSpec);
+        final GetDelinquencyBucketsResponse delinquencyBucket = 
DelinquencyBucketsHelper.getDelinquencyBucket(requestSpec, responseSpec,
+                delinquencyBucketId);
+
+        // Client and Loan account creation
+        final Integer clientId = ClientHelper.createClient(this.requestSpec, 
this.responseSpec, "01 January 2012");
+        final GetLoanProductsProductIdResponse getLoanProductsProductResponse 
= createLoanProduct(loanTransactionHelper,
+                delinquencyBucket.getId());
+        assertNotNull(getLoanProductsProductResponse);
+
+        // Older date to have more than one overdue installment
+        String operationDate = Utils.dateFormatter.format(businessDate);
+        log.info("Operation date  {}", businessDate);
+
+        // Create Loan Account
+        final Integer loanId = createLoanAccount(loanTransactionHelper, 
clientId.toString(),
+                getLoanProductsProductResponse.getId().toString(), 
operationDate, "3");
+
+        // Move the Business date 1 month to apply the first repayment
+        businessDate = businessDate.plusMonths(1);
+        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, businessDate);
+        log.info("Current Business date {}", businessDate);
+
+        String amountVal = "400.00";
+        Float transactionAmount = Float.valueOf(amountVal);
+        operationDate = Utils.dateFormatter.format(businessDate);
+        PostLoansLoanIdTransactionsResponse loanIdTransactionsResponse = 
loanTransactionHelper.makeLoanRepayment(operationDate,
+                transactionAmount, loanId);
+        assertNotNull(loanIdTransactionsResponse);
+        Long transactionId = loanIdTransactionsResponse.getResourceId();
+        loanTransactionHelper.reviewLoanTransactionRelations(loanId, 
transactionId, 0);
+
+        // Move the Business date 1 month more to apply the second repayment
+        businessDate = businessDate.plusMonths(1);
+        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, businessDate);
+        log.info("Current Business date {}", businessDate);
+
+        operationDate = Utils.dateFormatter.format(businessDate);
+        loanIdTransactionsResponse = 
loanTransactionHelper.makeLoanRepayment(operationDate, transactionAmount, 
loanId);
+        assertNotNull(loanIdTransactionsResponse);
+        transactionId = loanIdTransactionsResponse.getResourceId();
+        loanTransactionHelper.reviewLoanTransactionRelations(loanId, 
transactionId, 0);
+
+        // Get loan details expecting to have not a delinquency classification 
and 1,000 as Outstanding
+        GetLoansLoanIdResponse getLoansLoanIdResponse = 
loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId);
+        validateLoanAccount(getLoansLoanIdResponse, "0.00", "400.00", 0, 
doubleZERO);
+
+        // Move the Business date n days to apply the chargeback for the 
previous repayment
+        businessDate = businessDate.plusDays(15);
+        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, businessDate);
+        log.info("Current Business date {}", businessDate);
+
+        // Apply the Chargeback transaction
+        final Long chargebackTransactionId = 
loanTransactionHelper.applyChargebackTransaction(loanId, transactionId, 
amountVal, 0,
+                responseSpec);
+        loanTransactionHelper.reviewLoanTransactionRelations(loanId, 
transactionId, 1);
+
+        // Validate the account expecting to have an adjustment for 100.00 and 
Outstanding 1,100
+        getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, 
responseSpec, loanId);
+        assertNotNull(getLoansLoanIdResponse);
+        // Past Due Days in Zero because the Charge back transaction exists 
and It was done with the current date
+        validateLoanAccount(getLoansLoanIdResponse, amountVal, "800.00", 0, 
Double.valueOf("0.00"));
+
+        // Move the Business date n days to run the COB
+        businessDate = businessDate.plusDays(23);
+        BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, 
BusinessDateType.BUSINESS_DATE, businessDate);
+        log.info("Current Business date {}", businessDate);
+
+        // Run the Loan COB Job
+        final String jobName = "Loan COB";
+        schedulerJobHelper.executeAndAwaitJob(jobName);
+
+        // Get loan details expecting to have a delinquency classification
+        getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, 
responseSpec, loanId);
+        validateLoanAccount(getLoansLoanIdResponse, amountVal, "800.00", 23, 
Double.valueOf("800.00"));
+
+        // Move the Business date few days to apply the repayment for 
Chargeback
+        businessDate = LocalDate.parse("2022-03-20", 
DateUtils.DEFAULT_DATE_FORMATTER);
+        operationDate = Utils.dateFormatter.format(businessDate);
+        loanIdTransactionsResponse = 
loanTransactionHelper.makeLoanRepayment(operationDate, transactionAmount, 
loanId);
+        assertNotNull(loanIdTransactionsResponse);
+        transactionId = loanIdTransactionsResponse.getResourceId();
+        loanTransactionHelper.reviewLoanTransactionRelations(loanId, 
transactionId, 0);
+
+        // Get loan details expecting to have a delinquency classification
+        getLoansLoanIdResponse = loanTransactionHelper.getLoan(requestSpec, 
responseSpec, loanId);
+        validateLoanAccount(getLoansLoanIdResponse, amountVal, "400.00", 7, 
Double.valueOf("400.00"));
+
+        GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, 
responseSpec, Boolean.FALSE);
+    }
+
     private GetLoanProductsProductIdResponse createLoanProduct(final 
LoanTransactionHelper loanTransactionHelper,
             final Integer delinquencyBucketId) {
         final HashMap<String, Object> loanProductMap = new 
LoanProductTestBuilder().build(null, delinquencyBucketId);
@@ -190,9 +292,9 @@ public class DelinquencyAndChargebackIntegrationTest {
     }
 
     private Integer createLoanAccount(final LoanTransactionHelper 
loanTransactionHelper, final String clientId, final String loanProductId,
-            final String operationDate) {
-        final String loanApplicationJSON = new 
LoanApplicationTestBuilder().withPrincipal(principalAmount).withLoanTermFrequency("12")
-                
.withLoanTermFrequencyAsMonths().withNumberOfRepayments("12").withRepaymentEveryAfter("1")
+            final String operationDate, final String periods) {
+        final String loanApplicationJSON = new 
LoanApplicationTestBuilder().withPrincipal(principalAmount).withLoanTermFrequency(periods)
+                
.withLoanTermFrequencyAsMonths().withNumberOfRepayments(periods).withRepaymentEveryAfter("1")
                 .withRepaymentFrequencyTypeAsMonths() //
                 .withInterestRatePerPeriod("0") //
                 .withExpectedDisbursementDate(operationDate) //

Reply via email to