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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
{
"default": null,
"name": "dailyPaymentAmount",
"doc": "Payment amount per repayment period of the segment this change opened (per day on a daily schedule)",
"type": [
"null",
"bigdecimal"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.CURRENCY_CODE;
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.CURRENCY_CODE_USD;
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.DATE_FORMAT;
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.DAYS_IN_MONTH_TYPE_30;
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.DAYS_IN_YEAR_TYPE_360;
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.FUND_ID;
import static org.apache.fineract.test.factory.LoanProductsRequestFactory.LOCALE_EN;
Expand Down Expand Up @@ -142,7 +141,7 @@ public PostWorkingCapitalLoanProductsRequest defaultWorkingCapitalLoanProductReq
.fundId(FUND_ID)//
.periodPaymentRate(new BigDecimal(1))//
.repaymentFrequencyType(PostWorkingCapitalLoanProductsRequest.RepaymentFrequencyTypeEnum.DAYS)//
.repaymentEvery(DAYS_IN_MONTH_TYPE_30)//
.repaymentEvery(1)//
.startDate(null)//
.closeDate(null)//
.currencyCode(CURRENCY_CODE)//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,3 +427,134 @@ Feature: WorkingCapitalAmortizationScheduleMatrixPt1
| 2 | 2026-01-03 | 50.00 | 0.00 | 0.00 | | | 0.00 | | |
And The retrieved amortization schedule has no negative monetary amounts
And The retrieved amortization schedule has exactly 3 payment rows

# =============================================================================
# FINERACT-2455: Dynamic repaymentFrequencyType / repaymentEvery
# =============================================================================

@TestRailId:C115289
Scenario: Verify dynamic repayment frequency - UC1: weekly-equivalent frequency DAYS/7
When Admin sets the business date to "01 January 2026"
And Admin creates a client with random data
And Admin creates a new Working Capital Loan Product with the following matrix data:
| accountingRule | npvDayCount | repaymentFrequencyType | repaymentEvery |
| NONE | 360 | DAYS | 7 |
And Admin creates a working capital loan using created product with the following data:
| submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount |
| 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 1000 |
When Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and "1000" discount 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 "1000" discount amount
# --- Amortization schedule verification ---
And Admin retrieves the projected amortization schedule
Then The retrieved amortization schedule has the following summary fields:
| discountFeeAmount | netDisbursementAmount | totalPaymentVolume | periodPaymentRate | npvDayCount | expectedPaymentAmount | originalPaymentNumber |
| 1000.00 | 9000.00 | 100000.00 | 18 | 360 | 350.00 | 29 |
And The retrieved amortization schedule has payments with the following details for the listed payment numbers:
| paymentNo | date | expectedPaymentAmount | expectedBalance | expectedDiscountFeeBalance |
| 0 | 2026-01-01 | -9000.00 | 9000.00 | 1000.00 |
| 1 | 2026-01-08 | 350.00 | 8715.44 | 934.56 |
| 2 | 2026-01-15 | 350.00 | 8428.81 | 871.19 |
| 28 | 2026-07-16 | 350.00 | 198.56 | 1.44 |
| 29 | 2026-07-23 | 200.00 | 0.00 | 0.00 |
And The retrieved amortization schedule has exactly 30 payment rows
And The retrieved amortization schedule has no negative monetary amounts

@TestRailId:C115290
Scenario: Verify dynamic repayment frequency - UC2: native WEEKS/2 frequency
When Admin sets the business date to "01 January 2026"
And Admin creates a client with random data
And Admin creates a new Working Capital Loan Product with the following matrix data:
| accountingRule | npvDayCount | repaymentFrequencyType | repaymentEvery |
| NONE | 360 | WEEKS | 2 |
And Admin creates a working capital loan using created product with the following data:
| submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount |
| 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 1000 |
When Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and "1000" discount 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 "1000" discount amount
# --- Amortization schedule verification ---
And Admin retrieves the projected amortization schedule
Then The retrieved amortization schedule has the following summary fields:
| discountFeeAmount | netDisbursementAmount | totalPaymentVolume | periodPaymentRate | npvDayCount | expectedPaymentAmount | originalPaymentNumber |
| 1000.00 | 9000.00 | 100000.00 | 18 | 360 | 700.00 | 15 |
And The retrieved amortization schedule has payments with the following details for the listed payment numbers:
| paymentNo | date | expectedPaymentAmount | expectedBalance | expectedDiscountFeeBalance |
| 0 | 2026-01-01 | -9000.00 | 9000.00 | 1000.00 |
| 1 | 2026-01-15 | 700.00 | 8426.80 | 873.20 |
| 2 | 2026-01-29 | 700.00 | 7845.52 | 754.48 |
| 15 | 2026-07-30 | 200.00 | 0.00 | 0.00 |
And The retrieved amortization schedule has exactly 16 payment rows
And The retrieved amortization schedule has no negative monetary amounts

@TestRailId:C115291
Scenario: Verify dynamic repayment frequency - UC3: monthly frequency MONTHS/1
When Admin sets the business date to "01 January 2026"
And Admin creates a client with random data
And Admin creates a new Working Capital Loan Product with the following matrix data:
| accountingRule | npvDayCount | repaymentFrequencyType | repaymentEvery |
| NONE | 360 | MONTHS | 1 |
And Admin creates a working capital loan using created product with the following data:
| submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount |
| 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 1000 |
When Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and "1000" discount 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 "1000" discount amount
# --- Amortization schedule verification ---
And Admin retrieves the projected amortization schedule
Then The retrieved amortization schedule has the following summary fields:
| discountFeeAmount | netDisbursementAmount | totalPaymentVolume | periodPaymentRate | npvDayCount | expectedPaymentAmount | originalPaymentNumber |
| 1000.00 | 9000.00 | 100000.00 | 18 | 360 | 1500.00 | 7 |
And The retrieved amortization schedule has payments with the following details for the listed payment numbers:
| paymentNo | date | expectedPaymentAmount | expectedBalance | expectedDiscountFeeBalance |
| 0 | 2026-01-01 | -9000.00 | 9000.00 | 1000.00 |
| 1 | 2026-02-01 | 1500.00 | 7753.14 | 746.86 |
| 2 | 2026-03-01 | 1500.00 | 6471.21 | 528.79 |
| 6 | 2026-07-01 | 1500.00 | 972.64 | 27.36 |
| 7 | 2026-08-01 | 1000.00 | 0.00 | 0.00 |
And The retrieved amortization schedule has exactly 8 payment rows
And The retrieved amortization schedule has no negative monetary amounts

@TestRailId:C115292
Scenario: Verify dynamic repayment frequency - UC4: MONTHS/1 keeps month-end anchor for 31st disbursement
When Admin sets the business date to "31 January 2026"
And Admin creates a client with random data
And Admin creates a new Working Capital Loan Product with the following matrix data:
| accountingRule | npvDayCount | repaymentFrequencyType | repaymentEvery |
| NONE | 360 | MONTHS | 1 |
And Admin creates a working capital loan using created product with the following data:
| submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount |
| 31 January 2026 | 31 January 2026 | 9000 | 100000 | 18 | 1000 |
When Admin successfully approves the working capital loan on "31 January 2026" with "9000" amount and "1000" discount amount and expected disbursement date on "31 January 2026"
And Admin successfully disburse the Working Capital loan on "31 January 2026" with "9000" EUR transaction amount and "1000" discount amount
# --- Amortization schedule verification: due dates snap back to the 31st after February ---
And Admin retrieves the projected amortization schedule
And The retrieved amortization schedule has payments with the following details for the listed payment numbers:
| paymentNo | date | expectedPaymentAmount | expectedBalance | expectedDiscountFeeBalance |
| 0 | 2026-01-31 | -9000.00 | 9000.00 | 1000.00 |
| 1 | 2026-02-28 | 1500.00 | 7753.14 | 746.86 |
| 2 | 2026-03-31 | 1500.00 | 6471.21 | 528.79 |
| 3 | 2026-04-30 | 1500.00 | 5153.22 | 346.78 |
And The retrieved amortization schedule has no negative monetary amounts

@TestRailId:C115293
Scenario: Verify dynamic repayment frequency - UC5: repayment on DAYS/7 due date
When Admin sets the business date to "01 January 2026"
And Admin creates a client with random data
And Admin creates a new Working Capital Loan Product with the following matrix data:
| accountingRule | npvDayCount | repaymentFrequencyType | repaymentEvery |
| NONE | 360 | DAYS | 7 |
And Admin creates a working capital loan using created product with the following data:
| submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount |
| 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 1000 |
When Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and "1000" discount 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 "1000" discount amount
# --- Repayment on the first due date ---
When Admin sets the business date to "08 January 2026"
And Customer makes repayment on "08 January 2026" with 350 transaction amount on Working Capital loan
Then Working Capital loan status will be "ACTIVE"
# --- Schedule after repayment ---
When Admin retrieves the projected amortization schedule
Then The retrieved amortization schedule has payments with the following details for the listed payment numbers:
| paymentNo | date | expectedPaymentAmount | expectedBalance | actualPaymentAmount | expectedDiscountFeeBalance | actualBalance | actualDiscountFeeBalance |
| 0 | 2026-01-01 | -9000.00 | 9000.00 | | 1000.00 | 9000.00 | 1000.00 |
| 1 | 2026-01-08 | 350.00 | 8715.44 | 350.00 | 934.56 | 8715.44 | 934.56 |
| 2 | 2026-01-15 | 350.00 | 8428.81 | | 871.19 | | |
And The retrieved amortization schedule has no negative monetary amounts
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,25 @@ Feature: WorkingCapitalAmortizationScheduleMatrixPt2
| paymentNo | date | expectedPaymentAmount | expectedBalance | expectedAmortizationAmount | actualPaymentAmount | actualAmortizationAmount | expectedDiscountFeeBalance | actualBalance | actualDiscountFeeBalance |
| 0 | 2026-01-01 | -9000.00 | 9000.00 | | | | 1000.00 | 9000.00 | 1000.00 |
| 1 | 2026-01-02 | 50.00 | 8959.61 | 1000.00 | 10000.00 | 1000.00 | 0.00 | 0.00 | 0.00 |
And The retrieved amortization schedule has exactly 201 payment rows
# The fee repayment carries no principal, so the schedule still ends on the payoff day
And The retrieved amortization schedule has exactly 2 payment rows
And The retrieved amortization schedule actual amortization total is "1000"


# =============================================================================
# FINERACT-2455: Dynamic repaymentFrequencyType / repaymentEvery
# =============================================================================

@TestRailId:C115294
Scenario: Verify annual EIR - UC2: DAYS/7 frequency annualizes per-period rate
When Admin sets the business date to "01 January 2026"
And Admin creates a client with random data
And Admin creates a new Working Capital Loan Product with the following matrix data:
| accountingRule | npvDayCount | repaymentFrequencyType | repaymentEvery |
| NONE | 360 | DAYS | 7 |
And Admin creates a working capital loan using created product with the following data:
| submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount |
| 01 January 2026 | 01 January 2026 | 9000 | 100000 | 18 | 1000 |
When Admin successfully approves the working capital loan on "01 January 2026" with "9000" amount and "1000" discount 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 "1000" discount amount
Then Working capital loan details has annual EIR "45.146503"
Original file line number Diff line number Diff line change
Expand Up @@ -2092,3 +2092,11 @@ Feature: WorkingCapitalLoanAccount
| WCLP | 01 January 2026 | 01 January 2026 | 100.0 | 100.0 | 1.0 | 0.0 |
Then Working capital loan creation was successful
When Admin modifies the working capital loan resenting its current delinquencyBucketId

@TestRailId:C115287
Scenario: Create Working Capital Loan account - UC4.3: With LP overridable disabled, overriding to non-daily frequency is rejected (Negative)
When Admin sets the business date to "01 January 2026"
And Admin creates a client with random data
Then Creating a working capital loan with LP overridable disabled and with the following data will result an error:
| LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPaymentVolume | periodPaymentRate | discount | delinquencyBucketId | repaymentEvery | repaymentFrequencyType |
| WCLP_DISALLOW_ATTRIBUTES_OVERRIDE | 01 January 2026 | 01 January 2026 | 100.0 | 100.0 | 1.0 | 0.0 | WC_DELINQUENCY_BUCKET | 1 | MONTHS |
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Feature: Working Capital Loan Details
| currency.displayLabel | Euro (€) |
| fundId | null |
| fundName | null |
| repaymentEvery | 30 |
| repaymentEvery | 1 |
| repaymentFrequencyType.code | DAYS |
| repaymentFrequencyType.value | present |
| delinquencyGraceDays | null |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -542,3 +542,13 @@ Feature: WorkingCapitalLoanProduct
Examples:
| wcp_field_name | wcp_invalid_field_value | wcp_error_message |
| delinquencyBucketId | "BASIC_DELINQUENCY_BUCKET" | "The parameter `delinquencyBucketId` must reference a WORKING_CAPITAL delinquency bucket." |

@TestRailId:C115288
Scenario Outline: Verify WC Loan Product create rejects unsupported repayment frequency settings
Then Admin failed to create a new Working Capital Loan Product with field "<wcp_field_name>" invalid data <wcp_invalid_field_value> and got an error <wcp_error_message>

Examples:
| wcp_field_name | wcp_invalid_field_value | wcp_error_message |
| repaymentFrequencyType | "YEARS" | "invalid.period.frequency.type" |
| repaymentEvery | "0" | "The parameter `repaymentEvery` must be greater than 0." |
| repaymentEvery | "-3" | "The parameter `repaymentEvery` must be greater than 0." |
Loading
Loading