diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/LoanRescheduleErrorMessage.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/LoanRescheduleErrorMessage.java index f14725ce58b..67da5f51258 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/LoanRescheduleErrorMessage.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/data/LoanRescheduleErrorMessage.java @@ -22,6 +22,8 @@ public enum LoanRescheduleErrorMessage { LOAN_CHARGED_OFF("Loan: %s reschedule installment is not allowed. Loan Account is Charged-off"), // LOAN_RESCHEDULE_DATE_NOT_IN_FUTURE("Loan Reschedule From date (%s) for Loan: %s should be in the future."), // + LOAN_RESCHEDULE_FROM_DATE_INSTALLMENT_NOT_FOUND( + "Validation errors: [rescheduleFromDate] Failed data validation due to: repayment.schedule.installment.does.not.exist."), // LOAN_LOCKED_BY_COB("Loan is locked by the COB job. Loan ID: %s"), // LOAN_RESCHEDULE_NOT_ALLOWED_FROM_ZERO_TO_NEW_INTEREST_RATE("Failed data validation due to: newInterestRate."), // LOAN_RESCHEDULE_NOT_ALLOWED_FROM_CURRENT_INTEREST_RATE_TO_ZERO("The parameter `newInterestRate` must be greater than 0."), // diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanReschedule.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanReschedule.feature index eb8a5e45fa6..2428579648f 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanReschedule.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanReschedule.feature @@ -1172,6 +1172,7 @@ Feature: LoanReschedule And Customer makes "AUTOPAY" repayment on "29 June 2025" with 60 EUR transaction amount Then In Loan Transactions the "1"th Transaction of "Accrual Activity" on "31 October 2025" has "1" relationship with type="REPLAYED" + @TestRailId:C4391 Scenario: Verify progressive loan due date reschedule maintains EMI When Admin sets the business date to "05 September 2025" And Admin creates a client with random data @@ -1264,6 +1265,7 @@ Feature: LoanReschedule | 23 | 31 | 31 January 2027 | | 96.08 | 56.03 | 3.23 | 0.0 | 0.0 | 59.26 | 0.0 | 0.0 | 0.0 | 59.26 | | 24 | 28 | 28 February 2027 | | 0.0 | 96.08 | 1.84 | 0.0 | 0.0 | 97.92 | 0.0 | 0.0 | 0.0 | 97.92 | + @TestRailId:C4392 Scenario: Verify basic loan rescheduling When Admin sets the business date to "1 January 2024" When Admin creates a client with random data @@ -1319,6 +1321,7 @@ Feature: LoanReschedule | 5 | 31 | 15 June 2024 | | 17.3 | 16.86 | 0.27 | 0.0 | 0.0 | 17.13 | 0.0 | 0.0 | 0.0 | 17.13 | | 6 | 30 | 15 July 2024 | | 0.0 | 17.3 | 0.14 | 0.0 | 0.0 | 17.44 | 0.0 | 0.0 | 0.0 | 17.44 | + @TestRailId:C4393 Scenario: Verify loan rescheduling with N+1 period When Admin sets the business date to "1 January 2024" When Admin creates a client with random data @@ -1377,6 +1380,7 @@ Feature: LoanReschedule | 5 | 31 | 30 June 2024 | | 17.63 | 16.86 | 0.27 | 0.0 | 0.0 | 17.13 | 0.0 | 0.0 | 0.0 | 17.13 | | 6 | 30 | 30 July 2024 | | 0.0 | 17.63 | 0.14 | 10.0 | 0.0 | 27.77 | 0.0 | 0.0 | 0.0 | 27.77 | + @TestRailId:C4394 Scenario: Verify loan rescheduling with automatic down payment When Admin sets the business date to "1 January 2024" When Admin creates a client with random data @@ -1432,4 +1436,27 @@ Feature: LoanReschedule | 3 | 43 | 15 March 2024 | | 45.56 | 14.67 | 0.69 | 0.0 | 0.0 | 15.36 | 0.0 | 0.0 | 0.0 | 15.36 | | 4 | 31 | 15 April 2024 | | 30.56 | 15.0 | 0.36 | 0.0 | 0.0 | 15.36 | 0.0 | 0.0 | 0.0 | 15.36 | | 5 | 30 | 15 May 2024 | | 15.44 | 15.12 | 0.24 | 0.0 | 0.0 | 15.36 | 0.0 | 0.0 | 0.0 | 15.36 | - | 6 | 31 | 15 June 2024 | | 0.0 | 15.44 | 0.12 | 0.0 | 0.0 | 15.56 | 0.0 | 0.0 | 0.0 | 15.56 | \ No newline at end of file + | 6 | 31 | 15 June 2024 | | 0.0 | 15.44 | 0.12 | 0.0 | 0.0 | 15.56 | 0.0 | 0.0 | 0.0 | 15.56 | + + @TestRailId:C4395 + Scenario: Verify Progressive Loan reschedule with non-existing installment due date results in validation error + When Admin sets the business date to "01 January 2024" + When Admin creates a client with random data + 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_CUSTOM_PMT_ALLOC_PROGRESSIVE_LOAN_SCHEDULE_HORIZONTAL | 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" + And 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 | + When Admin sets the business date to "02 April 2024" + Then Loan reschedule with the following data results a 400 error and "LOAN_RESCHEDULE_FROM_DATE_INSTALLMENT_NOT_FOUND" error message + | rescheduleFromDate | submittedOnDate | adjustedDueDate | graceOnPrincipal | graceOnInterest | extraTerms | newInterestRate | + | 01 August 2024 | 02 April 2024 | | | | 2 | | \ No newline at end of file diff --git a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java index 33c5d216c03..20f14807e17 100644 --- a/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java +++ b/fineract-progressive-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/rescheduleloan/data/ProgressiveLoanRescheduleRequestDataValidator.java @@ -94,7 +94,7 @@ public void validateForCreateAction(JsonCommand jsonCommand, Loan loan) { } if (hasExtraTermsChange) { - validateExtraTerms(dataValidatorBuilder, loan); + validateExtraTerms(dataValidatorBuilder, loan, rescheduleFromDate); } else if (hasAdjustDueDateChange) { validateAdjustDueDateChange(dataValidatorBuilder, loan, rescheduleFromDate); } else if (hasInterestRateChange) { @@ -124,8 +124,10 @@ private void validateInterestRate(DataValidatorBuilder dataValidatorBuilder, Loa validateForOverdueCharges(dataValidatorBuilder, loan, installment); } - private void validateExtraTerms(DataValidatorBuilder dataValidatorBuilder, Loan loan) { + private void validateExtraTerms(DataValidatorBuilder dataValidatorBuilder, Loan loan, LocalDate rescheduleFromDate) { validateLoanIsActive(loan, dataValidatorBuilder); + final LoanRepaymentScheduleInstallment installment = loan.getRelatedRepaymentScheduleInstallment(rescheduleFromDate); + validateReschedulingInstallment(dataValidatorBuilder, installment); } private Integer validateExtraTermsParam(FromJsonHelper fromJsonHelper, JsonElement jsonElement,