Skip to content

Commit bf58c90

Browse files
committed
FINERACT-2455: WC - Delinquency Management - Delinquency days & Delinquency Bucket handling
- create SetWorkingCapitalLoanDelinquencyTagsBusinessStep - QA test for business step order - create ENABLE_INSTANT_DELINQUENCY_CALCULATION + integration tests - Delinquency History for Working Capital Loans - DTOs Entity & Repository - Get API - introduce WorkingCapitalLoanDelinquencyReadPlatformService - for read operations. - Cucumber StepDef + basic tests - WIP - WorkingCapitalLoanDelinquencyClassificationService - Handle loan level delinquency + grace day handling
1 parent 44617c9 commit bf58c90

File tree

37 files changed

+1755
-168
lines changed

37 files changed

+1755
-168
lines changed

fineract-core/src/main/java/org/apache/fineract/infrastructure/configuration/api/GlobalConfigurationConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ public final class GlobalConfigurationConstants {
8181
public static final String ALLOWED_LOAN_STATUSES_OF_DELAYED_SETTLEMENT_FOR_EXTERNAL_ASSET_TRANSFER = "allowed-loan-statuses-of-delayed-settlement-for-external-asset-transfer";
8282
public static final String MAX_LOGIN_RETRY_ATTEMPTS = "max-login-retry-attempts";
8383
public static final String ENABLE_ORIGINATOR_CREATION_DURING_LOAN_APPLICATION = "enable-originator-creation-during-loan-application";
84+
public static final String ENABLE_INSTANT_DELINQUENCY_CALCULATION = "enable-instant-delinquency-calculation";
8485
public static final String PASSWORD_REUSE_CHECK_HISTORY_COUNT = "password-reuse-check-history-count";
8586
public static final String FORCE_WITHDRAWAL_ON_SAVINGS_ACCOUNT = "allow-force-withdrawal-on-savings-account";
8687
public static final String FORCE_WITHDRAWAL_ON_SAVINGS_ACCOUNT_LIMIT = "force-withdrawal-on-savings-account-limit";

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/workingcapitalproduct/DefaultWorkingCapitalLoanProduct.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
public enum DefaultWorkingCapitalLoanProduct implements WorkingCapitalLoanProduct {
2222

2323
WCLP, //
24-
WCLP_FOR_UPDATE; //
24+
WCLP_FOR_UPDATE, WCLP_GRACE_5; //
2525

2626
@Override
2727
public String getName() {

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/WorkingCapitalProductLoanAccountStepDef.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,9 @@ public void checkDisbursementData(String actualDisbursementDate, String transact
562562
.orElseThrow(() -> new RuntimeException(""));
563563
String formattedDate = disbursementDetails.getActualDisbursementDate().format(FORMATTER);
564564
assertThat(formattedDate).isEqualTo(actualDisbursementDate);
565+
log.info(
566+
"Verified working capital loan disbursement was successful for loan ID: {} with actual disbursement date: {} and amount: {}",
567+
loanId, actualDisbursementDate, disbursementDetails.getActualAmount());
565568
assertThat(disbursementDetails.getActualAmount().compareTo(new BigDecimal(transactionAmount))).isEqualTo(0);
566569
}
567570

@@ -639,6 +642,12 @@ private void createWorkingCapitalLoanAccount(final List<String> loanData) {
639642
final PostWorkingCapitalLoansResponse response = ok(
640643
() -> fineractClient.workingCapitalLoans().submitWorkingCapitalLoanApplication(loansRequest));
641644
testContext().set(TestContextKey.LOAN_CREATE_RESPONSE, response);
645+
List<Long> loanIds = testContext().get(TestContextKey.WC_LOAN_IDS);
646+
if (loanIds == null) {
647+
loanIds = new ArrayList<>();
648+
testContext().set(TestContextKey.WC_LOAN_IDS, loanIds);
649+
}
650+
loanIds.add(response.getLoanId());
642651
log.info("Working Capital Loan created with ID: {}", response.getLoanId());
643652
}
644653

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/WorkingCapitalStepDef.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import io.cucumber.java.en.Then;
2727
import io.cucumber.java.en.When;
2828
import java.math.BigDecimal;
29+
import java.time.LocalDate;
2930
import java.util.List;
3031
import java.util.Map;
3132
import java.util.UUID;
@@ -37,11 +38,14 @@
3738
import org.apache.fineract.client.models.DeleteWorkingCapitalLoanProductsProductIdResponse;
3839
import org.apache.fineract.client.models.GetConfigurableAttributes;
3940
import org.apache.fineract.client.models.GetPaymentAllocation;
41+
import org.apache.fineract.client.models.GetWorkingCapitalLoanDelinquencyRangeScheduleTagHistoryResponse;
4042
import org.apache.fineract.client.models.GetWorkingCapitalLoanProductsProductIdResponse;
4143
import org.apache.fineract.client.models.GetWorkingCapitalLoanProductsTemplateResponse;
44+
import org.apache.fineract.client.models.InternalWorkingCapitalLoanPaymentRequest;
4245
import org.apache.fineract.client.models.PostAllowAttributeOverrides;
4346
import org.apache.fineract.client.models.PostWorkingCapitalLoanProductsRequest;
4447
import org.apache.fineract.client.models.PostWorkingCapitalLoanProductsResponse;
48+
import org.apache.fineract.client.models.PostWorkingCapitalLoansResponse;
4549
import org.apache.fineract.client.models.PutWorkingCapitalLoanProductsProductIdRequest;
4650
import org.apache.fineract.client.models.PutWorkingCapitalLoanProductsProductIdResponse;
4751
import org.apache.fineract.client.models.StringEnumOptionData;
@@ -53,6 +57,7 @@
5357
import org.apache.fineract.test.stepdef.AbstractStepDef;
5458
import org.apache.fineract.test.support.TestContextKey;
5559
import org.assertj.core.api.SoftAssertions;
60+
import org.junit.jupiter.api.Assertions;
5661
import org.springframework.beans.factory.annotation.Autowired;
5762

5863
@Slf4j
@@ -350,6 +355,40 @@ public void checkWorkingCapitalLoanProductIsDeletedViaExternalId() {
350355
.contains(ErrorMessageHelper.workingCapitalLoanProductIdentifiedDoesNotExistFailure(String.valueOf(externalId)));
351356
}
352357

358+
@When("make Internal Payment {string} on {string}")
359+
public void internalPayWCLoan(String amount, String transactionDate) {
360+
PostWorkingCapitalLoansResponse workingCapitalLoanProductsResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
361+
Long resourceId = workingCapitalLoanProductsResponse.getResourceId();
362+
fineractFeignClient.workingCapitalLoans().payment(resourceId, new InternalWorkingCapitalLoanPaymentRequest()
363+
.amount(BigDecimal.valueOf(Double.parseDouble(amount))).transactionDate(LocalDate.parse(transactionDate)));
364+
}
365+
366+
@Then("Delinquency Tag History for WC Loan has lines:")
367+
public void checkDelinquencyHistory(final DataTable table) {
368+
PostWorkingCapitalLoansResponse workingCapitalLoanProductsResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
369+
Long resourceId = workingCapitalLoanProductsResponse.getResourceId();
370+
List<GetWorkingCapitalLoanDelinquencyRangeScheduleTagHistoryResponse> actualLines = ok(
371+
() -> fineractFeignClient.workingCapitalLoans().getDelinquencyRangeScheduleTagHistoryById(resourceId));
372+
log.info("Loan {}", actualLines);
373+
List<List<String>> rows = table.asLists();
374+
Assertions.assertEquals(rows.size() - 1, actualLines.size());
375+
for (int i = 0; i < rows.size() - 1; i++) {
376+
GetWorkingCapitalLoanDelinquencyRangeScheduleTagHistoryResponse actual = actualLines.get(i);
377+
Assertions.assertNotNull(actual);
378+
List<String> expected = rows.get(i + 1);
379+
Assertions.assertEquals(expected.get(0), actual.getPeriodNumber() != null ? actual.getPeriodNumber().toString() : null);
380+
Assertions.assertEquals(expected.get(1), actual.getAddedOnDate() != null ? actual.getAddedOnDate().toString() : null);
381+
Assertions.assertEquals(expected.get(2), actual.getLiftedOnDate() != null ? actual.getLiftedOnDate().toString() : null);
382+
383+
Assertions.assertNotNull(actual.getDelinquencyRange());
384+
Assertions.assertEquals(expected.get(3), actual.getDelinquencyRange().getClassification());
385+
Assertions.assertEquals(expected.get(4), actual.getDelinquencyRange().getMinimumAgeDays() == null ? null
386+
: actual.getDelinquencyRange().getMinimumAgeDays().toString());
387+
Assertions.assertEquals(expected.get(5), actual.getDelinquencyRange().getMaximumAgeDays() == null ? null
388+
: actual.getDelinquencyRange().getMaximumAgeDays().toString());
389+
}
390+
}
391+
353392
public PostWorkingCapitalLoanProductsResponse createWorkingCapitalLoanProduct(
354393
PostWorkingCapitalLoanProductsRequest workingCapitalProductRequest) {
355394
String workingCapitalProductName = workingCapitalProductRequest.getName();

fineract-e2e-tests-runner/src/test/java/org/apache/fineract/test/initializer/global/WorkingCapitalInitializerStep.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@ public void initialize() throws Exception {
6161
TestContext.GLOBAL.set(TestContextKey.DEFAULT_WORKING_CAPITAL_LOAN_PRODUCT_CREATE_REQUEST_FOR_UPDATE_WCLP,
6262
defaultForUpdateWCPLRequest);
6363
TestContext.GLOBAL.set(TestContextKey.DEFAULT_WORKING_CAPITAL_LOAN_PRODUCT_CREATE_RESPONSE_FOR_UPDATE_WCLP, responseForUpdateWCPL);
64+
65+
// Delinquency grace period testing
66+
67+
final String WCLP_GRACE_5 = DefaultWorkingCapitalLoanProduct.WCLP_GRACE_5.getName();
68+
final PostWorkingCapitalLoanProductsRequest WCLP_GRACE_5Request = workingCapitalRequestFactory
69+
.defaultWorkingCapitalLoanProductRequest() //
70+
.name(WCLP_GRACE_5) //
71+
.delinquencyBucketId(2L) //
72+
.delinquencyGraceDays(5); //
73+
74+
createWorkingCapitalLoanProductIdempotent(WCLP_GRACE_5Request);
6475
}
6576

6677
private PostWorkingCapitalLoanProductsResponse createWorkingCapitalLoanProductIdempotent(

0 commit comments

Comments
 (0)