diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/GlobalConfigurationStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/GlobalConfigurationStepDef.java index 0536c477528..60c89d38fbc 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/GlobalConfigurationStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/common/GlobalConfigurationStepDef.java @@ -44,7 +44,7 @@ public class GlobalConfigurationStepDef { private FineractFeignClient fineractClient; // restore the default even when a scenario fails mid-way, so the submitted-date setting cannot leak - @After("@WorkingCapitalLoanChargeAccrualFeature") + @After("@WorkingCapitalLoanChargeAccrualFeature or @WorkingCapitalTransactionSummaryReportFeature") public void restoreChargeAccrualDateConfig() { globalConfigurationHelper.setGlobalConfigValueString("charge-accrual-date", "due-date"); globalConfigurationHelper.setGlobalConfigValueString("wcl-charge-accrual-time", "eod"); diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java index 5635a4b01f6..a39770ccc57 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java @@ -3397,6 +3397,19 @@ public void writeOffLoan(String transactionDate, String writeOffReason) { testContext().set(TestContextKey.LOAN_WRITE_OFF_RESPONSE, writeOffResponse); } + @And("Admin makes a recovery payment of {double} on the loan on {string}") + public void makeRecoveryPayment(final double transactionAmount, final String transactionDate) { + final long loanId = getLoanId(); + final PostLoansLoanIdTransactionsRequest recoveryRequest = new PostLoansLoanIdTransactionsRequest()// + .transactionDate(transactionDate)// + .transactionAmount(transactionAmount)// + .dateFormat(DATE_FORMAT)// + .locale(DEFAULT_LOCALE); + + ok(() -> fineractClient.loanTransactions().handleCommandsLoanTransaction(loanId, recoveryRequest, + Map.of("command", "recoverypayment"))); + } + @Then("Write-off transaction is not possible on {string}") public void writeOffFailure(final String transactionDate) { final long loanId = getLoanId(); diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/reporting/ReportingStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/reporting/ReportingStepDef.java index 7d1cebe9878..5dcb1e5b440 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/reporting/ReportingStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/reporting/ReportingStepDef.java @@ -26,11 +26,14 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; import lombok.RequiredArgsConstructor; import org.apache.fineract.client.feign.FineractFeignClient; import org.apache.fineract.client.models.PostOfficesResponse; @@ -44,6 +47,8 @@ public class ReportingStepDef extends AbstractStepDef { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.ENGLISH); private static final String TRIAL_BALANCE_REPORT = "Trial Balance Summary Report with Asset Owner"; + private static final String WC_TRANSACTION_SUMMARY_REPORT = "Transaction Summary Report for Working Capital Loans"; + private static final String WC_TRANSACTION_SUMMARY_REPORT_WITH_ASSET_OWNER = "Transaction Summary Report with Asset Owner for Working Capital Loans"; private final FineractFeignClient fineractClient; @Then("Transaction Summary Report for date {string} has the following data:") @@ -72,6 +77,22 @@ public void transactionSummaryReportWithAssetOwnerColumnEmpty(final String dateS verifyColumnNullability("Transaction Summary Report with Asset Owner", dateStr, columnName, true); } + @Then("Transaction Summary Report for Working Capital Loans for date {string} has the following data:") + public void transactionSummaryReportForWorkingCapitalLoansHasData(final String dateStr, final DataTable dataTable) { + verifyReportDataWithEmptyValues(WC_TRANSACTION_SUMMARY_REPORT, dateStr, dataTable); + } + + @Then("Transaction Summary Report with Asset Owner for Working Capital Loans for date {string} has the following data:") + public void transactionSummaryReportWithAssetOwnerForWorkingCapitalLoansHasData(final String dateStr, final DataTable dataTable) { + verifyReportDataWithEmptyValues(WC_TRANSACTION_SUMMARY_REPORT_WITH_ASSET_OWNER, dateStr, dataTable); + } + + @Then("Transaction Summary Report with Asset Owner for Working Capital Loans for date {string} has originatorId, asset owner externalId and the following data:") + public void transactionSummaryReportWithAssetOwnerForWorkingCapitalLoansHasDataWithOriginatorId(final String dateStr, + final DataTable dataTable) { + verifyReportDataWithOwnerExternalIdAndOriginatorId(WC_TRANSACTION_SUMMARY_REPORT_WITH_ASSET_OWNER, dateStr, dataTable); + } + @Then("Trial Balance Summary Report with Asset Owner for date {string} has originatorId, asset owner externalId and the following data:") public void trialBalanceSummaryReportWithAssetOwnerHasDataWithOwnerExternalIdAndOriginatorId(final String dateStr, final DataTable dataTable) { @@ -106,6 +127,15 @@ private void verifyReportData(final String reportName, final String dateStr, fin verifyReportData(reportName, response, expected, headers); } + private void verifyReportDataWithEmptyValues(final String reportName, final String dateStr, final DataTable dataTable) { + final RunReportsResponse response = executeReport(reportName, dateStr); + + final List> expected = dataTable.asLists(); + final List headers = expected.getFirst(); + + verifyReportDataWithEmptyValues(reportName, response, expected, headers); + } + private List> verifyReportDataHeaders(final String reportName, final RunReportsResponse response, final List> expected, List headers) { assertThat(response.getColumnHeaders()).isNotNull(); @@ -204,6 +234,11 @@ private void verifyBalanceReportData(final String reportName, final RunReportsRe private void verifyReportDataWithOwnerExternalIdAndOriginatorId(final String reportName, final String dateStr, final DataTable dataTable) { String originatorExternalId = testContext().get(TestContextKey.ORIGINATOR_EXTERNAL_ID); + String secondOriginatorExternalId = testContext().get(TestContextKey.ORIGINATOR_SECOND_EXTERNAL_ID); + // "originator_external_ids" = every originator created in the scenario, rendered like the report column: + // sorted, comma-separated. The ids are UUIDs, so the Java sort order matches the DB collation of STRING_AGG. + String allOriginatorExternalIds = Stream.of(originatorExternalId, secondOriginatorExternalId).filter(Objects::nonNull).sorted() + .collect(Collectors.joining(", ")); String ownerExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_OWNER_EXTERNAL_ID); String previousOwnerExternalId = testContext().get(TestContextKey.ASSET_EXTERNALIZATION_PREVIOUS_OWNER_EXTERNAL_ID); @@ -232,6 +267,7 @@ private void verifyReportDataWithOwnerExternalIdAndOriginatorId(final String rep expectedRow.set(index, originatorExternalId); } } + Collections.replaceAll(expectedRow, "originator_external_ids", allOriginatorExternalIds); }); verifyReportDataWithEmptyValues(reportName, response, expected, headers); } diff --git a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalTransactionSummaryReport.feature b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalTransactionSummaryReport.feature new file mode 100644 index 00000000000..76e54bac75b --- /dev/null +++ b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalTransactionSummaryReport.feature @@ -0,0 +1,1143 @@ +@SerialChargeAccrualConfig +@WorkingCapital +@WorkingCapitalTransactionSummaryReportFeature +Feature: Working Capital Transaction Summary Reports + + @TestRailId:C115281 + Scenario: Verify Transaction Summary Reports for Working Capital loans show every transaction type with its allocation, payment type and sign + Given Global config "charge-accrual-date" value set to "due-date" + And A code value "REFUND_TO_CUSTOMER" exists for code name "working_capital_loan_credit_balance_refund_classification" + When Admin sets the business date to "01 January 2026" + And Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds Discount fee with "1000" amount on Working Capital loan account for last disbursement + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Principal | | 1000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Principal | | 1000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "05 January 2026" + And Admin runs inline COB job for Working Capital Loan + And Customer makes repayment on "05 January 2026" with 50 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Admin sets the business date to "08 January 2026" + And Admin runs inline COB job for Working Capital Loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Fees | | 9.61 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Interest | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Principal | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -50.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Fees | | 9.61 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Interest | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Penalty | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Principal | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -50.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin adds Discount fee adjustment with "500" amount on transaction date "08 January 2026" on Working Capital loan account for last discount + And Admin sets the business date to "09 January 2026" + And Admin runs inline COB job for Working Capital Loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "08 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Fees | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Interest | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Principal | | -500.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Fees | | -4.47 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Interest | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Principal | | 0.0 | | | | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "08 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Fees | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Interest | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Penalty | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Principal | | -500.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Fees | | -4.47 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Interest | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Penalty | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Principal | | 0.0 | + | 2026-01-08 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "10 January 2026" + And Admin undo the last Discount fee adjustment on Working Capital loan account + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "10 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Fees | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Interest | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Penalty | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Principal | | 500.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Fees | | 4.47 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Interest | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Penalty | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Principal | | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "10 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Fees | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Interest | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Penalty | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Principal | | 500.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Fees | | 4.47 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Interest | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Penalty | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Principal | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization Adjustment | | | 1 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "15 January 2026" + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 15 January 2026 | 15 January 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "15 January 2026" with "9000" amount and expected disbursement date on "15 January 2026" + And Admin successfully disburse the Working Capital loan on "15 January 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "16 January 2026" due date and 45.0 transaction amount + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_PENALTY" specified due date charge to working capital loan with "16 January 2026" due date and 25.0 transaction amount + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "15 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "15 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-01-15 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "17 January 2026" + And Admin runs inline COB job for Working Capital Loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "16 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-16 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | | | | + | 2026-01-16 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | | | | + | 2026-01-16 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "16 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-16 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | + | 2026-01-16 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | + | 2026-01-16 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | + When Customer makes repayment on "17 January 2026" with 40 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Admin makes a charge adjustment for the last added fee charge with 20.0 amount on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "17 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Fees | | -20.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Interest | | 0.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Principal | | 0.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | -15.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | -25.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | 0.0 | | | | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "17 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Interest | | 0.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Principal | | 0.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | Working Capital Loan Fee | 0 | Fees | | -20.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | -15.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | -25.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | 0.0 | + | 2026-01-17 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "18 January 2026" + And Customer makes "GOODWILL_CREDIT" transaction on "18 January 2026" with 110 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Customer makes "PAYOUT_REFUND" transaction on "18 January 2026" with 200 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "18 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Fees | | -10.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Principal | | -100.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Principal | | -200.0 | | | | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "18 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Fees | | -10.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Principal | | -100.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Principal | | -200.0 | + | 2026-01-18 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "19 January 2026" + And Customer makes repayment on "19 January 2026" with 8750 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + Then Working Capital loan status will be "OVERPAID" + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "19 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -8700.0 | | | | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | -50.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "19 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -8700.0 | + | 2026-01-19 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | -50.0 | + When Admin sets the business date to "20 January 2026" + And Customer makes credit balance refund on "20 January 2026" with 30 transaction amount on Working Capital loan with valid classification "REFUND_TO_CUSTOMER" + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "20 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | REFUND_TO_CUSTOMER | | 0 | Fees | | 0.0 | | | | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | REFUND_TO_CUSTOMER | | 0 | Interest | | 0.0 | | | | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | REFUND_TO_CUSTOMER | | 0 | Penalty | | 0.0 | | | | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | REFUND_TO_CUSTOMER | | 0 | Principal | | 0.0 | | | | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | REFUND_TO_CUSTOMER | | 0 | Unallocated Credit (UNC) | | 30.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "20 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | | | 0 | Fees | | 0.0 | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | | | 0 | Interest | | 0.0 | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | | | 0 | Penalty | | 0.0 | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | | | 0 | Principal | | 0.0 | + | 2026-01-20 | WCLP_ACC_DEF_REV_AM | Credit Balance Refund | | | 0 | Unallocated Credit (UNC) | | 30.0 | + + @TestRailId:C115282 + Scenario: Verify Transaction Summary Reports for Working Capital loans show reversals on the reversal date with the opposite sign and a charge waiver with the full waived amount + Given Global config "charge-accrual-date" value set to "due-date" + When Admin sets the business date to "01 January 2026" + And Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds Discount fee with "1000" amount on Working Capital loan account for last disbursement + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Principal | | 1000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Principal | | 1000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "05 January 2026" + And Admin runs inline COB job for Working Capital Loan + And Customer makes repayment on "05 January 2026" with 50 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "06 January 2026" due date and 45.0 transaction amount + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_PENALTY" specified due date charge to working capital loan with "06 January 2026" due date and 25.0 transaction amount + And Admin sets the business date to "07 January 2026" + And Admin runs inline COB job for Working Capital Loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Fees | | 9.61 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Interest | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Principal | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -50.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Fees | | 9.61 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Interest | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Penalty | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Principal | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -50.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | + When Customer undo "1"th "REPAYMENT" transaction made on "05 January 2026" on Working Capital loan + And Admin adds Discount fee adjustment with "500" amount on transaction date "07 January 2026" on Working Capital loan account for last discount and "working_capital_loan_discount_fee_classification_value" classification + And Admin successfully undo Working Capital disbursal + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "07 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 1 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 1 | Fees | | -45.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 1 | Penalty | | -25.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Principal | | -9000.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Fees | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Penalty | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Principal | | -1000.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 0 | Fees | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 0 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 0 | Penalty | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 0 | Principal | | -500.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 1 | Fees | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 1 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 1 | Penalty | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 1 | Principal | | 500.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | working_capital_loan_discount_fee_classification_value | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Fees | | -9.61 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Penalty | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Principal | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | | 50.0 | | | | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "07 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 1 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 1 | Fees | | -45.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 1 | Penalty | | -25.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Principal | | -9000.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Fees | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Penalty | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Principal | | -1000.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Fees | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Penalty | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Principal | | -500.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Fees | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Penalty | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Principal | | 500.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Adjustment | | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Fees | | -9.61 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Penalty | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Principal | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | | 50.0 | + | 2026-01-07 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | + And Working Capital Loan Transactions tab has a reversed "ACCRUAL" transaction with date "06 January 2026" which has the following Journal entries: + | Type | Account code | Account name | Debit | Credit | + | ASSET | 112603 | Interest/Fee Receivable | 45.0 | | + | INCOME | 404007 | Fee Income | | 45.0 | + | ASSET | 112603 | Interest/Fee Receivable | | 45.0 | + | INCOME | 404007 | Fee Income | 45.0 | | + | ASSET | 112603 | Interest/Fee Receivable | 25.0 | | + | INCOME | 404007 | Fee Income | | 25.0 | + | ASSET | 112603 | Interest/Fee Receivable | | 25.0 | + | INCOME | 404007 | Fee Income | 25.0 | | + When Admin sets the business date to "01 February 2026" + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 February 2026 | 01 February 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 February 2026" with "9000" amount and expected disbursement date on "01 February 2026" + And Admin successfully disburse the Working Capital loan on "01 February 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "01 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "02 February 2026" + And Customer makes repayment on "02 February 2026" with 100 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Customer undo "1"th "REPAYMENT" transaction made on "02 February 2026" on Working Capital loan + And Customer makes "GOODWILL_CREDIT" transaction on "02 February 2026" with 110 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Customer makes "PAYOUT_REFUND" transaction on "02 February 2026" with 200 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Customer undo "1"th "PAYOUT_REFUND" transaction made on "02 February 2026" on Working Capital loan + And Customer undo "1"th "GOODWILL_CREDIT" transaction made on "02 February 2026" on Working Capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "02 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Principal | | -110.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Principal | | 110.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Principal | | -200.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Principal | | 200.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -100.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | | 100.0 | | | | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "02 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Principal | | -110.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Principal | | 110.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Goodwill Credit | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Principal | | -200.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Principal | | 200.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Payout Refund | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -100.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | | 100.0 | + | 2026-02-02 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + When Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "03 February 2026" due date and 30.0 transaction amount + And Admin sets the business date to "03 February 2026" + And Admin makes a charge adjustment for the last added fee charge with 30.0 amount on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "03 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Fees | | -30.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Interest | | 0.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Penalty | | 0.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Principal | | 0.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "03 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Interest | | 0.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Principal | | 0.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | Working Capital Loan Fee | 0 | Fees | | -30.0 | + When Admin sets the business date to "04 February 2026" + And Admin reverts the last charge adjustment on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "04 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-04 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Fees | | 30.0 | | | | + | 2026-02-04 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Interest | | 0.0 | | | | + | 2026-02-04 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Penalty | | 0.0 | | | | + | 2026-02-04 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Principal | | 0.0 | | | | + | 2026-02-04 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + When Admin sets the business date to "05 February 2026" + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "10 February 2026" due date and 40.0 transaction amount + And Admin waives the last added charge on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "05 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Fees | | -40.0 | | | | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Interest | | 0.0 | | | | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Penalty | | 0.0 | | | | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Principal | | 0.0 | | | | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "05 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Fees | | -40.0 | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Interest | | 0.0 | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Penalty | | 0.0 | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Principal | | 0.0 | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "06 February 2026" + And Admin reverts the last charge waiver on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "06 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Fees | | 40.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Interest | | 0.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Penalty | | 0.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Principal | | 0.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "06 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Fees | | 40.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Interest | | 0.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Penalty | | 0.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Principal | | 0.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Waive Charges | | | 1 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "10 February 2026" + And Global config "wcl-charge-accrual-time" value set to "real-time" + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 10 February 2026 | 10 February 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "10 February 2026" with "9000" amount and expected disbursement date on "10 February 2026" + And Admin successfully disburse the Working Capital loan on "10 February 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "15 February 2026" due date and 35.0 transaction amount + And Admin successfully undo Working Capital disbursal + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "10 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 1 | Interest | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 35.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 1 | Fees | | -35.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Principal | | -9000.0 | | | | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "10 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 1 | Interest | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 35.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 1 | Fees | | -35.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Principal | | -9000.0 | + | 2026-02-10 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + + @TestRailId:C115283 + Scenario: Verify Transaction Summary Reports for Working Capital loans show the charge-off reason from the charge-off date on + Given Global config "charge-accrual-date" value set to "due-date" + And A code value "Fraud" exists for code name "ChargeOffReasons" + When Admin sets the business date to "01 January 2026" + And Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds Discount fee with "1000" amount on Working Capital loan account for last disbursement + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Principal | | 1000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Principal | | 1000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Discount Fee | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "05 January 2026" + And Customer makes repayment on "05 January 2026" with 50 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -50.0 | | | | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -50.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "10 January 2026" + And Admin charges off the Working Capital loan on "10 January 2026" with charge-off reason "Fraud" + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "10 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Fees | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Interest | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Penalty | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Principal | Fraud | -9950.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Fees | Fraud | 1000.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Interest | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Penalty | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Principal | Fraud | 0.0 | | | | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "10 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Fees | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Interest | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Penalty | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Principal | | -9950.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Fees | | 1000.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Interest | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Penalty | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Principal | | 0.0 | + | 2026-01-10 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "11 January 2026" + And Customer makes repayment on "11 January 2026" with 100 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "11 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | Fraud | 0.0 | | | | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | Fraud | 0.0 | | | | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | Fraud | 0.0 | | | | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | Fraud | -100.0 | | | | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "11 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -100.0 | + | 2026-01-11 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "12 January 2026" + And Customer undo "1"th "REPAYMENT" transaction made on "11 January 2026" on Working Capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "12 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | Fraud | 0.0 | | | | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | Fraud | 0.0 | | | | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | Fraud | 0.0 | | | | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | Fraud | 100.0 | | | | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "12 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | | 0.0 | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | | 0.0 | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | | 0.0 | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | | 100.0 | + | 2026-01-12 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "13 January 2026" + And Admin undoes the charge-off on the Working Capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "13 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Fees | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Interest | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Penalty | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Principal | | 9950.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Fees | | -1000.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Interest | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Penalty | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Principal | | 0.0 | | | | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "13 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Fees | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Interest | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Penalty | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Principal | | 9950.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 1 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Fees | | -1000.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Interest | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Penalty | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Principal | | 0.0 | + | 2026-01-13 | WCLP_ACC_DEF_REV_AM | Discount Fee Amortization | | | 1 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "01 February 2026" + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 February 2026 | 01 February 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 February 2026" with "9000" amount and expected disbursement date on "01 February 2026" + And Admin successfully disburse the Working Capital loan on "01 February 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "05 February 2026" due date and 45.0 transaction amount + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_PENALTY" specified due date charge to working capital loan with "05 February 2026" due date and 25.0 transaction amount + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "01 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-02-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "03 February 2026" + And Admin charges off the Working Capital loan on "03 February 2026" with charge-off reason "Fraud" + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "03 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Fees | Fraud | -45.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Interest | Fraud | 0.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Penalty | Fraud | -25.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Principal | Fraud | -9000.0 | | | | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "03 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Fees | | -45.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Interest | | 0.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Penalty | | -25.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Principal | | -9000.0 | + | 2026-02-03 | WCLP_ACC_DEF_REV_AM | Charge-off | | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "06 February 2026" + And Admin runs inline COB job for Working Capital Loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "05 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | Fraud | 0.0 | | | | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | Fraud | 45.0 | | | | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | Fraud | 25.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "05 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 45.0 | + | 2026-02-05 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Penalty | 0 | Penalty | | 25.0 | + When Admin makes a charge adjustment for the last added penalty charge with 25.0 amount on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "06 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Fees | Fraud | 0.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Interest | Fraud | 0.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Penalty | Fraud | -25.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Principal | Fraud | 0.0 | | | | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "06 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Interest | | 0.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Principal | | 0.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-02-06 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | Working Capital Loan Penalty | 0 | Penalty | | -25.0 | + When Admin sets the business date to "07 February 2026" + And Admin reverts the last charge adjustment on working capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "07 February 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-02-07 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Fees | Fraud | 0.0 | | | | + | 2026-02-07 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Interest | Fraud | 0.0 | | | | + | 2026-02-07 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Penalty | Fraud | 25.0 | | | | + | 2026-02-07 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Principal | Fraud | 0.0 | | | | + | 2026-02-07 | WCLP_ACC_DEF_REV_AM | Charge Adjustment | | | 1 | Unallocated Credit (UNC) | Fraud | 0.0 | | | | + + @TestRailId:C115284 + Scenario: Verify Transaction Summary Report with Asset Owner for Working Capital loans gives the same rows as for a regular loan and keeps both loan types and offices apart + Given Global config "charge-accrual-date" value set to "due-date" + When Admin sets the business date to "01 January 2026" + And Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a new loan originator with external ID and name "WC Transaction Summary Report Originator" + And 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_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 01 January 2026 | 1000 | 0 | DECLINING_BALANCE | SAME_AS_REPAYMENT_PERIOD | EQUAL_INSTALLMENTS | 1 | MONTHS | 1 | MONTHS | 1 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin attaches the originator to the loan + And Admin successfully approves the loan on "01 January 2026" with "1000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the loan on "01 January 2026" with "1000" EUR transaction amount + And Admin adds "LOAN_SNOOZE_FEE" due date charge with "02 January 2026" due date and 10 EUR transaction amount + And Admin sets the business date to "03 January 2026" + And Admin runs inline COB job for Loan + And Customer makes "AUTOPAY" repayment on "03 January 2026" with 100 EUR transaction amount + And Admin sets the business date to "04 January 2026" + And Admin does write-off the loan on "04 January 2026" + And Admin sets the business date to "05 January 2026" + And Admin makes a recovery payment of 50 on the loan on "05 January 2026" + When Admin sets the business date to "01 January 2026" + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 1000 | 10000 | 18 | 0 | + And Admin attaches the originator to the working capital loan + And Admin successfully approves the working capital loan on "01 January 2026" with "1000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "1000" EUR transaction amount and "AUTOPAY" payment type + And Admin adds "WORKING_CAPITAL_SPECIFIED_DUE_DATE_FEE" specified due date charge to working capital loan with "02 January 2026" due date and 10.0 transaction amount + And Admin sets the business date to "03 January 2026" + And Admin runs inline COB job for Working Capital Loan + And Customer makes repayment on "03 January 2026" with 100 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + And Admin sets the business date to "04 January 2026" + And Admin writes off the Working Capital loan on "04 January 2026" + And Admin sets the business date to "05 January 2026" + And Admin makes a recovery payment of "50" on the Working Capital loan on "05 January 2026" + Then Transaction Summary Report with Asset Owner for date "01 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-01 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-01 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-01 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Disbursement | AUTOPAY | | 0 | Principal | | 1000.0 | | | originator_external_id | + | 2026-01-01 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 1000.0 | | | originator_external_id | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 1000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + And Transaction Summary Report with Asset Owner for date "02 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-02 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Apply Charges | | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-02 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Apply Charges | | Snooze fee | 0 | Fees | | 10.0 | | | originator_external_id | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "02 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-02 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-02 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 10.0 | | | originator_external_id | + And Transaction Summary Report for Working Capital Loans for date "02 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-02 | WCLP_ACC_DEF_REV_AM | Apply Charges | | | 0 | Interest | | 0.0 | + | 2026-01-02 | WCLP_ACC_DEF_REV_AM | Apply Charges | | Working Capital Loan Fee | 0 | Fees | | 10.0 | + And Transaction Summary Report with Asset Owner for date "03 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-03 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Repayment | AUTOPAY | | 0 | Fees | | -10.0 | | | originator_external_id | + | 2026-01-03 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-03 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-03 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Repayment | AUTOPAY | | 0 | Principal | | -90.0 | | | originator_external_id | + | 2026-01-03 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "03 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | -10.0 | | | originator_external_id | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -90.0 | | | originator_external_id | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report for Working Capital Loans for date "03 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | -10.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -90.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + And Transaction Summary Report with Asset Owner for date "04 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-04 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Write-Off | | | 0 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-04 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Write-Off | | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-04 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Write-Off | | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-04 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Write-Off | | | 0 | Principal | | -910.0 | | | originator_external_id | + | 2026-01-04 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Write-Off | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "04 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Principal | | -910.0 | | | originator_external_id | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report for Working Capital Loans for date "04 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Fees | | 0.0 | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Interest | | 0.0 | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Penalty | | 0.0 | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Principal | | -910.0 | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 0 | Unallocated Credit (UNC) | | 0.0 | + And Transaction Summary Report with Asset Owner for date "05 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-05 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Recovery Repayment | | | 0 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-05 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Recovery Repayment | | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-05 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Recovery Repayment | | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-05 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Recovery Repayment | | | 0 | Principal | | 0.0 | | | originator_external_id | + | 2026-01-05 | LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | Recovery Repayment | | | 0 | Unallocated Credit (UNC) | | -50.0 | | | originator_external_id | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "05 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Principal | | 0.0 | | | originator_external_id | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Unallocated Credit (UNC) | | -50.0 | | | originator_external_id | + And Transaction Summary Report for Working Capital Loans for date "05 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Fees | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Interest | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Penalty | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Principal | | 0.0 | + | 2026-01-05 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 0 | Unallocated Credit (UNC) | | -50.0 | + When Admin sets the business date to "06 January 2026" + And Admin undoes the last recovery payment on the Working Capital loan + And Admin undoes the write-off on the Working Capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "06 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Principal | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Unallocated Credit (UNC) | | 50.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Fees | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Interest | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Penalty | | 0.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Principal | | 910.0 | | | originator_external_id | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_id | + And Transaction Summary Report for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Fees | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Interest | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Penalty | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Principal | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Recovery Repayment | | | 1 | Unallocated Credit (UNC) | | 50.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Fees | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Interest | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Penalty | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Principal | | 910.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Write-Off | | | 1 | Unallocated Credit (UNC) | | 0.0 | + When Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 06 January 2026 | 06 January 2026 | 1000 | 10000 | 18 | 0 | + And Admin successfully approves the working capital loan on "06 January 2026" with "1000" amount and expected disbursement date on "06 January 2026" + And Admin successfully disburse the Working Capital loan on "06 January 2026" with "1000" EUR transaction amount and "AUTOPAY" payment type + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 1000.0 | | | | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "06 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 1000.0 | + | 2026-01-06 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + + @TestRailId:C115285 + Scenario: Verify Transaction Summary Reports for Working Capital loans report a backdated repayment and its undo on their submitted dates and not on the transaction date + When Admin sets the business date to "01 January 2026" + And Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + When Admin sets the business date to "03 January 2026" + And Customer makes repayment on "01 January 2026" with 100 transaction amount on Working Capital loan with the following payment details: + | paymentType | + | AUTOPAY | + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "03 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -100.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "03 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -100.0 | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + When Admin sets the business date to "04 January 2026" + And Customer undo "1"th "REPAYMENT" transaction made on "01 January 2026" on Working Capital loan + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "04 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Fees | | 0.0 | | | | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Interest | | 0.0 | | | | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Penalty | | 0.0 | | | | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Principal | | 100.0 | | | | + | 2026-01-04 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 1 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "03 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Principal | | -100.0 | | | | + | 2026-01-03 | WCLP_ACC_DEF_REV_AM | Repayment | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + + @TestRailId:C115286 + Scenario: Verify Transaction Summary Reports for Working Capital loans sum same-day transactions of several loans into one row per product, payment type and originator set and list several originators sorted and comma-separated + When Admin sets the business date to "01 January 2026" + And Admin creates a new office + And Admin creates a client with random data in the last created office + And Admin creates a new loan originator with external ID and name "WC Transaction Summary Report Originator A" + And Admin creates a second loan originator with external ID and name "WC Transaction Summary Report Originator B" + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 0 | + And Admin attaches the originator to the working capital loan + And Admin attaches the second originator to the working capital loan + And Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount and "AUTOPAY" payment type + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 1000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "1000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "1000" EUR transaction amount and "CHECK_PAYMENT" payment type + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP_ACC_DEF_REV_AM | 01 January 2026 | 01 January 2026 | 500 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "500" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "500" EUR transaction amount and "CHECK_PAYMENT" payment type + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP | 01 January 2026 | 01 January 2026 | 2000 | 100000 | 18 | 0 | + And Admin successfully approves the working capital loan on "01 January 2026" with "2000" amount and expected disbursement date on "01 January 2026" + And Admin successfully disburse the Working Capital loan on "01 January 2026" with "2000" EUR transaction amount and "AUTOPAY" payment type + Then Transaction Summary Report with Asset Owner for Working Capital Loans for date "01 January 2026" has originatorId, asset owner externalId and the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | Asset_owner_id | From_asset_owner_id | Originator_External_Ids | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Principal | | 2000.0 | | | | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | | | originator_external_ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | | | originator_external_ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | | | originator_external_ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | | | originator_external_ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | | | originator_external_ids | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Fees | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Interest | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Penalty | | 0.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Principal | | 1500.0 | | | | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Unallocated Credit (UNC) | | 0.0 | | | | + And Transaction Summary Report for Working Capital Loans for date "01 January 2026" has the following data: + | TransactionDate | Product | TransactionType_Name | PaymentType_Name | chargetype | Reversed | Allocation_Type | Chargeoff_ReasonCode | Transaction_Amount | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Principal | | 2000.0 | + | 2026-01-01 | WCLP | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Principal | | 9000.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | AUTOPAY | | 0 | Unallocated Credit (UNC) | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Fees | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Interest | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Penalty | | 0.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Principal | | 1500.0 | + | 2026-01-01 | WCLP_ACC_DEF_REV_AM | Disbursement | CHECK_PAYMENT | | 0 | Unallocated Credit (UNC) | | 0.0 | diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml index b0874d94241..eb16b3b5e88 100644 --- a/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml +++ b/fineract-provider/src/main/resources/db/changelog/tenant/changelog-tenant.xml @@ -279,4 +279,5 @@ + diff --git a/fineract-provider/src/main/resources/db/changelog/tenant/parts/0261_transaction_summary_reports_for_working_capital_loans.xml b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0261_transaction_summary_reports_for_working_capital_loans.xml new file mode 100644 index 00000000000..6cd3a8f7a65 --- /dev/null +++ b/fineract-provider/src/main/resources/db/changelog/tenant/parts/0261_transaction_summary_reports_for_working_capital_loans.xml @@ -0,0 +1,1900 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanTransactionSummaryReportTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanTransactionSummaryReportTest.java new file mode 100644 index 00000000000..af6dd31051d --- /dev/null +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanTransactionSummaryReportTest.java @@ -0,0 +1,843 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.fineract.integrationtests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Stream; +import org.apache.fineract.client.feign.FineractFeignClient; +import org.apache.fineract.client.models.ChargeRequest; +import org.apache.fineract.client.models.GetWorkingCapitalLoanTransactionIdResponse; +import org.apache.fineract.client.models.PaymentTypeCreateRequest; +import org.apache.fineract.client.models.PostLoanProductsRequest; +import org.apache.fineract.client.models.PostWorkingCapitalLoanProductsRequest.AccountingRuleEnum; +import org.apache.fineract.client.models.ResultsetColumnHeaderData; +import org.apache.fineract.client.models.ResultsetRowData; +import org.apache.fineract.client.models.RunReportsResponse; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignAccountHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignBusinessDateHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignChargesHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignClientHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignCodeHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignLoanHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignOfficeHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignPaymentTypeHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignReportHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignTransactionHelper; +import org.apache.fineract.integrationtests.client.feign.helpers.FeignWorkingCapitalLoanHelper; +import org.apache.fineract.integrationtests.client.feign.modules.ChargeRequestBuilders; +import org.apache.fineract.integrationtests.client.feign.modules.ClientRequestBuilders; +import org.apache.fineract.integrationtests.client.feign.modules.LoanRequestBuilders; +import org.apache.fineract.integrationtests.client.feign.modules.LoanTestAccounts; +import org.apache.fineract.integrationtests.client.feign.modules.LoanTestData.TransactionProcessingStrategyCode; +import org.apache.fineract.integrationtests.client.feign.modules.WorkingCapitalLoanRequestBuilders; +import org.apache.fineract.integrationtests.common.FineractFeignClientHelper; +import org.apache.fineract.integrationtests.common.Utils; +import org.apache.fineract.integrationtests.common.accounting.Account; +import org.apache.fineract.integrationtests.common.workingcapitalloan.WorkingCapitalLoanDisbursementTestBuilder; +import org.apache.fineract.integrationtests.common.workingcapitalloan.WorkingCapitalLoanHelper; +import org.apache.fineract.integrationtests.common.workingcapitalloanproduct.WorkingCapitalLoanProductHelper; +import org.apache.fineract.integrationtests.common.workingcapitalloanproduct.WorkingCapitalLoanProductTestBuilder; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +public class WorkingCapitalLoanTransactionSummaryReportTest { + + private static final String TRANSACTION_SUMMARY_REPORT = "Transaction Summary Report with Asset Owner for Working Capital Loans"; + private static final String REGULAR_TRANSACTION_SUMMARY_REPORT = "Transaction Summary Report with Asset Owner"; + private static final String REPORT_DATE = "2026-03-02"; + private static final String COB_BUSINESS_DATE = "2026-03-03"; + private static final String TRANSACTION_DATE = "02 March 2026"; + private static final String CLIENT_ACTIVATION_DATE = "01 January 2026"; + private static final LocalDate OFFICE_OPENING_DATE = LocalDate.of(2026, 1, 1); + private static final DateTimeFormatter API_DATE_FORMAT = DateTimeFormatter.ofPattern("dd MMMM yyyy", Locale.ENGLISH); + private static final BigDecimal PRINCIPAL = BigDecimal.valueOf(5000); + private static final BigDecimal LOAN_PRINCIPAL = BigDecimal.valueOf(9000); + private static final BigDecimal SMALL_LOAN_PRINCIPAL = BigDecimal.valueOf(1000); + private static final BigDecimal DISCOUNT_FEE = BigDecimal.valueOf(1000); + private static final double PENALTY_AMOUNT = 10.0; + private static final BigDecimal PARTIAL_REPAYMENT_AMOUNT = BigDecimal.valueOf(5); + + private static final int REPORT_COLUMN_COUNT = 12; + private static final int TRANSACTION_DATE_COLUMN = 0; + private static final int PRODUCT_NAME_COLUMN = 1; + private static final int TRANSACTION_TYPE_COLUMN = 2; + private static final int PAYMENT_TYPE_COLUMN = 3; + private static final int CHARGE_TYPE_COLUMN = 4; + private static final int REVERSED_COLUMN = 5; + private static final int ALLOCATION_TYPE_COLUMN = 6; + private static final int CHARGE_OFF_REASON_COLUMN = 7; + private static final int AMOUNT_COLUMN = 8; + private static final int ASSET_OWNER_ID_COLUMN = 9; + private static final int FROM_ASSET_OWNER_ID_COLUMN = 10; + private static final int ORIGINATOR_EXTERNAL_IDS_COLUMN = 11; + + private static final String APPLY_CHARGES_TRANSACTION = "Apply Charges"; + private static final String DISBURSEMENT_TRANSACTION = "Disbursement"; + private static final String REPAYMENT_TRANSACTION = "Repayment"; + private static final String WRITE_OFF_TRANSACTION = "Write-Off"; + private static final String RECOVERY_REPAYMENT_TRANSACTION = "Recovery Repayment"; + private static final String WAIVE_CHARGES_TRANSACTION = "Waive Charges"; + private static final String CREDIT_BALANCE_REFUND_TRANSACTION = "Credit Balance Refund"; + private static final String PAYOUT_REFUND_TRANSACTION = "Payout Refund"; + private static final String GOODWILL_CREDIT_TRANSACTION = "Goodwill Credit"; + private static final String CHARGE_ADJUSTMENT_TRANSACTION = "Charge Adjustment"; + private static final String CHARGE_OFF_TRANSACTION = "Charge-off"; + private static final String DISCOUNT_FEE_TRANSACTION = "Discount Fee"; + private static final String DISCOUNT_FEE_AMORTIZATION_TRANSACTION = "Discount Fee Amortization"; + private static final String DISCOUNT_FEE_ADJUSTMENT_TRANSACTION = "Discount Fee Adjustment"; + private static final String DISCOUNT_FEE_AMORTIZATION_ADJUSTMENT_TRANSACTION = "Discount Fee Amortization Adjustment"; + private static final String DISCOUNT_FEE_TYPE_CODE = "loanTransactionType.discountFee"; + private static final String DISCOUNT_FEE_AMORTIZATION_TYPE_CODE = "loanTransactionType.discountFeeAmortization"; + private static final String DISCOUNT_FEE_AMORTIZATION_ADJUSTMENT_TYPE_CODE = "loanTransactionType.discountFeeAmortizationAdjustment"; + private static final String PRINCIPAL_ALLOCATION = "Principal"; + private static final String INTEREST_ALLOCATION = "Interest"; + private static final String FEES_ALLOCATION = "Fees"; + private static final String PENALTY_ALLOCATION = "Penalty"; + private static final String UNALLOCATED_CREDIT_ALLOCATION = "Unallocated Credit (UNC)"; + private static final List ALLOCATION_TYPES = List.of(FEES_ALLOCATION, INTEREST_ALLOCATION, PENALTY_ALLOCATION, + PRINCIPAL_ALLOCATION, UNALLOCATED_CREDIT_ALLOCATION); + private static final String NO_CHARGE_TYPE = ""; + private static final double AMOUNT_TOLERANCE = 0.01; + + private static FeignOfficeHelper officeHelper; + private static FeignClientHelper clientHelper; + private static FeignBusinessDateHelper businessDateHelper; + private static FeignWorkingCapitalLoanHelper wcLoanHelper; + private static WorkingCapitalLoanHelper wcLoanTransactionHelper; + private static FeignReportHelper reportHelper; + private static FeignAccountHelper accountHelper; + private static FeignCodeHelper codeHelper; + private static FeignPaymentTypeHelper paymentTypeHelper; + private static FeignChargesHelper chargesHelper; + private static FeignLoanHelper loanHelper; + private static FeignTransactionHelper loanTransactionHelper; + private static WorkingCapitalLoanProductHelper productHelper; + + private static Account fundSourceAccount; + private static Account loanPortfolioAccount; + private static Account transfersSuspenseAccount; + private static Account incomeFromDiscountFeeAccount; + private static Account feesReceivableAccount; + private static Account penaltiesReceivableAccount; + private static Account incomeFromFeeAccount; + private static Account incomeFromPenaltyAccount; + private static Account incomeFromRecoveryAccount; + private static Account writeOffAccount; + private static Account overpaymentAccount; + private static Account deferredIncomeAccount; + + private final List createdLoanIds = new ArrayList<>(); + private final Map repaymentIdByLoanId = new HashMap<>(); + + @BeforeAll + public static void setup() { + final FineractFeignClient fineractClient = FineractFeignClientHelper.getFineractFeignClient(); + officeHelper = new FeignOfficeHelper(fineractClient); + clientHelper = new FeignClientHelper(fineractClient); + businessDateHelper = new FeignBusinessDateHelper(fineractClient); + wcLoanHelper = new FeignWorkingCapitalLoanHelper(fineractClient); + wcLoanTransactionHelper = new WorkingCapitalLoanHelper(); + reportHelper = new FeignReportHelper(fineractClient); + accountHelper = new FeignAccountHelper(fineractClient); + codeHelper = new FeignCodeHelper(fineractClient); + paymentTypeHelper = new FeignPaymentTypeHelper(fineractClient); + chargesHelper = new FeignChargesHelper(fineractClient); + loanHelper = new FeignLoanHelper(fineractClient); + loanTransactionHelper = new FeignTransactionHelper(fineractClient); + productHelper = new WorkingCapitalLoanProductHelper(); + + fundSourceAccount = accountHelper.createLiabilityAccount("wcTsrFundSource"); + loanPortfolioAccount = accountHelper.createAssetAccount("wcTsrLoanPortfolio"); + transfersSuspenseAccount = accountHelper.createAssetAccount("wcTsrTransfersSuspense"); + incomeFromDiscountFeeAccount = accountHelper.createIncomeAccount("wcTsrIncomeDiscountFee"); + feesReceivableAccount = accountHelper.createAssetAccount("wcTsrFeesReceivable"); + penaltiesReceivableAccount = accountHelper.createAssetAccount("wcTsrPenaltiesReceivable"); + incomeFromFeeAccount = accountHelper.createIncomeAccount("wcTsrIncomeFee"); + incomeFromPenaltyAccount = accountHelper.createIncomeAccount("wcTsrIncomePenalty"); + incomeFromRecoveryAccount = accountHelper.createIncomeAccount("wcTsrIncomeRecovery"); + writeOffAccount = accountHelper.createExpenseAccount("wcTsrWriteOff"); + overpaymentAccount = accountHelper.createLiabilityAccount("wcTsrOverpayment"); + deferredIncomeAccount = accountHelper.createLiabilityAccount("wcTsrDeferredIncome"); + } + + @AfterEach + void cleanupLoans() { + repaymentIdByLoanId.forEach(wcLoanHelper::undoTransaction); + createdLoanIds.forEach(wcLoanHelper::cleanupLoan); + repaymentIdByLoanId.clear(); + createdLoanIds.clear(); + } + + @Test + public void transactionSummaryReportWithAssetOwner() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createAccrualWithDeferredRevenueAmortizationProduct(productName); + final AtomicLong officeId = new AtomicLong(); + final AtomicReference penaltyName = new AtomicReference<>(); + + businessDateHelper.runAt(REPORT_DATE, () -> { + + final Long createdOfficeId = officeHelper.createOffice(OFFICE_OPENING_DATE).getResourceId(); + assertNotNull(createdOfficeId); + officeId.set(createdOfficeId); + final Long clientId = createClientInOffice(officeId.get()); + final Long loanId = createApprovedAndDisbursedLoan(clientId, productId); + penaltyName.set(addPenaltyForLoan(loanId)); + makePartialRepayment(loanId); + + businessDateHelper.updateBusinessDate("BUSINESS_DATE", COB_BUSINESS_DATE); + wcLoanHelper.executeInlineWCCOB(loanId); + }); + + final RunReportsResponse report = runTransactionSummaryReport(REPORT_DATE, officeId.get()); + + final List columnHeaders = report.getColumnHeaders(); + assertNotNull(columnHeaders); + assertEquals(REPORT_COLUMN_COUNT, columnHeaders.size()); + columnHeaders.forEach(columnHeader -> { + assertNotNull(columnHeader.getColumnType()); + assertNotNull(columnHeader.getColumnDisplayType()); + final Boolean columnNullable = columnHeader.getIsColumnNullable(); + assertNotNull(columnNullable); + assertFalse(columnNullable); + }); + + final List reportData = report.getData(); + assertNotNull(reportData); + final List> rows = reportData.stream().map(rowData -> Objects.requireNonNull(rowData.getRow())).toList(); + assertEquals(12, rows.size()); + assertReportRow(rows.get(0), productName, APPLY_CHARGES_TRANSACTION, NO_CHARGE_TYPE, INTEREST_ALLOCATION, 0.00); + assertReportRow(rows.get(1), productName, APPLY_CHARGES_TRANSACTION, penaltyName.get(), PENALTY_ALLOCATION, 10.00); + assertReportRow(rows.get(2), productName, DISBURSEMENT_TRANSACTION, NO_CHARGE_TYPE, FEES_ALLOCATION, 0.00); + assertReportRow(rows.get(3), productName, DISBURSEMENT_TRANSACTION, NO_CHARGE_TYPE, INTEREST_ALLOCATION, 0.00); + assertReportRow(rows.get(4), productName, DISBURSEMENT_TRANSACTION, NO_CHARGE_TYPE, PENALTY_ALLOCATION, 0.00); + assertReportRow(rows.get(5), productName, DISBURSEMENT_TRANSACTION, NO_CHARGE_TYPE, PRINCIPAL_ALLOCATION, 5000.00); + assertReportRow(rows.get(6), productName, DISBURSEMENT_TRANSACTION, NO_CHARGE_TYPE, UNALLOCATED_CREDIT_ALLOCATION, 0.00); + assertReportRow(rows.get(7), productName, REPAYMENT_TRANSACTION, NO_CHARGE_TYPE, FEES_ALLOCATION, 0.00); + assertReportRow(rows.get(8), productName, REPAYMENT_TRANSACTION, NO_CHARGE_TYPE, INTEREST_ALLOCATION, 0.00); + assertReportRow(rows.get(9), productName, REPAYMENT_TRANSACTION, NO_CHARGE_TYPE, PENALTY_ALLOCATION, -5.00); + assertReportRow(rows.get(10), productName, REPAYMENT_TRANSACTION, NO_CHARGE_TYPE, PRINCIPAL_ALLOCATION, 0.00); + assertReportRow(rows.get(11), productName, REPAYMENT_TRANSACTION, NO_CHARGE_TYPE, UNALLOCATED_CREDIT_ALLOCATION, 0.00); + } + + @Test + public void transactionSummaryReportShowsPaymentsChargeAdjustmentAndWaiverWithTheirReversals() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createProductWithoutAccounting(productName); + final LocalDate disbursementDate = LocalDate.of(2026, 4, 1); + final LocalDate paymentDate = disbursementDate.plusDays(1); + final LocalDate chargeAdjustmentDate = disbursementDate.plusDays(2); + final LocalDate chargeAdjustmentReversalDate = disbursementDate.plusDays(3); + final LocalDate waiverDate = disbursementDate.plusDays(4); + final LocalDate waiverReversalDate = disbursementDate.plusDays(5); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + final AtomicLong chargeAdjustmentId = new AtomicLong(); + final AtomicLong waiverId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + loanId.set(createDisbursedLoan(borrower.get().clientId(), productId, apiDate(disbursementDate), LOAN_PRINCIPAL)); + }); + final Long officeId = borrower.get().officeId(); + assertReport(disbursementDate, officeId, productName, + allocationRows(DISBURSEMENT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(9000)))); + + businessDateHelper.runAt(paymentDate.toString(), () -> { + final Long repaymentId = wcLoanHelper.makeRepayment(loanId.get(), + WorkingCapitalLoanRequestBuilders.repayment(BigDecimal.valueOf(100), apiDate(paymentDate))); + final Long goodwillCreditId = wcLoanHelper.makeGoodwillCredit(loanId.get(), + WorkingCapitalLoanRequestBuilders.goodwillCredit(BigDecimal.valueOf(110), apiDate(paymentDate))); + final Long payoutRefundId = wcLoanHelper.payoutRefund(loanId.get(), + WorkingCapitalLoanRequestBuilders.payoutRefund(BigDecimal.valueOf(200), apiDate(paymentDate))); + wcLoanHelper.undoTransaction(loanId.get(), payoutRefundId); + wcLoanHelper.undoTransaction(loanId.get(), goodwillCreditId); + wcLoanHelper.undoTransaction(loanId.get(), repaymentId); + }); + assertReport(paymentDate, officeId, productName, + concat(allocationRows(GOODWILL_CREDIT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-110))), + allocationRows(GOODWILL_CREDIT_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(110))), + allocationRows(PAYOUT_REFUND_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-200))), + allocationRows(PAYOUT_REFUND_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(200))), + allocationRows(REPAYMENT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-100))), + allocationRows(REPAYMENT_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(100))))); + + businessDateHelper.runAt(chargeAdjustmentDate.toString(), () -> { + final Long feeId = wcLoanHelper.createGlobalCharge(WorkingCapitalLoanRequestBuilders.specifiedDueDateCharge(false, 30.0)); + final Long loanChargeId = wcLoanHelper.addCharge(loanId.get(), + WorkingCapitalLoanRequestBuilders.addCharge(feeId, 30.0, apiDate(chargeAdjustmentDate))); + chargeAdjustmentId.set(wcLoanHelper.adjustCharge(loanId.get(), loanChargeId, + WorkingCapitalLoanRequestBuilders.chargeAdjustment(BigDecimal.valueOf(30)))); + }); + assertReport(chargeAdjustmentDate, officeId, productName, + allocationRows(CHARGE_ADJUSTMENT_TRANSACTION, false, Map.of(FEES_ALLOCATION, amount(-30)))); + + businessDateHelper.runAt(chargeAdjustmentReversalDate.toString(), + () -> wcLoanHelper.undoTransaction(loanId.get(), chargeAdjustmentId.get())); + assertReport(chargeAdjustmentReversalDate, officeId, productName, + allocationRows(CHARGE_ADJUSTMENT_TRANSACTION, true, Map.of(FEES_ALLOCATION, amount(30)))); + + businessDateHelper.runAt(waiverDate.toString(), () -> { + final Long feeId = wcLoanHelper.createGlobalCharge(WorkingCapitalLoanRequestBuilders.specifiedDueDateCharge(false, 40.0)); + final Long loanChargeId = wcLoanHelper.addCharge(loanId.get(), + WorkingCapitalLoanRequestBuilders.addCharge(feeId, 40.0, apiDate(waiverDate.plusDays(5)))); + waiverId.set(wcLoanHelper.waiveCharge(loanId.get(), loanChargeId, WorkingCapitalLoanRequestBuilders.chargeWaiver())); + }); + assertReport(waiverDate, officeId, productName, + allocationRows(WAIVE_CHARGES_TRANSACTION, false, Map.of(FEES_ALLOCATION, amount(-40)))); + + businessDateHelper.runAt(waiverReversalDate.toString(), () -> wcLoanHelper.undoTransaction(loanId.get(), waiverId.get())); + assertReport(waiverReversalDate, officeId, productName, + allocationRows(WAIVE_CHARGES_TRANSACTION, true, Map.of(FEES_ALLOCATION, amount(40)))); + } + + @Test + public void transactionSummaryReportShowsDiscountFeeAndItsAmortizationWithTheirReversals() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createProductWithOverridableDiscount(productName); + final LocalDate disbursementDate = LocalDate.of(2026, 5, 1); + final LocalDate repaymentDate = disbursementDate.plusDays(1); + final LocalDate amortizationCobDate = disbursementDate.plusDays(2); + final LocalDate adjustmentDate = disbursementDate.plusDays(3); + final LocalDate adjustmentCobDate = disbursementDate.plusDays(4); + final LocalDate adjustmentReversalDate = disbursementDate.plusDays(5); + final LocalDate disbursementReversalDate = disbursementDate.plusDays(6); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + final AtomicLong repaymentId = new AtomicLong(); + final AtomicLong adjustmentId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + loanId.set(createDisbursedLoanWithDiscount(borrower.get().clientId(), productId, apiDate(disbursementDate))); + }); + final Long officeId = borrower.get().officeId(); + assertReport(disbursementDate, officeId, productName, + concat(allocationRows(DISBURSEMENT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(9000))), + allocationRows(DISCOUNT_FEE_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(1000))))); + + businessDateHelper.runAt(repaymentDate.toString(), () -> repaymentId.set(wcLoanHelper.makeRepayment(loanId.get(), + WorkingCapitalLoanRequestBuilders.repayment(BigDecimal.valueOf(50), apiDate(repaymentDate))))); + businessDateHelper.runAt(amortizationCobDate.toString(), () -> wcLoanHelper.executeInlineWCCOB(loanId.get())); + final Long amortizationId = activeTransactionId(loanId.get(), DISCOUNT_FEE_AMORTIZATION_TYPE_CODE); + assertReport(repaymentDate, officeId, productName, + concat(allocationRows(DISCOUNT_FEE_AMORTIZATION_TRANSACTION, false, + Map.of(FEES_ALLOCATION, transactionAmount(loanId.get(), amortizationId))), + allocationRows(REPAYMENT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-50))))); + + businessDateHelper.runAt(adjustmentDate.toString(), + () -> adjustmentId.set(wcLoanHelper.makeDiscountFeeAdjustment(loanId.get(), + WorkingCapitalLoanRequestBuilders.discountFeeAdjustment(activeTransactionId(loanId.get(), DISCOUNT_FEE_TYPE_CODE), + BigDecimal.valueOf(500), apiDate(adjustmentDate))))); + businessDateHelper.runAt(adjustmentCobDate.toString(), () -> wcLoanHelper.executeInlineWCCOB(loanId.get())); + final BigDecimal amortizationAdjustment = transactionAmount(loanId.get(), + activeTransactionId(loanId.get(), DISCOUNT_FEE_AMORTIZATION_ADJUSTMENT_TYPE_CODE)); + assertReport(adjustmentDate, officeId, productName, + concat(allocationRows(DISCOUNT_FEE_ADJUSTMENT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-500))), + allocationRows(DISCOUNT_FEE_AMORTIZATION_ADJUSTMENT_TRANSACTION, false, + Map.of(FEES_ALLOCATION, amortizationAdjustment.negate())))); + + businessDateHelper.runAt(adjustmentReversalDate.toString(), () -> wcLoanHelper.undoTransaction(loanId.get(), adjustmentId.get())); + assertReport(adjustmentReversalDate, officeId, productName, concat( + allocationRows(DISCOUNT_FEE_ADJUSTMENT_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(500))), + allocationRows(DISCOUNT_FEE_AMORTIZATION_ADJUSTMENT_TRANSACTION, true, Map.of(FEES_ALLOCATION, amortizationAdjustment)))); + + businessDateHelper.runAt(disbursementReversalDate.toString(), () -> { + wcLoanHelper.undoTransaction(loanId.get(), repaymentId.get()); + wcLoanHelper.undoDisbursal(loanId.get(), WorkingCapitalLoanRequestBuilders.undoDisbursal()); + }); + assertReport(disbursementReversalDate, officeId, productName, + concat(allocationRows(DISBURSEMENT_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(-9000))), + allocationRows(DISCOUNT_FEE_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(-1000))), + allocationRows(DISCOUNT_FEE_AMORTIZATION_TRANSACTION, true, + Map.of(FEES_ALLOCATION, transactionAmount(loanId.get(), amortizationId).negate())), + allocationRows(REPAYMENT_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(50))))); + } + + @Test + public void transactionSummaryReportShowsChargeOffReasonFromTheChargeOffUntilItIsUndone() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createProductWithOverridableDiscount(productName); + final String chargeOffReason = Utils.uniqueRandomStringGenerator("WC TSR Reason ", 6); + final Long chargeOffReasonId = codeHelper.createChargeOffCodeValue(chargeOffReason, 1); + final LocalDate disbursementDate = LocalDate.of(2026, 6, 1); + final LocalDate repaymentDate = disbursementDate.plusDays(1); + final LocalDate chargeOffDate = disbursementDate.plusDays(2); + final LocalDate postChargeOffRepaymentDate = disbursementDate.plusDays(3); + final LocalDate repaymentReversalDate = disbursementDate.plusDays(4); + final LocalDate chargeOffReversalDate = disbursementDate.plusDays(5); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + final AtomicLong postChargeOffRepaymentId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + loanId.set(createDisbursedLoanWithDiscount(borrower.get().clientId(), productId, apiDate(disbursementDate))); + }); + final Long officeId = borrower.get().officeId(); + + businessDateHelper.runAt(repaymentDate.toString(), () -> repaymentIdByLoanId.put(loanId.get(), wcLoanHelper + .makeRepayment(loanId.get(), WorkingCapitalLoanRequestBuilders.repayment(BigDecimal.valueOf(50), apiDate(repaymentDate))))); + assertReport(repaymentDate, officeId, productName, + allocationRows(REPAYMENT_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-50)))); + + businessDateHelper.runAt(chargeOffDate.toString(), () -> wcLoanHelper.chargeOff(loanId.get(), + WorkingCapitalLoanRequestBuilders.chargeOff(apiDate(chargeOffDate), null).chargeOffReasonId(chargeOffReasonId))); + assertReport(chargeOffDate, officeId, productName, + concat(allocationRows(CHARGE_OFF_TRANSACTION, null, false, chargeOffReason, Map.of(PRINCIPAL_ALLOCATION, amount(-9950))), + allocationRows(DISCOUNT_FEE_AMORTIZATION_TRANSACTION, null, false, chargeOffReason, + Map.of(FEES_ALLOCATION, amount(1000))))); + + businessDateHelper.runAt(postChargeOffRepaymentDate.toString(), + () -> postChargeOffRepaymentId.set(wcLoanHelper.makeRepayment(loanId.get(), + WorkingCapitalLoanRequestBuilders.repayment(BigDecimal.valueOf(100), apiDate(postChargeOffRepaymentDate))))); + assertReport(postChargeOffRepaymentDate, officeId, productName, + allocationRows(REPAYMENT_TRANSACTION, null, false, chargeOffReason, Map.of(PRINCIPAL_ALLOCATION, amount(-100)))); + + businessDateHelper.runAt(repaymentReversalDate.toString(), + () -> wcLoanHelper.undoTransaction(loanId.get(), postChargeOffRepaymentId.get())); + assertReport(repaymentReversalDate, officeId, productName, + allocationRows(REPAYMENT_TRANSACTION, null, true, chargeOffReason, Map.of(PRINCIPAL_ALLOCATION, amount(100)))); + + businessDateHelper.runAt(chargeOffReversalDate.toString(), + () -> wcLoanHelper.undoChargeOff(loanId.get(), WorkingCapitalLoanRequestBuilders.undoChargeOff(null))); + assertReport(chargeOffReversalDate, officeId, productName, + concat(allocationRows(CHARGE_OFF_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(9950))), + allocationRows(DISCOUNT_FEE_AMORTIZATION_TRANSACTION, true, Map.of(FEES_ALLOCATION, amount(-1000))))); + } + + @Test + public void transactionSummaryReportShowsWriteOffAndRecoveryWithTheirReversals() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createProductWithoutAccounting(productName); + final LocalDate disbursementDate = LocalDate.of(2026, 7, 1); + final LocalDate writeOffDate = disbursementDate.plusDays(1); + final LocalDate recoveryDate = disbursementDate.plusDays(2); + final LocalDate reversalDate = disbursementDate.plusDays(3); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + final AtomicLong recoveryId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + loanId.set(createDisbursedLoan(borrower.get().clientId(), productId, apiDate(disbursementDate), SMALL_LOAN_PRINCIPAL)); + }); + final Long officeId = borrower.get().officeId(); + + businessDateHelper.runAt(writeOffDate.toString(), () -> wcLoanTransactionHelper.writeOffByLoanId(loanId.get(), + WorkingCapitalLoanDisbursementTestBuilder.buildWriteOffRequest(writeOffDate))); + assertReport(writeOffDate, officeId, productName, + allocationRows(WRITE_OFF_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-1000)))); + + businessDateHelper.runAt(recoveryDate.toString(), () -> recoveryId.set(wcLoanTransactionHelper.recoveryPaymentByLoanId(loanId.get(), + WorkingCapitalLoanDisbursementTestBuilder.buildRecoveryPaymentRequest(recoveryDate, BigDecimal.valueOf(50))))); + assertReport(recoveryDate, officeId, productName, + allocationRows(RECOVERY_REPAYMENT_TRANSACTION, false, Map.of(UNALLOCATED_CREDIT_ALLOCATION, amount(-50)))); + + businessDateHelper.runAt(reversalDate.toString(), () -> { + wcLoanHelper.undoTransaction(loanId.get(), recoveryId.get()); + wcLoanTransactionHelper.undoWriteOffByLoanId(loanId.get(), + WorkingCapitalLoanDisbursementTestBuilder.buildUndoWriteOffRequest()); + }); + assertReport(reversalDate, officeId, productName, + concat(allocationRows(RECOVERY_REPAYMENT_TRANSACTION, true, Map.of(UNALLOCATED_CREDIT_ALLOCATION, amount(50))), + allocationRows(WRITE_OFF_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(1000))))); + } + + @Test + public void transactionSummaryReportShowsOverpaymentAndCreditBalanceRefund() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createProductWithoutAccounting(productName); + final LocalDate disbursementDate = LocalDate.of(2026, 8, 1); + final LocalDate overpaymentDate = disbursementDate.plusDays(1); + final LocalDate refundDate = disbursementDate.plusDays(2); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + loanId.set(createDisbursedLoan(borrower.get().clientId(), productId, apiDate(disbursementDate), LOAN_PRINCIPAL)); + }); + final Long officeId = borrower.get().officeId(); + + businessDateHelper.runAt(overpaymentDate.toString(), () -> wcLoanHelper.makeRepayment(loanId.get(), + WorkingCapitalLoanRequestBuilders.repayment(BigDecimal.valueOf(9050), apiDate(overpaymentDate)))); + assertReport(overpaymentDate, officeId, productName, allocationRows(REPAYMENT_TRANSACTION, false, + Map.of(PRINCIPAL_ALLOCATION, amount(-9000), UNALLOCATED_CREDIT_ALLOCATION, amount(-50)))); + + businessDateHelper.runAt(refundDate.toString(), () -> wcLoanHelper.creditBalanceRefund(loanId.get(), + WorkingCapitalLoanRequestBuilders.creditBalanceRefund(BigDecimal.valueOf(30), apiDate(refundDate)))); + assertReport(refundDate, officeId, productName, + allocationRows(CREDIT_BALANCE_REFUND_TRANSACTION, false, Map.of(UNALLOCATED_CREDIT_ALLOCATION, amount(30)))); + } + + @Test + public void transactionSummaryReportShowsAccrualPerChargeAndItsReversal() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createAccrualWithDeferredRevenueAmortizationProduct(productName); + final ChargeRequest fee = WorkingCapitalLoanRequestBuilders.specifiedDueDateCharge(false, 45.0) + .name(Utils.uniqueRandomStringGenerator("WC TSR Fee ", 6)); + final ChargeRequest penalty = WorkingCapitalLoanRequestBuilders.specifiedDueDateCharge(true, 25.0) + .name(Utils.uniqueRandomStringGenerator("WC TSR Penalty ", 6)); + final Long feeId = wcLoanHelper.createGlobalCharge(fee); + final Long penaltyId = wcLoanHelper.createGlobalCharge(penalty); + final LocalDate disbursementDate = LocalDate.of(2026, 9, 1); + final LocalDate chargeDueDate = disbursementDate.plusDays(1); + final LocalDate reversalDate = disbursementDate.plusDays(2); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + loanId.set(createDisbursedLoan(borrower.get().clientId(), productId, apiDate(disbursementDate), LOAN_PRINCIPAL)); + wcLoanHelper.addCharge(loanId.get(), WorkingCapitalLoanRequestBuilders.addCharge(feeId, 45.0, apiDate(chargeDueDate))); + wcLoanHelper.addCharge(loanId.get(), WorkingCapitalLoanRequestBuilders.addCharge(penaltyId, 25.0, apiDate(chargeDueDate))); + }); + final Long officeId = borrower.get().officeId(); + final List accrualRows = List.of( + new ReportRow(APPLY_CHARGES_TRANSACTION, null, NO_CHARGE_TYPE, false, INTEREST_ALLOCATION, null, amount(0)), + new ReportRow(APPLY_CHARGES_TRANSACTION, null, fee.getName(), false, FEES_ALLOCATION, null, amount(45)), + new ReportRow(APPLY_CHARGES_TRANSACTION, null, penalty.getName(), false, PENALTY_ALLOCATION, null, amount(25))); + + businessDateHelper.runAt(reversalDate.toString(), () -> wcLoanHelper.executeInlineWCCOB(loanId.get())); + assertReport(chargeDueDate, officeId, productName, accrualRows); + + businessDateHelper.runAt(reversalDate.toString(), + () -> wcLoanHelper.undoDisbursal(loanId.get(), WorkingCapitalLoanRequestBuilders.undoDisbursal())); + assertReport( + reversalDate, officeId, productName, concat( + List.of(new ReportRow(APPLY_CHARGES_TRANSACTION, null, NO_CHARGE_TYPE, true, INTEREST_ALLOCATION, null, amount(0)), + new ReportRow(APPLY_CHARGES_TRANSACTION, null, fee.getName(), true, FEES_ALLOCATION, null, amount(-45)), + new ReportRow(APPLY_CHARGES_TRANSACTION, null, penalty.getName(), true, PENALTY_ALLOCATION, null, + amount(-25))), + allocationRows(DISBURSEMENT_TRANSACTION, true, Map.of(PRINCIPAL_ALLOCATION, amount(-9000))))); + assertReport(chargeDueDate, officeId, productName, accrualRows); + } + + @Test + public void transactionSummaryReportGivesTheSameRowsForWorkingCapitalAndRegularLoans() { + final String productName = Utils.uniqueRandomStringGenerator("WCL TSR ", 8); + final Long productId = createAccrualWithDeferredRevenueAmortizationProduct(productName); + final PostLoanProductsRequest regularProduct = new LoanTestAccounts(accountHelper) + .onePeriod30DaysPeriodicAccrualWithAdvancedAllocation(); + final Long regularProductId = Objects.requireNonNull(loanHelper.createLoanProduct(regularProduct).getResourceId()); + final String paymentTypeName = Utils.uniqueRandomStringGenerator("WC TSR Payment ", 6); + final Long paymentTypeId = Objects.requireNonNull(paymentTypeHelper + .createPaymentType( + new PaymentTypeCreateRequest().name(paymentTypeName).description(paymentTypeName).isCashPayment(false).position(1L)) + .getResourceId()); + final ChargeRequest fee = WorkingCapitalLoanRequestBuilders.specifiedDueDateCharge(false, 10.0); + final Long feeId = wcLoanHelper.createGlobalCharge(fee); + final ChargeRequest regularFee = ChargeRequestBuilders.loanSpecifiedDueDateFee(10.0); + final Long regularFeeId = Objects.requireNonNull(chargesHelper.createCharge(regularFee).getResourceId()); + final LocalDate disbursementDate = LocalDate.of(2026, 10, 1); + final LocalDate chargeDueDate = disbursementDate.plusDays(1); + final LocalDate repaymentDate = disbursementDate.plusDays(2); + final LocalDate writeOffDate = disbursementDate.plusDays(3); + final LocalDate recoveryDate = disbursementDate.plusDays(4); + final AtomicReference borrower = new AtomicReference<>(); + final AtomicLong loanId = new AtomicLong(); + final AtomicLong regularLoanId = new AtomicLong(); + + businessDateHelper.runAt(disbursementDate.toString(), () -> { + borrower.set(createBorrower()); + regularLoanId + .set(createDisbursedRegularLoan(borrower.get().clientId(), regularProductId, apiDate(disbursementDate), paymentTypeId)); + loanHelper.addLoanCharge(regularLoanId.get(), LoanRequestBuilders.addLoanCharge(regularFeeId, 10.0, apiDate(chargeDueDate))); + loanId.set(createApprovedLoan(borrower.get().clientId(), productId, apiDate(disbursementDate), SMALL_LOAN_PRINCIPAL)); + wcLoanHelper.disburse(loanId.get(), WorkingCapitalLoanDisbursementTestBuilder.buildDisburseRequest(disbursementDate, + SMALL_LOAN_PRINCIPAL, null, null, paymentTypeId.intValue(), null, null, null, null, null)); + wcLoanHelper.addCharge(loanId.get(), WorkingCapitalLoanRequestBuilders.addCharge(feeId, 10.0, apiDate(chargeDueDate))); + }); + final ComparedReports compared = new ComparedReports(borrower.get().officeId(), productName, regularProduct.getName(), + regularFee.getName(), fee.getName()); + assertSameRows(compared, disbursementDate, + allocationRows(DISBURSEMENT_TRANSACTION, paymentTypeName, false, null, Map.of(PRINCIPAL_ALLOCATION, amount(1000)))); + + businessDateHelper.runAt(repaymentDate.toString(), () -> { + loanTransactionHelper.executeInlineCOB(regularLoanId.get()); + wcLoanHelper.executeInlineWCCOB(loanId.get()); + loanTransactionHelper.addRepayment(regularLoanId.get(), + LoanRequestBuilders.repayLoan(100.0, apiDate(repaymentDate)).paymentTypeId(paymentTypeId)); + wcLoanHelper.makeRepayment(loanId.get(), WorkingCapitalLoanDisbursementTestBuilder.buildRepaymentRequest(repaymentDate, + BigDecimal.valueOf(100), null, null, paymentTypeId.intValue(), null)); + }); + assertSameRows(compared, chargeDueDate, + List.of(new ReportRow(APPLY_CHARGES_TRANSACTION, null, NO_CHARGE_TYPE, false, INTEREST_ALLOCATION, null, amount(0)), + new ReportRow(APPLY_CHARGES_TRANSACTION, null, fee.getName(), false, FEES_ALLOCATION, null, amount(10)))); + assertSameRows(compared, repaymentDate, allocationRows(REPAYMENT_TRANSACTION, paymentTypeName, false, null, + Map.of(FEES_ALLOCATION, amount(-10), PRINCIPAL_ALLOCATION, amount(-90)))); + + businessDateHelper.runAt(writeOffDate.toString(), () -> { + loanTransactionHelper.writeOff(regularLoanId.get(), LoanRequestBuilders.writeOff(apiDate(writeOffDate))); + wcLoanTransactionHelper.writeOffByLoanId(loanId.get(), + WorkingCapitalLoanDisbursementTestBuilder.buildWriteOffRequest(writeOffDate)); + }); + assertSameRows(compared, writeOffDate, allocationRows(WRITE_OFF_TRANSACTION, false, Map.of(PRINCIPAL_ALLOCATION, amount(-910)))); + + businessDateHelper.runAt(recoveryDate.toString(), () -> { + loanTransactionHelper.makeRecoveryPayment(regularLoanId.get(), LoanRequestBuilders.repayLoan(50.0, apiDate(recoveryDate))); + wcLoanTransactionHelper.recoveryPaymentByLoanId(loanId.get(), + WorkingCapitalLoanDisbursementTestBuilder.buildRecoveryPaymentRequest(recoveryDate, BigDecimal.valueOf(50))); + }); + assertSameRows(compared, recoveryDate, + allocationRows(RECOVERY_REPAYMENT_TRANSACTION, false, Map.of(UNALLOCATED_CREDIT_ALLOCATION, amount(-50)))); + } + + private Long createAccrualWithDeferredRevenueAmortizationProduct(final String productName) { + return createProduct(accrualProductBuilder(productName)); + } + + private Long createProductWithoutAccounting(final String productName) { + return createProduct(productBuilder(productName)); + } + + private Long createProductWithOverridableDiscount(final String productName) { + return createProduct(productBuilder(productName).withAllowAttributeOverrides(Map.of("discountDefault", Boolean.TRUE))); + } + + private Long createProduct(final WorkingCapitalLoanProductTestBuilder productBuilder) { + return Objects.requireNonNull(productHelper.createWorkingCapitalLoanProduct(productBuilder.build()).getResourceId()); + } + + private WorkingCapitalLoanProductTestBuilder productBuilder(final String productName) { + return new WorkingCapitalLoanProductTestBuilder().withName(productName).withShortName(Utils.uniqueRandomStringGenerator("", 4)); + } + + private WorkingCapitalLoanProductTestBuilder accrualProductBuilder(final String productName) { + return productBuilder(productName).withAccountingRule(AccountingRuleEnum.ACC_DEF_REV_AM) + .withFundSourceAccountId(fundSourceAccount.getAccountID().longValue()) + .withLoanPortfolioAccountId(loanPortfolioAccount.getAccountID().longValue()) + .withTransfersInSuspenseAccountId(transfersSuspenseAccount.getAccountID().longValue()) + .withIncomeFromDiscountFeeAccountId(incomeFromDiscountFeeAccount.getAccountID().longValue()) + .withReceivableFeeAccountId(feesReceivableAccount.getAccountID().longValue()) + .withReceivablePenaltyAccountId(penaltiesReceivableAccount.getAccountID().longValue()) + .withIncomeFromFeeAccountId(incomeFromFeeAccount.getAccountID().longValue()) + .withIncomeFromPenaltyAccountId(incomeFromPenaltyAccount.getAccountID().longValue()) + .withIncomeFromRecoveryAccountId(incomeFromRecoveryAccount.getAccountID().longValue()) + .withWriteOffAccountId(writeOffAccount.getAccountID().longValue()) + .withOverpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue()) + .withDeferredIncomeLiabilityAccountId(deferredIncomeAccount.getAccountID().longValue()); + } + + private Borrower createBorrower() { + final Long officeId = officeHelper.createOffice(OFFICE_OPENING_DATE).getResourceId(); + assertNotNull(officeId); + return new Borrower(officeId, createClientInOffice(officeId)); + } + + private Long createClientInOffice(final Long officeId) { + return Objects.requireNonNull(clientHelper + .createClient(ClientRequestBuilders.createActivePersonClient(CLIENT_ACTIVATION_DATE).officeId(officeId)).getClientId()); + } + + private Long createApprovedAndDisbursedLoan(final Long clientId, final Long productId) { + return createDisbursedLoan(clientId, productId, TRANSACTION_DATE, PRINCIPAL); + } + + private Long createDisbursedLoan(final Long clientId, final Long productId, final String disbursementDate, final BigDecimal principal) { + final Long loanId = createApprovedLoan(clientId, productId, disbursementDate, principal); + wcLoanHelper.disburse(loanId, WorkingCapitalLoanRequestBuilders.disburse(disbursementDate, principal)); + return loanId; + } + + private Long createApprovedLoan(final Long clientId, final Long productId, final String disbursementDate, final BigDecimal principal) { + final Long loanId = wcLoanHelper.submitApplication(WorkingCapitalLoanRequestBuilders.submitApplication(clientId, productId, + principal, WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT, disbursementDate, disbursementDate)); + createdLoanIds.add(loanId); + wcLoanHelper.approve(loanId, WorkingCapitalLoanRequestBuilders.approve(disbursementDate, principal, disbursementDate)); + return loanId; + } + + private Long createDisbursedLoanWithDiscount(final Long clientId, final Long productId, final String disbursementDate) { + final Long loanId = wcLoanHelper.submitApplication(WorkingCapitalLoanRequestBuilders.submitApplicationWithDiscount(clientId, + productId, LOAN_PRINCIPAL, WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT, disbursementDate, + disbursementDate, DISCOUNT_FEE)); + createdLoanIds.add(loanId); + wcLoanHelper.approve(loanId, + WorkingCapitalLoanRequestBuilders.approveWithDiscount(disbursementDate, LOAN_PRINCIPAL, disbursementDate, DISCOUNT_FEE)); + wcLoanHelper.disburse(loanId, + WorkingCapitalLoanRequestBuilders.disburseWithDiscount(disbursementDate, LOAN_PRINCIPAL, DISCOUNT_FEE)); + return loanId; + } + + private Long createDisbursedRegularLoan(final Long clientId, final Long productId, final String disbursementDate, + final Long paymentTypeId) { + final Long loanId = Objects + .requireNonNull( + loanHelper + .applyForLoan(LoanRequestBuilders + .applyLoanRequest(clientId, productId, disbursementDate, SMALL_LOAN_PRINCIPAL.doubleValue(), 1, + request -> request.transactionProcessingStrategyCode( + TransactionProcessingStrategyCode.ADVANCED_PAYMENT_ALLOCATION_STRATEGY))) + .getLoanId()); + loanHelper.approveLoan(loanId, LoanRequestBuilders.approveLoan(SMALL_LOAN_PRINCIPAL.doubleValue(), disbursementDate)); + loanHelper.disburseLoan(loanId, LoanRequestBuilders.disburseLoan(SMALL_LOAN_PRINCIPAL.doubleValue(), disbursementDate) + .paymentTypeId(paymentTypeId.intValue())); + return loanId; + } + + private String addPenaltyForLoan(final Long loanId) { + final ChargeRequest penalty = WorkingCapitalLoanRequestBuilders.specifiedDueDateCharge(true, PENALTY_AMOUNT); + final Long chargeId = wcLoanHelper.createGlobalCharge(penalty); + wcLoanHelper.addCharge(loanId, WorkingCapitalLoanRequestBuilders.addCharge(chargeId, PENALTY_AMOUNT, TRANSACTION_DATE)); + return penalty.getName(); + } + + private void makePartialRepayment(final Long loanId) { + repaymentIdByLoanId.put(loanId, wcLoanHelper.makeRepayment(loanId, + WorkingCapitalLoanRequestBuilders.repayment(PARTIAL_REPAYMENT_AMOUNT, TRANSACTION_DATE))); + } + + private Long activeTransactionId(final Long loanId, final String typeCode) { + return wcLoanHelper.getTransactions(loanId).stream() + .filter(transaction -> typeCode.equals(Objects.requireNonNull(transaction.getType()).getCode()) + && !Boolean.TRUE.equals(transaction.getReversed())) + .findFirst().map(GetWorkingCapitalLoanTransactionIdResponse::getId) + .orElseThrow(() -> new AssertionError("No active " + typeCode + " transaction on Working Capital loan " + loanId)); + } + + private BigDecimal transactionAmount(final Long loanId, final Long transactionId) { + return amount(Objects.requireNonNull(wcLoanHelper.getTransaction(loanId, transactionId).getTransactionAmount())); + } + + private RunReportsResponse runTransactionSummaryReport(final String endDate, final Long officeId) { + return runReport(TRANSACTION_SUMMARY_REPORT, endDate, officeId); + } + + private RunReportsResponse runReport(final String reportName, final String endDate, final Long officeId) { + return reportHelper.runReport(reportName, Map.of("R_endDate", endDate, "R_officeId", officeId.toString(), "output-type", "CSV")); + } + + private void assertReport(final LocalDate reportDate, final Long officeId, final String productName, + final List expectedRows) { + assertEquals(expectedRows, reportRows(TRANSACTION_SUMMARY_REPORT, reportDate, officeId, productName), + "Rows of " + TRANSACTION_SUMMARY_REPORT + " for " + reportDate); + } + + private void assertSameRows(final ComparedReports compared, final LocalDate reportDate, final List expectedRows) { + assertReport(reportDate, compared.officeId(), compared.productName(), expectedRows); + final List regularRows = reportRows(REGULAR_TRANSACTION_SUMMARY_REPORT, reportDate, compared.officeId(), + compared.regularProductName()).stream() + .map(row -> compared.regularChargeName().equals(row.chargeType()) ? row.withChargeType(compared.chargeName()) : row) + .toList(); + assertEquals(expectedRows, regularRows, "Rows of " + REGULAR_TRANSACTION_SUMMARY_REPORT + " for " + reportDate); + } + + private List reportRows(final String reportName, final LocalDate reportDate, final Long officeId, final String productName) { + final List reportData = runReport(reportName, reportDate.toString(), officeId).getData(); + assertNotNull(reportData); + return reportData.stream().map(rowData -> toReportRow(Objects.requireNonNull(rowData.getRow()), reportDate, productName)).toList(); + } + + private ReportRow toReportRow(final List row, final LocalDate reportDate, final String productName) { + assertEquals(reportDate.toString(), row.get(TRANSACTION_DATE_COLUMN)); + assertEquals(productName, row.get(PRODUCT_NAME_COLUMN)); + assertNull(row.get(ASSET_OWNER_ID_COLUMN)); + assertNull(row.get(FROM_ASSET_OWNER_ID_COLUMN)); + assertNull(row.get(ORIGINATOR_EXTERNAL_IDS_COLUMN)); + return new ReportRow((String) row.get(TRANSACTION_TYPE_COLUMN), (String) row.get(PAYMENT_TYPE_COLUMN), + (String) row.get(CHARGE_TYPE_COLUMN), isReversed(row.get(REVERSED_COLUMN)), (String) row.get(ALLOCATION_TYPE_COLUMN), + (String) row.get(CHARGE_OFF_REASON_COLUMN), amount(((Number) row.get(AMOUNT_COLUMN)).doubleValue())); + } + + private void assertReportRow(final List row, final String productName, final String transactionType, final String chargeType, + final String allocationType, final double amount) { + assertEquals(REPORT_DATE, row.get(TRANSACTION_DATE_COLUMN)); + assertEquals(productName, row.get(PRODUCT_NAME_COLUMN)); + assertEquals(transactionType, row.get(TRANSACTION_TYPE_COLUMN)); + assertNull(row.get(PAYMENT_TYPE_COLUMN)); + assertEquals(chargeType, row.get(CHARGE_TYPE_COLUMN)); + assertNotReversed(row.get(REVERSED_COLUMN)); + assertEquals(allocationType, row.get(ALLOCATION_TYPE_COLUMN)); + assertNull(row.get(CHARGE_OFF_REASON_COLUMN)); + assertEquals(amount, ((Number) row.get(AMOUNT_COLUMN)).doubleValue(), AMOUNT_TOLERANCE); + assertNull(row.get(ASSET_OWNER_ID_COLUMN)); + assertNull(row.get(FROM_ASSET_OWNER_ID_COLUMN)); + assertNull(row.get(ORIGINATOR_EXTERNAL_IDS_COLUMN)); + } + + private void assertNotReversed(final Object reversed) { + assertFalse(isReversed(reversed), "Expected a non-reversed transaction, but the report reported reversed=" + reversed); + } + + private static boolean isReversed(final Object reversed) { + return reversed instanceof Number number ? number.intValue() != 0 : Boolean.TRUE.equals(reversed); + } + + private static List allocationRows(final String transactionType, final boolean reversed, + final Map amounts) { + return allocationRows(transactionType, null, reversed, null, amounts); + } + + private static List allocationRows(final String transactionType, final String paymentType, final boolean reversed, + final String chargeOffReason, final Map amounts) { + return ALLOCATION_TYPES.stream().map(allocationType -> new ReportRow(transactionType, paymentType, NO_CHARGE_TYPE, reversed, + allocationType, chargeOffReason, amounts.getOrDefault(allocationType, amount(0)))).toList(); + } + + @SafeVarargs + private static List concat(final List... groups) { + return Stream.of(groups).flatMap(List::stream).toList(); + } + + private static BigDecimal amount(final double value) { + return amount(BigDecimal.valueOf(value)); + } + + private static BigDecimal amount(final BigDecimal value) { + return value.setScale(2, RoundingMode.HALF_UP); + } + + private static String apiDate(final LocalDate date) { + return date.format(API_DATE_FORMAT); + } + + private record Borrower(Long officeId, Long clientId) { + } + + private record ComparedReports(Long officeId, String productName, String regularProductName, String regularChargeName, + String chargeName) { + } + + private record ReportRow(String transactionType, String paymentType, String chargeType, boolean reversed, String allocationType, + String chargeOffReason, BigDecimal amount) { + + ReportRow withChargeType(final String newChargeType) { + return new ReportRow(transactionType, paymentType, newChargeType, reversed, allocationType, chargeOffReason, amount); + } + } +} diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ReportsTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ReportsTest.java index 90607df6a65..59679593317 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ReportsTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/ReportsTest.java @@ -79,8 +79,8 @@ public void teardownStringParamReport() { @Test void listReports() { - // count is 85 because @BeforeAll creates StringParamIntegrationTest fixture report - assertThat(ok(() -> fineractClient().reports().retrieveAllReports())).hasSize(85); + // count is 87 because @BeforeAll creates StringParamIntegrationTest fixture report + assertThat(ok(() -> fineractClient().reports().retrieveAllReports())).hasSize(87); } @Test diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignWorkingCapitalLoanHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignWorkingCapitalLoanHelper.java index 5c14943a647..8d6bc1f32ee 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignWorkingCapitalLoanHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignWorkingCapitalLoanHelper.java @@ -319,6 +319,12 @@ public Long adjustCharge(Long loanId, Long loanChargeId, PostWorkingCapitalLoans return response.getSubResourceId(); } + public Long waiveCharge(Long loanId, Long loanChargeId, PostWorkingCapitalLoansLoanIdChargesChargeIdRequest request) { + PostWorkingCapitalLoansLoanIdChargesChargeIdResponse response = ok( + () -> fineractClient.workingCapitalLoanCharges().adjustLoanCharge(loanId, loanChargeId, request, "waive")); + return response.getSubResourceId(); + } + public void undoLoanTransaction(Long loanId, Long transactionId, ExecuteWorkingCapitalLoanTransactionCommandRequest request) { ok(() -> fineractClient.workingCapitalLoanTransactions().executeWorkingCapitalLoanTransactionCommandByLoanIdTransactionId(loanId, transactionId, "undo", request)); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/modules/WorkingCapitalLoanRequestBuilders.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/modules/WorkingCapitalLoanRequestBuilders.java index add190f10a3..9ae1d51e780 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/modules/WorkingCapitalLoanRequestBuilders.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/modules/WorkingCapitalLoanRequestBuilders.java @@ -253,6 +253,10 @@ public static PostWorkingCapitalLoansLoanIdChargesChargeIdRequest chargeAdjustme return new PostWorkingCapitalLoansLoanIdChargesChargeIdRequest().amount(amount).locale(LOCALE).dateFormat(DATE_FORMAT); } + public static PostWorkingCapitalLoansLoanIdChargesChargeIdRequest chargeWaiver() { + return new PostWorkingCapitalLoansLoanIdChargesChargeIdRequest().locale(LOCALE); + } + public static PostWorkingCapitalLoanTransactionsRequest creditBalanceRefund(BigDecimal amount, String transactionDate) { return repayment(amount, transactionDate); }