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 1c8d1ed4c..3d98dafab 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 @@ -967,7 +967,7 @@ public final class ErrorMessageHelper { return "Loan re-aging is not allowed on contract terminated loan."; } - public static String reAgeWrittenOffLoanFailure() { + public static String reAgeClosedLoanFailure() { return "Loan reaging can only be done on active loans"; } } diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanReAgingStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanReAgingStepDef.java index e8920460b..145c8e12a 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanReAgingStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanReAgingStepDef.java @@ -27,17 +27,13 @@ import io.cucumber.datatable.DataTable; import io.cucumber.java.en.Then; import io.cucumber.java.en.When; import java.io.IOException; -import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.RoundingMode; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -72,125 +68,19 @@ public class LoanReAgingStepDef extends AbstractStepDef { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); long loanId = loanResponse.getLoanId(); - List> tableRows = table.asLists(); - List headers = tableRows.get(0); - List values = tableRows.get(1); + PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgeingRequestProperties(// + LoanRequestFactory.defaultReAgingRequest(), // + table.row(0), // + table.row(1) // + ); - Map rowData = new LinkedHashMap<>(); - int columnCount = Math.min(headers.size(), values.size()); - for (int i = 0; i < columnCount; i++) { - rowData.put(headers.get(i), values.get(i)); - } - - int frequencyNumber = Integer.parseInt(resolveValue(rowData, values, 0, "frequencyNumber")); - String frequencyType = resolveValue(rowData, values, 1, "frequencyType"); - String startDate = resolveValue(rowData, values, 2, "startDate"); - int numberOfInstallments = Integer.parseInt(resolveValue(rowData, values, 3, "numberOfInstallments")); - - PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory// - .defaultReAgingRequest()// - .frequencyNumber(frequencyNumber)// - .frequencyType(frequencyType)// - .startDate(startDate)// - .numberOfInstallments(numberOfInstallments);// - - applyAdditionalFields(reAgingRequest, rowData, Set.of("frequencyNumber", "frequencyType", "startDate", "numberOfInstallments")); - - PostLoansLoanIdTransactionsResponse response = ok(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, - reAgingRequest, Map.of("command", "reAge"))); + PostLoansLoanIdTransactionsResponse response = ok( + () -> fineractClient.loanTransactions().executeLoanTransaction(loanId, reAgingRequest, Map.of("command", "reAge"))); testContext().set(TestContextKey.LOAN_REAGING_RESPONSE, response); } - private void applyAdditionalFields(PostLoansLoanIdTransactionsRequest request, Map rowData, Set excludedKeys) { - rowData.forEach((key, value) -> { - if (!excludedKeys.contains(key)) { - setRequestField(request, key, value); - } - }); - } - - private void setRequestField(PostLoansLoanIdTransactionsRequest request, String fieldName, String rawValue) { - if (fieldName == null || fieldName.isBlank()) { - return; - } - - try { - Method targetMethod = Arrays.stream(PostLoansLoanIdTransactionsRequest.class.getMethods()) - .filter(method -> method.getParameterCount() == 1 && method.getName().equals(fieldName)).findFirst().orElse(null); - - if (targetMethod == null) { - log.warn("No setter method found on PostLoansLoanIdTransactionsRequest for field {}", fieldName); - return; - } - - Class parameterType = targetMethod.getParameterTypes()[0]; - Object convertedValue = convertValue(rawValue, parameterType); - - if (convertedValue == null && parameterType.isPrimitive()) { - log.warn("Cannot assign null to primitive field {} on PostLoansLoanIdTransactionsRequest", fieldName); - return; - } - - targetMethod.invoke(request, convertedValue); - } catch (Exception ex) { - log.warn("Failed to set additional field {} on PostLoansLoanIdTransactionsRequest", fieldName, ex); - } - } - - private Object convertValue(String rawValue, Class targetType) { - if (rawValue == null || rawValue.isBlank()) { - return null; - } - - try { - if (String.class.equals(targetType)) { - return rawValue; - } - if (Integer.class.equals(targetType) || int.class.equals(targetType)) { - return Integer.valueOf(rawValue); - } - if (Long.class.equals(targetType) || long.class.equals(targetType)) { - return Long.valueOf(rawValue); - } - if (Double.class.equals(targetType) || double.class.equals(targetType)) { - return Double.valueOf(rawValue); - } - if (Float.class.equals(targetType) || float.class.equals(targetType)) { - return Float.valueOf(rawValue); - } - if (Short.class.equals(targetType) || short.class.equals(targetType)) { - return Short.valueOf(rawValue); - } - if (Byte.class.equals(targetType) || byte.class.equals(targetType)) { - return Byte.valueOf(rawValue); - } - if (Boolean.class.equals(targetType) || boolean.class.equals(targetType)) { - return Boolean.parseBoolean(rawValue); - } - if (BigDecimal.class.equals(targetType)) { - return new BigDecimal(rawValue); - } - } catch (NumberFormatException ex) { - log.warn("Unable to convert value '{}' to type {}. Falling back to raw string.", rawValue, targetType.getSimpleName(), ex); - return rawValue; - } - - return rawValue; - } - - private String resolveValue(Map rowData, List values, int index, String key) { - String value = rowData.get(key); - if (value != null) { - return value; - } - if (index >= 0 && index < values.size()) { - return values.get(index); - } - return null; - } - @When("Admin creates a Loan re-aging transaction by Loan external ID with the following data:") - public void createReAgingTransactionByLoanExternalId(DataTable table) throws IOException { + public void createReAgingTransactionByLoanExternalId(DataTable table) { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); String loanExternalId = loanResponse.getResourceExternalId(); @@ -201,17 +91,17 @@ public class LoanReAgingStepDef extends AbstractStepDef { ); PostLoansLoanIdTransactionsResponse response = ok(() -> fineractClient.loanTransactions().executeLoanTransaction1(loanExternalId, - reAgingRequest, Map.of("command", "reAge"))); + reAgingRequest, Map.of("command", "reAge"))); testContext().set(TestContextKey.LOAN_REAGING_RESPONSE, response); } @When("Admin successfully undo Loan re-aging transaction") - public void undoReAgingTransaction() throws IOException { + public void undoReAgingTransaction() { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); long loanId = loanResponse.getLoanId(); PostLoansLoanIdTransactionsResponse response = ok(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, - new PostLoansLoanIdTransactionsRequest(), Map.of("command", "undoReAge"))); + new PostLoansLoanIdTransactionsRequest(), Map.of("command", "undoReAge"))); testContext().set(TestContextKey.LOAN_REAGING_UNDO_RESPONSE, response); } @@ -224,28 +114,10 @@ public class LoanReAgingStepDef extends AbstractStepDef { } @When("Admin fails to create a Loan re-aging transaction with status code {int} error {string} and with the following data:") - public void adminFailsToCreateReAgingTransactionWithError(final int statusCode, final String expectedError, final DataTable table) - throws IOException { - final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); - final long loanId = loanResponse.getLoanId(); - - final List data = table.asLists().get(1); - final int frequencyNumber = Integer.parseInt(data.get(0)); - final String frequencyType = data.get(1); - final String startDate = data.get(2); - final int numberOfInstallments = Integer.parseInt(data.get(3)); - - final PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory// - .defaultReAgingRequest()// - .frequencyNumber(frequencyNumber)// - .frequencyType(frequencyType)// - .startDate(startDate)// - .numberOfInstallments(numberOfInstallments);// - - CallFailedRuntimeException exception = fail(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, reAgingRequest, - Map.of("command", "reAge"))); - + public void adminFailsToCreateReAgingTransactionWithError(final int statusCode, final String expectedError, final DataTable table) { + CallFailedRuntimeException exception = getCreateLoanReAgeFailureResponse(table); assertThat(exception.getStatus()).isEqualTo(statusCode); + String developerMessage = exception.getDeveloperMessage(); if (developerMessage.contains(expectedError)) { assertThat(developerMessage).contains(expectedError); @@ -256,81 +128,18 @@ public class LoanReAgingStepDef extends AbstractStepDef { } @Then("Admin fails to create a Loan re-aging transaction with the following data because loan was charged-off:") - public void reAgeChargedOffLoanFailure(final DataTable table) throws IOException { - final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); - Assertions.assertNotNull(loanResponse); - final long loanId = loanResponse.getLoanId(); + public void reAgeChargedOffLoanFailure(final DataTable table) { + checkCreateLoanReAgeFailure(table, ErrorMessageHelper.reAgeChargedOffLoanFailure()); + } - final List data = table.asLists().get(1); - - final PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory// - .defaultReAgingRequest()// - .frequencyNumber(Integer.parseInt(data.get(0)))// - .frequencyType(data.get(1))// - .startDate(data.get(2))// - .numberOfInstallments(Integer.parseInt(data.get(3)));// - - CallFailedRuntimeException exception = fail(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, reAgingRequest, - Map.of("command", "reAge"))); - assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); - assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.reAgeChargedOffLoanFailure()); + @Then("Admin fails to create a Loan re-aging transaction with the following data because loan was closed:") + public void reAgeClosedLoanFailure(final DataTable table) { + checkCreateLoanReAgeFailure(table, ErrorMessageHelper.reAgeClosedLoanFailure()); } @Then("Admin fails to create a Loan re-aging transaction with the following data because loan was contract terminated:") - public void reAgeContractTerminatedLoanFailure(final DataTable table) throws IOException { - final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); - Assertions.assertNotNull(loanResponse); - final long loanId = loanResponse.getLoanId(); - - final List data = table.asLists().get(1); - - final PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory// - .defaultReAgingRequest()// - .frequencyNumber(Integer.parseInt(data.get(0)))// - .frequencyType(data.get(1))// - .startDate(data.get(2))// - .numberOfInstallments(Integer.parseInt(data.get(3)));// - - CallFailedRuntimeException exception = fail(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, reAgingRequest, - Map.of("command", "reAge"))); - assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); - assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.reAgeContractTerminatedLoanFailure()); - } - - @Then("Admin fails to create a Loan re-aging transaction with the following data because loan was written-off:") - public void reAgeWrittenOffLoanFailure(final DataTable table) throws IOException { - final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); - Assertions.assertNotNull(loanResponse); - final long loanId = loanResponse.getLoanId(); - - List> tableRows = table.asLists(); - List headers = tableRows.get(0); - List values = tableRows.get(1); - - Map rowData = new LinkedHashMap<>(); - int columnCount = Math.min(headers.size(), values.size()); - for (int i = 0; i < columnCount; i++) { - rowData.put(headers.get(i), values.get(i)); - } - - int frequencyNumber = Integer.parseInt(resolveValue(rowData, values, 0, "frequencyNumber")); - String frequencyType = resolveValue(rowData, values, 1, "frequencyType"); - String startDate = resolveValue(rowData, values, 2, "startDate"); - int numberOfInstallments = Integer.parseInt(resolveValue(rowData, values, 3, "numberOfInstallments")); - - final PostLoansLoanIdTransactionsRequest reAgingRequest = LoanRequestFactory// - .defaultReAgingRequest()// - .frequencyNumber(frequencyNumber)// - .frequencyType(frequencyType)// - .startDate(startDate)// - .numberOfInstallments(numberOfInstallments);// - - applyAdditionalFields(reAgingRequest, rowData, Set.of("frequencyNumber", "frequencyType", "startDate", "numberOfInstallments")); - - CallFailedRuntimeException exception = fail(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, reAgingRequest, - Map.of("command", "reAge"))); - assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); - assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.reAgeWrittenOffLoanFailure()); + public void reAgeContractTerminatedLoanFailure(final DataTable table) { + checkCreateLoanReAgeFailure(table, ErrorMessageHelper.reAgeContractTerminatedLoanFailure()); } private Map resolveReAgingQueryParams(DataTable table) { @@ -344,7 +153,7 @@ public class LoanReAgingStepDef extends AbstractStepDef { } @When("Admin creates a Loan re-aging preview with the following data:") - public void createReAgingPreview(DataTable table) throws IOException { + public void createReAgingPreview(DataTable table) { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); long loanId = loanResponse.getLoanId(); @@ -355,7 +164,7 @@ public class LoanReAgingStepDef extends AbstractStepDef { log.info("Re-aging preview created for loan ID: {} with parameters: {}", loanId, queryParams); } - public LoanScheduleData reAgingPreviewByLoanExternalId(DataTable table) throws IOException { + public LoanScheduleData reAgingPreviewByLoanExternalId(DataTable table) { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); String loanExternalId = loanResponse.getResourceExternalId(); @@ -366,7 +175,7 @@ public class LoanReAgingStepDef extends AbstractStepDef { } @When("Admin creates a Loan re-aging preview by Loan external ID with the following data:") - public void createReAgingPreviewByLoanExternalId(DataTable table) throws IOException { + public void createReAgingPreviewByLoanExternalId(DataTable table) { LoanScheduleData response = reAgingPreviewByLoanExternalId(table); testContext().set(TestContextKey.LOAN_REAGING_PREVIEW_RESPONSE, response); @@ -374,18 +183,11 @@ public class LoanReAgingStepDef extends AbstractStepDef { } @Then("Admin fails to create a Loan re-aging preview with the following data because loan was charged-off:") - public void reAgePreviewChargedOffLoanFailure(final DataTable table) throws IOException { + public void reAgePreviewChargedOffLoanFailure(final DataTable table) { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); String loanExternalId = loanResponse.getResourceExternalId(); - List data = table.asLists().get(1); - int frequencyNumber = Integer.parseInt(data.get(0)); - String frequencyType = data.get(1); - String startDate = data.get(2); - int numberOfInstallments = Integer.parseInt(data.get(3)); - - Map queryParams = Map.of("frequencyNumber", frequencyNumber, "frequencyType", frequencyType, "startDate", startDate, - "numberOfInstallments", numberOfInstallments, "dateFormat", DATE_FORMAT, "locale", "en"); + Map queryParams = resolveReAgingQueryParams(table); CallFailedRuntimeException exception = fail( () -> fineractClient.loanTransactions().previewReAgeSchedule1(loanExternalId, queryParams)); @@ -394,18 +196,12 @@ public class LoanReAgingStepDef extends AbstractStepDef { } @Then("Admin fails to create a Loan re-aging preview with the following data because loan was contract terminated:") - public void reAgePreviewContractTerminatedLoanFailure(final DataTable table) throws IOException { + public void reAgePreviewContractTerminatedLoanFailure(final DataTable table) { PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); String loanExternalId = loanResponse.getResourceExternalId(); - List data = table.asLists().get(1); - int frequencyNumber = Integer.parseInt(data.get(0)); - String frequencyType = data.get(1); - String startDate = data.get(2); - int numberOfInstallments = Integer.parseInt(data.get(3)); + Map queryParams = resolveReAgingQueryParams(table); - Map queryParams = Map.of("frequencyNumber", frequencyNumber, "frequencyType", frequencyType, "startDate", startDate, - "numberOfInstallments", numberOfInstallments, "dateFormat", DATE_FORMAT, "locale", "en"); CallFailedRuntimeException exception = fail( () -> fineractClient.loanTransactions().previewReAgeSchedule1(loanExternalId, queryParams)); @@ -413,6 +209,19 @@ public class LoanReAgingStepDef extends AbstractStepDef { assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.reAgeContractTerminatedLoanFailure()); } + @Then("Admin fails to create a Loan re-aging preview with the following data because loan was closed:") + public void reAgePreviewClosedLoanFailure(final DataTable table) throws IOException { + PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); + String loanExternalId = loanResponse.getResourceExternalId(); + + Map queryParams = resolveReAgingQueryParams(table); + CallFailedRuntimeException exception = fail( + () -> fineractClient.loanTransactions().previewReAgeSchedule1(loanExternalId, queryParams)); + + assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); + assertThat(exception.getDeveloperMessage()).contains(ErrorMessageHelper.reAgeClosedLoanFailure()); + } + @Then("Loan Re-Aged Repayment schedule preview has {int} periods, with the following data for periods:") public void loanRepaymentSchedulePreviewPeriodsCheck(int linesExpected, DataTable table) { LoanScheduleData scheduleResponse = testContext().get(TestContextKey.LOAN_REAGING_PREVIEW_RESPONSE); @@ -581,7 +390,28 @@ public class LoanReAgingStepDef extends AbstractStepDef { ); CallFailedRuntimeException response = fail(() -> fineractClient.loanTransactions().executeLoanTransaction1(loanExternalId, - reAgingRequest, Map.of("command", "reAge"))); + reAgingRequest, Map.of("command", "reAge"))); assertThat(response.getStatus()).isEqualTo(errorCode); } + + public CallFailedRuntimeException getCreateLoanReAgeFailureResponse(DataTable table) { + final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); + Assertions.assertNotNull(loanResponse); + final long loanId = loanResponse.getLoanId(); + + PostLoansLoanIdTransactionsRequest reAgingRequest = setReAgeingRequestProperties(// + LoanRequestFactory.defaultReAgingRequest(), // + table.row(0), // + table.row(1) // + ); + + return fail(() -> fineractClient.loanTransactions().executeLoanTransaction(loanId, reAgingRequest, Map.of("command", "reAge"))); + } + + public void checkCreateLoanReAgeFailure(DataTable table, String errorMessage) { + CallFailedRuntimeException exception = getCreateLoanReAgeFailureResponse(table); + assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(403); + assertThat(exception.getDeveloperMessage()).contains(errorMessage); + } + } diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanReAging.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanReAging.feature index 46fddbfe8..f24b08ffa 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanReAging.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanReAging.feature @@ -10576,118 +10576,7 @@ Then Loan Repayment schedule has 4 periods, with the following data for periods: | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | | 01 March 2024 | Close (as written-off) | 85.04 | 83.57 | 1.47 | 0.0 | 0.0 | 0.0 | false | false | When Admin sets the business date to "15 March 2024" - Then Admin fails to create a Loan re-aging transaction with the following data because loan was written-off: + Then Admin fails to create a Loan re-aging transaction with the following data because loan was closed: | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | | 1 | MONTHS | 01 April 2024 | 6 | DEFAULT | - @TestRailId:C4387 @AdvancedPaymentAllocation - Scenario: Verify that Re-aging with EQUAL_AMORTIZATION_FULL_INTEREST interest handling is forbidden on written-off loan - When Admin sets the business date to "01 January 2024" - When Admin creates a client with random data - When Admin set "LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule - When Admin creates a fully customized loan with the following data: - | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | - | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | - And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024" - When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount - Then Loan Repayment schedule has 6 periods, with the following data for periods: - | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | - Then Loan Repayment schedule has the following data in Total row: - | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 | - Then Loan Transactions tab has the following data: - | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | - | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | - When Admin sets the business date to "01 February 2024" - And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount - Then Loan Repayment schedule has 6 periods, with the following data for periods: - | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | - | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | - Then Loan Repayment schedule has the following data in Total row: - | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 | - Then Loan Transactions tab has the following data: - | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | - | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | - | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | - When Admin sets the business date to "01 March 2024" - And Admin does write-off the loan on "01 March 2024" - Then Loan status will be "CLOSED_WRITTEN_OFF" - Then Loan Transactions tab has the following data: - | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | - | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | - | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | - | 01 March 2024 | Close (as written-off) | 85.04 | 83.57 | 1.47 | 0.0 | 0.0 | 0.0 | false | false | - When Admin sets the business date to "15 March 2024" - Then Admin fails to create a Loan re-aging transaction with the following data because loan was written-off: - | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | - | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_FULL_INTEREST | - - @TestRailId:C4388 @AdvancedPaymentAllocation - Scenario: Verify that Re-aging with EQUAL_AMORTIZATION_PAYABLE_INTEREST interest handling is forbidden on written-off loan - When Admin sets the business date to "01 January 2024" - When Admin creates a client with random data - When Admin set "LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule - When Admin creates a fully customized loan with the following data: - | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | - | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | - And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024" - When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount - Then Loan Repayment schedule has 6 periods, with the following data for periods: - | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | - Then Loan Repayment schedule has the following data in Total row: - | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 | - Then Loan Transactions tab has the following data: - | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | - | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | - When Admin sets the business date to "01 February 2024" - And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount - Then Loan Repayment schedule has 6 periods, with the following data for periods: - | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | - | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | - | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | - Then Loan Repayment schedule has the following data in Total row: - | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | - | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 | - Then Loan Transactions tab has the following data: - | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | - | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | - | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | - When Admin sets the business date to "01 March 2024" - And Admin does write-off the loan on "01 March 2024" - Then Loan status will be "CLOSED_WRITTEN_OFF" - Then Loan Transactions tab has the following data: - | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | - | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | - | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | - | 01 March 2024 | Close (as written-off) | 85.04 | 83.57 | 1.47 | 0.0 | 0.0 | 0.0 | false | false | - When Admin sets the business date to "15 March 2024" - Then Admin fails to create a Loan re-aging transaction with the following data because loan was written-off: - | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | - | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_PAYABLE_INTEREST | diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanReAgingEqualAmortization.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanReAgingEqualAmortization.feature index 78a276f93..71427d4ac 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanReAgingEqualAmortization.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanReAgingEqualAmortization.feature @@ -505,18 +505,19 @@ Feature: LoanReAgingEqualAmortization When Admin creates a Loan re-aging transaction by Loan external ID with the following data: | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_PAYABLE_INTEREST | - Then Loan Repayment schedule has 8 periods, with the following data for periods: + Then Loan Repayment schedule has 9 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | | 2 | 29 | 01 March 2024 | 15 March 2024 | 83.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | | | | 01 March 2024 | | 50.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 3 | 31 | 01 April 2024 | | 111.31 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 4 | 30 | 01 May 2024 | | 89.05 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 5 | 31 | 01 June 2024 | | 66.79 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 6 | 30 | 01 July 2024 | | 44.53 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 7 | 31 | 01 August 2024 | | 22.27 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 8 | 31 | 01 September 2024 | | 0.0 | 22.27 | 0.14 | 0.0 | 0.0 | 22.41 | 0.0 | 0.0 | 0.0 | 22.41 | + | 3 | 14 | 15 March 2024 | 15 March 2024 | 133.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + | 4 | 17 | 01 April 2024 | | 111.31 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 5 | 30 | 01 May 2024 | | 89.05 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 6 | 31 | 01 June 2024 | | 66.79 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 7 | 30 | 01 July 2024 | | 44.53 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 8 | 31 | 01 August 2024 | | 22.27 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 9 | 31 | 01 September 2024 | | 0.0 | 22.27 | 0.14 | 0.0 | 0.0 | 22.41 | 0.0 | 0.0 | 0.0 | 22.41 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 150.0 | 1.42 | 0.0 | 0.0 | 151.42 | 17.01 | 0.0 | 0.0 | 134.41 | @@ -529,18 +530,19 @@ Feature: LoanReAgingEqualAmortization When Admin sets the business date to "01 April 2024" When Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 17.01 EUR transaction amount - Then Loan Repayment schedule has 8 periods, with the following data for periods: + Then Loan Repayment schedule has 9 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | | 2 | 29 | 01 March 2024 | 15 March 2024 | 83.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | | | | 01 March 2024 | | 50.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 3 | 31 | 01 April 2024 | | 111.31 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 4 | 30 | 01 May 2024 | | 89.05 | 39.27 | 0.14 | 0.0 | 0.0 | 39.41 | 0.0 | 0.0 | 0.0 | 39.41 | - | 5 | 31 | 01 June 2024 | | 66.79 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 6 | 30 | 01 July 2024 | | 44.53 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 7 | 31 | 01 August 2024 | | 22.27 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | - | 8 | 31 | 01 September 2024 | | 0.0 | 22.27 | 0.14 | 0.0 | 0.0 | 22.41 | 0.0 | 0.0 | 0.0 | 22.41 | + | 3 | 14 | 15 March 2024 | 15 March 2024 | 133.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + | 4 | 17 | 01 April 2024 | | 111.31 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 5 | 30 | 01 May 2024 | | 89.05 | 39.27 | 0.14 | 0.0 | 0.0 | 39.41 | 0.0 | 0.0 | 0.0 | 39.41 | + | 6 | 31 | 01 June 2024 | | 66.79 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 7 | 30 | 01 July 2024 | | 44.53 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 8 | 31 | 01 August 2024 | | 22.27 | 22.26 | 0.14 | 0.0 | 0.0 | 22.4 | 0.0 | 0.0 | 0.0 | 22.4 | + | 9 | 31 | 01 September 2024 | | 0.0 | 22.27 | 0.14 | 0.0 | 0.0 | 22.41 | 0.0 | 0.0 | 0.0 | 22.41 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 167.01 | 1.42 | 0.0 | 0.0 | 168.43 | 17.01 | 0.0 | 0.0 | 151.42 | @@ -552,7 +554,7 @@ Feature: LoanReAgingEqualAmortization | 15 March 2024 | Re-age | 134.41 | 133.57 | 0.84 | 0.0 | 0.0 | 0.0 | false | false | | 01 April 2024 | Chargeback | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | 150.58 | false | false | -# --- undo last disbursement should be allowed on thet point --- # +# --- undo last disbursement should be allowed on that point --- # When Admin successfully undo last disbursal Then Loan Repayment schedule has 8 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | @@ -2820,18 +2822,19 @@ Feature: LoanReAgingEqualAmortization When Admin creates a Loan re-aging transaction by Loan external ID with the following data: | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_FULL_INTEREST | - Then Loan Repayment schedule has 8 periods, with the following data for periods: + Then Loan Repayment schedule has 9 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | | 2 | 29 | 01 March 2024 | 15 March 2024 | 83.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | | | | 01 March 2024 | | 50.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 3 | 31 | 01 April 2024 | | 111.3 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 4 | 30 | 01 May 2024 | | 89.03 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 5 | 31 | 01 June 2024 | | 66.76 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 6 | 30 | 01 July 2024 | | 44.49 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 7 | 31 | 01 August 2024 | | 22.22 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 8 | 31 | 01 September 2024 | | 0.0 | 22.22 | 0.39 | 0.0 | 0.0 | 22.61 | 0.0 | 0.0 | 0.0 | 22.61 | + | 3 | 14 | 15 March 2024 | 15 March 2024 | 133.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + | 4 | 17 | 01 April 2024 | | 111.3 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 5 | 30 | 01 May 2024 | | 89.03 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 6 | 31 | 01 June 2024 | | 66.76 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 7 | 30 | 01 July 2024 | | 44.49 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 8 | 31 | 01 August 2024 | | 22.22 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 9 | 31 | 01 September 2024 | | 0.0 | 22.22 | 0.39 | 0.0 | 0.0 | 22.61 | 0.0 | 0.0 | 0.0 | 22.61 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 150.0 | 2.82 | 0.0 | 0.0 | 152.82 | 17.01 | 0.0 | 0.0 | 135.81 | @@ -2844,18 +2847,19 @@ Feature: LoanReAgingEqualAmortization When Admin sets the business date to "01 April 2024" When Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 17.01 EUR transaction amount - Then Loan Repayment schedule has 8 periods, with the following data for periods: + Then Loan Repayment schedule has 9 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | | 2 | 29 | 01 March 2024 | 15 March 2024 | 83.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | | | | 01 March 2024 | | 50.0 | | | 0.0 | | 0.0 | 0.0 | | | | - | 3 | 31 | 01 April 2024 | | 111.3 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 4 | 30 | 01 May 2024 | | 89.03 | 39.28 | 0.37 | 0.0 | 0.0 | 39.65 | 0.0 | 0.0 | 0.0 | 39.65 | - | 5 | 31 | 01 June 2024 | | 66.76 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 6 | 30 | 01 July 2024 | | 44.49 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 7 | 31 | 01 August 2024 | | 22.22 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | - | 8 | 31 | 01 September 2024 | | 0.0 | 22.22 | 0.39 | 0.0 | 0.0 | 22.61 | 0.0 | 0.0 | 0.0 | 22.61 | + | 3 | 14 | 15 March 2024 | 15 March 2024 | 133.57 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | + | 4 | 17 | 01 April 2024 | | 111.3 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 5 | 30 | 01 May 2024 | | 89.03 | 39.28 | 0.37 | 0.0 | 0.0 | 39.65 | 0.0 | 0.0 | 0.0 | 39.65 | + | 6 | 31 | 01 June 2024 | | 66.76 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 7 | 30 | 01 July 2024 | | 44.49 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 8 | 31 | 01 August 2024 | | 22.22 | 22.27 | 0.37 | 0.0 | 0.0 | 22.64 | 0.0 | 0.0 | 0.0 | 22.64 | + | 9 | 31 | 01 September 2024 | | 0.0 | 22.22 | 0.39 | 0.0 | 0.0 | 22.61 | 0.0 | 0.0 | 0.0 | 22.61 | Then Loan Repayment schedule has the following data in Total row: | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | | 167.01 | 2.82 | 0.0 | 0.0 | 169.83 | 17.01 | 0.0 | 0.0 | 152.82 | @@ -2867,7 +2871,7 @@ Feature: LoanReAgingEqualAmortization | 15 March 2024 | Re-age | 135.81 | 133.57 | 2.24 | 0.0 | 0.0 | 0.0 | false | false | | 01 April 2024 | Chargeback | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | 150.58 | false | false | -# --- undo last disbursement should be allowed on thet point --- # +# --- undo last disbursement should be allowed on that point --- # When Admin successfully undo last disbursal Then Loan Repayment schedule has 8 periods, with the following data for periods: | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | @@ -5245,6 +5249,150 @@ Feature: LoanReAgingEqualAmortization When Loan Pay-off is made on "15 March 2024" Then Loan is closed with zero outstanding balance and it's all installments have obligations met + @TestRailId:C4387 @AdvancedPaymentAllocation + Scenario: Verify that Re-aging with equal amortization + outstanding full interest handling is forbidden on written-off loan + When Admin sets the business date to "01 January 2024" + When Admin creates a client with random data + When Admin set "LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule + When Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024" + When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount + Then Loan Repayment schedule has 6 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | + | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | + When Admin sets the business date to "01 February 2024" + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount + Then Loan Repayment schedule has 6 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | + | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | + | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | + When Admin sets the business date to "01 March 2024" + And Admin does write-off the loan on "01 March 2024" + Then Loan status will be "CLOSED_WRITTEN_OFF" + Then Loan Repayment schedule has 6 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 3 | 31 | 01 April 2024 | 01 March 2024 | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 4 | 30 | 01 May 2024 | 01 March 2024 | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 5 | 31 | 01 June 2024 | 01 March 2024 | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 6 | 30 | 01 July 2024 | 01 March 2024 | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 0.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | + | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | + | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | + | 01 March 2024 | Close (as written-off) | 85.04 | 83.57 | 1.47 | 0.0 | 0.0 | 0.0 | false | false | + When Admin sets the business date to "15 March 2024" + Then Admin fails to create a Loan re-aging transaction with the following data because loan was closed: + | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | + | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_FULL_INTEREST | + + Then Admin fails to create a Loan re-aging preview with the following data because loan was closed: + | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | + | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_FULL_INTEREST | + + @TestRailId:C4388 @AdvancedPaymentAllocation + Scenario: Verify that Re-aging with equal amortization + outstanding payable interest handling is forbidden on written-off loan + When Admin sets the business date to "01 January 2024" + When Admin creates a client with random data + When Admin set "LP2_ADV_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule + When Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024" + When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount + Then Loan Repayment schedule has 6 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 01 February 2024 | | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | + | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | + When Admin sets the business date to "01 February 2024" + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount + Then Loan Repayment schedule has 6 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 3 | 31 | 01 April 2024 | | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 4 | 30 | 01 May 2024 | | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 5 | 31 | 01 June 2024 | | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | + | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | + | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | + When Admin sets the business date to "01 March 2024" + And Admin does write-off the loan on "01 March 2024" + Then Loan status will be "CLOSED_WRITTEN_OFF" + Then Loan Repayment schedule has 6 periods, with the following data for periods: + | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | + | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.57 | 16.43 | 0.58 | 0.0 | 0.0 | 17.01 | 17.01 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | 01 March 2024 | 67.05 | 16.52 | 0.49 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 3 | 31 | 01 April 2024 | 01 March 2024 | 50.43 | 16.62 | 0.39 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 4 | 30 | 01 May 2024 | 01 March 2024 | 33.71 | 16.72 | 0.29 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 5 | 31 | 01 June 2024 | 01 March 2024 | 16.9 | 16.81 | 0.2 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | + | 6 | 30 | 01 July 2024 | 01 March 2024 | 0.0 | 16.9 | 0.1 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 0.0 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 0.0 | + Then Loan Transactions tab has the following data: + | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed | + | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | + | 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false | + | 01 March 2024 | Close (as written-off) | 85.04 | 83.57 | 1.47 | 0.0 | 0.0 | 0.0 | false | false | + When Admin sets the business date to "15 March 2024" + Then Admin fails to create a Loan re-aging transaction with the following data because loan was closed: + | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | + | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_PAYABLE_INTEREST | + + Then Admin fails to create a Loan re-aging preview with the following data because loan was closed: + | frequencyNumber | frequencyType | startDate | numberOfInstallments | reAgeInterestHandling | + | 1 | MONTHS | 01 April 2024 | 6 | EQUAL_AMORTIZATION_PAYABLE_INTEREST | + @TestRailId:C4237 @AdvancedPaymentAllocation Scenario: Verify Re-aging with Equal amortization payable interest - Fees and Interest Split after re-aging - UC12 When Admin sets the business date to "01 January 2024" @@ -6427,7 +6575,7 @@ Feature: LoanReAgingEqualAmortization | 15 March 2024 | Re-age | 134.41 | 133.57 | 0.84 | 0.0 | 0.0 | 0.0 | false | true | # --- undo last disbursement --- # - # When Admin successfully undo last disbursal + # When Admin successfully undo last disbursal # Then Loan Repayment schedule has 8 periods, with the following data for periods: # | Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | # | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |