Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@
"int"
]
},
{
"default": null,
"name": "pastDueDate",
"type": [
"null",
"string"
]
},
{
"default": null,
"name": "nextPaymentDueDate",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package org.apache.fineract.test.stepdef.loan;

import static org.apache.fineract.client.feign.util.FeignCalls.ok;
import static org.assertj.core.api.Assertions.assertThat;

import io.cucumber.java.en.Then;
import io.cucumber.java.en.When;
Expand All @@ -30,10 +31,12 @@
import org.apache.fineract.client.models.PostLoansResponse;
import org.apache.fineract.test.messaging.EventAssertion;
import org.apache.fineract.test.messaging.event.assetexternalization.LoanAccountCustomSnapshotEvent;
import org.apache.fineract.test.messaging.event.loan.LoanBalanceChangedEvent;
import org.apache.fineract.test.messaging.event.loan.repayment.LoanRepaymentDueEvent;
import org.apache.fineract.test.messaging.event.loan.repayment.LoanRepaymentOverdueEvent;
import org.apache.fineract.test.stepdef.AbstractStepDef;
import org.apache.fineract.test.support.TestContextKey;
import org.junit.jupiter.api.Assertions;
import org.springframework.beans.factory.annotation.Autowired;

public class InlineCOBStepDef extends AbstractStepDef {
Expand All @@ -49,6 +52,7 @@ public class InlineCOBStepDef extends AbstractStepDef {
@When("Admin runs inline COB job for Loan")
public void runInlineCOB() throws IOException {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
Assertions.assertNotNull(loanResponse);
long loanId = loanResponse.getLoanId();

InlineJobRequest inlineJobRequest = new InlineJobRequest().addLoanIdsItem(loanId);
Expand All @@ -59,6 +63,7 @@ public void runInlineCOB() throws IOException {
@Then("Loan Repayment Due Business Event is created")
public void checkLoanRepaymentDueBusinessEventCreated() {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
Assertions.assertNotNull(loanResponse);
long loanId = loanResponse.getLoanId();

eventAssertion.assertEventRaised(LoanRepaymentDueEvent.class, loanId);
Expand All @@ -67,6 +72,7 @@ public void checkLoanRepaymentDueBusinessEventCreated() {
@Then("Loan Repayment Overdue Business Event is created")
public void checkLoanRepaymentOverdueBusinessEventCreated() {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
Assertions.assertNotNull(loanResponse);
long loanId = loanResponse.getLoanId();

eventAssertion.assertEventRaised(LoanRepaymentOverdueEvent.class, loanId);
Expand All @@ -75,9 +81,26 @@ public void checkLoanRepaymentOverdueBusinessEventCreated() {
@Then("LoanAccountCustomSnapshotBusinessEvent is created with business date {string}")
public void checkLoanRepaymentDueBusinessEventCreatedWithBusinessDate(String expectedBusinessDate) {
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
Assertions.assertNotNull(loanResponse);
long loanId = loanResponse.getLoanId();

LocalDate expectedBusinessDateParsed = LocalDate.parse(expectedBusinessDate, FORMATTER);
eventAssertion.assertEvent(LoanAccountCustomSnapshotEvent.class, loanId).isRaisedOnBusinessDate(expectedBusinessDateParsed);
}

@Then("LoanBalanceChangedBusinessEvent has pastDueDate {string}")
public void checkLoanBalanceChangedBusinessEventHasPastDueDate(final String expectedPastDueDate) {
final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
Assertions.assertNotNull(loanResponse);
final long loanId = loanResponse.getLoanId();

final String expectedPastDueDateValue = "null".equals(expectedPastDueDate) ? null : expectedPastDueDate;

eventAssertion.assertEvent(LoanBalanceChangedEvent.class, loanId).extractingData(loanAccountDataV1 -> {
final String actualPastDueDate = loanAccountDataV1.getDelinquent() == null ? null
: loanAccountDataV1.getDelinquent().getPastDueDate();
assertThat(actualPastDueDate).as("pastDueDate in LoanBalanceChangedBusinessEvent").isEqualTo(expectedPastDueDateValue);
return null;
});
}
}

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -1622,6 +1622,7 @@ public void disburseLoan(String actualDisbursementDate, String transactionAmount
.isEqualTo(statusExpected);//
eventCheckHelper.disburseLoanEventCheck(loanId);
eventCheckHelper.loanDisbursalTransactionEventCheck(loanDisburseResponse);
eventCheckHelper.loanBalanceChangedEventCheck(loanId);
}

@And("Admin successfully add disbursement detail to the loan on {string} with {double} EUR transaction amount")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2176,3 +2176,96 @@ Feature: LoanDelinquency
And Loan has the following LOAN level delinquency data:
| classification | delinquentAmount | delinquentDate | delinquentDays | pastDueDays |
| RANGE_90 | 666.68 | 06 February 2025 | 98 | 103 |

@TestRailId:C4619
Scenario: Verify that pastDueDate is returned correctly for overdue loan
When Admin sets the business date to "01 October 2023"
When Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_INSTALLMENT_LEVEL_DELINQUENCY | 01 October 2023 | 1000 | 0 | FLAT | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 October 2023" with "1000" amount and expected disbursement date on "01 October 2023"
When Admin successfully disburse the loan on "01 October 2023" with "1000" EUR transaction amount
When Admin sets the business date to "10 October 2023"
When Admin runs inline COB job for Loan
Then Loan has the following LOAN level delinquency data:
| classification | delinquentAmount | delinquentDate | pastDueDate | delinquentDays | pastDueDays |
| RANGE_3 | 250.0 | 04 October 2023 | 01 October 2023 | 6 | 9 |

@TestRailId:C4620
Scenario: Verify that pastDueDate is null when loan has no overdue
When Admin sets the business date to "01 October 2023"
When Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_INSTALLMENT_LEVEL_DELINQUENCY | 01 October 2023 | 1000 | 0 | FLAT | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 October 2023" with "1000" amount and expected disbursement date on "01 October 2023"
When Admin successfully disburse the loan on "01 October 2023" with "1000" EUR transaction amount
And Customer makes "AUTOPAY" repayment on "01 October 2023" with 250 EUR transaction amount
When Admin runs inline COB job for Loan
Then Loan has the following LOAN level delinquency data:
| classification | delinquentAmount | delinquentDate | pastDueDate | delinquentDays | pastDueDays |
| NO_DELINQUENCY | 0.0 | null | null | 0 | 0 |

@TestRailId:C4621
Scenario: Verify that pastDueDate equals chargeback date when chargeback creates overdue
When Admin sets the business date to "01 October 2023"
When Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_DOWNPAYMENT_ADV_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL_INSTALLMENT_LEVEL_DELINQUENCY | 01 October 2023 | 1000 | 0 | FLAT | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 October 2023" with "1000" amount and expected disbursement date on "01 October 2023"
When Admin successfully disburse the loan on "01 October 2023" with "1000" EUR transaction amount
And Customer makes "AUTOPAY" repayment on "01 October 2023" with 250 EUR transaction amount
When Admin sets the business date to "05 October 2023"
When Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 250 EUR transaction amount
When Admin sets the business date to "10 October 2023"
When Admin runs inline COB job for Loan
Then Loan has the following LOAN level delinquency data:
| classification | delinquentAmount | delinquentDate | pastDueDate | delinquentDays | pastDueDays |
| RANGE_1 | 250.0 | 08 October 2023 | 05 October 2023 | 2 | 5 |

@TestRailId:C4622
Scenario: Verify that pastDueDate is present in LoanBalanceChangedBusinessEvent for overdue loan
When Admin sets the business date to "01 October 2023"
When Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 01 October 2023 | 1000 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 October 2023" with "1000" amount and expected disbursement date on "01 October 2023"
When Admin successfully disburse the loan on "01 October 2023" with "1000" EUR transaction amount
When Admin sets the business date to "20 October 2023"
And Create an interest pause period with start date "25 October 2023" and end date "30 October 2023"
And LoanBalanceChangedBusinessEvent has pastDueDate "2023-10-16"

@TestRailId:C4623
Scenario: Verify that pastDueDate is null in LoanBalanceChangedBusinessEvent when loan has no overdue
When Admin sets the business date to "01 October 2023"
When Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 01 October 2023 | 1000 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 October 2023" with "1000" amount and expected disbursement date on "01 October 2023"
When Admin successfully disburse the loan on "01 October 2023" with "1000" EUR transaction amount
When Admin sets the business date to "16 October 2023"
And Customer makes "AUTOPAY" repayment on "16 October 2023" with 335.28 EUR transaction amount
When Admin sets the business date to "20 October 2023"
And Create an interest pause period with start date "25 October 2023" and end date "30 October 2023"
And LoanBalanceChangedBusinessEvent has pastDueDate "null"

@TestRailId:C4624
Scenario: Verify that pastDueDate is present in LoanBalanceChangedBusinessEvent and equals chargeback date when chargeback creates overdue
When Admin sets the business date to "01 October 2023"
When Admin creates a client with random data
When Admin creates a fully customized loan with the following data:
| LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy |
| LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 01 October 2023 | 1000 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 45 | DAYS | 15 | DAYS | 3 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
And Admin successfully approves the loan on "01 October 2023" with "1000" amount and expected disbursement date on "01 October 2023"
When Admin successfully disburse the loan on "01 October 2023" with "1000" EUR transaction amount
When Admin sets the business date to "16 October 2023"
And Customer makes "AUTOPAY" repayment on "16 October 2023" with 335.28 EUR transaction amount
When Admin sets the business date to "20 October 2023"
When Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 335.28 EUR transaction amount
When Admin sets the business date to "25 October 2023"
And Create an interest pause period with start date "25 October 2023" and end date "30 October 2023"
Then LoanBalanceChangedBusinessEvent has pastDueDate "2023-10-20"
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ public CollectionData getOverdueCollectionData(final Loan loan, final List<LoanD
overdueDays = 0L;
}
collectionData.setPastDueDays(overdueDays);
collectionData.setPastDueDate(overdueSinceDate);
LocalDate delinquentStartDate = overdueSinceDate.plusDays(graceDays.longValue());
collectionData.setDelinquentDate(delinquentStartDate);
}
Expand Down Expand Up @@ -205,6 +206,7 @@ public LoanDelinquencyData getLoanDelinquencyData(final Loan loan, List<LoanDeli
overdueDays = 0L;
}
collectionData.setPastDueDays(overdueDays);
collectionData.setPastDueDate(overdueSinceDate);
LocalDate delinquentStartDate = overdueSinceDate.plusDays(graceDays.longValue());
collectionData.setDelinquentDate(delinquentStartDate);
}
Expand Down Expand Up @@ -244,6 +246,7 @@ private CollectionData getInstallmentOverdueCollectionData(final Loan loan, fina
overdueDays = 0L;
}
collectionData.setPastDueDays(overdueDays);
collectionData.setPastDueDate(overdueSinceDate);
collectionData.setDelinquentDate(overdueSinceDate);
}
collectionData.setDelinquentAmount(outstandingAmount);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public final class CollectionData {
private BigDecimal availableDisbursementAmount;
private BigDecimal availableDisbursementAmountWithOverApplied;
private Long pastDueDays;
private LocalDate pastDueDate;
private LocalDate nextPaymentDueDate;
private BigDecimal nextPaymentAmount;
private Long delinquentDays;
Expand All @@ -52,7 +53,8 @@ public final class CollectionData {

public static CollectionData template() {
final BigDecimal zero = BigDecimal.ZERO;
return new CollectionData(zero, zero, 0L, null, zero, 0L, null, zero, null, zero, null, zero, null, null, zero, zero, zero, zero);
return new CollectionData(zero, zero, 0L, null, null, zero, 0L, null, zero, null, zero, null, zero, null, null, zero, zero, zero,
zero);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1027,6 +1027,8 @@ private GetLoansLoanIdDelinquencySummary() {}
@Schema(example = "12")
public Integer pastDueDays;
@Schema(example = "[2022, 07, 01]")
public LocalDate pastDueDate;
@Schema(example = "[2022, 07, 01]")
public LocalDate nextPaymentDueDate;
@Schema(example = "123.23")
public BigDecimal nextPaymentAmount;
Expand Down
Loading
Loading