Skip to content
Draft
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 @@ -183,6 +183,7 @@ private CommandWrapperConstants() {}
public static final String ENTITY_LOANPRODUCT = "LOANPRODUCT";
public static final String ENTITY_WORKINGCAPITALLOANPRODUCT = "WORKINGCAPITALLOANPRODUCT";
public static final String ENTITY_WORKINGCAPITALLOAN = "WORKINGCAPITALLOAN";
public static final String ENTITY_WORKINGCAPITALLOANTRANSACTION = "ENTITY_WORKINGCAPITALLOANTRANSACTION";
public static final String ENTITY_CLIENTIDENTIFIER = "CLIENTIDENTIFIER";
public static final String ENTITY_CLIENT = "CLIENT";
public static final String ENTITY_DATATABLE = "DATATABLE";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@
import static org.apache.fineract.commands.domain.CommandWrapperConstants.ENTITY_WORKINGCAPITALLOAN;
import static org.apache.fineract.commands.domain.CommandWrapperConstants.ENTITY_WORKINGCAPITALLOANCHARGE;
import static org.apache.fineract.commands.domain.CommandWrapperConstants.ENTITY_WORKINGCAPITALLOANPRODUCT;
import static org.apache.fineract.commands.domain.CommandWrapperConstants.ENTITY_WORKINGCAPITALLOANTRANSACTION;
import static org.apache.fineract.useradministration.service.AppUserConstants.PASSWORD;
import static org.apache.fineract.useradministration.service.AppUserConstants.REPEAT_PASSWORD;

Expand Down Expand Up @@ -4068,4 +4069,13 @@ public CommandWrapperBuilder undoAccountTransfer(final Long transferId) {
this.href = "/accounttransfers";
return this;
}

public CommandWrapperBuilder undoWorkingCapitalLoanTransaction(Long resolvedLoanId, Long resolvedTransactionId) {
this.actionName = ACTION_UNDO;
this.entityName = ENTITY_WORKINGCAPITALLOANTRANSACTION;
this.entityId = resolvedTransactionId;
this.loanId = resolvedLoanId;
this.href = "/working-capital-loans/" + loanId + "/transactions/" + entityId + "?command=undo";
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ public void verifyRetrievedSummaryFields(final DataTable dataTable) {

@Then("The retrieved amortization schedule has payments with the following details:")
public void verifyRetrievedPaymentDetails(final DataTable dataTable) {
verifyPaymentDetails(dataTable);
verifyPaymentDetails(dataTable, null);
}

@Then("The retrieved amortization schedule has payments with the following details in first {string} lines:")
public void verifyRetrievedPaymentDetailsFirstNLines(final String firstNLines, final DataTable dataTable) {
verifyPaymentDetails(dataTable, Integer.valueOf(firstNLines));
}

private void verifySummaryFields(final DataTable dataTable) {
Expand All @@ -105,11 +110,13 @@ private void verifySummaryFields(final DataTable dataTable) {
assertions.assertAll();
}

private void verifyPaymentDetails(final DataTable dataTable) {
private void verifyPaymentDetails(final DataTable dataTable, final Integer firstNLines) {
final ProjectedAmortizationScheduleData response = TestContext.INSTANCE.get(WC_AMORT_SCHEDULE_KEY);
assertThat(response).as("Amortization schedule response").isNotNull();

final List<ProjectedAmortizationSchedulePaymentData> actualPayments = response.getPayments();
final List<ProjectedAmortizationSchedulePaymentData> actualPayments = firstNLines != null
? response.getPayments().subList(0, firstNLines)
: response.getPayments();
assertThat(actualPayments).as("payments list").isNotNull();

final List<Map<String, String>> expectedRows = dataTable.asMaps();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
import org.apache.fineract.client.feign.util.CallFailedRuntimeException;
import org.apache.fineract.client.models.CommandProcessingResult;
import org.apache.fineract.client.models.DeleteWorkingCapitalLoansLoanIdResponse;
import org.apache.fineract.client.models.ExecuteWorkingCapitalLoanTransactionCommandRequest;
import org.apache.fineract.client.models.ExecuteWorkingCapitalLoanTransactionCommandResponse;
import org.apache.fineract.client.models.GetBalance;
import org.apache.fineract.client.models.GetCodeValuesDataResponse;
import org.apache.fineract.client.models.GetDisbursementDetail;
Expand Down Expand Up @@ -3010,6 +3012,29 @@ public void verifyReversedWorkingCapitalLoanTransactionJournalEntries(final Stri
verifyTransactionsJournalEntries(transactionType, transactionDate, true, null, table);
}

@When("Customer undo {string}th working capital transaction made on {string}")
public void undoNthTransaction(String nthItemStr, String transactionDate) throws IOException {
final GetWorkingCapitalLoanTransactionsResponse getWorkingCapitalLoansLoanIdResponse = retrieveLoanTransactions(getCreatedLoanId());
final List<GetWorkingCapitalLoanTransactionIdResponse> actualTransactions = getWorkingCapitalLoansLoanIdResponse.getContent();

int nthItem = Integer.parseInt(nthItemStr) - 1;

GetWorkingCapitalLoanTransactionIdResponse transactionIdResponse = actualTransactions.stream()
.filter(t -> transactionDate.equals(FORMATTER.format(t.getTransactionDate()))).toList().get(nthItem);

String reversalExternalId = Utils.randomStringGenerator("wcl-reversal-ext-id", 8);
ExecuteWorkingCapitalLoanTransactionCommandRequest request = new ExecuteWorkingCapitalLoanTransactionCommandRequest()
.reversalExternalId(reversalExternalId);

ExecuteWorkingCapitalLoanTransactionCommandResponse undo = ok(
() -> fineractClient.workingCapitalLoanTransactions().executeWorkingCapitalLoanTransactionCommandByLoanIdTransactionId(
getCreatedLoanId(), transactionIdResponse.getId(), "undo", request));
Assertions.assertNotNull(undo);

// testContext().set(TestContextKey.LOAN_TRANSACTION_UNDO_RESPONSE, transactionUndoResponse);

}

private void verifyTransactionsJournalEntries(final String transactionType, final String transactionDate, final boolean reversed,
final Integer expectedCount, final DataTable table) {
final Long loanId = getCreatedLoanId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,18 @@ Feature: Working Capital Breach Evaluation
When Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount
And Admin runs inline COB job for Working Capital Loan by loanId
When Admin sets the business date to "15 January 2026"
And Admin makes Internal Payment "500.0" on "2026-01-15"
And Customer makes repayment on "15 January 2026" with 500.0 transaction amount on Working Capital loan
When Admin sets the business date to "01 February 2026"
And Admin runs inline COB job for Working Capital Loan by loanId
Then Working Capital loan breach schedule has the following data:
| periodNumber | fromDate | toDate | numberOfDays | minPaymentAmount | outstandingAmount | nearBreach | breach |
| 1 | 2026-01-01 | 2026-01-31 | 31 | 500.00 | 0.00 | null | false |
| 2 | 2026-02-01 | 2026-02-28 | 28 | 500.00 | 500.00 | null | null |
When Customer undo "1"th working capital transaction made on "15 January 2026"
Then Working Capital loan breach schedule has the following data:
| periodNumber | fromDate | toDate | numberOfDays | minPaymentAmount | outstandingAmount | nearBreach | breach |
| 1 | 2026-01-01 | 2026-01-31 | 31 | 500.00 | 500.00 | null | true |
| 2 | 2026-02-01 | 2026-02-28 | 28 | 500.00 | 500.00 | null | null |

@TestRailId:C76609
Scenario: Verify that partial payment less than minPayment results in breach true after period end
Expand Down
Loading