From d1db49478b95bc0cacf4d324bc2fe075a1f068a0 Mon Sep 17 00:00:00 2001 From: mariiaKraievska Date: Tue, 19 May 2026 14:54:48 +0300 Subject: [PATCH] FINERACT-2455: WC - Transaction Type - Discount adjustment --- .../domain/CommandWrapperConstants.java | 1 + .../service/CommandWrapperBuilder.java | 13 +- .../working-capital-discount-fee-txn.adoc | 88 + .../WorkingCapitalLoanRequestFactory.java | 6 - .../test/helper/ErrorMessageHelper.java | 12 + .../WorkingCapitalLoanAccountStepDef.java | 103 +- ...WorkingCapitalAmortizationSchedule.feature | 56 +- .../features/WorkingCapitalDiscount.feature | 471 +++ .../WorkingCapitalLoanRepayment.feature | 2762 ++++++++++++++++- .../domain/LoanTransactionType.java | 6 + .../loanproduct/service/LoanEnumerations.java | 2 + ...entConfigurationValidationServiceTest.java | 1 + ...FeeAdjustmentTransactionBusinessEvent.java | 40 + .../WorkingCapitalLoanConstants.java | 2 + .../api/WorkingCapitalLoanApiResource.java | 2 - .../WorkingCapitalLoanApiResourceSwagger.java | 2 - ...ingCapitalLoanTransactionsApiResource.java | 8 +- ...talLoanTransactionsApiResourceSwagger.java | 6 +- ...ojectedAmortizationScheduleCalculator.java | 6 +- .../ProjectedAmortizationScheduleModel.java | 158 +- .../domain/WorkingCapitalLoanTransaction.java | 17 + ...rkingCapitalLoanTransactionAllocation.java | 10 + ...italLoanTransactionRelationRepository.java | 4 + ...anDiscountFeeAdjustmentCommandHandler.java | 40 + .../WorkingCapitalLoanDataValidator.java | 64 + ...lLoanAmortizationScheduleWriteService.java | 6 + ...nAmortizationScheduleWriteServiceImpl.java | 52 +- ...orkingCapitalLoanWritePlatformService.java | 2 + ...ngCapitalLoanWritePlatformServiceImpl.java | 105 +- .../module-changelog-master.xml | 1 + ...oan_discount_adjustment_external_event.xml | 37 + ...tedAmortizationScheduleCalculatorTest.java | 44 +- ...WorkingCapitalLoanApplicationCRUDTest.java | 57 +- ...gCapitalLoanApplicationValidationTest.java | 128 +- ...rkingCapitalLoanApprovalRejectionTest.java | 14 +- ...ingCapitalLoanCreditBalanceRefundTest.java | 3 +- ...lLoanDelinquencyActionIntegrationTest.java | 3 +- ...linquencyRangeScheduleIntegrationTest.java | 4 +- .../WorkingCapitalLoanDisbursementTest.java | 74 +- .../WorkingCapitalLoanProductCRUDTest.java | 21 +- ...rkingCapitalLoanProductValidationTest.java | 18 +- ...ingCapitalLoanRepaymentAccountingTest.java | 3 +- .../WorkingCapitalLoanRepaymentTest.java | 23 +- .../ExternalEventConfigurationHelper.java | 6 + .../WorkingCapitalLoanProductTestBuilder.java | 6 +- 45 files changed, 4051 insertions(+), 436 deletions(-) create mode 100644 fineract-working-capital-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/workingcapitalloan/transaction/WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent.java create mode 100644 fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/handler/WorkingCapitalLoanDiscountFeeAdjustmentCommandHandler.java create mode 100644 fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/parts/0038_wc_loan_discount_adjustment_external_event.xml diff --git a/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapperConstants.java b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapperConstants.java index b99d79a58ad..898effa931f 100644 --- a/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapperConstants.java +++ b/fineract-core/src/main/java/org/apache/fineract/commands/domain/CommandWrapperConstants.java @@ -37,6 +37,7 @@ private CommandWrapperConstants() {} public static final String ACTION_DISBURSE = "DISBURSE"; public static final String ACTION_DISBURSALUNDO = "DISBURSALUNDO"; public static final String ACTION_DISCOUNTFEE = "DISCOUNTFEE"; + public static final String ACTION_DISCOUNTFEEADJUSTMENT = "DISCOUNTFEEADJUSTMENT"; public static final String ACTION_ACTIVATE = "ACTIVATE"; public static final String ACTION_CLOSE = "CLOSE"; public static final String ACTION_WITHDRAW = "WITHDRAW"; diff --git a/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java index 8b07bfa0e88..33b3fd3d891 100644 --- a/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java +++ b/fineract-core/src/main/java/org/apache/fineract/commands/service/CommandWrapperBuilder.java @@ -75,6 +75,7 @@ import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_DISBURSETOSAVINGS; import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_DISBURSEWITHOUTAUTODOWNPAYMENT; import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_DISCOUNTFEE; +import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_DISCOUNTFEEADJUSTMENT; import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_DOWNPAYMENT; import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_ENABLE; import static org.apache.fineract.commands.domain.CommandWrapperConstants.ACTION_EXECUTE; @@ -845,11 +846,19 @@ public CommandWrapperBuilder undoWorkingCapitalLoanApplicationDisbursal(final Lo return this; } - public CommandWrapperBuilder discountWorkingCapitalLoanApplicationDisbursal(final Long loanId) { + public CommandWrapperBuilder discountFeeWorkingCapitalLoanTransaction(final Long loanId) { this.actionName = ACTION_DISCOUNTFEE; this.entityName = ENTITY_WORKINGCAPITALLOAN; this.entityId = loanId; - this.href = "/workingcapitalloans/" + loanId; + this.href = "/working-capital-loans/" + loanId + "/transactions?command=discountFee"; + return this; + } + + public CommandWrapperBuilder discountFeeAdjustmentWorkingCapitalLoanTransaction(final Long loanId) { + this.actionName = ACTION_DISCOUNTFEEADJUSTMENT; + this.entityName = ENTITY_WORKINGCAPITALLOAN; + this.entityId = loanId; + this.href = "/working-capital-loans/" + loanId + "/transactions?command=discountFeeAdjustment"; return this; } diff --git a/fineract-doc/src/docs/en/chapters/features/working-capital-discount-fee-txn.adoc b/fineract-doc/src/docs/en/chapters/features/working-capital-discount-fee-txn.adoc index 30422ad4f6d..58bba4538ea 100644 --- a/fineract-doc/src/docs/en/chapters/features/working-capital-discount-fee-txn.adoc +++ b/fineract-doc/src/docs/en/chapters/features/working-capital-discount-fee-txn.adoc @@ -66,3 +66,91 @@ Schedule & balance updates: - Amortization Schedule * Discount Fee transaction cannot exist without its related disbursement + +=== 7. Discount Fee Adjustment + +A **Discount Fee Adjustment** reduces the loan-level discount (origination fee) that was established by an existing, non-reversed **Discount Fee** transaction. Behaviour is aligned with other *adjustment* transaction types (e.g. Capitalized Income Adjustment): linked parent transaction, allocation row, schedule restate, and business event. + +==== Purpose + +* Correct a discount fee amount +* Recalculate EIR and amortisation schedule + +==== Applicability + +* **Working Capital Loan** only (same as Discount Fee) +* Loan must be **Active** +* Parent transaction must be an active (non-reversed) **Discount Fee** transaction + +==== Transaction behaviour + +* Creates a separate transaction of type `DISCOUNT_FEE_ADJUSTMENT` +* Linked to the original Discount Fee transaction via `relatedResourceId` (in the request body) and a `RELATED` loan transaction relation +* **Multiple adjustments** are allowed against the same Discount Fee transaction until the remaining adjustable amount is zero +* Reduces `loanProductRelatedDetails.discount` by the adjustment amount + +==== Validation rules + +[cols="2,3"] +|=== +| Rule | Detail + +| Amount +| Mandatory; must be **> 0** + +| Maximum amount +| Must not exceed *remaining discount* = original discount fee amount minus sum of prior non-reversed adjustments + +| Transaction date +| Optional in request; defaults to the parent Discount Fee date if omitted + +| Date vs discount fee +| Must **not** be before the parent Discount Fee transaction date + +| Backdating +| **Not allowed** — transaction date must be on or after the current business date + +| Loan status +| Adjustment allowed only for **Active** loans + +| Parent transaction +| `relatedResourceId` must reference a non-reversed **Discount Fee** transaction +|=== + +==== Allocation + +* An allocation row is stored in `m_wc_loan_transaction_allocation` +* Adjustment amount is allocated entirely to **principal portion** (same pattern as Discount Fee) + +==== Schedule impact + +On adjustment the system: + +. Regenerates the projected amortization schedule using the updated loan discount and disbursement data +. Re-applies all recorded **actual repayments** (preserved from the previous model) +. Updates loan balances + +==== Business event + +* `WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent` — posted after a successful adjustment + +== API Endpoints + +* *Endpoint*: `POST /v1/working-capital-loans/{loanId}/transactions?command=discountFeeAdjustment` +* *Alternative*: `POST /v1/working-capital-loans/external-id/{loanExternalId}/transactions?command=discountFeeAdjustment` + +[source,json] +---- +{ + "transactionAmount": 50.0, + "relatedResourceId": 99, + "transactionDate": "10 January 2026", + "dateFormat": "dd MMMM yyyy", + "locale": "en", + "note": "Reduce discount fee", + "externalId": "WC-DISC-ADJ-001" +} +---- + +* `relatedResourceId` — **Discount Fee** transaction id (not disbursement id) +* `transactionAmount` — amount to reduce from the current loan discount (capped by remaining adjustable discount) diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/WorkingCapitalLoanRequestFactory.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/WorkingCapitalLoanRequestFactory.java index 4530254080a..0a2b1f80de6 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/WorkingCapitalLoanRequestFactory.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/factory/WorkingCapitalLoanRequestFactory.java @@ -101,12 +101,6 @@ public PostWorkingCapitalLoansLoanIdRequest defaultWorkingCapitalLoanDisburseReq .locale(DEFAULT_LOCALE);// } - public PostWorkingCapitalLoansLoanIdRequest defaultWorkingCapitalLoanDiscountFeeRequest() { - return new PostWorkingCapitalLoansLoanIdRequest()// - .dateFormat(DATE_FORMAT)// - .locale(DEFAULT_LOCALE);// - } - public PostWorkingCapitalLoansLoanIdRequest defaultWorkingCapitalLoanUndoDisburseRequest() { return new PostWorkingCapitalLoansLoanIdRequest()// .note("")// diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java index a0c0485e2bb..d6b58d5ca2e 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/helper/ErrorMessageHelper.java @@ -1126,6 +1126,18 @@ public static String discountExceedProductDiscountFailure() { return "Failed data validation due to: amount.cannot.exceed.product.discount."; } + public static String discountAdjustmentExceedFailure() { + return "Failed data validation due to: cannot.be.more.than.discount.fee."; + } + + public static String discountAdjustmentBackdatedFailure() { + return "Failed data validation due to: backdated.not.allowed."; + } + + public static String discountAdjustmentBeforeDiscountDateFailure() { + return "Failed data validation due to: cannot.be.before.discount.fee.date."; + } + public static String nearBreachCannotEnableWithoutBreachFailure() { return "Failed data validation due to: cannot.enable.near.breach.without.breach."; } diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/WorkingCapitalLoanAccountStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/WorkingCapitalLoanAccountStepDef.java index 744b71b20b7..ce2d9bf08d0 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/WorkingCapitalLoanAccountStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/WorkingCapitalLoanAccountStepDef.java @@ -1266,10 +1266,13 @@ public void undoDisbursalWCLoanFailure(String actualLoanStatus) { public void addDiscountFeeWCLoanDisbursement(String discountAmount) { PostWorkingCapitalLoansLoanIdResponse lastDisbursementResponse = testContext().get(TestContextKey.LOAN_DISBURSE_RESPONSE); - final PostWorkingCapitalLoansLoanIdRequest request = workingCapitalLoanRequestFactory.defaultWorkingCapitalLoanDiscountFeeRequest() // - .relatedResourceId(lastDisbursementResponse.getResourceId()).transactionAmount(new BigDecimal(discountAmount)); + final PostWorkingCapitalLoanTransactionsRequest request = workingCapitalProductRequestFactory + .defaultWorkingCapitalLoanRepaymentRequest().relatedResourceId(lastDisbursementResponse.getResourceId()) + .transactionAmount(new BigDecimal(discountAmount)); - executeStateTransition("DISCOUNTFEE", request, "DISCOUNT", false); + final PostWorkingCapitalLoanTransactionsResponse response = ok(() -> fineractClient.workingCapitalLoanTransactions() + .executeWorkingCapitalLoanTransactionById(getCreatedLoanId(), "discountFee", request)); + testContext().set("DISCOUNT", response); } @And("Add Discount fee with {string} amount on Working Capital loan account failed due to already added discount before disbursement") @@ -1296,6 +1299,55 @@ public void addDiscountFeeWCLoanExceedDiscountAmountProductFailure(String discou addDiscountFeeFailedCheck(discountAmount, errorMessage); } + @And("Admin adds Discount fee adjustment with {string} amount on Working Capital loan account for last discount") + public void addDiscountFeeAdjustmentWCLoan(final String adjustmentAmount) { + final PostWorkingCapitalLoanTransactionsResponse lastDiscountResponse = testContext().get("DISCOUNT"); + Assertions.assertNotNull(lastDiscountResponse); + final PostWorkingCapitalLoanTransactionsRequest request = workingCapitalProductRequestFactory + .defaultWorkingCapitalLoanRepaymentRequest().relatedResourceId(lastDiscountResponse.getResourceId()) + .transactionAmount(new BigDecimal(adjustmentAmount)); + executeDiscountFeeAdjustmentById(getCreatedLoanId(), request); + } + + @And("Admin adds Discount fee adjustment with {string} amount on transaction date {string} on Working Capital loan account for last discount") + public void addDiscountFeeAdjustmentWCLoanWithTransactionDate(final String adjustmentAmount, final String transactionDate) { + final PostWorkingCapitalLoanTransactionsResponse lastDiscountResponse = testContext().get("DISCOUNT"); + Assertions.assertNotNull(lastDiscountResponse); + final PostWorkingCapitalLoanTransactionsRequest request = workingCapitalProductRequestFactory + .defaultWorkingCapitalLoanRepaymentRequest().relatedResourceId(lastDiscountResponse.getResourceId()) + .transactionAmount(new BigDecimal(adjustmentAmount)).transactionDate(transactionDate); + executeDiscountFeeAdjustmentById(getCreatedLoanId(), request); + } + + @And("Admin loads discount fee transaction from Working Capital loan for adjustment") + public void loadDiscountFeeTransactionFromLoanForAdjustment() { + final GetWorkingCapitalLoansLoanIdResponse loan = retrieveLoanDetails(getCreatedLoanId()); + assert loan.getTransactions() != null; + final GetWorkingCapitalLoanTransactionIdResponse discountTxn = loan.getTransactions().stream() + .filter(t -> t.getType() != null && "loanTransactionType.discountFee".equals(t.getType().getCode())) + .filter(t -> !Boolean.TRUE.equals(t.getReversed())).reduce((first, second) -> second) + .orElseThrow(() -> new IllegalStateException("Active discount fee transaction not found on loan")); + final PostWorkingCapitalLoanTransactionsResponse synthetic = new PostWorkingCapitalLoanTransactionsResponse() + .resourceId(discountTxn.getId()); + testContext().set("DISCOUNT", synthetic); + } + + @And("Add Discount fee adjustment with {string} amount on Working Capital loan account failed due to exceeding discount amount") + public void addDiscountFeeAdjustmentExceededFailure(final String adjustmentAmount) { + addDiscountFeeAdjustmentFailedCheck(adjustmentAmount, null, ErrorMessageHelper.discountAdjustmentExceedFailure()); + } + + @Then("Add Discount fee adjustment with {string} amount and transaction date {string} on Working Capital loan account failed due to transaction date before discount fee date") + public void addDiscountFeeAdjustmentBeforeDiscountDateFailure(final String adjustmentAmount, final String transactionDate) { + addDiscountFeeAdjustmentFailedCheck(adjustmentAmount, transactionDate, + ErrorMessageHelper.discountAdjustmentBeforeDiscountDateFailure()); + } + + @Then("Add Discount fee adjustment with {string} amount and transaction date {string} on Working Capital loan account failed due to backdated transaction date") + public void addDiscountFeeAdjustmentBackdatedFailure(final String adjustmentAmount, final String transactionDate) { + addDiscountFeeAdjustmentFailedCheck(adjustmentAmount, transactionDate, ErrorMessageHelper.discountAdjustmentBackdatedFailure()); + } + @And("Working Capital Loan has transactions:") public void workingCapitalLoanHasTransactions(final DataTable dataTable) throws InvocationTargetException, IllegalAccessException { GetWorkingCapitalLoansLoanIdResponse getWorkingCapitalLoansLoanIdResponse = retrieveLoanDetails(getCreatedLoanId()); @@ -1304,11 +1356,8 @@ public void workingCapitalLoanHasTransactions(final DataTable dataTable) throws } @Then("Admin successfully update discount with {string} amount on Working Capital loan account") - public void adminSuccessfullyUpdateDiscountWithAmountOnWorkingCapitalLoanAccount(String discountAmount) { - PostWorkingCapitalLoansLoanIdResponse lastDisbursementResponse = testContext().get(TestContextKey.LOAN_DISBURSE_RESPONSE); - final PostWorkingCapitalLoansLoanIdRequest request = workingCapitalLoanRequestFactory.defaultWorkingCapitalLoanDiscountFeeRequest() // - .relatedResourceId(lastDisbursementResponse.getResourceId()).transactionAmount(new BigDecimal(discountAmount)); - executeStateTransition("DISCOUNTFEE", request, "DISCOUNT", false); + public void adminSuccessfullyUpdateDiscountWithAmountOnWorkingCapitalLoanAccount(final String discountAmount) { + addDiscountFeeWCLoanDisbursement(discountAmount); } @Then("Update discount with {string} amount on Working Capital loan account failed due to date diff from disbursement date") @@ -1498,16 +1547,41 @@ public void addDiscountFeeFailedCheck(String discountAmount, String errorMessage PostWorkingCapitalLoansLoanIdResponse lastDisbursementResponse = testContext().get(TestContextKey.LOAN_DISBURSE_RESPONSE); Assertions.assertNotNull(lastDisbursementResponse); - PostWorkingCapitalLoansLoanIdRequest updateDiscountRequest = workingCapitalLoanRequestFactory - .defaultWorkingCapitalLoanDiscountFeeRequest().relatedResourceId(lastDisbursementResponse.getResourceId()) + final PostWorkingCapitalLoanTransactionsRequest updateDiscountRequest = workingCapitalProductRequestFactory + .defaultWorkingCapitalLoanRepaymentRequest().relatedResourceId(lastDisbursementResponse.getResourceId()) .transactionAmount(new BigDecimal(discountAmount)); - CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoans().stateTransitionWorkingCapitalLoanById(loanId, - "DISCOUNTFEE", updateDiscountRequest)); + final CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoanTransactions() + .executeWorkingCapitalLoanTransactionById(loanId, "discountFee", updateDiscountRequest)); + assertThat(exception.getStatus()).as(errorMessage).isEqualTo(400); + assertThat(exception.getDeveloperMessage()).contains(errorMessage); + } + + private void addDiscountFeeAdjustmentFailedCheck(final String adjustmentAmount, final String transactionDateOrNull, + final String errorMessage) { + final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); + Assertions.assertNotNull(loanResponse); + Assertions.assertNotNull(loanResponse.getLoanId()); + final long loanId = loanResponse.getLoanId(); + final PostWorkingCapitalLoanTransactionsResponse lastDiscountResponse = testContext().get("DISCOUNT"); + Assertions.assertNotNull(lastDiscountResponse); + final PostWorkingCapitalLoanTransactionsRequest adjustmentRequest = workingCapitalProductRequestFactory + .defaultWorkingCapitalLoanRepaymentRequest().relatedResourceId(lastDiscountResponse.getResourceId()) + .transactionAmount(new BigDecimal(adjustmentAmount)); + if (transactionDateOrNull != null) { + adjustmentRequest.transactionDate(transactionDateOrNull); + } + final CallFailedRuntimeException exception = fail(() -> fineractClient.workingCapitalLoanTransactions() + .executeWorkingCapitalLoanTransactionById(loanId, "discountFeeAdjustment", adjustmentRequest)); assertThat(exception.getStatus()).as(errorMessage).isEqualTo(400); assertThat(exception.getDeveloperMessage()).contains(errorMessage); } + private void executeDiscountFeeAdjustmentById(final Long loanId, final PostWorkingCapitalLoanTransactionsRequest request) { + ok(() -> fineractClient.workingCapitalLoanTransactions().executeWorkingCapitalLoanTransactionById(loanId, "discountFeeAdjustment", + request)); + } + // Data Extraction Helpers private Long getCreatedLoanId() { final PostWorkingCapitalLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); @@ -2232,12 +2306,13 @@ public void verifyAmortizationSchedulePeriods(final int linesExpected, final Dat final boolean containsExpectedValues = matchingPeriods.stream() .anyMatch(period -> matchesExpectedWcAmortizationRow(headers, expectedValues, period)); assertThat(containsExpectedValues).as( - "Wrong value in line %s of amortization schedule. actual=%s, expected=%s", i, matchingPeriods.stream() + "Wrong value in line %s of amortization schedule: \n actual=%s,\n expected=%s", i, matchingPeriods.stream() .map(period -> fetchValuesOfWcAmortizationSchedule(headers, period)).collect(Collectors.toList()), expectedValues).isTrue(); } - assertThat(linesActual).as("Wrong number of lines in WC amortization schedule. actual=%s, expected=%s", linesActual, linesExpected) + assertThat(linesActual) + .as("Wrong number of lines in WC amortization schedule: \n actual=%s,\n expected=%s", linesActual, linesExpected) .isEqualTo(linesExpected); } diff --git a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalAmortizationSchedule.feature b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalAmortizationSchedule.feature index f36b92692ea..b89d4e13e75 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalAmortizationSchedule.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalAmortizationSchedule.feature @@ -8,11 +8,11 @@ Feature: WorkingCapitalAmortizationSchedule 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 | 100 | 100 | 1 | 0 | - When Admin generates a projected amortization schedule with discountFeeAmount 1000.0, netDisbursementAmount 9000.0, totalPaymentValue 100000.0, periodPaymentRate 0.18, npvDayCount 360, expectedDisbursementDate "2019-01-01" + When Admin generates a projected amortization schedule with discountFeeAmount 1000.0, netDisbursementAmount 9000.0, totalPaymentValue 100000.0, periodPaymentRate 18, npvDayCount 360, expectedDisbursementDate "2019-01-01" And Admin retrieves the projected amortization schedule Then The retrieved amortization schedule has the following summary fields: | discountFeeAmount | netDisbursementAmount | totalPaymentValue | periodPaymentRate | npvDayCount | expectedPaymentAmount | originalPaymentNumber | - | 1000.00 | 9000.00 | 100000.00 | 0.18 | 360 | 50.00 | 200 | + | 1000.00 | 9000.00 | 100000.00 | 18 | 360 | 50.00 | 200 | And The retrieved amortization schedule has payments with the following details: | paymentNo | date | expectedPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualPaymentAmount | actualAmortizationAmount | incomeModification | deferredBalance | | 0 | 2019-01-01 | -9000.00 | 1 | -9000.00 | 9000.00 | | | | | 1000.00 | @@ -228,11 +228,11 @@ Feature: WorkingCapitalAmortizationSchedule Then Admin successfully disburse the Working Capital loan on "01 January 2026" with "100" EUR transaction amount Then Working Capital loan status will be "ACTIVE" - When Admin generates a projected amortization schedule with discountFeeAmount 1000.0, netDisbursementAmount 9000.0, totalPaymentValue 1000.0, periodPaymentRate 18, npvDayCount 360, expectedDisbursementDate "2019-01-01" + When Admin generates a projected amortization schedule with discountFeeAmount 1000.0, netDisbursementAmount 9000.0, totalPaymentValue 100000.0, periodPaymentRate 18, npvDayCount 360, expectedDisbursementDate "2019-01-01" And Admin retrieves the projected amortization schedule Then The retrieved amortization schedule has the following summary fields: | discountFeeAmount | netDisbursementAmount | totalPaymentValue | periodPaymentRate | npvDayCount | expectedPaymentAmount | originalPaymentNumber | - | 1000.00 | 9000.00 | 1000.00 | 18 | 360 | 50.00 | 200 | + | 1000.00 | 9000.00 | 100000.00 | 18 | 360 | 50.00 | 200 | And The retrieved amortization schedule has payments with the following details: | paymentNo | date | expectedPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualPaymentAmount | actualAmortizationAmount | incomeModification | deferredBalance | | 0 | 2019-01-01 | -9000.00 | 1 | -9000.00 | 9000.00 | | | | | 1000.00 | @@ -443,33 +443,33 @@ Feature: WorkingCapitalAmortizationSchedule And Admin retrieves the projected amortization schedule Then The retrieved amortization schedule has the following summary fields: | discountFeeAmount | netDisbursementAmount | totalPaymentValue | periodPaymentRate | npvDayCount | expectedPaymentAmount | originalPaymentNumber | - | 1000.00 | 9000.00 | 1000.00 | 18 | 360 | 50.00 | 200 | + | 1000.00 | 9000.00 | 100000.00 | 18 | 360 | 50.00 | 200 | And The retrieved amortization schedule has payments with the following details: | paymentNo | date | expectedPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualPaymentAmount | actualAmortizationAmount | incomeModification | deferredBalance | | 0 | 2019-01-01 | -9000.00 | | -9000.00 | 9000.00 | | | | | 1000.00 | - | 1 | 2019-01-02 | 50.00 | | 49.95 | 8959.61 | 9.61 | | | | 1000.00 | - | 2 | 2019-01-03 | 50.00 | | 49.89 | 8919.18 | 9.57 | | | | 1000.00 | - | 3 | 2019-01-04 | 50.00 | | 49.84 | 8878.70 | 9.52 | | | | 1000.00 | - | 4 | 2019-01-05 | 50.00 | | 49.79 | 8838.18 | 9.48 | | | | 1000.00 | - | 5 | 2019-01-06 | 50.00 | | 49.73 | 8797.62 | 9.44 | | | | 1000.00 | - | 6 | 2019-01-07 | 50.00 | | 49.68 | 8757.01 | 9.39 | | | | 1000.00 | - | 7 | 2019-01-08 | 50.00 | | 49.63 | 8716.36 | 9.35 | | | | 1000.00 | - | 8 | 2019-01-09 | 50.00 | | 49.57 | 8675.67 | 9.31 | | | | 1000.00 | - | 9 | 2019-01-10 | 50.00 | | 49.52 | 8634.94 | 9.26 | | | | 1000.00 | - | 10 | 2019-01-11 | 50.00 | | 49.47 | 8594.16 | 9.22 | | | | 1000.00 | - | 11 | 2019-01-12 | 50.00 | | 49.42 | 8553.33 | 9.18 | | | | 1000.00 | - | 12 | 2019-01-13 | 50.00 | | 49.36 | 8512.47 | 9.13 | | | | 1000.00 | - | 13 | 2019-01-14 | 50.00 | | 49.31 | 8471.56 | 9.09 | | | | 1000.00 | - | 14 | 2019-01-15 | 50.00 | | 49.26 | 8430.60 | 9.05 | | | | 1000.00 | - | 15 | 2019-01-16 | 50.00 | | 49.21 | 8389.61 | 9.00 | | | | 1000.00 | - | 16 | 2019-01-17 | 50.00 | | 49.15 | 8348.56 | 8.96 | | | | 1000.00 | - | 17 | 2019-01-18 | 50.00 | | 49.10 | 8307.48 | 8.91 | | | | 1000.00 | - | 18 | 2019-01-19 | 50.00 | | 49.05 | 8266.35 | 8.87 | | | | 1000.00 | - | 19 | 2019-01-20 | 50.00 | | 49.00 | 8225.18 | 8.83 | | | | 1000.00 | - | 20 | 2019-01-21 | 50.00 | | 48.94 | 8183.96 | 8.78 | | | | 1000.00 | - | 21 | 2019-01-22 | 50.00 | | 48.89 | 8142.70 | 8.74 | | | | 1000.00 | - | 22 | 2019-01-23 | 50.00 | | 48.84 | 8101.39 | 8.69 | | | | 1000.00 | - | 23 | 2019-01-24 | 50.00 | | 48.79 | 8060.04 | 8.65 | | | | 1000.00 | + | 1 | 2019-01-02 | 50.00 | | 0.00 | 8959.61 | 9.61 | | | | 1000.00 | + | 2 | 2019-01-03 | 50.00 | | 0.00 | 8919.18 | 9.57 | | | | 1000.00 | + | 3 | 2019-01-04 | 50.00 | | 0.00 | 8878.70 | 9.52 | | | | 1000.00 | + | 4 | 2019-01-05 | 50.00 | | 0.00 | 8838.18 | 9.48 | | | | 1000.00 | + | 5 | 2019-01-06 | 50.00 | | 0.00 | 8797.62 | 9.44 | | | | 1000.00 | + | 6 | 2019-01-07 | 50.00 | | 0.00 | 8757.01 | 9.39 | | | | 1000.00 | + | 7 | 2019-01-08 | 50.00 | | 0.00 | 8716.36 | 9.35 | | | | 1000.00 | + | 8 | 2019-01-09 | 50.00 | | 0.00 | 8675.67 | 9.31 | | | | 1000.00 | + | 9 | 2019-01-10 | 50.00 | | 0.00 | 8634.94 | 9.26 | | | | 1000.00 | + | 10 | 2019-01-11 | 50.00 | | 0.00 | 8594.16 | 9.22 | | | | 1000.00 | + | 11 | 2019-01-12 | 50.00 | | 0.00 | 8553.33 | 9.18 | | | | 1000.00 | + | 12 | 2019-01-13 | 50.00 | | 0.00 | 8512.47 | 9.13 | | | | 1000.00 | + | 13 | 2019-01-14 | 50.00 | | 0.00 | 8471.56 | 9.09 | | | | 1000.00 | + | 14 | 2019-01-15 | 50.00 | | 0.00 | 8430.60 | 9.05 | | | | 1000.00 | + | 15 | 2019-01-16 | 50.00 | | 0.00 | 8389.61 | 9.00 | | | | 1000.00 | + | 16 | 2019-01-17 | 50.00 | | 0.00 | 8348.56 | 8.96 | | | | 1000.00 | + | 17 | 2019-01-18 | 50.00 | | 0.00 | 8307.48 | 8.91 | | | | 1000.00 | + | 18 | 2019-01-19 | 50.00 | | 0.00 | 8266.35 | 8.87 | | | | 1000.00 | + | 19 | 2019-01-20 | 50.00 | | 0.00 | 8225.18 | 8.83 | | | | 1000.00 | + | 20 | 2019-01-21 | 50.00 | | 0.00 | 8183.96 | 8.78 | | | | 1000.00 | + | 21 | 2019-01-22 | 50.00 | | 0.00 | 8142.70 | 8.74 | | | | 1000.00 | + | 22 | 2019-01-23 | 50.00 | | 0.00 | 8101.39 | 8.69 | | | | 1000.00 | + | 23 | 2019-01-24 | 50.00 | | 0.00 | 8060.04 | 8.65 | | | | 1000.00 | | 24 | 2019-01-25 | 47.22 | | 47.17 | 8020.77 | 7.95 | | | | 1000.00 | | 25 | 2019-01-26 | 47.22 | | 47.13 | 7981.46 | 7.91 | | | | 1000.00 | | 26 | 2019-01-27 | 47.22 | | 47.08 | 7942.11 | 7.87 | | | | 1000.00 | diff --git a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalDiscount.feature b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalDiscount.feature index c5dd9937654..22744858b05 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalDiscount.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalDiscount.feature @@ -1187,3 +1187,474 @@ Feature: Working Capital Discount And Working capital loan account has the correct data: | product.name | submittedOnDate | expectedDisbursementDate | status | principal | approvedPrincipal | totalPayment | periodPaymentRate | discountProposed | discountApproved | discount | | WCLP | 2026-01-01 | 2026-01-01 | Approved | 100.0 | 100.0 | 100.0 | 1.0 | null | 14.0 | null | + + Scenario: Discount fee adjustment is processed successfully - UC16 + When Admin sets the business date to "01 January 2026" + And Admin creates a client with random data + 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 | 100 | 100 | 1 | | + Then Working capital loan creation was successful + Then Admin successfully approves the working capital loan on "01 January 2026" with "100" amount and expected disbursement date on "01 January 2026" + Then Admin successfully disburse the Working Capital loan on "01 January 2026" with "100" EUR transaction amount + Then Admin adds Discount fee with "12" amount on Working Capital loan account for last disbursement + Then Admin adds Discount fee adjustment with "5" amount on Working Capital loan account for last discount + And Working capital loan account has the correct data: + | product.name | submittedOnDate | expectedDisbursementDate | status | principal | approvedPrincipal | totalPayment | periodPaymentRate | discount | + | WCLP | 2026-01-01 | 2026-01-01 | Active | 107.0 | 100.0 | 100.0 | 1.0 | 7.0 | + And Working Capital Loan has transactions: + | transactionDate | type | transactionAmount | principalPortion | feeChargesPortion | penaltyChargesPortion | reversed | + | 01 January 2026 | Disbursement | 100.0 | 100.0 | 0.0 | 0.0 | false | + | 01 January 2026 | Discount Fee | 12.0 | 12.0 | 0.0 | 0.0 | false | + | 01 January 2026 | Discount Fee Adjustment | 5.0 | 5.0 | 0.0 | 0.0 | false | + + Scenario: Discount fee adjustment fails when amount exceeds discount fee remainder - UC17 + When Admin sets the business date to "01 January 2026" + And Admin creates a client with random data + 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 | 100 | 100 | 1 | | + Then Working capital loan creation was successful + Then Admin successfully approves the working capital loan on "01 January 2026" with "100" amount and expected disbursement date on "01 January 2026" + Then Admin successfully disburse the Working Capital loan on "01 January 2026" with "100" EUR transaction amount + Then Admin adds Discount fee with "12" amount on Working Capital loan account for last disbursement + Then Add Discount fee adjustment with "13" amount on Working Capital loan account failed due to exceeding discount amount + + Scenario: Discount fee adjustment fails when transaction date is before discount fee date - UC18 + When Admin sets the business date to "01 January 2026" + And Admin creates a client with random data + 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 | 100 | 100 | 1 | | + Then Working capital loan creation was successful + Then Admin successfully approves the working capital loan on "01 January 2026" with "100" amount and expected disbursement date on "01 January 2026" + Then Admin successfully disburse the Working Capital loan on "01 January 2026" with "100" EUR transaction amount + Then Admin adds Discount fee with "12" amount on Working Capital loan account for last disbursement + Then Add Discount fee adjustment with "2" amount and transaction date "31 December 2025" on Working Capital loan account failed due to transaction date before discount fee date + + Scenario: Discount fee adjustment fails when transaction date is before business date - UC19 + When Admin sets the business date to "01 January 2026" + And Admin creates a client with random data + 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 | 100 | 100 | 1 | | + Then Working capital loan creation was successful + Then Admin successfully approves the working capital loan on "01 January 2026" with "100" amount and expected disbursement date on "01 January 2026" + Then Admin successfully disburse the Working Capital loan on "01 January 2026" with "100" EUR transaction amount + Then Admin adds Discount fee with "12" amount on Working Capital loan account for last disbursement + When Admin sets the business date to "20 January 2026" + Then Add Discount fee adjustment with "2" amount and transaction date "15 January 2026" on Working Capital loan account failed due to backdated transaction date + + Scenario: Verify amortization schedule after discount fee adjustment - EIR discount adjustment S1 + When Admin sets the business date to "01 January 2019" + And Admin creates a client with random data + And Admin creates a working capital loan with the following data: + | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | + | WCLP | 01 January 2019 | 01 January 2019 | 9000 | 100000 | 18 | 1000 | + And Admin successfully approves the working capital loan on "01 January 2019" with "9000" amount and "1000" discount amount and expected disbursement date on "01 January 2019" + And Admin successfully disburse the Working Capital loan on "01 January 2019" with "9000" EUR transaction amount and "1000" discount amount + Then Working Capital loan amortization schedule has 201 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | + | 0 | 01 January 2019 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 1000.00 | + | 1 | 02 January 2019 | 50.00 | | 0.9989333245 | 49.95 | 8959.61 | 9.61 | | | 1000.00 | + | 2 | 03 January 2019 | 50.00 | | 0.9978677868 | 49.89 | 8919.18 | 9.57 | | | 1000.00 | + | 3 | 04 January 2019 | 50.00 | | 0.9968033857 | 49.84 | 8878.70 | 9.52 | | | 1000.00 | + | 4 | 05 January 2019 | 50.00 | | 0.99574012 | 49.79 | 8838.18 | 9.48 | | | 1000.00 | + | 5 | 06 January 2019 | 50.00 | | 0.9946779885 | 49.73 | 8797.62 | 9.44 | | | 1000.00 | + | 6 | 07 January 2019 | 50.00 | | 0.9936169898 | 49.68 | 8757.01 | 9.39 | | | 1000.00 | + | 7 | 08 January 2019 | 50.00 | | 0.992557123 | 49.63 | 8716.36 | 9.35 | | | 1000.00 | + | 8 | 09 January 2019 | 50.00 | | 0.9914983866 | 49.57 | 8675.67 | 9.31 | | | 1000.00 | + | 9 | 10 January 2019 | 50.00 | | 0.9904407796 | 49.52 | 8634.94 | 9.26 | | | 1000.00 | + | 10 | 11 January 2019 | 50.00 | | 0.9893843007 | 49.47 | 8594.16 | 9.22 | | | 1000.00 | + | 11 | 12 January 2019 | 50.00 | | 0.9883289487 | 49.42 | 8553.33 | 9.18 | | | 1000.00 | + | 12 | 13 January 2019 | 50.00 | | 0.9872747225 | 49.36 | 8512.47 | 9.13 | | | 1000.00 | + | 13 | 14 January 2019 | 50.00 | | 0.9862216208 | 49.31 | 8471.56 | 9.09 | | | 1000.00 | + | 14 | 15 January 2019 | 50.00 | | 0.9851696423 | 49.26 | 8430.60 | 9.05 | | | 1000.00 | + | 15 | 16 January 2019 | 50.00 | | 0.984118786 | 49.21 | 8389.61 | 9.00 | | | 1000.00 | + | 16 | 17 January 2019 | 50.00 | | 0.9830690507 | 49.15 | 8348.56 | 8.96 | | | 1000.00 | + | 17 | 18 January 2019 | 50.00 | | 0.982020435 | 49.10 | 8307.48 | 8.91 | | | 1000.00 | + | 18 | 19 January 2019 | 50.00 | | 0.9809729379 | 49.05 | 8266.35 | 8.87 | | | 1000.00 | + | 19 | 20 January 2019 | 50.00 | | 0.9799265581 | 49.00 | 8225.18 | 8.83 | | | 1000.00 | + | 20 | 21 January 2019 | 50.00 | | 0.9788812945 | 48.94 | 8183.96 | 8.78 | | | 1000.00 | + | 21 | 22 January 2019 | 50.00 | | 0.9778371458 | 48.89 | 8142.70 | 8.74 | | | 1000.00 | + | 22 | 23 January 2019 | 50.00 | | 0.9767941109 | 48.84 | 8101.39 | 8.69 | | | 1000.00 | + | 23 | 24 January 2019 | 50.00 | | 0.9757521886 | 48.79 | 8060.04 | 8.65 | | | 1000.00 | + | 24 | 25 January 2019 | 50.00 | | 0.9747113777 | 48.74 | 8018.65 | 8.61 | | | 1000.00 | + | 25 | 26 January 2019 | 50.00 | | 0.9736716769498249835 | 48.68 | 7977.21 | 8.56 | | | 1000.00 | + | 26 | 27 January 2019 | 50.00 | | 0.9726330853 | 48.63 | 7935.73 | 8.52 | | | 1000.00 | + | 27 | 28 January 2019 | 50.00 | | 0.9715956014 | 48.58 | 7894.21 | 8.47 | | | 1000.00 | + | 28 | 29 January 2019 | 50.00 | | 0.9705592242 | 48.53 | 7852.63 | 8.43 | | | 1000.00 | + | 29 | 30 January 2019 | 50.00 | | 0.9695239525 | 48.48 | 7811.02 | 8.39 | | | 1000.00 | + | 30 | 31 January 2019 | 50.00 | | 0.968489785 | 48.42 | 7769.36 | 8.34 | | | 1000.00 | + | 31 | 01 February 2019 | 50.00 | | 0.9674567207 | 48.37 | 7727.66 | 8.30 | | | 1000.00 | + | 32 | 02 February 2019 | 50.00 | | 0.9664247584 | 48.32 | 7685.91 | 8.25 | | | 1000.00 | + | 33 | 03 February 2019 | 50.00 | | 0.9653938968 | 48.27 | 7644.12 | 8.21 | | | 1000.00 | + | 34 | 04 February 2019 | 50.00 | | 0.9643641348 | 48.22 | 7602.28 | 8.16 | | | 1000.00 | + | 35 | 05 February 2019 | 50.00 | | 0.9633354712 | 48.17 | 7560.40 | 8.12 | | | 1000.00 | + | 36 | 06 February 2019 | 50.00 | | 0.9623079049 | 48.12 | 7518.47 | 8.07 | | | 1000.00 | + | 37 | 07 February 2019 | 50.00 | | 0.9612814347 | 48.06 | 7476.50 | 8.03 | | | 1000.00 | + | 38 | 08 February 2019 | 50.00 | | 0.9602560593 | 48.01 | 7434.48 | 7.98 | | | 1000.00 | + | 39 | 09 February 2019 | 50.00 | | 0.9592317777 | 47.96 | 7392.42 | 7.94 | | | 1000.00 | + | 40 | 10 February 2019 | 50.00 | | 0.9582085887 | 47.91 | 7350.31 | 7.89 | | | 1000.00 | + | 41 | 11 February 2019 | 50.00 | | 0.9571864911 | 47.86 | 7308.16 | 7.85 | | | 1000.00 | + | 42 | 12 February 2019 | 50.00 | | 0.9561654838 | 47.81 | 7265.97 | 7.80 | | | 1000.00 | + | 43 | 13 February 2019 | 50.00 | | 0.9551455655 | 47.76 | 7223.72 | 7.76 | | | 1000.00 | + | 44 | 14 February 2019 | 50.00 | | 0.9541267351 | 47.71 | 7181.44 | 7.71 | | | 1000.00 | + | 45 | 15 February 2019 | 50.00 | | 0.9531089916 | 47.66 | 7139.11 | 7.67 | | | 1000.00 | + | 46 | 16 February 2019 | 50.00 | | 0.9520923336 | 47.60 | 7096.73 | 7.62 | | | 1000.00 | + | 47 | 17 February 2019 | 50.00 | | 0.95107676 | 47.55 | 7054.31 | 7.58 | | | 1000.00 | + | 48 | 18 February 2019 | 50.00 | | 0.9500622698 | 47.50 | 7011.84 | 7.53 | | | 1000.00 | + | 49 | 19 February 2019 | 50.00 | | 0.9490488616 | 47.45 | 6969.33 | 7.49 | | | 1000.00 | + | 50 | 20 February 2019 | 50.00 | | 0.9480365345 | 47.40 | 6926.77 | 7.44 | | | 1000.00 | + | 51 | 21 February 2019 | 50.00 | | 0.9470252872 | 47.35 | 6884.17 | 7.40 | | | 1000.00 | + | 52 | 22 February 2019 | 50.00 | | 0.9460151185 | 47.30 | 6841.52 | 7.35 | | | 1000.00 | + | 53 | 23 February 2019 | 50.00 | | 0.9450060274 | 47.25 | 6798.82 | 7.31 | | | 1000.00 | + | 54 | 24 February 2019 | 50.00 | | 0.9439980126 | 47.20 | 6756.08 | 7.26 | | | 1000.00 | + | 55 | 25 February 2019 | 50.00 | | 0.9429910731 | 47.15 | 6713.30 | 7.21 | | | 1000.00 | + | 56 | 26 February 2019 | 50.00 | | 0.9419852077 | 47.10 | 6670.47 | 7.17 | | | 1000.00 | + | 57 | 27 February 2019 | 50.00 | | 0.9409804151 | 47.05 | 6627.59 | 7.12 | | | 1000.00 | + | 58 | 28 February 2019 | 50.00 | | 0.9399766944 | 47.00 | 6584.67 | 7.08 | | | 1000.00 | + | 59 | 01 March 2019 | 50.00 | | 0.9389740443 | 46.95 | 6541.70 | 7.03 | | | 1000.00 | + | 60 | 02 March 2019 | 50.00 | | 0.9379724637 | 46.90 | 6498.68 | 6.99 | | | 1000.00 | + | 61 | 03 March 2019 | 50.00 | | 0.9369719515 | 46.85 | 6455.62 | 6.94 | | | 1000.00 | + | 62 | 04 March 2019 | 50.00 | | 0.9359725065 | 46.80 | 6412.51 | 6.89 | | | 1000.00 | + | 63 | 05 March 2019 | 50.00 | | 0.9349741276 | 46.75 | 6369.36 | 6.85 | | | 1000.00 | + | 64 | 06 March 2019 | 50.00 | | 0.9339768136 | 46.70 | 6326.16 | 6.80 | | | 1000.00 | + | 65 | 07 March 2019 | 50.00 | | 0.9329805635 | 46.65 | 6282.92 | 6.76 | | | 1000.00 | + | 66 | 08 March 2019 | 50.00 | | 0.931985376 | 46.60 | 6239.63 | 6.71 | | | 1000.00 | + | 67 | 09 March 2019 | 50.00 | | 0.93099125 | 46.55 | 6196.29 | 6.66 | | | 1000.00 | + | 68 | 10 March 2019 | 50.00 | | 0.9299981845 | 46.50 | 6152.91 | 6.62 | | | 1000.00 | + | 69 | 11 March 2019 | 50.00 | | 0.9290061782 | 46.45 | 6109.48 | 6.57 | | | 1000.00 | + | 70 | 12 March 2019 | 50.00 | | 0.9280152301 | 46.40 | 6066.00 | 6.52 | | | 1000.00 | + | 71 | 13 March 2019 | 50.00 | | 0.927025339 | 46.35 | 6022.48 | 6.48 | | | 1000.00 | + | 72 | 14 March 2019 | 50.00 | | 0.9260365038 | 46.30 | 5978.91 | 6.43 | | | 1000.00 | + | 73 | 15 March 2019 | 50.00 | | 0.9250487234 | 46.25 | 5935.29 | 6.38 | | | 1000.00 | + | 74 | 16 March 2019 | 50.00 | | 0.9240619966 | 46.20 | 5891.63 | 6.34 | | | 1000.00 | + | 75 | 17 March 2019 | 50.00 | | 0.9230763224 | 46.15 | 5847.92 | 6.29 | | | 1000.00 | + | 76 | 18 March 2019 | 50.00 | | 0.9220916995 | 46.10 | 5804.17 | 6.24 | | | 1000.00 | + | 77 | 19 March 2019 | 50.00 | | 0.9211081269 | 46.06 | 5760.36 | 6.20 | | | 1000.00 | + | 78 | 20 March 2019 | 50.00 | | 0.9201256034 | 46.01 | 5716.52 | 6.15 | | | 1000.00 | + | 79 | 21 March 2019 | 50.00 | | 0.919144128 | 45.96 | 5672.62 | 6.10 | | | 1000.00 | + | 80 | 22 March 2019 | 50.00 | | 0.9181636995 | 45.91 | 5628.68 | 6.06 | | | 1000.00 | + | 81 | 23 March 2019 | 50.00 | | 0.9171843168 | 45.86 | 5584.69 | 6.01 | | | 1000.00 | + | 82 | 24 March 2019 | 50.00 | | 0.9162059788 | 45.81 | 5540.65 | 5.96 | | | 1000.00 | + | 83 | 25 March 2019 | 50.00 | | 0.9152286843 | 45.76 | 5496.57 | 5.92 | | | 1000.00 | + | 84 | 26 March 2019 | 50.00 | | 0.9142524323 | 45.71 | 5452.44 | 5.87 | | | 1000.00 | + | 85 | 27 March 2019 | 50.00 | | 0.9132772217 | 45.66 | 5408.26 | 5.82 | | | 1000.00 | + | 86 | 28 March 2019 | 50.00 | | 0.9123030513 | 45.62 | 5364.03 | 5.78 | | | 1000.00 | + | 87 | 29 March 2019 | 50.00 | | 0.91132992 | 45.57 | 5319.76 | 5.73 | | | 1000.00 | + | 88 | 30 March 2019 | 50.00 | | 0.9103578267 | 45.52 | 5275.44 | 5.68 | | | 1000.00 | + | 89 | 31 March 2019 | 50.00 | | 0.9093867703 | 45.47 | 5231.08 | 5.63 | | | 1000.00 | + | 90 | 01 April 2019 | 50.00 | | 0.9084167498 | 45.42 | 5186.66 | 5.59 | | | 1000.00 | + | 91 | 02 April 2019 | 50.00 | | 0.9074477639 | 45.37 | 5142.20 | 5.54 | | | 1000.00 | + | 92 | 03 April 2019 | 50.00 | | 0.9064798116 | 45.32 | 5097.69 | 5.49 | | | 1000.00 | + | 93 | 04 April 2019 | 50.00 | | 0.9055128918 | 45.28 | 5053.13 | 5.44 | | | 1000.00 | + | 94 | 05 April 2019 | 50.00 | | 0.9045470035 | 45.23 | 5008.53 | 5.40 | | | 1000.00 | + | 95 | 06 April 2019 | 50.00 | | 0.9035821453 | 45.18 | 4963.88 | 5.35 | | | 1000.00 | + | 96 | 07 April 2019 | 50.00 | | 0.9026183164 | 45.13 | 4919.18 | 5.30 | | | 1000.00 | + | 97 | 08 April 2019 | 50.00 | | 0.9016555156 | 45.08 | 4874.43 | 5.25 | | | 1000.00 | + | 98 | 09 April 2019 | 50.00 | | 0.9006937418 | 45.03 | 4829.64 | 5.20 | | | 1000.00 | + | 99 | 10 April 2019 | 50.00 | | 0.8997329939 | 44.99 | 4784.79 | 5.16 | | | 1000.00 | + | 100 | 11 April 2019 | 50.00 | | 0.8987732707 | 44.94 | 4739.90 | 5.11 | | | 1000.00 | + | 101 | 12 April 2019 | 50.00 | | 0.8978145713 | 44.89 | 4694.96 | 5.06 | | | 1000.00 | + | 102 | 13 April 2019 | 50.00 | | 0.8968568945 | 44.84 | 4649.98 | 5.01 | | | 1000.00 | + | 103 | 14 April 2019 | 50.00 | | 0.8959002393 | 44.80 | 4604.94 | 4.97 | | | 1000.00 | + | 104 | 15 April 2019 | 50.00 | | 0.8949446045 | 44.75 | 4559.86 | 4.92 | | | 1000.00 | + | 105 | 16 April 2019 | 50.00 | | 0.893989989 | 44.70 | 4514.73 | 4.87 | | | 1000.00 | + | 106 | 17 April 2019 | 50.00 | | 0.8930363918 | 44.65 | 4469.55 | 4.82 | | | 1000.00 | + | 107 | 18 April 2019 | 50.00 | | 0.8920838118 | 44.60 | 4424.32 | 4.77 | | | 1000.00 | + | 108 | 19 April 2019 | 50.00 | | 0.8911322479 | 44.56 | 4379.05 | 4.72 | | | 1000.00 | + | 109 | 20 April 2019 | 50.00 | | 0.890181699 | 44.51 | 4333.72 | 4.68 | | | 1000.00 | + | 110 | 21 April 2019 | 50.00 | | 0.889232164 | 44.46 | 4288.35 | 4.63 | | | 1000.00 | + | 111 | 22 April 2019 | 50.00 | | 0.8882836418 | 44.41 | 4242.93 | 4.58 | | | 1000.00 | + | 112 | 23 April 2019 | 50.00 | | 0.8873361314 | 44.37 | 4197.46 | 4.53 | | | 1000.00 | + | 113 | 24 April 2019 | 50.00 | | 0.8863896318 | 44.32 | 4151.94 | 4.48 | | | 1000.00 | + | 114 | 25 April 2019 | 50.00 | | 0.8854441417 | 44.27 | 4106.38 | 4.43 | | | 1000.00 | + | 115 | 26 April 2019 | 50.00 | | 0.8844996601 | 44.22 | 4060.76 | 4.38 | | | 1000.00 | + | 116 | 27 April 2019 | 50.00 | | 0.883556186 | 44.18 | 4015.10 | 4.34 | | | 1000.00 | + | 117 | 28 April 2019 | 50.00 | | 0.8826137183 | 44.13 | 3969.38 | 4.29 | | | 1000.00 | + | 118 | 29 April 2019 | 50.00 | | 0.8816722559 | 44.08 | 3923.62 | 4.24 | | | 1000.00 | + | 119 | 30 April 2019 | 50.00 | | 0.8807317977 | 44.04 | 3877.81 | 4.19 | | | 1000.00 | + | 120 | 01 May 2019 | 50.00 | | 0.8797923427 | 43.99 | 3831.95 | 4.14 | | | 1000.00 | + | 121 | 02 May 2019 | 50.00 | | 0.8788538898 | 43.94 | 3786.04 | 4.09 | | | 1000.00 | + | 122 | 03 May 2019 | 50.00 | | 0.8779164379 | 43.90 | 3740.09 | 4.04 | | | 1000.00 | + | 123 | 04 May 2019 | 50.00 | | 0.876979986 | 43.85 | 3694.08 | 3.99 | | | 1000.00 | + | 124 | 05 May 2019 | 50.00 | | 0.8760445329 | 43.80 | 3648.03 | 3.94 | | | 1000.00 | + | 125 | 06 May 2019 | 50.00 | | 0.8751100777 | 43.76 | 3601.92 | 3.90 | | | 1000.00 | + | 126 | 07 May 2019 | 50.00 | | 0.8741766193 | 43.71 | 3555.77 | 3.85 | | | 1000.00 | + | 127 | 08 May 2019 | 50.00 | | 0.8732441565 | 43.66 | 3509.56 | 3.80 | | | 1000.00 | + | 128 | 09 May 2019 | 50.00 | | 0.8723126884 | 43.62 | 3463.31 | 3.75 | | | 1000.00 | + | 129 | 10 May 2019 | 50.00 | | 0.8713822138 | 43.57 | 3417.01 | 3.70 | | | 1000.00 | + | 130 | 11 May 2019 | 50.00 | | 0.8704527318 | 43.52 | 3370.66 | 3.65 | | | 1000.00 | + | 131 | 12 May 2019 | 50.00 | | 0.8695242412 | 43.48 | 3324.26 | 3.60 | | | 1000.00 | + | 132 | 13 May 2019 | 50.00 | | 0.868596741 | 43.43 | 3277.81 | 3.55 | | | 1000.00 | + | 133 | 14 May 2019 | 50.00 | | 0.8676702302 | 43.38 | 3231.31 | 3.50 | | | 1000.00 | + | 134 | 15 May 2019 | 50.00 | | 0.8667447076 | 43.34 | 3184.76 | 3.45 | | | 1000.00 | + | 135 | 16 May 2019 | 50.00 | | 0.8658201723 | 43.29 | 3138.16 | 3.40 | | | 1000.00 | + | 136 | 17 May 2019 | 50.00 | | 0.8648966231 | 43.24 | 3091.51 | 3.35 | | | 1000.00 | + | 137 | 18 May 2019 | 50.00 | | 0.8639740591 | 43.20 | 3044.81 | 3.30 | | | 1000.00 | + | 138 | 19 May 2019 | 50.00 | | 0.8630524792 | 43.15 | 2998.06 | 3.25 | | | 1000.00 | + | 139 | 20 May 2019 | 50.00 | | 0.8621318823 | 43.11 | 2951.26 | 3.20 | | | 1000.00 | + | 140 | 21 May 2019 | 50.00 | | 0.8612122673 | 43.06 | 2904.42 | 3.15 | | | 1000.00 | + | 141 | 22 May 2019 | 50.00 | | 0.8602936333 | 43.01 | 2857.52 | 3.10 | | | 1000.00 | + | 142 | 23 May 2019 | 50.00 | | 0.8593759792 | 42.97 | 2810.57 | 3.05 | | | 1000.00 | + | 143 | 24 May 2019 | 50.00 | | 0.8584593039 | 42.92 | 2763.57 | 3.00 | | | 1000.00 | + | 144 | 25 May 2019 | 50.00 | | 0.8575436064 | 42.88 | 2716.52 | 2.95 | | | 1000.00 | + | 145 | 26 May 2019 | 50.00 | | 0.8566288857 | 42.83 | 2669.42 | 2.90 | | | 1000.00 | + | 146 | 27 May 2019 | 50.00 | | 0.8557151407 | 42.79 | 2622.27 | 2.85 | | | 1000.00 | + | 147 | 28 May 2019 | 50.00 | | 0.8548023703 | 42.74 | 2575.07 | 2.80 | | | 1000.00 | + | 148 | 29 May 2019 | 50.00 | | 0.8538905736 | 42.69 | 2527.82 | 2.75 | | | 1000.00 | + | 149 | 30 May 2019 | 50.00 | | 0.8529797495 | 42.65 | 2480.52 | 2.70 | | | 1000.00 | + | 150 | 31 May 2019 | 50.00 | | 0.8520698969 | 42.60 | 2433.17 | 2.65 | | | 1000.00 | + | 151 | 01 June 2019 | 50.00 | | 0.8511610148 | 42.56 | 2385.77 | 2.60 | | | 1000.00 | + | 152 | 02 June 2019 | 50.00 | | 0.8502531022 | 42.51 | 2338.31 | 2.55 | | | 1000.00 | + | 153 | 03 June 2019 | 50.00 | | 0.8493461581 | 42.47 | 2290.81 | 2.50 | | | 1000.00 | + | 154 | 04 June 2019 | 50.00 | | 0.8484401814 | 42.42 | 2243.26 | 2.45 | | | 1000.00 | + | 155 | 05 June 2019 | 50.00 | | 0.8475351711 | 42.38 | 2195.65 | 2.40 | | | 1000.00 | + | 156 | 06 June 2019 | 50.00 | | 0.8466311261 | 42.33 | 2148.00 | 2.34 | | | 1000.00 | + | 157 | 07 June 2019 | 50.00 | | 0.8457280454 | 42.29 | 2100.29 | 2.29 | | | 1000.00 | + | 158 | 08 June 2019 | 50.00 | | 0.844825928 | 42.24 | 2052.53 | 2.24 | | | 1000.00 | + | 159 | 09 June 2019 | 50.00 | | 0.8439247729 | 42.20 | 2004.73 | 2.19 | | | 1000.00 | + | 160 | 10 June 2019 | 50.00 | | 0.8430245791 | 42.15 | 1956.87 | 2.14 | | | 1000.00 | + | 161 | 11 June 2019 | 50.00 | | 0.8421253454 | 42.11 | 1908.96 | 2.09 | | | 1000.00 | + | 162 | 12 June 2019 | 50.00 | | 0.841227071 | 42.06 | 1860.99 | 2.04 | | | 1000.00 | + | 163 | 13 June 2019 | 50.00 | | 0.8403297547 | 42.02 | 1812.98 | 1.99 | | | 1000.00 | + | 164 | 14 June 2019 | 50.00 | | 0.8394333956 | 41.97 | 1764.92 | 1.94 | | | 1000.00 | + | 165 | 15 June 2019 | 50.00 | | 0.8385379925 | 41.93 | 1716.80 | 1.88 | | | 1000.00 | + | 166 | 16 June 2019 | 50.00 | | 0.8376435446 | 41.88 | 1668.64 | 1.83 | | | 1000.00 | + | 167 | 17 June 2019 | 50.00 | | 0.8367500508 | 41.84 | 1620.42 | 1.78 | | | 1000.00 | + | 168 | 18 June 2019 | 50.00 | | 0.83585751 | 41.79 | 1572.15 | 1.73 | | | 1000.00 | + | 169 | 19 June 2019 | 50.00 | | 0.8349659213 | 41.75 | 1523.83 | 1.68 | | | 1000.00 | + | 170 | 20 June 2019 | 50.00 | | 0.8340752837 | 41.70 | 1475.45 | 1.63 | | | 1000.00 | + | 171 | 21 June 2019 | 50.00 | | 0.833185596 | 41.66 | 1427.03 | 1.58 | | | 1000.00 | + | 172 | 22 June 2019 | 50.00 | | 0.8322968574 | 41.61 | 1378.55 | 1.52 | | | 1000.00 | + | 173 | 23 June 2019 | 50.00 | | 0.8314090667 | 41.57 | 1330.02 | 1.47 | | | 1000.00 | + | 174 | 24 June 2019 | 50.00 | | 0.8305222231 | 41.53 | 1281.45 | 1.42 | | | 1000.00 | + | 175 | 25 June 2019 | 50.00 | | 0.8296363254 | 41.48 | 1232.81 | 1.37 | | | 1000.00 | + | 176 | 26 June 2019 | 50.00 | | 0.8287513727 | 41.44 | 1184.13 | 1.32 | | | 1000.00 | + | 177 | 27 June 2019 | 50.00 | | 0.8278673639 | 41.39 | 1135.39 | 1.26 | | | 1000.00 | + | 178 | 28 June 2019 | 50.00 | | 0.8269842981 | 41.35 | 1086.61 | 1.21 | | | 1000.00 | + | 179 | 29 June 2019 | 50.00 | | 0.8261021742 | 41.31 | 1037.77 | 1.16 | | | 1000.00 | + | 180 | 30 June 2019 | 50.00 | | 0.8252209913 | 41.26 | 988.88 | 1.11 | | | 1000.00 | + | 181 | 01 July 2019 | 50.00 | | 0.8243407483 | 41.22 | 939.93 | 1.06 | | | 1000.00 | + | 182 | 02 July 2019 | 50.00 | | 0.8234614442 | 41.17 | 890.93 | 1.00 | | | 1000.00 | + | 183 | 03 July 2019 | 50.00 | | 0.8225830781 | 41.13 | 841.89 | 0.95 | | | 1000.00 | + | 184 | 04 July 2019 | 50.00 | | 0.8217056489 | 41.09 | 792.79 | 0.90 | | | 1000.00 | + | 185 | 05 July 2019 | 50.00 | | 0.8208291556 | 41.04 | 743.63 | 0.85 | | | 1000.00 | + | 186 | 06 July 2019 | 50.00 | | 0.8199535973 | 41.00 | 694.43 | 0.79 | | | 1000.00 | + | 187 | 07 July 2019 | 50.00 | | 0.8190789729 | 40.95 | 645.17 | 0.74 | | | 1000.00 | + | 188 | 08 July 2019 | 50.00 | | 0.8182052815 | 40.91 | 595.86 | 0.69 | | | 1000.00 | + | 189 | 09 July 2019 | 50.00 | | 0.8173325219 | 40.87 | 546.49 | 0.64 | | | 1000.00 | + | 190 | 10 July 2019 | 50.00 | | 0.8164606934 | 40.82 | 497.08 | 0.58 | | | 1000.00 | + | 191 | 11 July 2019 | 50.00 | | 0.8155897948 | 40.78 | 447.61 | 0.53 | | | 1000.00 | + | 192 | 12 July 2019 | 50.00 | | 0.8147198252 | 40.74 | 398.08 | 0.48 | | | 1000.00 | + | 193 | 13 July 2019 | 50.00 | | 0.8138507835 | 40.69 | 348.51 | 0.43 | | | 1000.00 | + | 194 | 14 July 2019 | 50.00 | | 0.8129826688 | 40.65 | 298.88 | 0.37 | | | 1000.00 | + | 195 | 15 July 2019 | 50.00 | | 0.8121154802 | 40.61 | 249.20 | 0.32 | | | 1000.00 | + | 196 | 16 July 2019 | 50.00 | | 0.8112492165 | 40.56 | 199.47 | 0.27 | | | 1000.00 | + | 197 | 17 July 2019 | 50.00 | | 0.8103838768 | 40.52 | 149.68 | 0.21 | | | 1000.00 | + | 198 | 18 July 2019 | 50.00 | | 0.8095194602 | 40.48 | 99.84 | 0.16 | | | 1000.00 | + | 199 | 19 July 2019 | 50.00 | | 0.8086559657 | 40.43 | 49.95 | 0.11 | | | 1000.00 | + | 200 | 20 July 2019 | 50.00 | | 0.8077933922 | 40.39 | 0.00 | 0.05 | | | 1000.00 | + When Admin sets the business date to "02 January 2019" + And Customer makes repayment on "02 January 2019" with 50 transaction amount on Working Capital loan + When Admin sets the business date to "03 January 2019" + And Customer makes repayment on "03 January 2019" with 50 transaction amount on Working Capital loan + When Admin sets the business date to "04 January 2019" + And Customer makes repayment on "04 January 2019" with 50 transaction amount on Working Capital loan + When Admin sets the business date to "05 January 2019" + And Admin loads discount fee transaction from Working Capital loan for adjustment + And Admin adds Discount fee adjustment with "500" amount on transaction date "05 January 2019" on Working Capital loan account for last discount + Then Working Capital loan amortization schedule has 191 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | + | 0 | 01 January 2019 | -9000.00 | | 1 | -9000 | 9000.00 | | | | 500.00 | + | 1 | 02 January 2019 | 50.00 | 50.00 | 1 | 50 | 8955.14 | 5.14 | 5.14 | 0.00 | 494.86 | + | 2 | 03 January 2019 | 50.00 | 50.00 | 1 | 50 | 8910.26 | 5.12 | 5.12 | 0.00 | 489.74 | + | 3 | 04 January 2019 | 50.00 | 50.00 | 1 | 50 | 8865.35 | 5.09 | 5.09 | 0.00 | 484.65 | + | 4 | 05 January 2019 | 50.00 | | 0.9994288744 | 49.97 | 8820.42 | 5.07 | | | 484.65 | + | 5 | 06 January 2019 | 50.00 | | 0.998858075 | 49.94 | 8775.46 | 5.04 | | | 484.65 | + | 6 | 07 January 2019 | 50.00 | | 0.9982876016 | 49.91 | 8730.47 | 5.01 | | | 484.65 | + | 7 | 08 January 2019 | 50.00 | | 0.997717454 | 49.89 | 8685.46 | 4.99 | | | 484.65 | + | 8 | 09 January 2019 | 50.00 | | 0.997147632 | 49.86 | 8640.43 | 4.96 | | | 484.65 | + | 9 | 10 January 2019 | 50.00 | | 0.9965781355 | 49.83 | 8595.36 | 4.94 | | | 484.65 | + | 10 | 11 January 2019 | 50.00 | | 0.9960089642 | 49.80 | 8550.28 | 4.91 | | | 484.65 | + | 11 | 12 January 2019 | 50.00 | | 0.995440118 | 49.77 | 8505.16 | 4.89 | | | 484.65 | + | 12 | 13 January 2019 | 50.00 | | 0.9948715966 | 49.74 | 8460.02 | 4.86 | | | 484.65 | + | 13 | 14 January 2019 | 50.00 | | 0.9943034 | 49.72 | 8414.86 | 4.83 | | | 484.65 | + | 14 | 15 January 2019 | 50.00 | | 0.9937355279 | 49.69 | 8369.66 | 4.81 | | | 484.65 | + | 15 | 16 January 2019 | 50.00 | | 0.9931679801 | 49.66 | 8324.45 | 4.78 | | | 484.65 | + | 16 | 17 January 2019 | 50.00 | | 0.9926007564 | 49.63 | 8279.20 | 4.76 | | | 484.65 | + | 17 | 18 January 2019 | 50.00 | | 0.9920338567 | 49.60 | 8233.94 | 4.73 | | | 484.65 | + | 18 | 19 January 2019 | 50.00 | | 0.9914672808 | 49.57 | 8188.64 | 4.71 | | | 484.65 | + | 19 | 20 January 2019 | 50.00 | | 0.9909010285 | 49.55 | 8143.32 | 4.68 | | | 484.65 | + | 20 | 21 January 2019 | 50.00 | | 0.9903350995 | 49.52 | 8097.97 | 4.65 | | | 484.65 | + | 21 | 22 January 2019 | 50.00 | | 0.9897694938 | 49.49 | 8052.60 | 4.63 | | | 484.65 | + | 22 | 23 January 2019 | 50.00 | | 0.9892042111 | 49.46 | 8007.20 | 4.60 | | | 484.65 | + | 23 | 24 January 2019 | 50.00 | | 0.9886392513 | 49.43 | 7961.78 | 4.58 | | | 484.65 | + | 24 | 25 January 2019 | 50.00 | | 0.9880746141 | 49.40 | 7916.33 | 4.55 | | | 484.65 | + | 25 | 26 January 2019 | 50.00 | | 0.9875102994 | 49.38 | 7870.85 | 4.52 | | | 484.65 | + | 26 | 27 January 2019 | 50.00 | | 0.986946307 | 49.35 | 7825.35 | 4.50 | | | 484.65 | + | 27 | 28 January 2019 | 50.00 | | 0.9863826367 | 49.32 | 7779.82 | 4.47 | | | 484.65 | + | 28 | 29 January 2019 | 50.00 | | 0.9858192883 | 49.29 | 7734.27 | 4.45 | | | 484.65 | + | 29 | 30 January 2019 | 50.00 | | 0.9852562617 | 49.26 | 7688.69 | 4.42 | | | 484.65 | + | 30 | 31 January 2019 | 50.00 | | 0.9846935566 | 49.23 | 7643.08 | 4.39 | | | 484.65 | + | 31 | 01 February 2019 | 50.00 | | 0.9841311729 | 49.21 | 7597.45 | 4.37 | | | 484.65 | + | 32 | 02 February 2019 | 50.00 | | 0.9835691104 | 49.18 | 7551.79 | 4.34 | | | 484.65 | + | 33 | 03 February 2019 | 50.00 | | 0.9830073689 | 49.15 | 7506.11 | 4.32 | | | 484.65 | + | 34 | 04 February 2019 | 50.00 | | 0.9824459483 | 49.12 | 7460.40 | 4.29 | | | 484.65 | + | 35 | 05 February 2019 | 50.00 | | 0.9818848482 | 49.09 | 7414.66 | 4.26 | | | 484.65 | + | 36 | 06 February 2019 | 50.00 | | 0.9813240687 | 49.07 | 7368.90 | 4.24 | | | 484.65 | + | 37 | 07 February 2019 | 50.00 | | 0.9807636094 | 49.04 | 7323.11 | 4.21 | | | 484.65 | + | 38 | 08 February 2019 | 50.00 | | 0.9802034702 | 49.01 | 7277.29 | 4.18 | | | 484.65 | + | 39 | 09 February 2019 | 50.00 | | 0.9796436509 | 48.98 | 7231.45 | 4.16 | | | 484.65 | + | 40 | 10 February 2019 | 50.00 | | 0.9790841513 | 48.95 | 7185.58 | 4.13 | | | 484.65 | + | 41 | 11 February 2019 | 50.00 | | 0.9785249713 | 48.93 | 7139.69 | 4.11 | | | 484.65 | + | 42 | 12 February 2019 | 50.00 | | 0.9779661106 | 48.90 | 7093.77 | 4.08 | | | 484.65 | + | 43 | 13 February 2019 | 50.00 | | 0.9774075692 | 48.87 | 7047.82 | 4.05 | | | 484.65 | + | 44 | 14 February 2019 | 50.00 | | 0.9768493467 | 48.84 | 7001.85 | 4.03 | | | 484.65 | + | 45 | 15 February 2019 | 50.00 | | 0.976291443 | 48.81 | 6955.85 | 4.00 | | | 484.65 | + | 46 | 16 February 2019 | 50.00 | | 0.975733858 | 48.79 | 6909.83 | 3.97 | | | 484.65 | + | 47 | 17 February 2019 | 50.00 | | 0.9751765914 | 48.76 | 6863.78 | 3.95 | | | 484.65 | + | 48 | 18 February 2019 | 50.00 | | 0.9746196431 | 48.73 | 6817.70 | 3.92 | | | 484.65 | + | 49 | 19 February 2019 | 50.00 | | 0.9740630129 | 48.70 | 6771.59 | 3.90 | | | 484.65 | + | 50 | 20 February 2019 | 50.00 | | 0.9735067006 | 48.68 | 6725.46 | 3.87 | | | 484.65 | + | 51 | 21 February 2019 | 50.00 | | 0.972950706 | 48.65 | 6679.31 | 3.84 | | | 484.65 | + | 52 | 22 February 2019 | 50.00 | | 0.9723950289 | 48.62 | 6633.12 | 3.82 | | | 484.65 | + | 53 | 23 February 2019 | 50.00 | | 0.9718396692 | 48.59 | 6586.91 | 3.79 | | | 484.65 | + | 54 | 24 February 2019 | 50.00 | | 0.9712846267 | 48.56 | 6540.68 | 3.76 | | | 484.65 | + | 55 | 25 February 2019 | 50.00 | | 0.9707299012 | 48.54 | 6494.42 | 3.74 | | | 484.65 | + | 56 | 26 February 2019 | 50.00 | | 0.9701754925 | 48.51 | 6448.13 | 3.71 | | | 484.65 | + | 57 | 27 February 2019 | 50.00 | | 0.9696214004 | 48.48 | 6401.81 | 3.68 | | | 484.65 | + | 58 | 28 February 2019 | 50.00 | | 0.9690676248 | 48.45 | 6355.47 | 3.66 | | | 484.65 | + | 59 | 01 March 2019 | 50.00 | | 0.9685141655 | 48.43 | 6309.10 | 3.63 | | | 484.65 | + | 60 | 02 March 2019 | 50.00 | | 0.9679610223 | 48.40 | 6262.71 | 3.61 | | | 484.65 | + | 61 | 03 March 2019 | 50.00 | | 0.967408195 | 48.37 | 6216.29 | 3.58 | | | 484.65 | + | 62 | 04 March 2019 | 50.00 | | 0.9668556834 | 48.34 | 6169.84 | 3.55 | | | 484.65 | + | 63 | 05 March 2019 | 50.00 | | 0.9663034874 | 48.32 | 6123.36 | 3.53 | | | 484.65 | + | 64 | 06 March 2019 | 50.00 | | 0.9657516067 | 48.29 | 6076.86 | 3.50 | | | 484.65 | + | 65 | 07 March 2019 | 50.00 | | 0.9652000413 | 48.26 | 6030.34 | 3.47 | | | 484.65 | + | 66 | 08 March 2019 | 50.00 | | 0.9646487908 | 48.23 | 5983.78 | 3.45 | | | 484.65 | + | 67 | 09 March 2019 | 50.00 | | 0.9640978552 | 48.20 | 5937.20 | 3.42 | | | 484.65 | + | 68 | 10 March 2019 | 50.00 | | 0.9635472342 | 48.18 | 5890.59 | 3.39 | | | 484.65 | + | 69 | 11 March 2019 | 50.00 | | 0.9629969277 | 48.15 | 5843.96 | 3.37 | | | 484.65 | + | 70 | 12 March 2019 | 50.00 | | 0.9624469355 | 48.12 | 5797.30 | 3.34 | | | 484.65 | + | 71 | 13 March 2019 | 50.00 | | 0.9618972575 | 48.09 | 5750.61 | 3.31 | | | 484.65 | + | 72 | 14 March 2019 | 50.00 | | 0.9613478933 | 48.07 | 5703.90 | 3.29 | | | 484.65 | + | 73 | 15 March 2019 | 50.00 | | 0.9607988429 | 48.04 | 5657.16 | 3.26 | | | 484.65 | + | 74 | 16 March 2019 | 50.00 | | 0.9602501061 | 48.01 | 5610.39 | 3.23 | | | 484.65 | + | 75 | 17 March 2019 | 50.00 | | 0.9597016827 | 47.99 | 5563.60 | 3.21 | | | 484.65 | + | 76 | 18 March 2019 | 50.00 | | 0.9591535725 | 47.96 | 5516.78 | 3.18 | | | 484.65 | + | 77 | 19 March 2019 | 50.00 | | 0.9586057754 | 47.93 | 5469.93 | 3.15 | | | 484.65 | + | 78 | 20 March 2019 | 50.00 | | 0.9580582911 | 47.90 | 5423.06 | 3.13 | | | 484.65 | + | 79 | 21 March 2019 | 50.00 | | 0.9575111195 | 47.88 | 5376.15 | 3.10 | | | 484.65 | + | 80 | 22 March 2019 | 50.00 | | 0.9569642603 | 47.85 | 5329.23 | 3.07 | | | 484.65 | + | 81 | 23 March 2019 | 50.00 | | 0.9564177136 | 47.82 | 5282.27 | 3.05 | | | 484.65 | + | 82 | 24 March 2019 | 50.00 | | 0.9558714789 | 47.79 | 5235.29 | 3.02 | | | 484.65 | + | 83 | 25 March 2019 | 50.00 | | 0.9553255563 | 47.77 | 5188.28 | 2.99 | | | 484.65 | + | 84 | 26 March 2019 | 50.00 | | 0.9547799454 | 47.74 | 5141.25 | 2.96 | | | 484.65 | + | 85 | 27 March 2019 | 50.00 | | 0.9542346461 | 47.71 | 5094.18 | 2.94 | | | 484.65 | + | 86 | 28 March 2019 | 50.00 | | 0.9536896583 | 47.68 | 5047.10 | 2.91 | | | 484.65 | + | 87 | 29 March 2019 | 50.00 | | 0.9531449817 | 47.66 | 4999.98 | 2.88 | | | 484.65 | + | 88 | 30 March 2019 | 50.00 | | 0.9526006162 | 47.63 | 4952.84 | 2.86 | | | 484.65 | + | 89 | 31 March 2019 | 50.00 | | 0.9520565616 | 47.60 | 4905.67 | 2.83 | | | 484.65 | + | 90 | 01 April 2019 | 50.00 | | 0.9515128177 | 47.58 | 4858.47 | 2.80 | | | 484.65 | + | 91 | 02 April 2019 | 50.00 | | 0.9509693844 | 47.55 | 4811.25 | 2.78 | | | 484.65 | + | 92 | 03 April 2019 | 50.00 | | 0.9504262615 | 47.52 | 4764.00 | 2.75 | | | 484.65 | + | 93 | 04 April 2019 | 50.00 | | 0.9498834487 | 47.49 | 4716.72 | 2.72 | | | 484.65 | + | 94 | 05 April 2019 | 50.00 | | 0.949340946 | 47.47 | 4669.41 | 2.70 | | | 484.65 | + | 95 | 06 April 2019 | 50.00 | | 0.948798753 | 47.44 | 4622.08 | 2.67 | | | 484.65 | + | 96 | 07 April 2019 | 50.00 | | 0.9482568698 | 47.41 | 4574.72 | 2.64 | | | 484.65 | + | 97 | 08 April 2019 | 50.00 | | 0.947715296 | 47.39 | 4527.34 | 2.61 | | | 484.65 | + | 98 | 09 April 2019 | 50.00 | | 0.9471740316 | 47.36 | 4479.93 | 2.59 | | | 484.65 | + | 99 | 10 April 2019 | 50.00 | | 0.9466330762 | 47.33 | 4432.49 | 2.56 | | | 484.65 | + | 100 | 11 April 2019 | 50.00 | | 0.9460924298 | 47.30 | 4385.02 | 2.53 | | | 484.65 | + | 101 | 12 April 2019 | 50.00 | | 0.9455520922 | 47.28 | 4337.52 | 2.51 | | | 484.65 | + | 102 | 13 April 2019 | 50.00 | | 0.9450120632 | 47.25 | 4290.00 | 2.48 | | | 484.65 | + | 103 | 14 April 2019 | 50.00 | | 0.9444723427 | 47.22 | 4242.45 | 2.45 | | | 484.65 | + | 104 | 15 April 2019 | 50.00 | | 0.9439329303 | 47.20 | 4194.88 | 2.42 | | | 484.65 | + | 105 | 16 April 2019 | 50.00 | | 0.9433938261 | 47.17 | 4147.28 | 2.40 | | | 484.65 | + | 106 | 17 April 2019 | 50.00 | | 0.9428550297 | 47.14 | 4099.65 | 2.37 | | | 484.65 | + | 107 | 18 April 2019 | 50.00 | | 0.9423165411 | 47.12 | 4051.99 | 2.34 | | | 484.65 | + | 108 | 19 April 2019 | 50.00 | | 0.94177836 | 47.09 | 4004.30 | 2.32 | | | 484.65 | + | 109 | 20 April 2019 | 50.00 | | 0.9412404863 | 47.06 | 3956.59 | 2.29 | | | 484.65 | + | 110 | 21 April 2019 | 50.00 | | 0.9407029197 | 47.04 | 3908.85 | 2.26 | | | 484.65 | + | 111 | 22 April 2019 | 50.00 | | 0.9401656602 | 47.01 | 3861.09 | 2.23 | | | 484.65 | + | 112 | 23 April 2019 | 50.00 | | 0.9396287075 | 46.98 | 3813.29 | 2.21 | | | 484.65 | + | 113 | 24 April 2019 | 50.00 | | 0.9390920615 | 46.95 | 3765.47 | 2.18 | | | 484.65 | + | 114 | 25 April 2019 | 50.00 | | 0.938555722 | 46.93 | 3717.62 | 2.15 | | | 484.65 | + | 115 | 26 April 2019 | 50.00 | | 0.9380196888 | 46.90 | 3669.75 | 2.12 | | | 484.65 | + | 116 | 27 April 2019 | 50.00 | | 0.9374839618 | 46.87 | 3621.85 | 2.10 | | | 484.65 | + | 117 | 28 April 2019 | 50.00 | | 0.9369485407 | 46.85 | 3573.92 | 2.07 | | | 484.65 | + | 118 | 29 April 2019 | 50.00 | | 0.9364134254 | 46.82 | 3525.96 | 2.04 | | | 484.65 | + | 119 | 30 April 2019 | 50.00 | | 0.9358786157 | 46.79 | 3477.97 | 2.01 | | | 484.65 | + | 120 | 01 May 2019 | 50.00 | | 0.9353441115 | 46.77 | 3429.96 | 1.99 | | | 484.65 | + | 121 | 02 May 2019 | 50.00 | | 0.9348099125 | 46.74 | 3381.92 | 1.96 | | | 484.65 | + | 122 | 03 May 2019 | 50.00 | | 0.9342760186 | 46.71 | 3333.85 | 1.93 | | | 484.65 | + | 123 | 04 May 2019 | 50.00 | | 0.9337424297 | 46.69 | 3285.76 | 1.91 | | | 484.65 | + | 124 | 05 May 2019 | 50.00 | | 0.9332091455 | 46.66 | 3237.64 | 1.88 | | | 484.65 | + | 125 | 06 May 2019 | 50.00 | | 0.9326761659 | 46.63 | 3189.49 | 1.85 | | | 484.65 | + | 126 | 07 May 2019 | 50.00 | | 0.9321434906 | 46.61 | 3141.31 | 1.82 | | | 484.65 | + | 127 | 08 May 2019 | 50.00 | | 0.9316111196 | 46.58 | 3093.10 | 1.80 | | | 484.65 | + | 128 | 09 May 2019 | 50.00 | | 0.9310790527 | 46.55 | 3044.87 | 1.77 | | | 484.65 | + | 129 | 10 May 2019 | 50.00 | | 0.9305472896 | 46.53 | 2996.61 | 1.74 | | | 484.65 | + | 130 | 11 May 2019 | 50.00 | | 0.9300158302 | 46.50 | 2948.32 | 1.71 | | | 484.65 | + | 131 | 12 May 2019 | 50.00 | | 0.9294846744 | 46.47 | 2900.01 | 1.68 | | | 484.65 | + | 132 | 13 May 2019 | 50.00 | | 0.9289538219 | 46.45 | 2851.67 | 1.66 | | | 484.65 | + | 133 | 14 May 2019 | 50.00 | | 0.9284232726 | 46.42 | 2803.30 | 1.63 | | | 484.65 | + | 134 | 15 May 2019 | 50.00 | | 0.9278930263 | 46.39 | 2754.90 | 1.60 | | | 484.65 | + | 135 | 16 May 2019 | 50.00 | | 0.9273630828 | 46.37 | 2706.47 | 1.57 | | | 484.65 | + | 136 | 17 May 2019 | 50.00 | | 0.926833442 | 46.34 | 2658.02 | 1.55 | | | 484.65 | + | 137 | 18 May 2019 | 50.00 | | 0.9263041037 | 46.32 | 2609.54 | 1.52 | | | 484.65 | + | 138 | 19 May 2019 | 50.00 | | 0.9257750678 | 46.29 | 2561.03 | 1.49 | | | 484.65 | + | 139 | 20 May 2019 | 50.00 | | 0.9252463339 | 46.26 | 2512.49 | 1.46 | | | 484.65 | + | 140 | 21 May 2019 | 50.00 | | 0.9247179021 | 46.24 | 2463.93 | 1.44 | | | 484.65 | + | 141 | 22 May 2019 | 50.00 | | 0.924189772 | 46.21 | 2415.34 | 1.41 | | | 484.65 | + | 142 | 23 May 2019 | 50.00 | | 0.9236619436 | 46.18 | 2366.72 | 1.38 | | | 484.65 | + | 143 | 24 May 2019 | 50.00 | | 0.9231344166 | 46.16 | 2318.07 | 1.35 | | | 484.65 | + | 144 | 25 May 2019 | 50.00 | | 0.9226071909 | 46.13 | 2269.39 | 1.32 | | | 484.65 | + | 145 | 26 May 2019 | 50.00 | | 0.9220802663 | 46.10 | 2220.69 | 1.30 | | | 484.65 | + | 146 | 27 May 2019 | 50.00 | | 0.9215536427 | 46.08 | 2171.96 | 1.27 | | | 484.65 | + | 147 | 28 May 2019 | 50.00 | | 0.9210273198 | 46.05 | 2123.20 | 1.24 | | | 484.65 | + | 148 | 29 May 2019 | 50.00 | | 0.9205012975 | 46.03 | 2074.41 | 1.21 | | | 484.65 | + | 149 | 30 May 2019 | 50.00 | | 0.9199755757 | 46.00 | 2025.60 | 1.19 | | | 484.65 | + | 150 | 31 May 2019 | 50.00 | | 0.9194501541 | 45.97 | 1976.76 | 1.16 | | | 484.65 | + | 151 | 01 June 2019 | 50.00 | | 0.9189250325 | 45.95 | 1927.89 | 1.13 | | | 484.65 | + | 152 | 02 June 2019 | 50.00 | | 0.9184002109 | 45.92 | 1878.99 | 1.10 | | | 484.65 | + | 153 | 03 June 2019 | 50.00 | | 0.9178756891 | 45.89 | 1830.06 | 1.07 | | | 484.65 | + | 154 | 04 June 2019 | 50.00 | | 0.9173514668 | 45.87 | 1781.11 | 1.05 | | | 484.65 | + | 155 | 05 June 2019 | 50.00 | | 0.9168275439 | 45.84 | 1732.13 | 1.02 | | | 484.65 | + | 156 | 06 June 2019 | 50.00 | | 0.9163039202 | 45.82 | 1683.12 | 0.99 | | | 484.65 | + | 157 | 07 June 2019 | 50.00 | | 0.9157805956 | 45.79 | 1634.08 | 0.96 | | | 484.65 | + | 158 | 08 June 2019 | 50.00 | | 0.9152575698 | 45.76 | 1585.01 | 0.93 | | | 484.65 | + | 159 | 09 June 2019 | 50.00 | | 0.9147348428 | 45.74 | 1535.92 | 0.91 | | | 484.65 | + | 160 | 10 June 2019 | 50.00 | | 0.9142124143 | 45.71 | 1486.79 | 0.88 | | | 484.65 | + | 161 | 11 June 2019 | 50.00 | | 0.9136902842 | 45.68 | 1437.64 | 0.85 | | | 484.65 | + | 162 | 12 June 2019 | 50.00 | | 0.9131684523 | 45.66 | 1388.47 | 0.82 | | | 484.65 | + | 163 | 13 June 2019 | 50.00 | | 0.9126469184 | 45.63 | 1339.26 | 0.79 | | | 484.65 | + | 164 | 14 June 2019 | 50.00 | | 0.9121256824 | 45.61 | 1290.02 | 0.77 | | | 484.65 | + | 165 | 15 June 2019 | 50.00 | | 0.9116047441 | 45.58 | 1240.76 | 0.74 | | | 484.65 | + | 166 | 16 June 2019 | 50.00 | | 0.9110841033 | 45.55 | 1191.47 | 0.71 | | | 484.65 | + | 167 | 17 June 2019 | 50.00 | | 0.9105637598 | 45.53 | 1142.15 | 0.68 | | | 484.65 | + | 168 | 18 June 2019 | 50.00 | | 0.9100437136 | 45.50 | 1092.80 | 0.65 | | | 484.65 | + | 169 | 19 June 2019 | 50.00 | | 0.9095239643 | 45.48 | 1043.43 | 0.62 | | | 484.65 | + | 170 | 20 June 2019 | 50.00 | | 0.9090045119 | 45.45 | 994.02 | 0.60 | | | 484.65 | + | 171 | 21 June 2019 | 50.00 | | 0.9084853562 | 45.42 | 944.59 | 0.57 | | | 484.65 | + | 172 | 22 June 2019 | 50.00 | | 0.9079664969 | 45.40 | 895.13 | 0.54 | | | 484.65 | + | 173 | 23 June 2019 | 50.00 | | 0.907447934 | 45.37 | 845.64 | 0.51 | | | 484.65 | + | 174 | 24 June 2019 | 50.00 | | 0.9069296673 | 45.35 | 796.13 | 0.48 | | | 484.65 | + | 175 | 25 June 2019 | 50.00 | | 0.9064116965 | 45.32 | 746.58 | 0.45 | | | 484.65 | + | 176 | 26 June 2019 | 50.00 | | 0.9058940216 | 45.29 | 697.01 | 0.43 | | | 484.65 | + | 177 | 27 June 2019 | 50.00 | | 0.9053766423 | 45.27 | 647.41 | 0.40 | | | 484.65 | + | 178 | 28 June 2019 | 50.00 | | 0.9048595586 | 45.24 | 597.78 | 0.37 | | | 484.65 | + | 179 | 29 June 2019 | 50.00 | | 0.9043427701 | 45.22 | 548.12 | 0.34 | | | 484.65 | + | 180 | 30 June 2019 | 50.00 | | 0.9038262768 | 45.19 | 498.43 | 0.31 | | | 484.65 | + | 181 | 01 July 2019 | 50.00 | | 0.9033100785 | 45.17 | 448.72 | 0.28 | | | 484.65 | + | 182 | 02 July 2019 | 50.00 | | 0.902794175 | 45.14 | 398.97 | 0.26 | | | 484.65 | + | 183 | 03 July 2019 | 50.00 | | 0.9022785661 | 45.11 | 349.20 | 0.23 | | | 484.65 | + | 184 | 04 July 2019 | 50.00 | | 0.9017632517 | 45.09 | 299.40 | 0.20 | | | 484.65 | + | 185 | 05 July 2019 | 50.00 | | 0.9012482317 | 45.06 | 249.57 | 0.17 | | | 484.65 | + | 186 | 06 July 2019 | 50.00 | | 0.9007335057 | 45.04 | 199.71 | 0.14 | | | 484.65 | + | 187 | 07 July 2019 | 50.00 | | 0.9002190738 | 45.01 | 149.83 | 0.11 | | | 484.65 | + | 188 | 08 July 2019 | 50.00 | | 0.8997049356 | 44.99 | 99.91 | 0.09 | | | 484.65 | + | 189 | 09 July 2019 | 50.00 | | 0.8991910911 | 44.96 | 49.97 | 0.06 | | | 484.65 | + | 190 | 10 July 2019 | 50.00 | | 0.8986775401 | 44.93 | 0.00 | 0.03 | | | 484.65 | diff --git a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalLoanRepayment.feature b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalLoanRepayment.feature index 66cd3c1a367..fc40681d088 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalLoanRepayment.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/WorkingCapitalLoanRepayment.feature @@ -2,7 +2,7 @@ Feature: Working Capital Loan Repayment @TestRailId:C76617 - Scenario: Verify working capital loan repayment - UC1: simple repayment + Scenario: Verify working capital loan repayment - UC1: simple repayment: pay more than expected When Admin sets the business date to "01 January 2026" And Admin creates a client with random data And Admin creates a working capital loan with the following data: @@ -25,15 +25,196 @@ Feature: Working Capital Loan Repayment Then Working Capital loan delinquency range schedule has the following data: | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 270.0 | 0.0 | true | 0.0 | 0 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 185 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 270.00 | 0.00 | 0.00 | 8550.00 | 0.00 | + | 10 | 11 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76618 - Scenario: Verify working capital loan repayment - UC2: simple repayment by loan external ID + Scenario: Verify working capital loan repayment - UC2: simple repayment by loan external ID: pay less than expected When Admin sets the business date to "01 January 2026" And Admin creates a client with random data And Admin creates a working capital loan with the following data: @@ -52,16 +233,203 @@ Feature: Working Capital Loan Repayment | WCLP | 2026-01-01 | 2026-01-01 | Active | 9000.0 | 9000.0 | 100000.0 | 18.0 | null | When Admin sets the business date to "10 January 2026" And Admin runs inline COB job for Working Capital Loan by loanId - And Customer makes repayment by loan external ID on "10 January 2026" with 270.0 transaction amount on Working Capital loan + And Customer makes repayment by loan external ID on "10 January 2026" with 30.0 transaction amount on Working Capital loan Then Working Capital loan delinquency range schedule has the following data: | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | - | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 270.0 | 0.0 | true | 0.0 | 0 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 30.0 | 240.0 | null | null | null | + Then Working Capital loan amortization schedule has 190 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 30.00 | 0.00 | 0.00 | 8550.00 | 0.00 | + | 10 | 11 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 20.00 | 0.00 | | | | + @TestRailId:C76619 Scenario: Verify working capital loan repayment - UC3: simple repayment with zero amount results an error (Negative) @@ -154,21 +522,198 @@ Feature: Working Capital Loan Repayment | product.name | submittedOnDate | expectedDisbursementDate | status | principal | approvedPrincipal | totalPayment | periodPaymentRate | discount | | WCLP | 2026-01-01 | 2026-01-01 | Active | 9000.0 | 9000.0 | 100000.0 | 18.0 | null | When Admin runs inline COB job for Working Capital Loan by loanId - And Customer makes repayment on "01 January 2026" with 270.0 transaction amount on Working Capital loan + And Customer makes repayment on "01 January 2026" with 50.0 transaction amount on Working Capital loan Then Working Capital loan delinquency range schedule has the following data: | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | - | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 270.0 | 0.0 | true | 0.0 | 0 | + | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 50.0 | 220.0 | null | null | null | And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 181 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1.00 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8950.00 | 0.00 | + | 2 | 03 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 0.00 | | @TestRailId:C76623 - Scenario: Verify working capital loan repayment - UC7: full expectedAmount repaid after disbursement day + Scenario: Verify working capital loan repayment - UC7: full minimum payment after disbursement day When Admin sets the business date to "01 January 2026" And Admin creates a client with random data And Admin creates a working capital loan with the following data: @@ -207,12 +752,185 @@ Feature: Working Capital Loan Repayment | 2 | 2026-01-31 | 2026-03-01 | 270.0 | 0.0 | 270.0 | null | null | null | And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 177 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1.00 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1.00 | 270.00 | 0.00 | 0.00 | 8950.00 | 0.00 | + | 2 | 03 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1.00 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1.00 | 30.00 | 0.00 | 0.00 | 200.00 | | @TestRailId:C76624 Scenario: Verify working capital loan repayment - UC8: full expectedAmount repaid on last day of 1st period @@ -254,12 +972,213 @@ Feature: Working Capital Loan Repayment | 2 | 2026-01-31 | 2026-03-01 | 270.0 | 0.0 | 270.0 | null | null | null | And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 205 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 270.00 | 0.00 | 0.00 | 7550.00 | 0.00 | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 190 | 10 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 191 | 11 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 192 | 12 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 193 | 13 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 194 | 14 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 195 | 15 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 196 | 16 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 197 | 17 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 198 | 18 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 199 | 19 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 200 | 20 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 201 | 21 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 202 | 22 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 203 | 23 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 204 | 24 July 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76625 Scenario: Verify working capital loan repayment - UC9: full expectedAmount repaid on first day of 2nd period @@ -306,12 +1225,214 @@ Feature: Working Capital Loan Repayment And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | | 1 | 2026-01-31 | 2026-01-31 | D00 | 1 | 30 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 206 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 270.00 | 0.00 | 0.00 | 7500.00 | 0.00 | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 190 | 10 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 191 | 11 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 192 | 12 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 193 | 13 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 194 | 14 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 195 | 15 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 196 | 16 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 197 | 17 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 198 | 18 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 199 | 19 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 200 | 20 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 201 | 21 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 202 | 22 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 203 | 23 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 204 | 24 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 205 | 25 July 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76626 Scenario: Verify working capital loan repayment - UC10: full expectedAmount repaid in 1st period with multiple payments on same day @@ -354,13 +1475,185 @@ Feature: Working Capital Loan Repayment | 2 | 2026-01-31 | 2026-03-01 | 270.0 | 0.0 | 270.0 | null | null | null | And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - Then Working Capital loan amortization schedule has 5 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 170.00 | 1 | 170.00 | 4658.91 | 0.00 | 22.40 | 22.40 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | 100.00 | 1 | 100.00 | 0.00 | 0.00 | 13.18 | 13.18 | 0.00 | - | 3 | 04 January 2026 | | | 0.9317821063 | 4658.91 | | | | | 0.00 | - | 4 | 05 January 2026 | | | 0.8682178937 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 177 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 270.00 | 0.00 | 0.00 | 8950.00 | 0.00 | + | 2 | 03 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 30.00 | 0.00 | 0.00 | 200.00 | | @TestRailId:C76627 Scenario: Verify working capital loan repayment - UC11: full expectedAmount repaid in 1st period with multiple payments on different days @@ -409,61 +1702,198 @@ Feature: Working Capital Loan Repayment | 2 | 2026-01-31 | 2026-03-01 | 270.0 | 0.0 | 270.0 | null | null | null | And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - Then Working Capital loan amortization schedule has 5 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 170.00 | 1 | 170.00 | 4658.91 | 0.00 | 22.40 | 22.40 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | 100.00 | 1 | 100.00 | 0.00 | 0.00 | 13.18 | 13.18 | 0.00 | - | 3 | 04 January 2026 | | | 0.9317821063 | 4658.91 | | | | | 0.00 | - | 4 | 05 January 2026 | | | 0.8682178937 | 4106.67 | | | | | 0.00 | - - @TestRailId:C76628 - Scenario: Verify working capital loan repayment - UC12: partial expectedAmount repaid in 1st period - When Admin sets the business date to "01 January 2026" - And Admin creates a client with random data - 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 | 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" - Then Working capital loan approval was successful - And Working capital loan account has the correct data: - | product.name | submittedOnDate | expectedDisbursementDate | status | principal | approvedPrincipal | totalPayment | periodPaymentRate | discountApproved | - | WCLP | 2026-01-01 | 2026-01-01 | Approved | 9000.0 | 9000.0 | 100000.0 | 18.0 | null | - When Admin successfully disburse the Working Capital loan on "01 January 2026" with "9000" EUR transaction amount - Then Working Capital loan status will be "ACTIVE" - And Verify Working Capital loan disbursement was successful - And Working capital loan account has the correct data: - | product.name | submittedOnDate | expectedDisbursementDate | status | principal | approvedPrincipal | totalPayment | periodPaymentRate | discount | - | WCLP | 2026-01-01 | 2026-01-01 | Active | 9000.0 | 9000.0 | 100000.0 | 18.0 | null | - When Admin runs inline COB job for Working Capital Loan by loanId - Then Working Capital loan delinquency range schedule has the following data: - | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | - | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 0.0 | 270.0 | null | null | null | - And Delinquency Tag History for Working Capital loan has lines: - | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | -# --- Partial expectedAmount paid --- - When Admin sets the business date to "02 January 2026" - And Customer makes repayment on "02 January 2026" with 170.0 transaction amount on Working Capital loan - Then Working Capital loan delinquency range schedule has the following data: - | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | - | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 170.0 | 100.0 | null | null | null | - And Delinquency Tag History for Working Capital loan has lines: - | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - When Admin sets the business date to "31 January 2026" - And Admin runs inline COB job for Working Capital Loan by loanId - Then Working Capital loan delinquency range schedule has the following data: - | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | - | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 170.0 | 100.0 | false | 100.0 | 1 | - | 2 | 2026-01-31 | 2026-03-01 | 270.0 | 0.0 | 270.0 | null | null | null | - And Delinquency Tag History for Working Capital loan has lines: - | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - | 1 | 2026-01-31 | | D00 | 1 | 30 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 170.00 | 1 | 170.00 | 4658.91 | 0.00 | 22.40 | 22.40 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178937 | 4193.49 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 190 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 170.00 | 0.00 | 0.00 | 8950.00 | 0.00 | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 100.00 | 0.00 | 0.00 | 8300.00 | 0.00 | + | 15 | 16 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76629 Scenario: Verify working capital loan repayment - UC13: partial expectedAmount repaid in 2nd period @@ -510,12 +1940,226 @@ Feature: Working Capital Loan Repayment And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | | 1 | 2026-01-31 | | D00 | 1 | 30 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 170.00 | 1 | 170.00 | 4658.91 | 0.00 | 22.40 | 22.40 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178937 | 4193.49 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 218 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 170.00 | 0.00 | 0.00 | 7000.00 | 0.00 | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 190 | 10 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 191 | 11 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 192 | 12 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 193 | 13 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 194 | 14 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 195 | 15 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 196 | 16 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 197 | 17 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 198 | 18 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 199 | 19 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 200 | 20 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 201 | 21 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 202 | 22 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 203 | 23 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 204 | 24 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 205 | 25 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 206 | 26 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 207 | 27 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 208 | 28 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 209 | 29 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 210 | 30 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 211 | 31 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 212 | 01 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 213 | 02 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 214 | 03 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 215 | 04 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 216 | 05 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 217 | 06 August 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76630 Scenario: Verify working capital loan repayment - UC14: expectedAmount overpaid in 1st period @@ -559,12 +2203,191 @@ Feature: Working Capital Loan Repayment | 2 | 2026-01-31 | 2026-03-01 | 270.0 | 0.0 | 270.0 | null | null | null | And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 370.00 | 1 | 370.00 | 4658.91 | 0.00 | 48.76 | 48.76 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178937 | 4019.85 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 183 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 370.00 | 0.00 | 0.00 | 8550.00 | 0.00 | + | 10 | 11 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76631 Scenario: Verify working capital loan repayment - UC15: expectedAmount overpaid in 2nd period @@ -611,12 +2434,222 @@ Feature: Working Capital Loan Repayment And Delinquency Tag History for Working Capital loan has lines: | periodNumber | addedOnDate | liftedOnDate | classification | minimumAgeDays | maximumAgeDays | | 1 | 2026-01-31 | 2026-02-10 | D00 | 1 | 30 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 370.00 | 1 | 370.00 | 4658.91 | 0.00 | 48.76 | 48.76 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178937 | 4019.85 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 214 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 370.00 | 0.00 | 0.00 | 7000.00 | 0.00 | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 190 | 10 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 191 | 11 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 192 | 12 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 193 | 13 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 194 | 14 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 195 | 15 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 196 | 16 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 197 | 17 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 198 | 18 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 199 | 19 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 200 | 20 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 201 | 21 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 202 | 22 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 203 | 23 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 204 | 24 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 205 | 25 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 206 | 26 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 207 | 27 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 208 | 28 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 209 | 29 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 210 | 30 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 211 | 31 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 212 | 01 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 213 | 02 August 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76632 Scenario: Verify working capital loan repayment - UC16: expectedAmount overpaid in late period @@ -687,12 +2720,288 @@ Feature: Working Capital Loan Repayment | 2 | 2026-03-02 | 2026-05-10 | D00 | 1 | 30 | | 1 | 2026-03-02 | 2026-05-10 | D30 | 31 | 60 | | 1 | 2026-01-31 | 2026-05-10 | D00 | 1 | 30 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 1500.00 | 1 | 1500.00 | 4658.91 | 0.00 | 197.67 | 197.67 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178937 | 3038.76 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 280 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8550.00 | | + | 10 | 11 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 1500.00 | 0.00 | 0.00 | 2550.00 | 0.00 | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 185 | 05 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 186 | 06 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 187 | 07 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 188 | 08 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 189 | 09 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 190 | 10 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 191 | 11 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 192 | 12 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 193 | 13 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 194 | 14 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 195 | 15 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 196 | 16 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 197 | 17 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 198 | 18 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 199 | 19 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 200 | 20 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 201 | 21 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 202 | 22 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 203 | 23 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 204 | 24 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 205 | 25 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 206 | 26 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 207 | 27 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 208 | 28 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 209 | 29 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 210 | 30 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 211 | 31 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 212 | 01 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 213 | 02 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 214 | 03 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 215 | 04 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 216 | 05 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 217 | 06 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 218 | 07 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 219 | 08 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 220 | 09 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 221 | 10 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 222 | 11 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 223 | 12 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 224 | 13 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 225 | 14 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 226 | 15 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 227 | 16 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 228 | 17 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 229 | 18 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 230 | 19 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 231 | 20 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 232 | 21 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 233 | 22 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 234 | 23 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 235 | 24 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 236 | 25 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 237 | 26 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 238 | 27 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 239 | 28 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 240 | 29 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 241 | 30 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 242 | 31 August 2026 | | 1 | 50.00 | 0.00 | | | | + | 243 | 01 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 244 | 02 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 245 | 03 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 246 | 04 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 247 | 05 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 248 | 06 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 249 | 07 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 250 | 08 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 251 | 09 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 252 | 10 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 253 | 11 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 254 | 12 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 255 | 13 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 256 | 14 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 257 | 15 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 258 | 16 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 259 | 17 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 260 | 18 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 261 | 19 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 262 | 20 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 263 | 21 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 264 | 22 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 265 | 23 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 266 | 24 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 267 | 25 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 268 | 26 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 269 | 27 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 270 | 28 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 271 | 29 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 272 | 30 September 2026 | | 1 | 50.00 | 0.00 | | | | + | 273 | 01 October 2026 | | 1 | 50.00 | 0.00 | | | | + | 274 | 02 October 2026 | | 1 | 50.00 | 0.00 | | | | + | 275 | 03 October 2026 | | 1 | 50.00 | 0.00 | | | | + | 276 | 04 October 2026 | | 1 | 50.00 | 0.00 | | | | + | 277 | 05 October 2026 | | 1 | 50.00 | 0.00 | | | | + | 278 | 06 October 2026 | | 1 | 50.00 | 0.00 | | | | + | 279 | 07 October 2026 | | 1 | 50.00 | 0.00 | | | | @TestRailId:C76633 Scenario: Verify working capital loan repayment - UC17: simple repayment with payment details @@ -720,12 +3029,193 @@ Feature: Working Capital Loan Repayment Then Working Capital loan delinquency range schedule has the following data: | periodNumber | fromDate | toDate | expectedAmount | paidAmount | outstandingAmount | minPaymentCriteriaMet | delinquentAmount | delinquentDays | | 1 | 2026-01-01 | 2026-01-30 | 270.0 | 270.0 | 0.0 | true | 0.0 | 0 | - Then Working Capital loan amortization schedule has 4 periods, with the following data for periods: - | paymentNo | paymentDate | expectedPaymentAmount | actualPaymentAmount | discountFactor | npvValue | balance | expectedAmortizationAmount | actualAmortizationAmount | incomeModification | deferredBalance | - | 0 | 01 January 2026 | -9000.00 | | 1 | -9000.00 | 9000.00 | | | | 0.00 | - | 1 | 02 January 2026 | 5000.00 | 270.00 | 1 | 270.00 | 4658.91 | 0.00 | 35.58 | 35.58 | 0.00 | - | 2 | 03 January 2026 | 5000.00 | | 0.9317821063276353179 | 4658.91 | 0.00 | 0.00 | | | 0.00 | - | 3 | 04 January 2026 | | | 0.8682178936723646887 | 4106.67 | | | | | 0.00 | + Then Working Capital loan amortization schedule has 185 periods, with the following data for periods: + | paymentNo | paymentDate | expectedPaymentAmount | discountFactor | npvValue | deferredBalance | expectedAmortizationAmount | balance | incomeModification | + | 0 | 01 January 2026 | -9000.00 | 1 | -9000.00 | 0.00 | | 9000.00 | | + | 1 | 02 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8950.00 | | + | 2 | 03 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8900.00 | | + | 3 | 04 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8850.00 | | + | 4 | 05 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8800.00 | | + | 5 | 06 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8750.00 | | + | 6 | 07 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8700.00 | | + | 7 | 08 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8650.00 | | + | 8 | 09 January 2026 | 50.00 | 1 | 0.00 | 0.00 | 0.00 | 8600.00 | | + | 9 | 10 January 2026 | 50.00 | 1 | 270.00 | 0.00 | 0.00 | 8550.00 | 0.00 | + | 10 | 11 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8500.00 | | + | 11 | 12 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8450.00 | | + | 12 | 13 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8400.00 | | + | 13 | 14 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8350.00 | | + | 14 | 15 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8300.00 | | + | 15 | 16 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8250.00 | | + | 16 | 17 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8200.00 | | + | 17 | 18 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8150.00 | | + | 18 | 19 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8100.00 | | + | 19 | 20 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8050.00 | | + | 20 | 21 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 8000.00 | | + | 21 | 22 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7950.00 | | + | 22 | 23 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7900.00 | | + | 23 | 24 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7850.00 | | + | 24 | 25 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7800.00 | | + | 25 | 26 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7750.00 | | + | 26 | 27 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7700.00 | | + | 27 | 28 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7650.00 | | + | 28 | 29 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7600.00 | | + | 29 | 30 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7550.00 | | + | 30 | 31 January 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7500.00 | | + | 31 | 01 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7450.00 | | + | 32 | 02 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7400.00 | | + | 33 | 03 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7350.00 | | + | 34 | 04 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7300.00 | | + | 35 | 05 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7250.00 | | + | 36 | 06 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7200.00 | | + | 37 | 07 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7150.00 | | + | 38 | 08 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7100.00 | | + | 39 | 09 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7050.00 | | + | 40 | 10 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 7000.00 | | + | 41 | 11 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6950.00 | | + | 42 | 12 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6900.00 | | + | 43 | 13 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6850.00 | | + | 44 | 14 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6800.00 | | + | 45 | 15 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6750.00 | | + | 46 | 16 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6700.00 | | + | 47 | 17 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6650.00 | | + | 48 | 18 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6600.00 | | + | 49 | 19 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6550.00 | | + | 50 | 20 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6500.00 | | + | 51 | 21 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6450.00 | | + | 52 | 22 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6400.00 | | + | 53 | 23 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6350.00 | | + | 54 | 24 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6300.00 | | + | 55 | 25 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6250.00 | | + | 56 | 26 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6200.00 | | + | 57 | 27 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6150.00 | | + | 58 | 28 February 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6100.00 | | + | 59 | 01 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6050.00 | | + | 60 | 02 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 6000.00 | | + | 61 | 03 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5950.00 | | + | 62 | 04 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5900.00 | | + | 63 | 05 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5850.00 | | + | 64 | 06 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5800.00 | | + | 65 | 07 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5750.00 | | + | 66 | 08 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5700.00 | | + | 67 | 09 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5650.00 | | + | 68 | 10 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5600.00 | | + | 69 | 11 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5550.00 | | + | 70 | 12 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5500.00 | | + | 71 | 13 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5450.00 | | + | 72 | 14 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5400.00 | | + | 73 | 15 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5350.00 | | + | 74 | 16 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5300.00 | | + | 75 | 17 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5250.00 | | + | 76 | 18 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5200.00 | | + | 77 | 19 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5150.00 | | + | 78 | 20 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5100.00 | | + | 79 | 21 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5050.00 | | + | 80 | 22 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 5000.00 | | + | 81 | 23 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4950.00 | | + | 82 | 24 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4900.00 | | + | 83 | 25 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4850.00 | | + | 84 | 26 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4800.00 | | + | 85 | 27 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4750.00 | | + | 86 | 28 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4700.00 | | + | 87 | 29 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4650.00 | | + | 88 | 30 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4600.00 | | + | 89 | 31 March 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4550.00 | | + | 90 | 01 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4500.00 | | + | 91 | 02 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4450.00 | | + | 92 | 03 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4400.00 | | + | 93 | 04 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4350.00 | | + | 94 | 05 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4300.00 | | + | 95 | 06 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4250.00 | | + | 96 | 07 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4200.00 | | + | 97 | 08 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4150.00 | | + | 98 | 09 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4100.00 | | + | 99 | 10 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4050.00 | | + | 100 | 11 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 4000.00 | | + | 101 | 12 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3950.00 | | + | 102 | 13 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3900.00 | | + | 103 | 14 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3850.00 | | + | 104 | 15 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3800.00 | | + | 105 | 16 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3750.00 | | + | 106 | 17 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3700.00 | | + | 107 | 18 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3650.00 | | + | 108 | 19 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3600.00 | | + | 109 | 20 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3550.00 | | + | 110 | 21 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3500.00 | | + | 111 | 22 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3450.00 | | + | 112 | 23 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3400.00 | | + | 113 | 24 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3350.00 | | + | 114 | 25 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3300.00 | | + | 115 | 26 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3250.00 | | + | 116 | 27 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3200.00 | | + | 117 | 28 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3150.00 | | + | 118 | 29 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3100.00 | | + | 119 | 30 April 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3050.00 | | + | 120 | 01 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 3000.00 | | + | 121 | 02 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2950.00 | | + | 122 | 03 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2900.00 | | + | 123 | 04 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2850.00 | | + | 124 | 05 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2800.00 | | + | 125 | 06 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2750.00 | | + | 126 | 07 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2700.00 | | + | 127 | 08 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2650.00 | | + | 128 | 09 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2600.00 | | + | 129 | 10 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2550.00 | | + | 130 | 11 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2500.00 | | + | 131 | 12 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2450.00 | | + | 132 | 13 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2400.00 | | + | 133 | 14 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2350.00 | | + | 134 | 15 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2300.00 | | + | 135 | 16 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2250.00 | | + | 136 | 17 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2200.00 | | + | 137 | 18 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2150.00 | | + | 138 | 19 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2100.00 | | + | 139 | 20 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2050.00 | | + | 140 | 21 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 2000.00 | | + | 141 | 22 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1950.00 | | + | 142 | 23 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1900.00 | | + | 143 | 24 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1850.00 | | + | 144 | 25 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1800.00 | | + | 145 | 26 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1750.00 | | + | 146 | 27 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1700.00 | | + | 147 | 28 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1650.00 | | + | 148 | 29 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1600.00 | | + | 149 | 30 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1550.00 | | + | 150 | 31 May 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1500.00 | | + | 151 | 01 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1450.00 | | + | 152 | 02 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1400.00 | | + | 153 | 03 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1350.00 | | + | 154 | 04 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1300.00 | | + | 155 | 05 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1250.00 | | + | 156 | 06 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1200.00 | | + | 157 | 07 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1150.00 | | + | 158 | 08 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1100.00 | | + | 159 | 09 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1050.00 | | + | 160 | 10 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 1000.00 | | + | 161 | 11 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 950.00 | | + | 162 | 12 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 900.00 | | + | 163 | 13 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 850.00 | | + | 164 | 14 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 800.00 | | + | 165 | 15 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 750.00 | | + | 166 | 16 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 700.00 | | + | 167 | 17 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 650.00 | | + | 168 | 18 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 600.00 | | + | 169 | 19 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 550.00 | | + | 170 | 20 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 500.00 | | + | 171 | 21 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 450.00 | | + | 172 | 22 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 400.00 | | + | 173 | 23 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 350.00 | | + | 174 | 24 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 300.00 | | + | 175 | 25 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 250.00 | | + | 176 | 26 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 200.00 | | + | 177 | 27 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 150.00 | | + | 178 | 28 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 100.00 | | + | 179 | 29 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 50.00 | | + | 180 | 30 June 2026 | 50.00 | 1 | 50.00 | 0.00 | 0.00 | 0.00 | | + | 181 | 01 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 182 | 02 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 183 | 03 July 2026 | | 1 | 50.00 | 0.00 | | | | + | 184 | 04 July 2026 | | 1 | 30.00 | 0.00 | | | | @TestRailId:C76634 Scenario: Verify amortization schedule after repayment transaction - UC18 @@ -733,7 +3223,7 @@ Feature: Working Capital Loan Repayment And Admin creates a client with random data And Admin creates a working capital loan with the following data: | LoanProduct | submittedOnDate | expectedDisbursementDate | principalAmount | totalPayment | periodPaymentRate | discount | - | WCLP | 01 January 2019 | 01 January 2019 | 9000 | 100000 | 0.18 | 1000 | + | WCLP | 01 January 2019 | 01 January 2019 | 9000 | 100000 | 18 | 1000 | And Admin successfully approves the working capital loan on "01 January 2019" with "9000" amount and "1000" discount amount and expected disbursement date on "01 January 2019" And Admin successfully disburse the Working Capital loan on "01 January 2019" with "9000" EUR transaction amount and "1000" discount amount Then Working Capital loan amortization schedule has 201 periods, with the following data for periods: diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java index ad86ca1f5be..b9d1d086c55 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java @@ -77,6 +77,7 @@ public enum LoanTransactionType { BUY_DOWN_FEE_AMORTIZATION(42, "loanTransactionType.buyDownFeeAmortization"), // BUY_DOWN_FEE_AMORTIZATION_ADJUSTMENT(43, "loanTransactionType.buyDownFeeAmortizationAdjustment"), // DISCOUNT_FEE(44, "loanTransactionType.discountFee"), // + DISCOUNT_FEE_ADJUSTMENT(45, "loanTransactionType.discountFeeAdjustment"), // ; private final Integer value; @@ -137,6 +138,7 @@ public static LoanTransactionType fromInt(final Integer transactionType) { case 42 -> LoanTransactionType.BUY_DOWN_FEE_AMORTIZATION; case 43 -> LoanTransactionType.BUY_DOWN_FEE_AMORTIZATION_ADJUSTMENT; case 44 -> LoanTransactionType.DISCOUNT_FEE; + case 45 -> LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT; default -> LoanTransactionType.INVALID; }; } @@ -273,4 +275,8 @@ public boolean isBuyDownFee() { public boolean isBuyDownFeeAdjustment() { return this == LoanTransactionType.BUY_DOWN_FEE_ADJUSTMENT; } + + public boolean isDiscountFee() { + return this == LoanTransactionType.DISCOUNT_FEE; + } } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java index cc9eab6ac8a..a4314ffd148 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java @@ -350,6 +350,8 @@ public static LoanTransactionEnumData transactionType(final LoanTransactionType LoanTransactionType.BUY_DOWN_FEE_AMORTIZATION_ADJUSTMENT.getCode(), "Buy Down Fee Amortization Adjustment"); case DISCOUNT_FEE -> new LoanTransactionEnumData(LoanTransactionType.DISCOUNT_FEE.getValue().longValue(), LoanTransactionType.DISCOUNT_FEE.getCode(), "Discount Fee"); + case DISCOUNT_FEE_ADJUSTMENT -> new LoanTransactionEnumData(LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT.getValue().longValue(), + LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT.getCode(), "Discount Fee Adjustment"); }; } diff --git a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java index 95669ce2ac7..568a1e254cd 100644 --- a/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java +++ b/fineract-provider/src/test/java/org/apache/fineract/infrastructure/event/external/service/ExternalEventConfigurationValidationServiceTest.java @@ -116,6 +116,7 @@ public void givenAllConfigurationWhenValidatedThenValidationSuccessful() throws "SavingsAccountsStayedLockedBusinessEvent", "SavingsAccountForceWithdrawalBusinessEvent", "WorkingCapitalLoanDisbursalTransactionBusinessEvent", "WorkingCapitalLoanUndoDisbursalTransactionBusinessEvent", "WorkingCapitalLoanRepaymentTransactionBusinessEvent", "WorkingCapitalLoanDiscountFeeTransactionBusinessEvent", + "WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent", "WorkingCapitalLoanCreditBalanceRefundTransactionBusinessEvent"); List tenants = Arrays diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/workingcapitalloan/transaction/WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/workingcapitalloan/transaction/WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent.java new file mode 100644 index 00000000000..e705ad0a38a --- /dev/null +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/infrastructure/event/business/domain/workingcapitalloan/transaction/WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent.java @@ -0,0 +1,40 @@ +/** + * 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.infrastructure.event.business.domain.workingcapitalloan.transaction; + +import org.apache.fineract.portfolio.workingcapitalloan.domain.WorkingCapitalLoanTransaction; + +public class WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent extends WorkingCapitalLoanTransactionBusinessEvent { + + private static final String TYPE = "WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent"; + + public WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent(final WorkingCapitalLoanTransaction value) { + super(value); + } + + public WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent(final WorkingCapitalLoanTransaction value, + final Long aggregateRootId) { + super(value, aggregateRootId); + } + + @Override + public String getType() { + return TYPE; + } +} diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/WorkingCapitalLoanConstants.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/WorkingCapitalLoanConstants.java index baf46ba2072..763b5adc3fa 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/WorkingCapitalLoanConstants.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/WorkingCapitalLoanConstants.java @@ -49,6 +49,8 @@ private WorkingCapitalLoanConstants() { public static final String REPAYMENT_LOAN_COMMAND = "repayment"; public static final String GOODWILL_CREDIT_LOAN_COMMAND = "goodwillCredit"; public static final String CREDIT_BALANCE_REFUND_COMMAND = "creditBalanceRefund"; + public static final String DISCOUNT_FEE_LOAN_COMMAND = "discountFee"; + public static final String DISCOUNT_FEE_ADJUSTMENT_LOAN_COMMAND = "discountFeeAdjustment"; // Approval / Rejection / Undo-approval parameters public static final String RESOURCE_NAME = WCL_RESOURCE_NAME; diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResource.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResource.java index a53a057e794..7e01beba520 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResource.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResource.java @@ -302,8 +302,6 @@ private CommandProcessingResult handleStateTransition(final Long loanId, final S commandRequest = builder.disburseWorkingCapitalLoanApplication(resolvedLoanId).build(); } else if (CommandParameterUtil.is(commandParam, "undodisbursal")) { commandRequest = builder.undoWorkingCapitalLoanApplicationDisbursal(resolvedLoanId).build(); - } else if (CommandParameterUtil.is(commandParam, "discountfee")) { - commandRequest = builder.discountWorkingCapitalLoanApplicationDisbursal(resolvedLoanId).build(); } if (commandRequest == null) { diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResourceSwagger.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResourceSwagger.java index b2530a50167..1acbb375a99 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResourceSwagger.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanApiResourceSwagger.java @@ -522,8 +522,6 @@ private PostWorkingCapitalLoansLoanIdRequest() {} public String externalId; @Schema(description = "Payment details (Account No, Cheque No, Routing Code, Receipt No, Bank code)") public PostWorkingCapitalLoansLoanIdDisbursementPaymentDetails paymentDetails; - @Schema(description = "Related resource ID for transaction, e.g., related transaction ID") - public Long relatedResourceId; } @Schema(description = "Request for updating discount on a disbursed Working Capital Loan") diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResource.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResource.java index 9b2be8cb6c2..35d66d91904 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResource.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResource.java @@ -184,7 +184,7 @@ private WorkingCapitalLoanCommandTemplateData handleLoanTransactionTemplate(fina @Path("{loanId}/transactions") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - @Operation(operationId = "executeWorkingCapitalLoanTransactionById", summary = "Execute Working Capital Loan transaction", description = "Supported command query parameter: repayment, creditBalanceRefund") + @Operation(operationId = "executeWorkingCapitalLoanTransactionById", summary = "Execute Working Capital Loan transaction", description = "Supported command query parameter: repayment, creditBalanceRefund, discountFee, discountFeeAdjustment") @RequestBody(required = true, content = @Content(schema = @Schema(implementation = WorkingCapitalLoanTransactionsApiResourceSwagger.PostWorkingCapitalLoanTransactionsRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = WorkingCapitalLoanTransactionsApiResourceSwagger.PostWorkingCapitalLoanTransactionsResponse.class))) }) @@ -199,7 +199,7 @@ public CommandProcessingResult executeLoanTransactionById( @Path("external-id/{loanExternalId}/transactions") @Consumes({ MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_JSON }) - @Operation(operationId = "executeWorkingCapitalLoanTransactionByExternalId", summary = "Execute Working Capital Loan transaction by external id", description = "Supported command query parameter: repayment, creditBalanceRefund") + @Operation(operationId = "executeWorkingCapitalLoanTransactionByExternalId", summary = "Execute Working Capital Loan transaction by external id", description = "Supported command query parameter: repayment, creditBalanceRefund, discountFee, discountFeeAdjustment") @RequestBody(required = true, content = @Content(schema = @Schema(implementation = WorkingCapitalLoanTransactionsApiResourceSwagger.PostWorkingCapitalLoanTransactionsRequest.class))) @ApiResponses({ @ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = WorkingCapitalLoanTransactionsApiResourceSwagger.PostWorkingCapitalLoanTransactionsResponse.class))) }) @@ -225,6 +225,10 @@ private CommandProcessingResult executeTransaction(final Long loanId, final Stri commandRequest = builder.creditBalanceRefundWorkingCapitalLoanTransaction(resolvedLoanId).build(); } else if (CommandParameterUtil.is(commandParam, GOODWILL_CREDIT_LOAN_COMMAND)) { commandRequest = builder.goodwillCreditWorkingCapitalLoanTransaction(resolvedLoanId).build(); + } else if (CommandParameterUtil.is(commandParam, WorkingCapitalLoanConstants.DISCOUNT_FEE_LOAN_COMMAND)) { + commandRequest = builder.discountFeeWorkingCapitalLoanTransaction(resolvedLoanId).build(); + } else if (CommandParameterUtil.is(commandParam, WorkingCapitalLoanConstants.DISCOUNT_FEE_ADJUSTMENT_LOAN_COMMAND)) { + commandRequest = builder.discountFeeAdjustmentWorkingCapitalLoanTransaction(resolvedLoanId).build(); } else { throw new UnrecognizedQueryParamException("command", commandParam); } diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResourceSwagger.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResourceSwagger.java index 779233678f6..8dff5a81d7e 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResourceSwagger.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/api/WorkingCapitalLoanTransactionsApiResourceSwagger.java @@ -145,7 +145,7 @@ private CodeValueData() {} public String name; } - @Schema(description = "Request for transaction command: repayment or creditBalanceRefund") + @Schema(description = "Request for transaction command: repayment, creditBalanceRefund, discountFee, or discountFeeAdjustment") public static final class PostWorkingCapitalLoanTransactionsRequest { private PostWorkingCapitalLoanTransactionsRequest() {} @@ -156,6 +156,8 @@ private PostWorkingCapitalLoanTransactionsRequest() {} public String dateFormat; @Schema(example = "28 June 2024", description = "Transaction date") public String transactionDate; + @Schema(example = "42", description = "Disbursement transaction id for discountFee; discount fee transaction id for discountFeeAdjustment") + public Long relatedResourceId; @Schema(example = "100.0", description = "Transaction amount") public BigDecimal transactionAmount; @Schema(example = "12", description = "Optional code value id for transaction classification") @@ -168,7 +170,7 @@ private PostWorkingCapitalLoanTransactionsRequest() {} public PostWorkingCapitalLoanTransactionsPaymentDetailRequest paymentDetails; } - @Schema(description = "Response for repayment/creditBalanceRefund transaction command") + @Schema(description = "Response for repayment, creditBalanceRefund, discountFee, or discountFeeAdjustment transaction command") public static final class PostWorkingCapitalLoanTransactionsResponse { private PostWorkingCapitalLoanTransactionsResponse() {} diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/DefaultProjectedAmortizationScheduleCalculator.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/DefaultProjectedAmortizationScheduleCalculator.java index b6265311bec..a8dff82e848 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/DefaultProjectedAmortizationScheduleCalculator.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/DefaultProjectedAmortizationScheduleCalculator.java @@ -21,6 +21,7 @@ import java.math.BigDecimal; import java.math.MathContext; import java.time.LocalDate; +import org.apache.fineract.infrastructure.core.service.DateUtils; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.springframework.lang.NonNull; import org.springframework.stereotype.Component; @@ -39,14 +40,14 @@ public ProjectedAmortizationScheduleModel generateModel(@NonNull final BigDecima @NonNull final BigDecimal periodPaymentRate, final int npvDayCount, @NonNull final LocalDate expectedDisbursementDate, @NonNull final MathContext mc, @NonNull final CurrencyData currency) { return ProjectedAmortizationScheduleModel.generate(discountFeeAmount, netDisbursementAmount, totalPaymentValue, periodPaymentRate, - npvDayCount, expectedDisbursementDate, mc, currency); + npvDayCount, expectedDisbursementDate, mc, currency, DateUtils.getBusinessLocalDate()); } @Override @NonNull public ProjectedAmortizationScheduleModel addDisbursement(@NonNull final ProjectedAmortizationScheduleModel model, @NonNull final BigDecimal newDiscountAmount, @NonNull final BigDecimal newNetAmount, @NonNull final LocalDate newStartDate) { - return model.regenerate(newDiscountAmount, newNetAmount, newStartDate); + return model.regenerate(newDiscountAmount, newNetAmount, newStartDate, DateUtils.getBusinessLocalDate()); } @Override @@ -62,4 +63,5 @@ public ProjectedAmortizationScheduleModel applyRateChange(@NonNull final Project model.applyRateChange(newPeriodPaymentRate, rateChangeDate); return model; } + } diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleModel.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleModel.java index 5b8d39d18c8..8ce6efd5fc0 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleModel.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleModel.java @@ -26,7 +26,7 @@ import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Comparator; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -49,6 +49,7 @@ *
  • {@link #applyPayment} — record payments by date; schedule rebuilds after each
  • *
  • {@link #applyRateChange} — apply a mid-lifecycle rate change; adds a {@link RateSegment} and rebuilds the payment * list in-place
  • + *
  • Discount fee adjustment — regenerate schedule with the new discount and re-apply actual payments only
  • * */ @Getter @@ -56,7 +57,7 @@ @Slf4j public final class ProjectedAmortizationScheduleModel { - private static final String MODEL_VERSION = "3"; + private static final String MODEL_VERSION = "4"; @SerializedName(value = "discountFeeAmount", alternate = "originationFeeAmount") private final Money discountFeeAmount; @@ -96,10 +97,13 @@ public final class ProjectedAmortizationScheduleModel { @Getter(AccessLevel.NONE) private List originalProjectedPayments; + private LocalDate calculatedTillDate; + private ProjectedAmortizationScheduleModel(final Money discountFeeAmount, final Money netDisbursementAmount, final Money totalPaymentValue, final BigDecimal periodPaymentRate, final int npvDayCount, final LocalDate expectedDisbursementDate, final Money expectedPaymentAmount, final int originalPaymentNumber, - final BigDecimal effectiveInterestRate, final MathContext mc, final CurrencyData currency) { + final BigDecimal effectiveInterestRate, final MathContext mc, final CurrencyData currency, + final LocalDate currentBusinessDate) { this.discountFeeAmount = discountFeeAmount; this.netDisbursementAmount = netDisbursementAmount; this.totalPaymentValue = totalPaymentValue; @@ -113,6 +117,7 @@ private ProjectedAmortizationScheduleModel(final Money discountFeeAmount, final this.currency = currency; this.actualPayments = new ArrayList<>(); this.rateSegments = new ArrayList<>(); + this.calculatedTillDate = expectedDisbursementDate != null ? expectedDisbursementDate : currentBusinessDate; rebuildPayments(); } @@ -140,6 +145,7 @@ private ProjectedAmortizationScheduleModel(final MathContext mc, final CurrencyD this.rateSegments = new ArrayList<>(); this.projectedPayments = List.of(); this.originalProjectedPayments = List.of(); + this.calculatedTillDate = null; } public List projectedPayments() { @@ -154,6 +160,11 @@ public List rateSegments() { return rateSegments != null ? List.copyOf(rateSegments) : List.of(); } + /** Snapshot of repayments already applied; used when restating the schedule after a discount fee adjustment. */ + public List snapshotActualPayments() { + return List.copyOf(actualPayments); + } + public int effectiveTotalTerm() { if (rateSegments == null || rateSegments.isEmpty()) { return originalPaymentNumber; @@ -167,7 +178,7 @@ public int effectiveTotalTerm() { public static ProjectedAmortizationScheduleModel generate(final BigDecimal discountFeeAmount, final BigDecimal netDisbursementAmount, final BigDecimal totalPaymentValue, final BigDecimal periodPaymentRate, final int npvDayCount, - final LocalDate expectedDisbursementDate, final MathContext mc, final CurrencyData currency) { + final LocalDate expectedDisbursementDate, final MathContext mc, final CurrencyData currency, final LocalDate currentDate) { Objects.requireNonNull(discountFeeAmount, "discountFeeAmount"); Objects.requireNonNull(netDisbursementAmount, "netDisbursementAmount"); @@ -182,7 +193,8 @@ public static ProjectedAmortizationScheduleModel generate(final BigDecimal disco throw new IllegalArgumentException("npvDayCount must be positive"); } - final BigDecimal expectedPayment = totalPaymentValue.multiply(periodPaymentRate, mc).divide(BigDecimal.valueOf(npvDayCount), mc); + final BigDecimal expectedPayment = totalPaymentValue.multiply(periodPaymentRate, mc).divide(BigDecimal.valueOf(npvDayCount), mc) + .divide(BigDecimal.valueOf(100), mc); if (expectedPayment.signum() <= 0) { throw new IllegalArgumentException("expectedPaymentAmount must be positive (check totalPaymentValue and periodPaymentRate)"); } @@ -197,33 +209,17 @@ public static ProjectedAmortizationScheduleModel generate(final BigDecimal disco return new ProjectedAmortizationScheduleModel(Money.of(currency, discountFeeAmount, mc), Money.of(currency, netDisbursementAmount, mc), Money.of(currency, totalPaymentValue, mc), periodPaymentRate, npvDayCount, - expectedDisbursementDate, Money.of(currency, expectedPayment, mc), originalPaymentNumber, eir, mc, currency); + expectedDisbursementDate, Money.of(currency, expectedPayment, mc), originalPaymentNumber, eir, mc, currency, currentDate); } - public LocalDate normalizePaymentDateForSchedule(final LocalDate paymentDate) { - Objects.requireNonNull(paymentDate, "paymentDate"); + private LocalDate calculateAllocationDate(final LocalDate paymentDate) { final LocalDate firstInstallmentDate = expectedDisbursementDate.plusDays(1); final LocalDate lastInstallmentDate = expectedDisbursementDate.plusDays(effectiveTotalTerm()); if (paymentDate.isBefore(firstInstallmentDate) || paymentDate.equals(expectedDisbursementDate)) { return firstInstallmentDate; } - - if (projectedPayments == null || projectedPayments.isEmpty()) { - if (paymentDate.isAfter(lastInstallmentDate)) { - return lastInstallmentDate; - } - return paymentDate; - } - final ProjectedPayment nearestUnpaid = projectedPayments.stream().filter(p -> p.paymentNo() > 0) - .filter(p -> p.actualPaymentAmount() == null).findFirst().orElse(null); - if (nearestUnpaid != null && nearestUnpaid.date() != null) { - if (nearestUnpaid.date().isBefore(firstInstallmentDate)) { - return firstInstallmentDate; - } - if (nearestUnpaid.date().isAfter(lastInstallmentDate)) { - return lastInstallmentDate; - } - return nearestUnpaid.date(); + if (paymentDate.isAfter(lastInstallmentDate)) { + return lastInstallmentDate; } return paymentDate; } @@ -231,21 +227,28 @@ public LocalDate normalizePaymentDateForSchedule(final LocalDate paymentDate) { public void applyPayment(final LocalDate paymentDate, final BigDecimal amount) { Objects.requireNonNull(paymentDate, "paymentDate"); Objects.requireNonNull(amount, "amount"); - final LocalDate scheduleDate = normalizePaymentDateForSchedule(paymentDate); - final int index = resolvePaymentIndex(scheduleDate); + updateCalculatedTillDate(paymentDate); + final LocalDate allocationDate = calculateAllocationDate(paymentDate); + final int index = resolvePaymentIndex(allocationDate); if (index < 0 || index >= effectiveTotalTerm()) { throw new IllegalArgumentException("paymentDate " + paymentDate + " is outside the valid range [" + expectedDisbursementDate.plusDays(1) + " .. " + expectedDisbursementDate.plusDays(effectiveTotalTerm()) + "]"); } - actualPayments.add(new ActualPayment(scheduleDate, money(amount))); + actualPayments.add(new ActualPayment(allocationDate, money(amount))); rebuildPayments(); } + private void updateCalculatedTillDate(final LocalDate actionDate) { + if (calculatedTillDate == null || actionDate.isAfter(calculatedTillDate)) { + this.calculatedTillDate = actionDate; + } + } + /** Creates a new model with updated parameters, preserving applied payments. */ public ProjectedAmortizationScheduleModel regenerate(final BigDecimal newDiscountAmount, final BigDecimal newNetAmount, - final LocalDate newStartDate) { + final LocalDate newStartDate, final LocalDate currentDate) { final ProjectedAmortizationScheduleModel newModel = generate(newDiscountAmount, newNetAmount, totalPaymentValue.getAmount(), - periodPaymentRate, npvDayCount, newStartDate, mc, currency); + periodPaymentRate, npvDayCount, newStartDate, mc, currency, currentDate); newModel.actualPayments.addAll(actualPayments); newModel.rebuildPayments(); return newModel; @@ -255,6 +258,7 @@ public void recalculateNetAmortizationAndDeferredBalanceFrom(final LocalDate rep if (repaymentDate == null || projectedPayments == null || projectedPayments.isEmpty()) { return; } + updateCalculatedTillDate(repaymentDate); final ProjectedPayment lastRepayment = projectedPayments.stream().filter(p -> p.paymentNo() > 0) .filter(p -> repaymentDate.equals(p.date())).reduce((a, b) -> b).orElse(null); @@ -291,7 +295,7 @@ public void recalculateNetAmortizationAndDeferredBalanceFrom(final LocalDate rep * Any existing segments at or after the split point are removed first (supports undo/overwrite). * * @param newPeriodPaymentRate - * the new period payment rate + * the new period payment rate as a percentage (same convention as {@link #generate}) * @param rateChangeDate * the date of the rate change (must be within model's date range) */ @@ -299,6 +303,7 @@ public void applyRateChange(final BigDecimal newPeriodPaymentRate, final LocalDa Objects.requireNonNull(newPeriodPaymentRate, "newPeriodPaymentRate"); Objects.requireNonNull(rateChangeDate, "rateChangeDate"); + updateCalculatedTillDate(rateChangeDate); final int rawSplitDayIndex = (int) ChronoUnit.DAYS.between(expectedDisbursementDate, rateChangeDate); if (rawSplitDayIndex < 0) { throw new IllegalArgumentException("rateChangeDate must not be before expectedDisbursementDate"); @@ -357,7 +362,7 @@ public void applyRateChange(final BigDecimal newPeriodPaymentRate, final LocalDa } final int scale = currency.getDecimalPlaces(); final BigDecimal newDailyPayment = tpv.multiply(newPeriodPaymentRate, mc).divide(BigDecimal.valueOf(npvDayCount), mc) - .setScale(scale, mc.getRoundingMode()); + .divide(BigDecimal.valueOf(100), mc).setScale(scale, mc.getRoundingMode()); final BigDecimal fractionalTotalDays = newNetDisb.add(newDiscount, mc).divide(newDailyPayment, mc).setScale(scale, mc.getRoundingMode()); final int newTerm = fractionalTotalDays.intValue(); @@ -377,16 +382,6 @@ public void applyRateChange(final BigDecimal newPeriodPaymentRate, final LocalDa rebuildPayments(); } - /** - * Removes the last rate change segment and rebuilds the schedule. - */ - public void removeLastRateChange() { - if (rateSegments != null && !rateSegments.isEmpty()) { - rateSegments.removeLast(); - rebuildPayments(); - } - } - /** * Removes the last rate change segment without triggering a rebuild. Use when a subsequent operation (e.g., * {@link #applyRateChange}) will rebuild anyway. @@ -431,13 +426,34 @@ private void rebuildOriginalProjectedPayments(final BalancesAndAmortizations ba) } private Map aggregatePaymentsByDate() { - final Map result = new HashMap<>(); + final Map result = new LinkedHashMap<>(); + if (!actualPayments.isEmpty() && calculatedTillDate != null) { + final LocalDate firstInstallmentDate = expectedDisbursementDate.plusDays(1); + final LocalDate lastInstallmentDate = expectedDisbursementDate.plusDays(effectiveTotalTerm()); + if (!calculatedTillDate.isBefore(firstInstallmentDate)) { + final LocalDate mapEnd = calculatedTillDate.isAfter(lastInstallmentDate) ? lastInstallmentDate : calculatedTillDate; + result.putAll(generateDateMap(firstInstallmentDate, mapEnd)); + } + } for (final ActualPayment payment : actualPayments) { result.merge(payment.date(), payment.amount().getAmount(), BigDecimal::add); } return result; } + public static Map generateDateMap(LocalDate startDate, LocalDate endDate) { + Map result = new LinkedHashMap<>(); + + LocalDate current = startDate; + + while (!current.isAfter(endDate)) { + result.put(current, BigDecimal.ZERO); + current = current.plusDays(1); + } + + return result; + } + private List buildPaymentList(final Map paymentsByDate) { final int totalTerm = effectiveTotalTerm(); final List result = new ArrayList<>(totalTerm); @@ -455,11 +471,22 @@ private int resolvePaymentIndex(final LocalDate date) { private List buildPayments(final List payments, final int appliedCount, final BalancesAndAmortizations ba) { final PaymentAnalysis pa = analyzePayments(payments, appliedCount); + final BigDecimal amountToAdjustTail = pa.excess.subtract(pa.shortfall); final List expectedAmortizationAmounts = ba.expectedAmortizations().stream().map(Money::getAmount).toList(); final List actualAmortizations = computeActualAmortizations(expectedAmortizationAmounts, payments, appliedCount); - final List runningExpected = computeRunningExpectedPayments(pa.excess); + final List runningExpected; final List tailPayments = new ArrayList<>(); - final BigDecimal tailNpv = buildTailPeriodsAndComputeNpv(tailPayments, pa.shortfall, appliedCount); + final BigDecimal tailNpv; + if (amountToAdjustTail.compareTo(BigDecimal.ZERO) > 0) { + runningExpected = computeRunningExpectedPayments(amountToAdjustTail); + tailNpv = buildTailPeriodsAndComputeNpv(tailPayments, BigDecimal.ZERO, appliedCount); + } else if (amountToAdjustTail.compareTo(BigDecimal.ZERO) < 0) { + runningExpected = computeRunningExpectedPayments(BigDecimal.ZERO); + tailNpv = buildTailPeriodsAndComputeNpv(tailPayments, amountToAdjustTail.negate(), appliedCount); + } else { + runningExpected = computeRunningExpectedPayments(BigDecimal.ZERO); + tailNpv = buildTailPeriodsAndComputeNpv(tailPayments, BigDecimal.ZERO, appliedCount); + } final BigDecimal totalNetAmortization = computeTotalNetAmortization(payments, runningExpected, appliedCount, tailNpv); final BigDecimal discountFee = discountFeeAmount.getAmount(); @@ -470,12 +497,14 @@ private List buildPayments(final List payments, fi BigDecimal cumulativeActualAmort = BigDecimal.ZERO; for (int i = 0; i < effectiveTotalTerm(); i++) { final int periodNo = i + 1; - final boolean hasAppliedAmount = payments.get(i) != null; + final LocalDate periodDate = expectedDisbursementDate.plusDays(periodNo); + final BigDecimal periodPayment = payments.get(i); + final boolean hasPositivePayment = periodPayment != null && periodPayment.signum() > 0; final long paymentsLeft = paymentsLeft(periodNo, appliedCount); final BigDecimal safeDf = safeDiscountFactor(paymentsLeft, periodNo); final BigDecimal periodExpectedPayment = MathUtil.negativeToZero(expectedPaymentForDay(periodNo)); final BigDecimal safeRunningExpected = MathUtil.negativeToZero(runningExpected.get(i)); - final BigDecimal npvSource = hasAppliedAmount ? payments.get(i) : safeRunningExpected; + final BigDecimal npvSource = resolveNpvSource(hasPositivePayment, periodPayment, periodDate, safeRunningExpected); final BigDecimal npvValue = MathUtil.negativeToZero(npvSource.multiply(safeDf, mc)); final BigDecimal safeExpectedAmort = ba.expectedAmortizations().get(i).getAmount().min(discountFee); @@ -483,12 +512,11 @@ private List buildPayments(final List payments, fi final BigDecimal actualAmortization; final BigDecimal incomeModification; - if (hasAppliedAmount) { + if (hasPositivePayment) { actualAmortization = actualAmortizations.get(i); netAmortization = totalNetAmortization.subtract(cumulativeActualAmort, mc).min(discountFee); cumulativeActualAmort = cumulativeActualAmort.add(actualAmortization, mc).min(discountFee); - final boolean hasPositivePayment = payments.get(i).signum() > 0; - incomeModification = hasPositivePayment ? actualAmortization.subtract(safeExpectedAmort, mc) : null; + incomeModification = actualAmortization.subtract(safeExpectedAmort, mc); } else { netAmortization = BigDecimal.ZERO; actualAmortization = null; @@ -497,10 +525,9 @@ private List buildPayments(final List payments, fi final BigDecimal deferredBalance = discountFee.subtract(cumulativeActualAmort, mc); final BigDecimal balance = ba.balances().get(i).getAmount(); - result.add(new ProjectedPayment(periodNo, expectedDisbursementDate.plusDays(periodNo), paymentsLeft, - money(periodExpectedPayment), money(safeRunningExpected), safeDf, money(npvValue), money(balance), - money(safeExpectedAmort), money(netAmortization), hasAppliedAmount ? money(payments.get(i)) : null, - actualAmortization != null ? money(actualAmortization) : null, + result.add(new ProjectedPayment(periodNo, periodDate, paymentsLeft, money(periodExpectedPayment), money(safeRunningExpected), + safeDf, money(npvValue), money(balance), money(safeExpectedAmort), money(netAmortization), + hasPositivePayment ? money(periodPayment) : null, actualAmortization != null ? money(actualAmortization) : null, incomeModification != null ? money(incomeModification) : null, money(deferredBalance))); } @@ -518,6 +545,17 @@ private List buildPayments(final List payments, fi return result; } + private BigDecimal resolveNpvSource(final boolean hasPositivePayment, final BigDecimal periodPayment, final LocalDate periodDate, + final BigDecimal safeRunningExpected) { + if (hasPositivePayment) { + return periodPayment; + } + if (calculatedTillDate != null && periodDate.isBefore(calculatedTillDate)) { + return BigDecimal.ZERO; + } + return safeRunningExpected; + } + private static BigDecimal amountOrZero(final Money value) { return value != null && value.getAmount() != null ? value.getAmount() : BigDecimal.ZERO; } @@ -559,8 +597,13 @@ private PaymentAnalysis analyzePayments(final List payments, final i BigDecimal shortfall = BigDecimal.ZERO; BigDecimal excess = BigDecimal.ZERO; for (int i = 0; i < appliedCount; i++) { + final BigDecimal payment = payments.get(i); final BigDecimal expectedPayment = expectedPaymentForDay(i + 1); - final BigDecimal diff = payments.get(i).subtract(expectedPayment, mc); + if (payment == null || payment.signum() == 0) { + shortfall = shortfall.add(expectedPayment, mc); + continue; + } + final BigDecimal diff = payment.subtract(expectedPayment, mc); if (diff.signum() > 0) { excess = excess.add(diff, mc); } else if (diff.signum() < 0) { @@ -576,8 +619,11 @@ private List computeActualAmortizations(final List expec final List result = new ArrayList<>(appliedCount); BigDecimal cursor = BigDecimal.ZERO; for (int i = 0; i < appliedCount; i++) { + final BigDecimal periodPayment = payments.get(i); final BigDecimal expectedPayment = expectedPaymentForDay(i + 1); - final BigDecimal periodsConsumed = payments.get(i).divide(expectedPayment, mc); + final BigDecimal periodsConsumed = periodPayment != null && periodPayment.signum() > 0 + ? periodPayment.divide(expectedPayment, mc) + : BigDecimal.ZERO; result.add(consumeExpectedAmortization(expectedAmortizations, cursor, periodsConsumed)); cursor = cursor.add(periodsConsumed, mc); } diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransaction.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransaction.java index cc315114850..cc8edfbd109 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransaction.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransaction.java @@ -156,6 +156,23 @@ public static WorkingCapitalLoanTransaction discountFee(final WorkingCapitalLoan return transaction; } + public static WorkingCapitalLoanTransaction discountFeeAdjustment(final WorkingCapitalLoan loan, final ExternalId externalId, + final BigDecimal amount, final LocalDate transactionDate, final CodeValue classification, final PaymentDetail paymentDetail) { + WorkingCapitalLoanTransaction transaction = new WorkingCapitalLoanTransaction(); + transaction.wcLoan = loan; + transaction.transactionType = LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT; + transaction.transactionAmount = amount; + transaction.transactionDate = transactionDate; + transaction.submittedOnDate = transactionDate; + transaction.externalId = externalId != null ? externalId : ExternalId.empty(); + transaction.paymentDetail = paymentDetail; + transaction.classification = classification; + transaction.reversed = false; + transaction.reversalExternalId = null; + transaction.reversedOnDate = null; + return transaction; + } + private void initialize(final WorkingCapitalLoan loan, final LoanTransactionType transactionType, final LocalDate transactionDate, final BigDecimal amount, final PaymentDetail paymentDetail, final CodeValue classification, final ExternalId externalId) { this.wcLoan = loan; diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionAllocation.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionAllocation.java index 979fe734382..686c4e69641 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionAllocation.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionAllocation.java @@ -79,4 +79,14 @@ public static WorkingCapitalLoanTransactionAllocation forDisbursementDiscount(fi allocation.penaltyChargesPortion = BigDecimal.ZERO; return allocation; } + + public static WorkingCapitalLoanTransactionAllocation forDiscountFeeAdjustment(final WorkingCapitalLoanTransaction transaction, + final BigDecimal principalAmount) { + final WorkingCapitalLoanTransactionAllocation allocation = new WorkingCapitalLoanTransactionAllocation(); + allocation.wcLoanTransaction = transaction; + allocation.principalPortion = MathUtil.nullToZero(principalAmount); + allocation.feeChargesPortion = BigDecimal.ZERO; + allocation.penaltyChargesPortion = BigDecimal.ZERO; + return allocation; + } } diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionRelationRepository.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionRelationRepository.java index f1987daa417..6afa71ff1d0 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionRelationRepository.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/domain/WorkingCapitalLoanTransactionRelationRepository.java @@ -19,6 +19,7 @@ package org.apache.fineract.portfolio.workingcapitalloan.domain; +import java.util.List; import java.util.Optional; import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.springframework.data.jpa.repository.JpaRepository; @@ -31,4 +32,7 @@ public interface WorkingCapitalLoanTransactionRelationRepository Optional findByToTransactionAndFromTransactionReversedAndFromTransactionTransactionType( WorkingCapitalLoanTransaction relatedDisbursementTransaction, boolean reversed, LoanTransactionType transactionType); + + List findAllByToTransactionAndFromTransactionReversedAndFromTransactionTransactionType( + WorkingCapitalLoanTransaction relatedDisbursementTransaction, boolean reversed, LoanTransactionType transactionType); } diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/handler/WorkingCapitalLoanDiscountFeeAdjustmentCommandHandler.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/handler/WorkingCapitalLoanDiscountFeeAdjustmentCommandHandler.java new file mode 100644 index 00000000000..e25f649ec34 --- /dev/null +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/handler/WorkingCapitalLoanDiscountFeeAdjustmentCommandHandler.java @@ -0,0 +1,40 @@ +/** + * 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.portfolio.workingcapitalloan.handler; + +import lombok.RequiredArgsConstructor; +import org.apache.fineract.commands.annotation.CommandType; +import org.apache.fineract.commands.handler.NewCommandSourceHandler; +import org.apache.fineract.infrastructure.core.api.JsonCommand; +import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; +import org.apache.fineract.portfolio.workingcapitalloan.service.WorkingCapitalLoanWritePlatformService; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@CommandType(entity = "WORKINGCAPITALLOAN", action = "DISCOUNTFEEADJUSTMENT") +public class WorkingCapitalLoanDiscountFeeAdjustmentCommandHandler implements NewCommandSourceHandler { + + private final WorkingCapitalLoanWritePlatformService writePlatformService; + + @Override + public CommandProcessingResult processCommand(JsonCommand command) { + return writePlatformService.makeDiscountFeeAdjustment(command.getResourceId(), command); + } +} diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/serialization/WorkingCapitalLoanDataValidator.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/serialization/WorkingCapitalLoanDataValidator.java index 643c63a10c6..1208a3e4f6a 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/serialization/WorkingCapitalLoanDataValidator.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/serialization/WorkingCapitalLoanDataValidator.java @@ -48,6 +48,7 @@ import org.apache.fineract.portfolio.loanaccount.domain.LoanTransactionType; import org.apache.fineract.portfolio.workingcapitalloan.WorkingCapitalLoanConstants; import org.apache.fineract.portfolio.workingcapitalloan.domain.WorkingCapitalLoan; +import org.apache.fineract.portfolio.workingcapitalloan.domain.WorkingCapitalLoanTransaction; import org.apache.fineract.portfolio.workingcapitalloan.repository.WorkingCapitalLoanTransactionRepository; import org.apache.fineract.portfolio.workingcapitalloanproduct.domain.WorkingCapitalLoanProductRelatedDetail; import org.springframework.stereotype.Component; @@ -95,6 +96,11 @@ public class WorkingCapitalLoanDataValidator { WorkingCapitalLoanConstants.transactionAmountParamName, WorkingCapitalLoanConstants.classificationIdParamName, WorkingCapitalLoanConstants.relatedResourceIdParamName, WorkingCapitalLoanConstants.paymentDetailsParamName, WorkingCapitalLoanConstants.noteParamName, WorkingCapitalLoanConstants.transactionDateParamName)); + private static final Set DISCOUNT_ADJUSTMENT_TRANSACTION_SUPPORTED_PARAMETERS = new HashSet<>( + Arrays.asList("locale", "dateFormat", WorkingCapitalLoanConstants.noteParamName, + WorkingCapitalLoanConstants.transactionAmountParamName, WorkingCapitalLoanConstants.classificationIdParamName, + WorkingCapitalLoanConstants.relatedResourceIdParamName, WorkingCapitalLoanConstants.paymentDetailsParamName, + WorkingCapitalLoanConstants.externalIdParameterName, WorkingCapitalLoanConstants.transactionDateParamName)); private static final Set CREDIT_BALANCE_REFUND_SUPPORTED_PARAMETERS = new HashSet<>(REPAYMENT_SUPPORTED_PARAMETERS); private static final Set UPDATE_RATE_SUPPORTED_PARAMETERS = new HashSet<>( @@ -152,6 +158,64 @@ public void validateDiscountTransaction(final WorkingCapitalLoan loan, final Str throwExceptionIfValidationWarningsExist(dataValidationErrors); } + public void validateDiscountAdjustmentTransaction(final WorkingCapitalLoan loan, final String json, final BigDecimal amount, + final WorkingCapitalLoanTransaction relatedDiscountTransaction, final BigDecimal remainingDiscountAmount, + final LocalDate effectiveTransactionDate) { + if (StringUtils.isBlank(json)) { + throw new InvalidJsonException(); + } + final Type typeOfMap = new TypeToken>() {}.getType(); + fromApiJsonHelper.checkForUnsupportedParameters(typeOfMap, json, DISCOUNT_ADJUSTMENT_TRANSACTION_SUPPORTED_PARAMETERS); + final JsonElement element = this.fromApiJsonHelper.parse(json); + final List dataValidationErrors = new ArrayList<>(); + final DataValidatorBuilder baseDataValidator = new DataValidatorBuilder(dataValidationErrors) + .resource(WorkingCapitalLoanConstants.RESOURCE_NAME); + + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.transactionAmountParamName).value(amount).notNull() + .positiveAmount(); + if (amount != null && remainingDiscountAmount != null && amount.compareTo(remainingDiscountAmount) > 0) { + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.transactionAmountParamName) + .failWithCode("cannot.be.more.than.discount.fee"); + } + + if (effectiveTransactionDate != null) { + if (DateUtils.isDateInTheFuture(effectiveTransactionDate)) { + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.transactionDateParamName) + .failWithCode("cannot.be.a.future.date"); + } + if (relatedDiscountTransaction != null + && DateUtils.isBefore(effectiveTransactionDate, relatedDiscountTransaction.getTransactionDate())) { + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.transactionDateParamName) + .failWithCode("cannot.be.before.discount.fee.date"); + } + if (DateUtils.isBefore(effectiveTransactionDate, DateUtils.getBusinessLocalDate())) { + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.transactionDateParamName) + .failWithCode("backdated.not.allowed"); + } + } + + final String note = this.fromApiJsonHelper.extractStringNamed(WorkingCapitalLoanConstants.noteParamName, element); + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.noteParamName).value(note).ignoreIfNull() + .notExceedingLengthOf(NOTE_MAX_LENGTH); + if (this.fromApiJsonHelper.parameterHasValue(WorkingCapitalLoanConstants.externalIdParameterName, element)) { + final String externalIdStr = this.fromApiJsonHelper.extractStringNamed(WorkingCapitalLoanConstants.externalIdParameterName, + element); + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.externalIdParameterName).value(externalIdStr).ignoreIfNull() + .notExceedingLengthOf(EXTERNAL_ID_MAX_LENGTH); + if (externalIdStr != null && !externalIdStr.isBlank()) { + final ExternalId externalId = ExternalIdFactory.produce(externalIdStr); + if (!externalId.isEmpty() && this.transactionRepository.existsByExternalId(externalId)) { + baseDataValidator.reset().parameter(WorkingCapitalLoanConstants.externalIdParameterName).failWithCode("already.exists"); + } + } + } + validatePaymentDetails(baseDataValidator, element); + if (loan.getLoanStatus() == null || !loan.getLoanStatus().isActive()) { + baseDataValidator.reset().parameter("loanStatus").failWithCode("adjustment.only.allowed.for.active.loan"); + } + throwExceptionIfValidationWarningsExist(dataValidationErrors); + } + public void validateApproval(final String json, final WorkingCapitalLoan loan) { if (StringUtils.isBlank(json)) { throw new InvalidJsonException(); diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteService.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteService.java index 9fe9fb4c87f..7d3f8c1c6a0 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteService.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteService.java @@ -39,4 +39,10 @@ public interface WorkingCapitalLoanAmortizationScheduleWriteService { BigDecimal getWorkingCapitalLoanDiscountAmount(WorkingCapitalLoan loan); void regenerateAmortizationScheduleOnRateChange(WorkingCapitalLoan loan, BigDecimal newRate); + + /** + * After a discount fee adjustment: regenerates the projected schedule with the new loan-level discount (as on + * disbursement generation) and re-applies recorded actual repayments only. + */ + void applyDiscountFeeAdjustment(WorkingCapitalLoan loan, LocalDate adjustmentTransactionDate); } diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteServiceImpl.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteServiceImpl.java index 5463bb25c52..c6a1b58231f 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteServiceImpl.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAmortizationScheduleWriteServiceImpl.java @@ -22,6 +22,8 @@ import java.math.MathContext; import java.time.LocalDate; import java.time.temporal.ChronoUnit; +import java.util.Comparator; +import java.util.List; import lombok.RequiredArgsConstructor; import org.apache.commons.lang3.Validate; import org.apache.fineract.infrastructure.core.service.DateUtils; @@ -36,6 +38,7 @@ import org.apache.fineract.portfolio.workingcapitalloan.domain.WorkingCapitalLoanDisbursementDetails; import org.apache.fineract.portfolio.workingcapitalloan.exception.WorkingCapitalLoanNotFoundException; import org.apache.fineract.portfolio.workingcapitalloan.repository.WorkingCapitalLoanRepository; +import org.springframework.lang.NonNull; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -66,7 +69,7 @@ public void generateAndSaveAmortizationSchedule(final Long loanId, final Project request.getPeriodPaymentRate(), // request.getNpvDayCount(), // request.getExpectedDisbursementDate(), // - mc, WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan)); + mc, WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan), DateUtils.getBusinessLocalDate()); scheduleRepositoryWrapper.writeModel(loan, model); } @@ -74,6 +77,14 @@ public void generateAndSaveAmortizationSchedule(final Long loanId, final Project @Override public void generateAndSaveAmortizationScheduleOnDisbursement(final WorkingCapitalLoan loan, final BigDecimal disbursedAmount, final LocalDate disbursementDate) { + final ProjectedAmortizationScheduleModel model = generateProjectedAmortizationScheduleModel(loan, disbursedAmount, + disbursementDate); + scheduleRepositoryWrapper.writeModel(loan, model); + } + + @NonNull + private ProjectedAmortizationScheduleModel generateProjectedAmortizationScheduleModel(final WorkingCapitalLoan loan, + final BigDecimal disbursedAmount, final LocalDate disbursementDate) { Validate.notNull(loan, "loan must not be null"); Validate.notNull(disbursedAmount, "disbursedAmount must not be null"); Validate.notNull(disbursementDate, "disbursementDate must not be null"); @@ -93,10 +104,8 @@ public void generateAndSaveAmortizationScheduleOnDisbursement(final WorkingCapit Validate.notNull(periodPaymentRate, "periodPaymentRate must not be null"); Validate.notNull(npvDayCount, "npvDayCount must not be null"); - final ProjectedAmortizationScheduleModel model = ProjectedAmortizationScheduleModel.generate(discount, disbursedAmount, - totalPayment, periodPaymentRate, npvDayCount, disbursementDate, mc, - WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan)); - scheduleRepositoryWrapper.writeModel(loan, model); + return ProjectedAmortizationScheduleModel.generate(discount, disbursedAmount, totalPayment, periodPaymentRate, npvDayCount, + disbursementDate, mc, WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan), DateUtils.getBusinessLocalDate()); } @Override @@ -157,7 +166,7 @@ private void generateAndSaveForApprovedLoanState(final WorkingCapitalLoan loan) final ProjectedAmortizationScheduleModel model = ProjectedAmortizationScheduleModel.generate(discount, netDisbursementAmount, totalPayment, periodPaymentRate, npvDayCount, expectedDisbursementDate, mc, - WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan)); + WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan), DateUtils.getBusinessLocalDate()); scheduleRepositoryWrapper.writeModel(loan, model); } @@ -174,9 +183,8 @@ public RepaymentAmortizationData applyRepayment(final WorkingCapitalLoan loan, f .orElseThrow(() -> new IllegalStateException("Projected amortization schedule is not found for loan " + loan.getId())); final BigDecimal previousTotalAmortized = sumRunningNpv(model); - final LocalDate scheduleRepaymentDate = model.normalizePaymentDateForSchedule(transactionDate); model.applyPayment(transactionDate, repaymentAmount); - model.recalculateNetAmortizationAndDeferredBalanceFrom(scheduleRepaymentDate); + model.recalculateNetAmortizationAndDeferredBalanceFrom(transactionDate); final BigDecimal totalAmortized = sumRunningNpv(model); scheduleRepositoryWrapper.writeModel(loan, model); @@ -216,6 +224,34 @@ public void regenerateAmortizationScheduleOnRateChange(final WorkingCapitalLoan scheduleRepositoryWrapper.writeModel(loan, model); } + @Override + public void applyDiscountFeeAdjustment(final WorkingCapitalLoan loan, final LocalDate adjustmentTransactionDate) { + Validate.notNull(loan, "loan must not be null"); + Validate.notNull(adjustmentTransactionDate, "adjustmentTransactionDate must not be null"); + + final MathContext mc = MoneyHelper.getMathContext(); + final CurrencyData currency = WorkingCapitalLoanCurrencyResolver.resolveCurrency(loan); + final ProjectedAmortizationScheduleModel currentModel = scheduleRepositoryWrapper.readModel(loan.getId(), mc, currency) + .orElseThrow(() -> new IllegalStateException("Projected amortization schedule is not found for loan " + loan.getId())); + + final List preservedPayments = currentModel.snapshotActualPayments(); + + final BigDecimal disbursedAmount = loan.getDisbursementDetails() != null && !loan.getDisbursementDetails().isEmpty() + && loan.getDisbursementDetails().getFirst().getActualAmount() != null + ? loan.getDisbursementDetails().getFirst().getActualAmount() + : BigDecimal.ZERO; + final LocalDate disbursementDate = loan.getDisbursementDetails() != null && !loan.getDisbursementDetails().isEmpty() + ? loan.getDisbursementDetails().getFirst().getActualDisbursementDate() + : null; + + final ProjectedAmortizationScheduleModel restatedModel = generateProjectedAmortizationScheduleModel(loan, disbursedAmount, + disbursementDate); + preservedPayments.stream().sorted(Comparator.comparing(ProjectedAmortizationScheduleModel.ActualPayment::date)) + .forEach(payment -> restatedModel.applyPayment(payment.date(), payment.amount().getAmount())); + + scheduleRepositoryWrapper.writeModel(loan, restatedModel); + } + private LocalDate resolveLoanDisbursementDate(final WorkingCapitalLoan loan) { if (loan.getDisbursementDetails() != null && !loan.getDisbursementDetails().isEmpty()) { final LocalDate actualDate = loan.getDisbursementDetails().getFirst().getActualDisbursementDate(); diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformService.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformService.java index 6d604b0ef5b..5619b9aaf26 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformService.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformService.java @@ -37,6 +37,8 @@ public interface WorkingCapitalLoanWritePlatformService { CommandProcessingResult makeDiscountFee(Long resourceId, JsonCommand command); + CommandProcessingResult makeDiscountFeeAdjustment(Long loanId, JsonCommand command); + CommandProcessingResult creditBalanceRefund(Long loanId, JsonCommand command); CommandProcessingResult makeGoodwillCredit(Long loanId, JsonCommand command); diff --git a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformServiceImpl.java b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformServiceImpl.java index 3385e8f85f3..1bdf1c6a620 100644 --- a/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformServiceImpl.java +++ b/fineract-working-capital-loan/src/main/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanWritePlatformServiceImpl.java @@ -44,6 +44,7 @@ import org.apache.fineract.infrastructure.event.business.domain.BusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction.WorkingCapitalLoanCreditBalanceRefundTransactionBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction.WorkingCapitalLoanDisbursalTransactionBusinessEvent; +import org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction.WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction.WorkingCapitalLoanDiscountFeeTransactionBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction.WorkingCapitalLoanRepaymentTransactionBusinessEvent; import org.apache.fineract.infrastructure.event.business.domain.workingcapitalloan.transaction.WorkingCapitalLoanUndoDisbursalTransactionBusinessEvent; @@ -498,6 +499,81 @@ public CommandProcessingResult makeDiscountFee(Long loanId, JsonCommand command) .withLoanId(loanId).with(changes).build(); } + @Override + public CommandProcessingResult makeDiscountFeeAdjustment(final Long loanId, final JsonCommand command) { + final WorkingCapitalLoan loan = loanRepository.findById(loanId).orElseThrow(() -> new WorkingCapitalLoanNotFoundException(loanId)); + final Long relatedDiscountTransactionId = fromApiJsonHelper.extractLongNamed(WorkingCapitalLoanConstants.relatedResourceIdParamName, + command.parsedJson()); + if (relatedDiscountTransactionId == null) { + throw new PlatformApiDataValidationException("validation.msg.wc.loan.related.resource.id.required", + "Related discount transaction ID is required for discount fee adjustment", + WorkingCapitalLoanConstants.relatedResourceIdParamName); + } + final WorkingCapitalLoanTransaction relatedDiscountTransaction = transactionRepository.findById(relatedDiscountTransactionId) + .orElseThrow(() -> new PlatformApiDataValidationException("validation.msg.wc.loan.discount.transaction.not.found", + "Discount transaction not found", WorkingCapitalLoanConstants.relatedResourceIdParamName)); + if (!relatedDiscountTransaction.getTypeOf().isDiscountFee() || relatedDiscountTransaction.isReversed()) { + throw new PlatformApiDataValidationException("validation.msg.wc.loan.discount.transaction.invalid", + "Related transaction must be an active discount fee transaction", + WorkingCapitalLoanConstants.relatedResourceIdParamName); + } + final BigDecimal amount = fromApiJsonHelper.extractBigDecimalNamed(WorkingCapitalLoanConstants.transactionAmountParamName, + command.parsedJson(), new HashSet<>()); + final BigDecimal totalAdjusted = relationRepository + .findAllByToTransactionAndFromTransactionReversedAndFromTransactionTransactionType(relatedDiscountTransaction, false, + LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT) + .stream().map(relation -> relation.getFromTransaction().getTransactionAmount()).reduce(BigDecimal.ZERO, BigDecimal::add); + final BigDecimal remainingDiscountAmount = relatedDiscountTransaction.getTransactionAmount().subtract(totalAdjusted); + + final LocalDate requestedTransactionDate = command + .localDateValueOfParameterNamed(WorkingCapitalLoanConstants.transactionDateParamName); + final LocalDate transactionDate = requestedTransactionDate != null ? requestedTransactionDate + : relatedDiscountTransaction.getTransactionDate(); + validator.validateDiscountAdjustmentTransaction(loan, command.json(), amount, relatedDiscountTransaction, remainingDiscountAmount, + transactionDate); + final Long classificationId = command.longValueOfParameterNamed(WorkingCapitalLoanConstants.classificationIdParamName); + final CodeValue classification = classificationId != null + ? codeValueRepository.findByCodeNameAndId(WorkingCapitalLoanConstants.REPAYMENT_CLASSIFICATION_CODE_NAME, classificationId) + : null; + final ExternalId txnExternalId = externalIdFactory.createFromCommand(command, WorkingCapitalLoanConstants.externalIdParameterName); + final Map changes = new LinkedHashMap<>(); + final PaymentDetail paymentDetail = createAndPersistPaymentDetailFromCommand(command, changes); + final WorkingCapitalLoanTransaction adjustmentTransaction = WorkingCapitalLoanTransaction.discountFeeAdjustment(loan, txnExternalId, + amount, transactionDate, classification, paymentDetail); + transactionRepository.saveAndFlush(adjustmentTransaction); + saveNewTransactionRelation(adjustmentTransaction, relatedDiscountTransaction, LoanTransactionRelationTypeEnum.RELATED); + allocationRepository.saveAndFlush(WorkingCapitalLoanTransactionAllocation.forDiscountFeeAdjustment(adjustmentTransaction, amount)); + + if (loan.getLoanProductRelatedDetails() == null) { + throw new PlatformApiDataValidationException("validation.msg.wc.loan.discount.not.available", + "Discount adjustment is not available when loan product details are missing", "loanProductRelatedDetails"); + } + final BigDecimal currentDiscount = loan.getLoanProductRelatedDetails().getDiscount(); + loan.getLoanProductRelatedDetails() + .setDiscount((currentDiscount != null ? currentDiscount : BigDecimal.ZERO).subtract(amount).max(BigDecimal.ZERO)); + + amortizationScheduleWriteService.applyDiscountFeeAdjustment(loan, transactionDate); + updateBalanceForDiscountChange(loan); + loanRepository.saveAndFlush(loan); + + final String noteText = command.stringValueOfParameterNamed(WorkingCapitalLoanConstants.noteParamName); + createNote(noteText, loan); + changes.put(WorkingCapitalLoanConstants.transactionAmountParamName, amount); + changes.put(WorkingCapitalLoanConstants.relatedResourceIdParamName, relatedDiscountTransactionId); + changes.put(WorkingCapitalLoanConstants.transactionDateParamName, transactionDate); + changes.put(WorkingCapitalLoanConstants.transactionTypeParamName, LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT); + changes.put(WorkingCapitalLoanConstants.classificationIdParamName, classificationId); + if (StringUtils.isNotBlank(noteText)) { + changes.put(WorkingCapitalLoanConstants.noteParamName, noteText); + } + businessEventNotifierService + .notifyPostBusinessEvent(new WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent(adjustmentTransaction)); + return new CommandProcessingResultBuilder().withCommandId(command.commandId()).withEntityId(adjustmentTransaction.getId()) + .withEntityExternalId(adjustmentTransaction.getExternalId()).withSubEntityId(relatedDiscountTransaction.getId()) + .withSubEntityExternalId(relatedDiscountTransaction.getExternalId()).withOfficeId(loan.getOfficeId()) + .withClientId(loan.getClientId()).withLoanId(loanId).with(changes).build(); + } + @Override public CommandProcessingResult makeRepayment(final Long loanId, final JsonCommand command) { return makeRepaymentLikeTransaction(loanId, command, LoanTransactionType.REPAYMENT); @@ -837,11 +913,7 @@ private WorkingCapitalLoanTransaction reverseDisbursementTransactionAndResetBala } final WorkingCapitalLoanTransaction txn = activeDisbursements.getFirst(); reverseTransaction(txn); - loan.getTransactions().stream() - .filter(t -> t.getTransactionType() == LoanTransactionType.DISCOUNT_FEE && !t.isReversed() - && t.getLoanTransactionRelations().stream().anyMatch(r -> r.getToTransaction() != null - && r.getToTransaction().getId() != null && r.getToTransaction().getId().equals(txn.getId()))) - .forEach(this::reverseTransaction); + reverseDiscountFeesLinkedToDisbursement(loan, txn); final Optional balanceOpt = this.balanceRepository.findByWcLoan_Id(loan.getId()); balanceOpt.ifPresent(b -> { @@ -864,13 +936,34 @@ private void ensureUndoDisbursalAllowed(final WorkingCapitalLoan loan) { if (txn.isReversed()) { continue; } - if (txn.getTypeOf() != LoanTransactionType.DISBURSEMENT && txn.getTypeOf() != LoanTransactionType.DISCOUNT_FEE) { + if (txn.getTypeOf() != LoanTransactionType.DISBURSEMENT && txn.getTypeOf() != LoanTransactionType.DISCOUNT_FEE + && txn.getTypeOf() != LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT) { throw new PlatformApiDataValidationException("validation.msg.wc.loan.undo.disbursal.not.allowed", "Undo disbursal is not allowed when there are other monetary transactions on the loan", "loanId"); } } } + private void reverseDiscountFeesLinkedToDisbursement(final WorkingCapitalLoan loan, + final WorkingCapitalLoanTransaction disbursementTransaction) { + loan.getTransactions().stream().filter(t -> t.getTypeOf() == LoanTransactionType.DISCOUNT_FEE && !t.isReversed() + && isRelatedToTransaction(t, disbursementTransaction.getId())).forEach(discountTxn -> { + reverseDiscountFeeAdjustmentsLinkedToDiscount(loan, discountTxn); + reverseTransaction(discountTxn); + }); + } + + private void reverseDiscountFeeAdjustmentsLinkedToDiscount(final WorkingCapitalLoan loan, + final WorkingCapitalLoanTransaction discountTransaction) { + loan.getTransactions().stream().filter(t -> t.getTypeOf() == LoanTransactionType.DISCOUNT_FEE_ADJUSTMENT && !t.isReversed() + && isRelatedToTransaction(t, discountTransaction.getId())).forEach(this::reverseTransaction); + } + + private boolean isRelatedToTransaction(final WorkingCapitalLoanTransaction transaction, final Long relatedTransactionId) { + return transaction.getLoanTransactionRelations().stream().anyMatch( + relation -> relation.getToTransaction() != null && relatedTransactionId.equals(relation.getToTransaction().getId())); + } + private void createNote(final String noteText, final WorkingCapitalLoan loan) { if (StringUtils.isNotBlank(noteText)) { final WorkingCapitalLoanNote note = WorkingCapitalLoanNote.create(loan, noteText); diff --git a/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/module-changelog-master.xml b/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/module-changelog-master.xml index 4d42188f366..89a0faeb064 100644 --- a/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/module-changelog-master.xml +++ b/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/module-changelog-master.xml @@ -59,4 +59,5 @@ + diff --git a/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/parts/0038_wc_loan_discount_adjustment_external_event.xml b/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/parts/0038_wc_loan_discount_adjustment_external_event.xml new file mode 100644 index 00000000000..87009444a13 --- /dev/null +++ b/fineract-working-capital-loan/src/main/resources/db/changelog/tenant/module/workingcapitalloan/parts/0038_wc_loan_discount_adjustment_external_event.xml @@ -0,0 +1,37 @@ + + + + + + + SELECT COUNT(*) + FROM m_external_event_configuration + WHERE type = 'WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent' + + + + + + + diff --git a/fineract-working-capital-loan/src/test/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleCalculatorTest.java b/fineract-working-capital-loan/src/test/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleCalculatorTest.java index 5e47ac8a6d3..3db4d62725d 100644 --- a/fineract-working-capital-loan/src/test/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleCalculatorTest.java +++ b/fineract-working-capital-loan/src/test/java/org/apache/fineract/portfolio/workingcapitalloan/calc/ProjectedAmortizationScheduleCalculatorTest.java @@ -29,8 +29,16 @@ import java.math.MathContext; import java.math.RoundingMode; import java.time.LocalDate; +import java.util.HashMap; +import java.util.Map; +import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType; +import org.apache.fineract.infrastructure.core.domain.ActionContext; +import org.apache.fineract.infrastructure.core.domain.FineractPlatformTenant; +import org.apache.fineract.infrastructure.core.service.ThreadLocalContextUtil; import org.apache.fineract.organisation.monetary.data.CurrencyData; import org.apache.fineract.organisation.monetary.domain.Money; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; class ProjectedAmortizationScheduleCalculatorTest { @@ -41,13 +49,25 @@ class ProjectedAmortizationScheduleCalculatorTest { private static final BigDecimal DISCOUNT_FEE = new BigDecimal("1000"); private static final BigDecimal NET_DISBURSEMENT = new BigDecimal("9000"); private static final BigDecimal TPV = new BigDecimal("100000"); - private static final BigDecimal RATE = new BigDecimal("0.18"); + private static final BigDecimal RATE = new BigDecimal("18"); private static final int DAY_COUNT = 360; private static final LocalDate EXPECTED_DISBURSEMENT_DATE = LocalDate.of(2019, 1, 1); private static final int TERM = 200; private final ProjectedAmortizationScheduleCalculator calculator = new DefaultProjectedAmortizationScheduleCalculator(); + @BeforeEach + void setBusinessDate() { + ThreadLocalContextUtil.setTenant(new FineractPlatformTenant(1L, "default", "Default", "UTC", null)); + ThreadLocalContextUtil.setActionContext(ActionContext.DEFAULT); + ThreadLocalContextUtil.setBusinessDates(new HashMap<>(Map.of(BusinessDateType.BUSINESS_DATE, EXPECTED_DISBURSEMENT_DATE))); + } + + @AfterEach + void resetContext() { + ThreadLocalContextUtil.reset(); + } + @Test void testAddDisbursement_term10_discountFee50_netDisbursement450_then430() { final BigDecimal discountFee = new BigDecimal("50"); @@ -515,7 +535,7 @@ void testProjectedSchedule_term200_discountFee1000_netDisbursement9000() { void testNoDiscountLoan_term180_discountFee0_netDisbursement9000() { final BigDecimal zeroDiscount = BigDecimal.ZERO; final ProjectedAmortizationScheduleModel model = ProjectedAmortizationScheduleModel.generate(zeroDiscount, NET_DISBURSEMENT, TPV, - RATE, DAY_COUNT, EXPECTED_DISBURSEMENT_DATE, MC, CURRENCY); + RATE, DAY_COUNT, EXPECTED_DISBURSEMENT_DATE, MC, CURRENCY, EXPECTED_DISBURSEMENT_DATE); assertEquals(180, model.originalPaymentNumber(), "loanTerm = ceil(9000/50) = 180"); assertEquals(BigDecimal.ZERO, model.effectiveInterestRate(), "EIR should be 0 when no discount fee"); @@ -1772,8 +1792,8 @@ void testNoPayment_term200_discountFee1000_netDisbursement9000_pay0_0_50() { checkInst(model, 0, 0, EXPECTED_DISBURSEMENT_DATE, 0, -9000.00, null, null, 1.00000000, -9000.00, 9000.00, null, null, null, null, 1000.00); - checkInst(model, 1, 1, LocalDate.of(2019, 1, 2), 0, 50.00, 50.00, 0.00, 1.00000000, 0.00, 8959.61, 9.61, 9.61, 0.00, null, 1000.00); - checkInst(model, 2, 2, LocalDate.of(2019, 1, 3), 0, 50.00, 50.00, 0.00, 1.00000000, 0.00, 8919.18, 9.57, 9.61, 0.00, null, 1000.00); + checkInst(model, 1, 1, LocalDate.of(2019, 1, 2), 0, 50.00, 50.00, null, 1.00000000, 0.00, 8959.61, 9.61, 0.00, null, null, 1000.00); + checkInst(model, 2, 2, LocalDate.of(2019, 1, 3), 0, 50.00, 50.00, null, 1.00000000, 0.00, 8919.18, 9.57, 0.00, null, null, 1000.00); checkInst(model, 3, 3, LocalDate.of(2019, 1, 4), 0, 50.00, 50.00, 50.00, 1.00000000, 50.00, 8878.70, 9.52, 9.61, 9.61, 0.09, 990.39); @@ -2239,7 +2259,7 @@ void testExcessPayment_term10_discountFee50_netDisbursement450_pay110() { @Test void testApplyRateChange_sameDayAsDisburse() { final ProjectedAmortizationScheduleModel model = generateModel(); - model.applyRateChange(new BigDecimal("0.15"), EXPECTED_DISBURSEMENT_DATE); + model.applyRateChange(new BigDecimal("15"), EXPECTED_DISBURSEMENT_DATE); assertFalse(model.rateSegments().isEmpty()); assertTrue(model.effectiveTotalTerm() > 0, "effective total term should be positive"); @@ -2249,7 +2269,7 @@ void testApplyRateChange_sameDayAsDisburse() { void testApplyRateChange_8daysAfterDisburse() { final ProjectedAmortizationScheduleModel model = generateModel(); final LocalDate rateChangeDate = EXPECTED_DISBURSEMENT_DATE.plusDays(8); - model.applyRateChange(new BigDecimal("0.15"), rateChangeDate); + model.applyRateChange(new BigDecimal("15"), rateChangeDate); assertFalse(model.rateSegments().isEmpty()); assertTrue(model.effectiveTotalTerm() > 0, "effective total term should be positive"); @@ -2259,12 +2279,12 @@ void testApplyRateChange_8daysAfterDisburse() { void testApplyRateChange_twiceWithDateGap() { final ProjectedAmortizationScheduleModel model = generateModel(); - model.applyRateChange(new BigDecimal("0.15"), EXPECTED_DISBURSEMENT_DATE); + model.applyRateChange(new BigDecimal("15"), EXPECTED_DISBURSEMENT_DATE); assertNotNull(model.rateSegments()); assertFalse(model.rateSegments().isEmpty()); final LocalDate secondChangeDate = EXPECTED_DISBURSEMENT_DATE.plusDays(8); - model.applyRateChange(new BigDecimal("0.11"), secondChangeDate); + model.applyRateChange(new BigDecimal("11"), secondChangeDate); assertTrue(model.effectiveTotalTerm() > 0, "effective total term should be positive"); } @@ -2276,7 +2296,7 @@ void testApplyRateChange_twiceWithDateGapAndPayment() { model.applyPayment(EXPECTED_DISBURSEMENT_DATE.plusDays(1), new BigDecimal("500")); final LocalDate rateChangeDate = EXPECTED_DISBURSEMENT_DATE.plusDays(8); - model.applyRateChange(new BigDecimal("0.15"), rateChangeDate); + model.applyRateChange(new BigDecimal("15"), rateChangeDate); assertTrue(model.effectiveTotalTerm() > 0, "effective total term should be positive"); } @@ -2285,7 +2305,7 @@ void testApplyRateChange_twiceWithDateGapAndPayment() { void testApplyRateChange_nearEndOfTerm() { final ProjectedAmortizationScheduleModel model = generateModel(); final LocalDate rateChangeDate = EXPECTED_DISBURSEMENT_DATE.plusDays(195); - model.applyRateChange(new BigDecimal("0.15"), rateChangeDate); + model.applyRateChange(new BigDecimal("15"), rateChangeDate); assertTrue(model.effectiveTotalTerm() > 0, "effective total term should be positive"); } @@ -2296,7 +2316,7 @@ void testApplyRateChange_pastEndOfTerm() { final int originalTerm = model.originalPaymentNumber(); final LocalDate rateChangeDate = EXPECTED_DISBURSEMENT_DATE.plusDays(250); - model.applyRateChange(new BigDecimal("0.15"), rateChangeDate); + model.applyRateChange(new BigDecimal("15"), rateChangeDate); // Past-term rate change should succeed — segment starts clamped at originalPaymentNumber assertFalse(model.rateSegments().isEmpty(), "should have a rate segment"); @@ -2309,7 +2329,7 @@ void testApplyRateChange_pastEndOfTerm() { void testApplyRateChange_beforeDisburseDate() { final ProjectedAmortizationScheduleModel model = generateModel(); assertThrows(IllegalArgumentException.class, () -> { - model.applyRateChange(new BigDecimal("0.15"), EXPECTED_DISBURSEMENT_DATE.minusDays(1)); + model.applyRateChange(new BigDecimal("15"), EXPECTED_DISBURSEMENT_DATE.minusDays(1)); }); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationCRUDTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationCRUDTest.java index 2a8cd2e8af7..e74f9b77859 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationCRUDTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationCRUDTest.java @@ -89,7 +89,7 @@ public void testSubmitWorkingCapitalLoanApplication() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson(); @@ -113,7 +113,7 @@ public void testSubmitWithoutOverridableParamsUsesProductDefaults() { final Long productId = createProductWithKnownDefaults(productRepaymentEvery, productRepaymentFrequencyType, productDiscount); final Long clientId = createClient(); final BigDecimal principal = BigDecimal.valueOf(5000); - final BigDecimal periodPaymentRate = BigDecimal.ONE; + final BigDecimal periodPaymentRate = WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT; final BigDecimal totalPayment = BigDecimal.valueOf(5500); final LocalDate expectedDisbursementDate = LocalDate.now(ZoneId.systemDefault()).plusDays(7); @@ -166,7 +166,7 @@ public void testSubmitWithoutBreachAndNearBreachParamsUsesProductBreachDefaults( .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson(); @@ -206,7 +206,7 @@ public void testNegativeSubmitWithBreachAndNearBreachParams() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withBreachId(null) // .withNearBreachId(nearBreachId) // @@ -221,7 +221,7 @@ public void testNegativeSubmitWithBreachAndNearBreachParams() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withBreachId(breachId) // .withNearBreachId(nearBreachId) // @@ -244,7 +244,7 @@ public void testRetrieveWorkingCapitalLoanByIdWithAllFieldsVerified() { final String accountNo = "wcl-get-" + UUID.randomUUID().toString().substring(0, 8); final String externalId = "wcl-get-ext-" + UUID.randomUUID().toString().substring(0, 8); final BigDecimal principal = BigDecimal.valueOf(6000); - final BigDecimal periodPaymentRate = BigDecimal.valueOf(1.05); + final BigDecimal periodPaymentRate = BigDecimal.valueOf(10.5); final BigDecimal totalPayment = BigDecimal.valueOf(6300); final BigDecimal discount = BigDecimal.valueOf(25); final LocalDate submittedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -295,7 +295,7 @@ public void testClientAccountsIncludeWorkingCapitalLoans() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(3000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(3150)) // .withAccountNo(accountNo) // .buildSubmitJson()); @@ -336,21 +336,21 @@ public void testWorkingCapitalLoanCycleInClientAccountSummary() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(1000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(1100)) // .buildSubmitJson()); final Long loanId2 = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(2000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(2200)) // .buildSubmitJson()); final Long loanId3 = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(3000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(3300)) // .buildSubmitJson()); @@ -399,7 +399,7 @@ public void testRetrieveWorkingCapitalLoanByExternalIdWithAllFieldsVerified() { final String accountNo = "wcl-extget-" + UUID.randomUUID().toString().substring(0, 8); final String externalId = "wcl-by-ext-" + UUID.randomUUID().toString().substring(0, 8); final BigDecimal principal = BigDecimal.valueOf(7000); - final BigDecimal periodPaymentRate = BigDecimal.valueOf(1.15); + final BigDecimal periodPaymentRate = BigDecimal.valueOf(11.5); final BigDecimal totalPayment = BigDecimal.valueOf(8050); final BigDecimal discount = BigDecimal.ZERO; final LocalDate submittedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -503,7 +503,8 @@ public void testRetrieveTemplateWithProductId() { } if (loanData != null) { if (loanData.has("periodPaymentRate") && !loanData.get("periodPaymentRate").isJsonNull()) { - assertEqualBigDecimal(BigDecimal.valueOf(1.0), loanData.get("periodPaymentRate")); + assertEqualBigDecimal(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT, + loanData.get("periodPaymentRate")); } if (loanData.has("repaymentEvery") && !loanData.get("repaymentEvery").isJsonNull()) { assertEquals(30, loanData.get("repaymentEvery").getAsInt()); @@ -592,7 +593,7 @@ public void testModifyWorkingCapitalLoan() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -615,14 +616,14 @@ public void testModifyWithAllFieldsAndVerifyEachField() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); final String newAccountNo = "wcl-mod-" + UUID.randomUUID().toString().substring(0, 8); final String newExternalId = "wcl-mod-ext-" + UUID.randomUUID().toString().substring(0, 8); final BigDecimal principal = BigDecimal.valueOf(9000); - final BigDecimal periodPaymentRate = BigDecimal.valueOf(1.2); + final BigDecimal periodPaymentRate = BigDecimal.valueOf(12); final BigDecimal totalPayment = BigDecimal.valueOf(10800); final BigDecimal discount = BigDecimal.valueOf(100); final LocalDate submittedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -676,7 +677,7 @@ public void testDeleteWorkingCapitalLoan() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -693,7 +694,7 @@ public void testSubmitWithAllFieldsAndVerifyEachField() { final String accountNo = "wcl-" + UUID.randomUUID().toString().substring(0, 8); final String externalId = "wcl-ext-" + UUID.randomUUID().toString().substring(0, 8); final BigDecimal principal = BigDecimal.valueOf(7500); - final BigDecimal periodPaymentRate = BigDecimal.valueOf(1.1); + final BigDecimal periodPaymentRate = BigDecimal.valueOf(11); final BigDecimal totalPayment = BigDecimal.valueOf(8250); final BigDecimal discount = BigDecimal.valueOf(50); final LocalDate submittedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -749,7 +750,7 @@ public void testRetrieveAllPaged() { final String accountNo = "wcl-paged-" + UUID.randomUUID().toString().substring(0, 8); final String externalId = "wcl-paged-ext-" + UUID.randomUUID().toString().substring(0, 8); final BigDecimal principal = BigDecimal.valueOf(5500); - final BigDecimal periodPaymentRate = BigDecimal.valueOf(1.05); + final BigDecimal periodPaymentRate = BigDecimal.valueOf(10.5); final BigDecimal totalPayment = BigDecimal.valueOf(5775); final BigDecimal discount = BigDecimal.ZERO; final LocalDate submittedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -813,7 +814,7 @@ public void testModifyByExternalId() { .withProductId(productId) // .withExternalId(externalId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -843,7 +844,7 @@ public void testDeleteByExternalId() { .withProductId(productId) // .withExternalId(externalId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -862,7 +863,7 @@ public void testWorkingCapitalDiscountAttributes() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(discountProposed) // .buildSubmitJson()); @@ -1064,9 +1065,9 @@ private Long createProductWithAllOverridables() { .withPrincipalAmountMin(BigDecimal.valueOf(1000)) // .withPrincipalAmountMax(BigDecimal.valueOf(50000)) // .withPrincipalAmountDefault(BigDecimal.valueOf(10000)) // - .withMinPeriodPaymentRate(BigDecimal.ONE) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(2)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withMinPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT) // + .withMaxPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withDelinquencyBucketId(delinquencyBucketId) // .withAllowAttributeOverrides(Map.of(// "delinquencyBucketClassification", Boolean.TRUE, // @@ -1091,9 +1092,9 @@ private Long createProductWithKnownDefaults(final Integer repaymentEvery, final .withPrincipalAmountMin(BigDecimal.valueOf(1000)) // .withPrincipalAmountMax(BigDecimal.valueOf(50000)) // .withPrincipalAmountDefault(BigDecimal.valueOf(10000)) // - .withMinPeriodPaymentRate(BigDecimal.ONE) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(2)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withMinPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT) // + .withMaxPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withDelinquencyBucketId(delinquencyBucketId) // .withRepaymentEvery(repaymentEvery) // .withRepaymentFrequencyType(repaymentFrequencyType) // @@ -1114,7 +1115,7 @@ private Long createProductWithBreachAndNearBreach(final Long breachId, final Lon .withName(uniqueName) // .withShortName(uniqueShortName) // .withPrincipalAmountDefault(BigDecimal.valueOf(10000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withRepaymentEvery(1) // .withRepaymentFrequencyType("MONTHS") // .withBreachId(breachId) // diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationValidationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationValidationTest.java index 366ba42f19d..be3537ee0c5 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationValidationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApplicationValidationTest.java @@ -68,7 +68,8 @@ public void testSubmitWithMissingClientId() { final Long productId = createProduct(); final Long clientId = createClient(); final String json = buildSubmitJsonWithoutField(new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson(), "clientId"); final CallFailedRuntimeException ex = applicationHelper.runSubmitExpectingFailure(json); @@ -83,7 +84,8 @@ public void testSubmitWithMissingProductId() { final Long productId = createProduct(); final Long clientId = createClient(); final String json = buildSubmitJsonWithoutField(new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson(), "productId"); final CallFailedRuntimeException ex = applicationHelper.runSubmitExpectingFailure(json); @@ -98,7 +100,8 @@ public void testSubmitWithMissingPrincipal() { final Long productId = createProduct(); final Long clientId = createClient(); final String json = buildSubmitJsonWithoutField(new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson(), "principalAmount"); final CallFailedRuntimeException ex = applicationHelper.runSubmitExpectingFailure(json); @@ -113,7 +116,8 @@ public void testSubmitWithMissingPeriodPaymentRate() { final Long productId = createProduct(); final Long clientId = createClient(); final String json = buildSubmitJsonWithoutField(new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson(), "periodPaymentRate"); final CallFailedRuntimeException ex = applicationHelper.runSubmitExpectingFailure(json); @@ -128,7 +132,8 @@ public void testSubmitWithMissingTotalPayment() { final Long productId = createProduct(); final Long clientId = createClient(); final String json = buildSubmitJsonWithoutField(new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson(), "totalPayment"); final CallFailedRuntimeException ex = applicationHelper.runSubmitExpectingFailure(json); @@ -143,7 +148,8 @@ public void testSubmitWithMissingExpectedDisbursementDate() { final Long productId = createProduct(); final Long clientId = createClient(); final String json = buildSubmitJsonWithoutField(new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson(), "expectedDisbursementDate"); final CallFailedRuntimeException ex = applicationHelper.runSubmitExpectingFailure(json); @@ -162,7 +168,7 @@ public void testSubmitWithNegativePrincipal() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(-100)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson(); @@ -182,7 +188,7 @@ public void testSubmitWithZeroPrincipal() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.ZERO) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson(); @@ -222,7 +228,7 @@ public void testSubmitWithNegativeDiscount() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.valueOf(-1)) // .buildSubmitJson(); @@ -244,7 +250,7 @@ public void testSubmitWithInvalidFundId() { .withProductId(productId) // .withFundId(-1L) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson(); @@ -263,7 +269,7 @@ public void testSubmitWithInvalidDelinquencyBucketId() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDelinquencyBucketId(-1L) // .buildSubmitJson(); @@ -284,7 +290,7 @@ public void testSubmitWithInvalidBreachId() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withBreachId(0L) // .buildSubmitJson(); @@ -304,7 +310,7 @@ public void testSubmitWithNonExistingBreachId() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withBreachId(Long.MAX_VALUE) // .buildSubmitJson(); @@ -326,7 +332,7 @@ public void testSubmitWithSubmittedOnNoteExceedingLength() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withSubmittedOnNote(longNote) // .buildSubmitJson(); @@ -341,13 +347,15 @@ public void testSubmitWithSubmittedOnNoteExceedingLength() { @Test public void testSubmitWithPrincipalBelowProductMin() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.ONE, BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final String json = new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(500)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(550)) // .buildSubmitJson(); @@ -361,13 +369,15 @@ public void testSubmitWithPrincipalBelowProductMin() { @Test public void testSubmitWithPrincipalAboveProductMax() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.ONE, BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final String json = new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(25000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(27500)) // .buildSubmitJson(); @@ -381,13 +391,15 @@ public void testSubmitWithPrincipalAboveProductMax() { @Test public void testSubmitWithPeriodPaymentRateBelowProductMin() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.valueOf(0.5), BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final String json = new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.valueOf(0.2)) // + .withPeriodPaymentRate(BigDecimal.valueOf(2)) // .withTotalPayment(BigDecimal.valueOf(5100)) // .buildSubmitJson(); @@ -401,13 +413,15 @@ public void testSubmitWithPeriodPaymentRateBelowProductMin() { @Test public void testSubmitWithPeriodPaymentRateAboveProductMax() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.valueOf(0.5), BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final String json = new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.valueOf(3)) // + .withPeriodPaymentRate(BigDecimal.valueOf(30)) // .withTotalPayment(BigDecimal.valueOf(6500)) // .buildSubmitJson(); @@ -431,7 +445,7 @@ public void testSubmitWithOverrideNotAllowedByProduct() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.ONE) // .buildSubmitJson(); @@ -457,7 +471,7 @@ public void testSubmitWithDiscountOverrideWhenProductHasNoOverridesConfigured() .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.ONE) // .buildSubmitJson(); @@ -483,7 +497,7 @@ public void testSubmitWithOverrideNotAllowedByProductForBreach() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withBreachId(breachId) // .buildSubmitJson(); @@ -509,7 +523,7 @@ public void testSubmitWithDuplicateAccountNo() { .withProductId(productId) // .withAccountNo(accountNo) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -518,7 +532,7 @@ public void testSubmitWithDuplicateAccountNo() { .withProductId(productId) // .withAccountNo(accountNo) // .withPrincipal(BigDecimal.valueOf(6000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(6600)) // .buildSubmitJson(); @@ -541,7 +555,7 @@ public void testSubmitWithDuplicateExternalId() { .withProductId(productId) // .withExternalId(externalId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -550,7 +564,7 @@ public void testSubmitWithDuplicateExternalId() { .withProductId(productId) // .withExternalId(externalId) // .withPrincipal(BigDecimal.valueOf(6000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(6600)) // .buildSubmitJson(); @@ -573,7 +587,7 @@ public void testSubmitWithSubmittedOnDateAfterExpectedDisbursementDate() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withSubmittedOnDate(submittedOn) // .withExpectedDisbursementDate(expectedDisbursement) // @@ -594,7 +608,7 @@ public void testModifyWithEmptyJson() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -615,7 +629,7 @@ public void testModifyWithInvalidDateRange() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -637,13 +651,15 @@ public void testModifyWithInvalidDateRange() { @Test public void testModifyWithPrincipalBelowProductMin() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.ONE, BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final Long loanId = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -660,13 +676,15 @@ public void testModifyWithPrincipalBelowProductMin() { @Test public void testModifyWithPrincipalAboveProductMax() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.ONE, BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final Long loanId = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -683,17 +701,19 @@ public void testModifyWithPrincipalAboveProductMax() { @Test public void testModifyWithPeriodPaymentRateBelowProductMin() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.valueOf(0.5), BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final Long loanId = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); - final String modifyJson = new WorkingCapitalLoanApplicationTestBuilder().withPeriodPaymentRate(BigDecimal.valueOf(0.2)) + final String modifyJson = new WorkingCapitalLoanApplicationTestBuilder().withPeriodPaymentRate(BigDecimal.valueOf(2)) .buildModifyJson(); final CallFailedRuntimeException ex = applicationHelper.runModifyExpectingFailure(loanId, modifyJson); assertEquals(400, ex.getStatus()); @@ -707,17 +727,19 @@ public void testModifyWithPeriodPaymentRateBelowProductMin() { @Test public void testModifyWithPeriodPaymentRateAboveProductMax() { - final Long productId = createProductWithMinMax(1000, 20000, BigDecimal.valueOf(0.5), BigDecimal.valueOf(2)); + final Long productId = createProductWithMinMax(1000, 20000, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT, + WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT); final Long clientId = createClient(); final Long loanId = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); - final String modifyJson = new WorkingCapitalLoanApplicationTestBuilder().withPeriodPaymentRate(BigDecimal.valueOf(3)) + final String modifyJson = new WorkingCapitalLoanApplicationTestBuilder().withPeriodPaymentRate(BigDecimal.valueOf(30)) .buildModifyJson(); final CallFailedRuntimeException ex = applicationHelper.runModifyExpectingFailure(loanId, modifyJson); assertEquals(400, ex.getStatus()); @@ -737,7 +759,7 @@ public void testModifyWithNegativePrincipal() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -760,7 +782,7 @@ public void testModifyWithNegativePeriodPaymentRate() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -784,7 +806,7 @@ public void testModifyWithNegativeDiscount() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -810,7 +832,7 @@ public void testModifyWithSubmittedOnNoteExceedingLength() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -837,7 +859,7 @@ public void testModifyWithInvalidFundId() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -862,7 +884,7 @@ public void testModifyWithDuplicateExternalId() { .withProductId(productId) // .withExternalId(externalId1) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); final Long loanId2 = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // @@ -870,7 +892,7 @@ public void testModifyWithDuplicateExternalId() { .withProductId(productId) // .withExternalId(externalId2) // .withPrincipal(BigDecimal.valueOf(6000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(6600)) // .buildSubmitJson()); @@ -893,7 +915,7 @@ public void testModifyWithBlankAccountNo() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); @@ -918,7 +940,7 @@ public void testModifyWithDuplicateAccountNo() { .withProductId(productId) // .withAccountNo(accountNo1) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); final Long loanId2 = applicationHelper.submit(new WorkingCapitalLoanApplicationTestBuilder() // @@ -926,7 +948,7 @@ public void testModifyWithDuplicateAccountNo() { .withProductId(productId) // .withAccountNo(accountNo2) // .withPrincipal(BigDecimal.valueOf(6000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(6600)) // .buildSubmitJson()); @@ -990,7 +1012,7 @@ public void testSubmitWithValidZeroDiscount() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.ZERO) // .buildSubmitJson(); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApprovalRejectionTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApprovalRejectionTest.java index e0fe209c79f..584967b5d96 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApprovalRejectionTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanApprovalRejectionTest.java @@ -88,7 +88,7 @@ public void testApproveWithPrincipalAndDiscountOverride() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.valueOf(100)) // .buildSubmitJson()); @@ -151,7 +151,7 @@ public void testUndoApprovalResetsToCreatedState() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.valueOf(100)) // .buildSubmitJson()); @@ -262,7 +262,7 @@ public void testApproveWithDateBeforeSubmittedOnDateFails() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withSubmittedOnDate(submittedOnDate) // .buildSubmitJson()); @@ -342,7 +342,7 @@ public void testApproveWithDiscountExceedingCreatedValueFails() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withDiscount(BigDecimal.valueOf(100)) // .buildSubmitJson()); @@ -386,7 +386,7 @@ public void testApproveAndUndoByExternalId() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withExternalId(externalId) // .buildSubmitJson()); @@ -413,7 +413,7 @@ public void testRejectByExternalId() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .withExternalId(externalId) // .buildSubmitJson()); @@ -432,7 +432,7 @@ private Long submitLoan(final Long clientId, final Long productId) { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(5500)) // .buildSubmitJson()); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanCreditBalanceRefundTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanCreditBalanceRefundTest.java index c9a6cb43510..e554c4296f5 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanCreditBalanceRefundTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanCreditBalanceRefundTest.java @@ -254,7 +254,8 @@ private Long createOverpaidLoan(final BigDecimal overpaymentAmount, final LocalD private Long createApprovedAndDisbursedLoan(final Long productId, final BigDecimal principal, final BigDecimal disburseAmount, final LocalDate approvedOnDate) { final Long loanId = submitAndTrackLoan(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(principal).withPeriodPaymentRate(BigDecimal.ONE).buildSubmitJson()); + .withProductId(productId).withPrincipal(principal) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT).buildSubmitJson()); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(approvedOnDate, principal, null)); loanHelper.disburseById(loanId, WorkingCapitalLoanDisbursementTestBuilder.buildDisburseJson(approvedOnDate, disburseAmount)); return loanId; diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyActionIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyActionIntegrationTest.java index 68ba89360e8..ac6ee590999 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyActionIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyActionIntegrationTest.java @@ -447,7 +447,8 @@ private Long submitAndApproveLoan(final Long clientId, final Long productId) { private Long submitAndApproveLoanWithExternalId(final Long clientId, final Long productId, final String externalId) { final WorkingCapitalLoanApplicationTestBuilder builder = new WorkingCapitalLoanApplicationTestBuilder().withClientId(clientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(10000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(10000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(10000)); if (externalId != null) { builder.withExternalId(externalId); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyRangeScheduleIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyRangeScheduleIntegrationTest.java index d4cd244c50e..04b456c427e 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyRangeScheduleIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDelinquencyRangeScheduleIntegrationTest.java @@ -129,7 +129,7 @@ public void testRangeScheduleEndpointReturnsEmptyForUndisbursedLoan() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(10000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(11000)) // .buildSubmitJson()); assertNotNull(loanId); @@ -176,7 +176,7 @@ public void testRangeScheduleExpectedAmountIncludesDiscount() { .withClientId(clientId) // .withProductId(productId) // .withPrincipal(principal) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withTotalPayment(BigDecimal.valueOf(10000)) // .buildSubmitJson()); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDisbursementTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDisbursementTest.java index 9e33796fcc7..6effdae1ff3 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDisbursementTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanDisbursementTest.java @@ -123,7 +123,7 @@ public void testDisburseWorkingCapitalLoan() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -180,7 +180,7 @@ public void testDisburseWithClassificationIdStoredOnTransaction() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -215,7 +215,7 @@ public void testDisburseWithNonExistentClassificationIdFails() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -242,7 +242,7 @@ public void testDisburseWithClassificationIdFromWrongCodeBookFails() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -268,7 +268,7 @@ public void testDisburseWithAllRequestFieldsAndVerifyResponse() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(approvedPrincipal) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -354,7 +354,7 @@ public void testUndoDisburseWorkingCapitalLoan() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -404,7 +404,7 @@ public void testDisbursementExternalBusinessEventPublished() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -441,7 +441,7 @@ public void testUndoDisbursementExternalBusinessEventPublished() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -478,7 +478,7 @@ public void testUndoDisbursalWithNote() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -503,7 +503,7 @@ public void testDisburseWithMissingActualDisbursementDate() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -526,7 +526,7 @@ public void testDisburseWithMissingTransactionAmount() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -552,7 +552,7 @@ public void testDisburseWithTransactionAmountExceedingApproved() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -575,7 +575,7 @@ public void testDisburseWithNegativeTransactionAmount() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -599,7 +599,7 @@ public void testDisburseWithFutureDate() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -622,7 +622,7 @@ public void testDisburseWithDateBeforeApproval() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -646,7 +646,7 @@ public void testDisburseWithActualDateBeforeSubmittedDate() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withSubmittedOnDate(submittedOnDate) // .buildSubmitJson()); @@ -671,7 +671,7 @@ public void testDisburseWithNoteExceedingLength() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -697,7 +697,7 @@ public void testDisburseWithDiscountExceedingCreated() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(approvedPrincipal) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -721,7 +721,7 @@ public void testDisburseWithDiscountFailsWhenProductDisallowsDiscountOverride() .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(approvedPrincipal) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, @@ -745,7 +745,7 @@ public void testDisburseWithDuplicateTransactionExternalId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId1, WorkingCapitalLoanApplicationTestBuilder .buildApproveJson(LocalDate.now(ZoneId.systemDefault()), BigDecimal.valueOf(5000), null)); @@ -757,7 +757,7 @@ public void testDisburseWithDuplicateTransactionExternalId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(3000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId2, WorkingCapitalLoanApplicationTestBuilder .buildApproveJson(LocalDate.now(ZoneId.systemDefault()), BigDecimal.valueOf(3000), null)); @@ -778,7 +778,7 @@ public void testDisburseWhenLoanNotApproved() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final String disburseJson = WorkingCapitalLoanDisbursementTestBuilder.buildDisburseJson(LocalDate.now(ZoneId.systemDefault()), @@ -809,7 +809,7 @@ public void testUndoDisbursalWhenLoanNotDisbursed() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); final LocalDate approvedOnDate = LocalDate.now(ZoneId.systemDefault()); @@ -841,7 +841,7 @@ public void testUndoDisbursalWithNoteExceedingLength() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -866,7 +866,7 @@ public void testGetTransactionsListAfterDisburse() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -903,7 +903,7 @@ public void testGetTransactionByIdAfterDisburse() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(6000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -941,7 +941,7 @@ public void testGetTransactionsListEmptyWhenNotDisbursed() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -962,7 +962,7 @@ public void testGetTransactionByNonExistentIdReturns404() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder .buildApproveJson(LocalDate.now(ZoneId.systemDefault()), BigDecimal.valueOf(5000), null)); @@ -984,7 +984,7 @@ public void testGetTransactionsByLoanExternalId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withExternalId(loanExternalId) // .buildSubmitJson()); @@ -1013,7 +1013,7 @@ public void testGetTransactionByLoanIdAndTransactionExternalId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(7000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -1038,7 +1038,7 @@ public void testStateTransitionByLoanExternalId_ApproveAndDisburse() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withExternalId(loanExternalId) // .buildSubmitJson()); @@ -1066,7 +1066,7 @@ public void testGetTransactionByExternalLoanIdAndTransactionId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(8000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withExternalId(loanExternalId) // .buildSubmitJson()); @@ -1095,7 +1095,7 @@ public void testGetTransactionByExternalLoanIdAndTransactionExternalId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(9000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .withExternalId(loanExternalId) // .buildSubmitJson()); @@ -1120,7 +1120,7 @@ public void testDisburseWithInvalidPaymentTypeId() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -1143,7 +1143,7 @@ public void testDisburseWithPaymentDetailsStringExceedingLength() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -1166,7 +1166,7 @@ public void testDisburseGeneratesAmortizationSchedule() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder @@ -1193,7 +1193,7 @@ public void testUndoDisbursalRegeneratesAmortizationScheduleToExpectedDate() { .withClientId(createdClientId) // .withProductId(productId) // .withPrincipal(BigDecimal.valueOf(5000)) // - .withPeriodPaymentRate(BigDecimal.ONE) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // .buildSubmitJson()); applicationHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductCRUDTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductCRUDTest.java index f4d16523c98..01a92800f25 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductCRUDTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductCRUDTest.java @@ -307,9 +307,9 @@ public void testCreateWorkingCapitalLoanProductWithAllFields() { .withPrincipalAmountMin(BigDecimal.valueOf(1000)) // .withPrincipalAmountDefault(BigDecimal.valueOf(5000)) // .withPrincipalAmountMax(BigDecimal.valueOf(10000)) // - .withMinPeriodPaymentRate(BigDecimal.valueOf(0.5)) // - .withPeriodPaymentRate(BigDecimal.valueOf(1.0)) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(2.0)) // + .withMinPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // + .withMaxPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT) // .withDiscount(BigDecimal.valueOf(0.1)) // .withRepaymentEvery(60) // .withRepaymentFrequencyType("DAYS") // @@ -393,9 +393,9 @@ public void testHappyPath_CreateAndRetrieve_VerifyAllFields() { .withPrincipalAmountMin(BigDecimal.valueOf(1000)) // .withPrincipalAmountDefault(BigDecimal.valueOf(5000)) // .withPrincipalAmountMax(BigDecimal.valueOf(10000)) // - .withMinPeriodPaymentRate(BigDecimal.valueOf(0.5)) // - .withPeriodPaymentRate(BigDecimal.valueOf(1.0)) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(2.0)) // + .withMinPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT) // + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) // + .withMaxPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT) // .withDiscount(BigDecimal.valueOf(0.1)) // .withRepaymentEvery(30) // .withRepaymentFrequencyType("DAYS") // @@ -479,11 +479,14 @@ public void testHappyPath_CreateAndRetrieve_VerifyAllFields() { assertEquals(0, BigDecimal.valueOf(10000).compareTo(retrieved.getMaxPrincipal())); } if (retrieved.getMinPeriodPaymentRate() != null) { - assertEquals(0, BigDecimal.valueOf(0.5).compareTo(retrieved.getMinPeriodPaymentRate())); + assertEquals(0, WorkingCapitalLoanProductTestBuilder.DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT + .compareTo(retrieved.getMinPeriodPaymentRate())); } - assertEquals(0, BigDecimal.valueOf(1.0).compareTo(retrieved.getPeriodPaymentRate())); + assertEquals(0, + WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT.compareTo(retrieved.getPeriodPaymentRate())); if (retrieved.getMaxPeriodPaymentRate() != null) { - assertEquals(0, BigDecimal.valueOf(2.0).compareTo(retrieved.getMaxPeriodPaymentRate())); + assertEquals(0, WorkingCapitalLoanProductTestBuilder.DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT + .compareTo(retrieved.getMaxPeriodPaymentRate())); } if (retrieved.getDiscount() != null) { assertEquals(0, BigDecimal.valueOf(0.1).compareTo(retrieved.getDiscount())); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductValidationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductValidationTest.java index 76f2eaf920a..fcadb34cf33 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductValidationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanProductValidationTest.java @@ -631,9 +631,9 @@ public void testCreateWorkingCapitalLoanProductWithDefaultGreaterThanMaxPrincipa public void testCreateWorkingCapitalLoanProductWithMinGreaterThanMaxPeriodPaymentRate() { // Given final PostWorkingCapitalLoanProductsRequest request = new WorkingCapitalLoanProductTestBuilder() // - .withMinPeriodPaymentRate(BigDecimal.valueOf(2.0)) // - .withPeriodPaymentRate(BigDecimal.valueOf(1.0)) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(3.0)) // + .withMinPeriodPaymentRate(BigDecimal.valueOf(20)) // + .withPeriodPaymentRate(BigDecimal.valueOf(10)) // + .withMaxPeriodPaymentRate(BigDecimal.valueOf(30)) // .build(); // When & Then - Should throw CallFailedRuntimeException with status 400 @@ -649,9 +649,9 @@ public void testCreateWorkingCapitalLoanProductWithMinGreaterThanMaxPeriodPaymen public void testCreateWorkingCapitalLoanProductWithDefaultLessThanMinPeriodPaymentRate() { // Given final PostWorkingCapitalLoanProductsRequest request = new WorkingCapitalLoanProductTestBuilder() // - .withMinPeriodPaymentRate(BigDecimal.valueOf(1.0)) // - .withPeriodPaymentRate(BigDecimal.valueOf(0.5)) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(2.0)) // + .withMinPeriodPaymentRate(BigDecimal.valueOf(10)) // + .withPeriodPaymentRate(BigDecimal.valueOf(5)) // + .withMaxPeriodPaymentRate(BigDecimal.valueOf(25)) // .build(); // When & Then - Should throw CallFailedRuntimeException with status 400 @@ -667,9 +667,9 @@ public void testCreateWorkingCapitalLoanProductWithDefaultLessThanMinPeriodPayme public void testCreateWorkingCapitalLoanProductWithDefaultGreaterThanMaxPeriodPaymentRate() { // Given final PostWorkingCapitalLoanProductsRequest request = new WorkingCapitalLoanProductTestBuilder() // - .withMinPeriodPaymentRate(BigDecimal.valueOf(0.5)) // - .withPeriodPaymentRate(BigDecimal.valueOf(3.0)) // - .withMaxPeriodPaymentRate(BigDecimal.valueOf(2.0)) // + .withMinPeriodPaymentRate(BigDecimal.valueOf(5)) // + .withPeriodPaymentRate(BigDecimal.valueOf(30)) // + .withMaxPeriodPaymentRate(BigDecimal.valueOf(25)) // .build(); // When & Then - Should throw CallFailedRuntimeException with status 400 diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentAccountingTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentAccountingTest.java index 11402db9472..32c06ad419b 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentAccountingTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentAccountingTest.java @@ -262,7 +262,8 @@ private Long createCashBasedProduct() { private Long createApprovedAndDisbursedLoan(final Long productId, final BigDecimal principal, final LocalDate approvedOnDate) { final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(principal).withPeriodPaymentRate(BigDecimal.ONE).buildSubmitJson()); + .withProductId(productId).withPrincipal(principal) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT).buildSubmitJson()); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(approvedOnDate, principal, null)); loanHelper.disburseById(loanId, WorkingCapitalLoanDisbursementTestBuilder.buildDisburseJson(approvedOnDate, principal)); return loanId; diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentTest.java index ae8b2e5b000..b3dbcd929d4 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/WorkingCapitalLoanRepaymentTest.java @@ -104,7 +104,8 @@ void cleanupEntities() { public void testRepaymentUpdatesTransactionAllocationBalanceAndStatus() { final Long productId = createProductWithDiscountAllowed(); final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).withDiscount(BigDecimal.valueOf(100)).buildSubmitJson()); final LocalDate approvedOnDate = Utils.getLocalDateOfTenant(); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(approvedOnDate, BigDecimal.valueOf(5000), @@ -132,7 +133,8 @@ public void testRepaymentRaisesExternalBusinessEvent() { externalEventHelper.enableBusinessEvent(WC_REPAYMENT_TXN_EVENT); final Long productId = createProduct(); final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(5500)).buildSubmitJson()); final LocalDate approvedOnDate = Utils.getLocalDateOfTenant(); loanHelper.approveById(loanId, @@ -197,7 +199,8 @@ public void testRepaymentWithInvalidClassificationIdFails() { public void testRepaymentWhenLoanNotDisbursedFails() { final Long productId = createProduct(); final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE).buildSubmitJson()); + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT).buildSubmitJson()); final LocalDate approvedOnDate = Utils.getLocalDateOfTenant(); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(approvedOnDate, BigDecimal.valueOf(5000), null)); @@ -212,7 +215,8 @@ public void testRepaymentWithDateBeforeDisbursementFails() { final LocalDate approvedOnDate = Utils.getLocalDateOfTenant(); final Long productId = createProduct(); final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE).buildSubmitJson()); + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT).buildSubmitJson()); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(approvedOnDate, BigDecimal.valueOf(5000), null)); loanHelper.disburseById(loanId, @@ -241,7 +245,8 @@ public void testRepaymentByExternalId() { final Long productId = createProduct(); final String loanExternalId = "wcl-loan-ext-" + UUID.randomUUID().toString().replace("-", "").substring(0, 8); final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)).withPeriodPaymentRate(BigDecimal.ONE) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(5000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withExternalId(loanExternalId).buildSubmitJson()); final LocalDate approvedOnDate = Utils.getLocalDateOfTenant(); loanHelper.approveById(loanId, @@ -295,7 +300,8 @@ public void testRepaymentAmortizationMatchesProvidedReferenceSchedule() { final Long productId = createProductForReferenceSchedule(); final LocalDate disbursementDate = LocalDate.of(2019, 1, 1); final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(BigDecimal.valueOf(9000)).withPeriodPaymentRate(new BigDecimal("0.18")) + .withProductId(productId).withPrincipal(BigDecimal.valueOf(9000)) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT) .withTotalPayment(BigDecimal.valueOf(100000)).withDiscount(BigDecimal.valueOf(1000)).withSubmittedOnDate(disbursementDate) .buildSubmitJson()); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(disbursementDate, BigDecimal.valueOf(9000), @@ -316,7 +322,7 @@ public void testRepaymentAmortizationMatchesProvidedReferenceSchedule() { assertEqualBigDecimal(BigDecimal.valueOf(1000), schedule.get("discountFeeAmount")); assertEqualBigDecimal(BigDecimal.valueOf(9000), schedule.get("netDisbursementAmount")); assertEqualBigDecimal(BigDecimal.valueOf(100000), schedule.get("totalPaymentValue")); - assertEqualBigDecimal(new BigDecimal("0.18"), schedule.get("periodPaymentRate")); + assertEqualBigDecimal(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT, schedule.get("periodPaymentRate")); assertEquals(360, schedule.get("npvDayCount").getAsInt()); assertTrue(schedule.get("expectedPaymentAmount").getAsBigDecimal().compareTo(BigDecimal.ZERO) > 0, "expectedPaymentAmount should be positive"); @@ -343,7 +349,8 @@ private Long createApprovedAndDisbursedLoan(final Long productId, final BigDecim private Long createApprovedAndDisbursedLoan(final Long productId, final BigDecimal principal, final BigDecimal disburseAmount, final LocalDate approvedOnDate) { final Long loanId = submitAndTrack(new WorkingCapitalLoanApplicationTestBuilder().withClientId(createdClientId) - .withProductId(productId).withPrincipal(principal).withPeriodPaymentRate(BigDecimal.ONE).buildSubmitJson()); + .withProductId(productId).withPrincipal(principal) + .withPeriodPaymentRate(WorkingCapitalLoanProductTestBuilder.DEFAULT_PERIOD_PAYMENT_RATE_PERCENT).buildSubmitJson()); loanHelper.approveById(loanId, WorkingCapitalLoanApplicationTestBuilder.buildApproveJson(approvedOnDate, principal, null)); loanHelper.disburseById(loanId, WorkingCapitalLoanDisbursementTestBuilder.buildDisburseJson(approvedOnDate, disburseAmount)); return loanId; diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java index 74abc75c35d..d6750fbfe26 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/ExternalEventConfigurationHelper.java @@ -699,6 +699,12 @@ public static ArrayList> getDefaultExternalEventConfiguratio workingCapitalLoanDiscountDisbursalTransactionBusinessEvent.put("enabled", false); defaults.add(workingCapitalLoanDiscountDisbursalTransactionBusinessEvent); + Map workingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent = new HashMap<>(); + workingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent.put("type", + "WorkingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent"); + workingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent.put("enabled", false); + defaults.add(workingCapitalLoanDiscountFeeAdjustmentTransactionBusinessEvent); + return defaults; } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/workingcapitalloanproduct/WorkingCapitalLoanProductTestBuilder.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/workingcapitalloanproduct/WorkingCapitalLoanProductTestBuilder.java index 5971069caf2..f171693651e 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/workingcapitalloanproduct/WorkingCapitalLoanProductTestBuilder.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/workingcapitalloanproduct/WorkingCapitalLoanProductTestBuilder.java @@ -45,7 +45,9 @@ public class WorkingCapitalLoanProductTestBuilder { private static final String DEFAULT_AMORTIZATION = WorkingCapitalAmortizationType.EIR.name(); private static final Integer DEFAULT_NPV_DAY_COUNT = 360; private static final BigDecimal DEFAULT_PRINCIPAL_AMOUNT = BigDecimal.valueOf(10000); - private static final BigDecimal DEFAULT_PERIOD_PAYMENT_RATE = BigDecimal.valueOf(1.0); + public static final BigDecimal DEFAULT_PERIOD_PAYMENT_RATE_PERCENT = BigDecimal.valueOf(18); + public static final BigDecimal DEFAULT_MIN_PERIOD_PAYMENT_RATE_PERCENT = BigDecimal.valueOf(5); + public static final BigDecimal DEFAULT_MAX_PERIOD_PAYMENT_RATE_PERCENT = BigDecimal.valueOf(25); private static final Integer DEFAULT_PERIOD_PAYMENT_FREQUENCY = 30; private static final String DEFAULT_PERIOD_PAYMENT_FREQUENCY_TYPE = WorkingCapitalLoanPeriodFrequencyType.DAYS.name(); private static final List DEFAULT_PAYMENT_ALLOCATION_TYPES = List.of("PENALTY", "FEE", "PRINCIPAL"); @@ -66,7 +68,7 @@ public class WorkingCapitalLoanProductTestBuilder { private BigDecimal principalAmountDefault = DEFAULT_PRINCIPAL_AMOUNT; private BigDecimal principalAmountMax; private BigDecimal minPeriodPaymentRate; - private BigDecimal periodPaymentRate = DEFAULT_PERIOD_PAYMENT_RATE; + private BigDecimal periodPaymentRate = DEFAULT_PERIOD_PAYMENT_RATE_PERCENT; private BigDecimal maxPeriodPaymentRate; private BigDecimal discount; private Integer repaymentEvery = DEFAULT_PERIOD_PAYMENT_FREQUENCY;