diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanChargeStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanChargeStepDef.java index 8acfc8dbd..35c254762 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanChargeStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanChargeStepDef.java @@ -101,6 +101,7 @@ public class LoanChargeStepDef extends AbstractStepDef { .execute(); ErrorHelper.checkSuccessfulApiCall(loanChargeResponse); testContext().set(TestContextKey.ADD_DUE_DATE_CHARGE_RESPONSE, loanChargeResponse); + testContext().set(TestContextKey.ADD_NSF_FEE_RESPONSE, loanChargeResponse); addChargeEventCheck(loanChargeResponse); } diff --git a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java index 5a0f8bbb8..6e3177472 100644 --- a/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java +++ b/fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java @@ -24,6 +24,7 @@ import static org.apache.fineract.test.data.loanproduct.DefaultLoanProduct.LP2_A import static org.apache.fineract.test.data.loanproduct.DefaultLoanProduct.LP2_ADV_PYMNT_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR; import static org.assertj.core.api.Assertions.assertThat; import static org.awaitility.Awaitility.await; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -1404,6 +1405,24 @@ public class LoanStepDef extends AbstractStepDef { .isEqualTo(loanId).extractingData(LoanTransactionDataV1::getId).isEqualTo(chargeOffResponse.body().getResourceId()); } + @And("Admin tries to charge-off the loan on {string} but fails due to monetary activity after the charge-off date") + public void chargeOffLoanWithError(final String transactionDate) throws IOException { + final Response loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); + final long loanId = loanResponse.body().getLoanId(); + + final PostLoansLoanIdTransactionsRequest chargeOffRequest = LoanRequestFactory.defaultChargeOffRequest() + .transactionDate(transactionDate).dateFormat(DATE_FORMAT).locale(DEFAULT_LOCALE); + + final Response chargeOffResponse = loanTransactionsApi + .executeLoanTransaction(loanId, chargeOffRequest, "charge-off").execute(); + final ErrorResponse errorDetails = ErrorResponse.from(chargeOffResponse); + final String expectedErrorMessage = "Loan: " + loanId + + " charge-off cannot be executed. Loan has monetary activity after the charge-off transaction date!"; + assertThat(errorDetails.getSingleError().getDeveloperMessage()).isEqualTo(expectedErrorMessage); + + assertFalse(chargeOffResponse.isSuccessful()); + } + @Then("Charge-off attempt on {string} results an error") public void chargeOffOnLoanWithInterestFails(String transactionDate) throws IOException { Response loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE); diff --git a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature index d37ab0156..e9cc3cb4e 100644 --- a/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature +++ b/fineract-e2e-tests-runner/src/test/resources/features/LoanChargeOff.feature @@ -1757,7 +1757,7 @@ Feature: Charge-off | 15 July 2023 | Charge-off | 103.48 | 100.0 | 3.48 | 0.0 | 0.0 | 0.0 | Scenario: Charge-off when charge is added before the charge-off date, loan behaviour is zero-interest and interestRecalculation = true - When Admin sets the business date to "1 March 2023" + When Admin sets the business date to "1 January 2023" And Admin creates a client with random data When Admin creates a new zero charge-off Loan with interest recalculation and date: "1 January 2023" Then Loan Repayment schedule has 6 periods, with the following data for periods: @@ -1775,6 +1775,7 @@ Feature: Charge-off And Admin successfully approves the loan on "1 January 2023" with "100" amount and expected disbursement date on "1 January 2023" And Admin successfully disburse the loan on "1 January 2023" with "100" EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "27 February 2023" due date and 3 EUR transaction amount + When Admin sets the business date to "28 February 2023" And Admin does charge-off the loan on "28 February 2023" 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 | @@ -1794,7 +1795,7 @@ Feature: Charge-off | 28 February 2023 | Charge-off | 104.14 | 100.0 | 1.14 | 3.0 | 0.0 | 0.0 | Scenario: Charge-off when charge is added on charge-off date, loan behaviour is zero-interest and interestRecalculation = true - When Admin sets the business date to "1 March 2023" + When Admin sets the business date to "1 January 2023" And Admin creates a client with random data When Admin creates a new zero charge-off Loan with interest recalculation and date: "1 January 2023" Then Loan Repayment schedule has 6 periods, with the following data for periods: @@ -1812,6 +1813,7 @@ Feature: Charge-off And Admin successfully approves the loan on "1 January 2023" with "100" amount and expected disbursement date on "1 January 2023" And Admin successfully disburse the loan on "1 January 2023" with "100" EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "28 February 2023" due date and 3 EUR transaction amount + When Admin sets the business date to "28 February 2023" And Admin does charge-off the loan on "28 February 2023" 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 | @@ -1831,7 +1833,7 @@ Feature: Charge-off | 28 February 2023 | Charge-off | 104.14 | 100.0 | 1.14 | 3.0 | 0.0 | 0.0 | Scenario: Charge-off when charge is added after the charge off date, loan behaviour is zero-interest and interestRecalculation = true - When Admin sets the business date to "1 March 2023" + When Admin sets the business date to "1 January 2023" And Admin creates a client with random data When Admin creates a new zero charge-off Loan with interest recalculation and date: "1 January 2023" Then Loan Repayment schedule has 6 periods, with the following data for periods: @@ -1849,6 +1851,7 @@ Feature: Charge-off And Admin successfully approves the loan on "1 January 2023" with "100" amount and expected disbursement date on "1 January 2023" And Admin successfully disburse the loan on "1 January 2023" with "100" EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "1 March 2023" due date and 3 EUR transaction amount + When Admin sets the business date to "28 February 2023" And Admin does charge-off the loan on "28 February 2023" 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 | @@ -1865,7 +1868,7 @@ Feature: Charge-off Then Loan Transactions tab has the following data: | Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | | 01 January 2023 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | - | 28 February 2023 | Charge-off | 101.14 | 100.0 | 1.14 | 0.0 | 0.0 | 0.0 | + | 28 February 2023 | Charge-off | 104.14 | 100.0 | 1.14 | 3.0 | 0.0 | 0.0 | Scenario: Undo the charge-off when loan behaviour is zero-interest and interestRecalculation = true When Admin sets the business date to "1 March 2023" @@ -2316,6 +2319,313 @@ Feature: Charge-off | 29 February 2024 | Charge-off | 83.99 | 82.99 | 1.0 | 0.0 | 0.0 | 0.0 | false | false | And Admin set "LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR" loan product "DEFAULT" transaction type to "NEXT_INSTALLMENT" future installment allocation rule + @scenario_9.3_interest_recalculation_enabled_after_3349 + Scenario: Verify error when backdated charge-off happened with charge is added after the charge off date when loan behavior is zero-interest with interestRecalculation + When Admin sets the business date to "1 January 2024" + And Admin creates a client with random data + And Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + 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 | 2.05 | 0 | 0 | 102.05 | 0 | 0 | 0 | 102.05 | + And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024" + And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount + When Admin sets the business date to "1 February 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "01 February 2024" due date and 5 EUR transaction amount + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 22.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 | 5.0 | 0.0 | 22.01 | 22.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 | 2.05 | 5.0 | 0 | 107.05 | 22.01| 0 | 0 | 85.04 | + When Admin sets the business date to "01 March 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 3 EUR transaction amount + And Admin tries to charge-off the loan on "29 February 2024" but fails due to monetary activity after the charge-off date + + @scenario_9.3_interest_recalculation_enabled_after_3349 + Scenario: Charge-off with charge is added after the charge off date when loan behavior is zero-interest with interestRecalculation + When Admin sets the business date to "1 January 2024" + And Admin creates a client with random data + And Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + 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 | 2.05 | 0 | 0 | 102.05 | 0 | 0 | 0 | 102.05 | + And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024" + And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount + When Admin sets the business date to "1 February 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "01 February 2024" due date and 5 EUR transaction amount + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 22.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 | 5.0 | 0.0 | 22.01 | 22.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 | 2.05 | 5.0 | 0 | 107.05 | 22.01| 0 | 0 | 85.04 | + When Admin sets the business date to "01 March 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 3 EUR transaction amount + And Admin does charge-off the loan on "01 March 2024" + 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 | Waived | 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 | 5.0 | 0.0 | 22.01 | 22.01| 0.0 | 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 | 0.0 | 17.01 | + | 3 | 31 | 01 April 2024 | | 50.04 | 17.01 | 0.0 | 3.0 | 0.0 | 20.01 | 0.0 | 0.0 | 0.0 | 0.0 | 20.01 | + | 4 | 30 | 01 May 2024 | | 33.03 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | 17.01 | + | 5 | 31 | 01 June 2024 | | 16.02 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | 17.01 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.02 | 0.0 | 0.0 | 0.0 | 16.02 | 0.0 | 0.0 | 0.0 | 0.0 | 16.02 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding | + | 100 | 1.07 | 8.0 | 0 | 109.07 | 22.01| 0 | 0 | 0.0 | 87.06 | + 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 | 22.01 | 16.43 | 0.58 | 5.0 | 0.0 | 83.57 | false | false | + | 01 March 2024 | Charge-off | 87.06 | 83.57 | 0.49 | 3.0 | 0.0 | 0.0 | false | false | + + @TestRailId:3349 + Scenario: Charge-off with charge is added after the charge off date when loan behavior is zero-interest with interestRecalculation, when charge is waived + When Admin sets the business date to "1 January 2024" + And Admin creates a client with random data + And Admin creates a fully customized loan with the following data: + | LoanProduct | submitted on date | with Principal | ANNUAL interest rate % | interest type | interest calculation period | amortization type | loanTermFrequency | loanTermFrequencyType | repaymentEvery | repaymentFrequencyType | numberOfRepayments | graceOnPrincipalPayment | graceOnInterestPayment | interest free period | Payment strategy | + | LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALCULATION_ZERO_INTEREST_CHARGE_OFF_BEHAVIOUR | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION | + 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 | 2.05 | 0 | 0 | 102.05 | 0 | 0 | 0 | 102.05 | + And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024" + And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount + When Admin sets the business date to "1 February 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "01 February 2024" due date and 5 EUR transaction amount + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 22.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 | 5.0 | 0.0 | 22.01 | 22.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 | 2.05 | 5.0 | 0 | 107.05 | 22.01| 0 | 0 | 85.04 | + When Admin sets the business date to "01 March 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 3 EUR transaction amount + And Admin does charge-off the loan on "01 March 2024" + And Admin waives charge + 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 | Waived | 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 | 5.0 | 0.0 | 22.01 | 22.01| 0.0 | 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 | 0.0 | 17.01 | + | 3 | 31 | 01 April 2024 | | 50.04 | 17.01 | 0.0 | 3.0 | 0.0 | 20.01 | 0.0 | 0.0 | 0.0 | 3.0 | 17.01 | + | 4 | 30 | 01 May 2024 | | 33.03 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | 17.01 | + | 5 | 31 | 01 June 2024 | | 16.02 | 17.01 | 0.0 | 0.0 | 0.0 | 17.01 | 0.0 | 0.0 | 0.0 | 0.0 | 17.01 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.02 | 0.0 | 0.0 | 0.0 | 16.02 | 0.0 | 0.0 | 0.0 | 0.0 | 16.02 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding | + | 100 | 1.07 | 8.0 | 0 | 109.07 | 22.01| 0 | 0 | 3.0 | 84.06 | + 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 | 22.01 | 16.43 | 0.58 | 5.0 | 0.0 | 83.57 | false | false | + | 01 March 2024 | Waive loan charges| 3.0 | 0.0 | 0.0 | 0.0 | 0.0 | 83.57 | false | false | + | 01 March 2024 | Charge-off | 84.06 | 83.57 | 0.49 | 0.0 | 0.0 | 0.0 | false | true | + + @scenario_9.3_interest_recalculation_disabled_after_3373 + Scenario: Verify error when backdated charge-off happened with charge is added after the charge off date when loan behavior is zero-interest with interestRecalculation disabled + When Admin sets the business date to "1 January 2024" + And Admin creates a client with random data + When Admin creates a new zero charge-off Loan without interest recalculation and with date: "1 January 2024" + 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.59 | 16.41 | 0.59 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 2.04 | 0 | 0 | 102.04 | 0 | 0 | 0 | 102.04 | + And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024" + And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount + When Admin sets the business date to "1 February 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "01 February 2024" due date and 5 EUR transaction amount + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 22.0 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.59 | 16.41 | 0.59 | 5.0 | 0.0 | 22.0 | 22.0 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 2.04 | 5 | 0 | 107.04 | 22.0 | 0 | 0 | 85.04 | + When Admin sets the business date to "01 March 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 3 EUR transaction amount + When Admin sets the business date to "29 February 2024" + And Admin tries to charge-off the loan on "29 February 2024" but fails due to monetary activity after the charge-off date + + @scenario_9.3_interest_recalculation_disabled_after_3373 + Scenario: Charge-off with charge is added after the charge off date when loan behavior is zero-interest with interestRecalculation disabled + When Admin sets the business date to "1 January 2024" + And Admin creates a client with random data + When Admin creates a new zero charge-off Loan without interest recalculation and with date: "1 January 2024" + 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.59 | 16.41 | 0.59 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 2.04 | 0 | 0 | 102.04 | 0 | 0 | 0 | 102.04 | + And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024" + And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount + When Admin sets the business date to "1 February 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "01 February 2024" due date and 5 EUR transaction amount + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 22.0 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.59 | 16.41 | 0.59 | 5.0 | 0.0 | 22.0 | 22.0 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 2.04 | 5 | 0 | 107.04 | 22.0 | 0 | 0 | 85.04 | + When Admin sets the business date to "01 March 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 3 EUR transaction amount + And Admin does charge-off the loan on "01 March 2024" + 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.59 | 16.41 | 0.59 | 5.0 | 0.0 | 22.0 | 22.0 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.05 | 17.0 | 0.0 | 3.0 | 0.0 | 20.0 | 0.0 | 0.0 | 0.0 | 20.0 | + | 4 | 30 | 01 May 2024 | | 33.05 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.05 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.05 | 0.0 | 0.0 | 0.0 | 16.05 | 0.0 | 0.0 | 0.0 | 16.05 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 1.05 | 8 | 0 | 109.05 | 22.0 | 0 | 0 | 87.05 | + 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 | 22.0 | 16.41 | 0.59 | 5.0 | 0.0 | 83.59 | false | false | + | 01 March 2024 | Charge-off | 87.05 | 83.59 | 0.46 | 3.0 | 0.0 | 0.0 | false | false | + + @TestRailId:3373 + Scenario: Charge-off with charge is added after the charge off date when loan behavior is zero-interest with interestRecalculation disabled, when charge is waived + When Admin sets the business date to "1 January 2024" + And Admin creates a client with random data + When Admin creates a new zero charge-off Loan without interest recalculation and with date: "1 January 2024" + 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.59 | 16.41 | 0.59 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 2.04 | 0 | 0 | 102.04 | 0 | 0 | 0 | 102.04 | + And Admin successfully approves the loan on "1 January 2024" with "100" amount and expected disbursement date on "1 January 2024" + And Admin successfully disburse the loan on "1 January 2024" with "100" EUR transaction amount + When Admin sets the business date to "1 February 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "01 February 2024" due date and 5 EUR transaction amount + And Customer makes "AUTOPAY" repayment on "01 February 2024" with 22.0 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.59 | 16.41 | 0.59 | 5.0 | 0.0 | 22.0 | 22.0 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.45 | 16.6 | 0.4 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.74 | 16.71 | 0.29 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.94 | 16.8 | 0.2 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.94 | 0.1 | 0.0 | 0.0 | 17.04 | 0.0 | 0.0 | 0.0 | 17.04 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding | + | 100 | 2.04 | 5 | 0 | 107.04 | 22.0 | 0 | 0 | 85.04 | + When Admin sets the business date to "01 March 2024" + When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 3 EUR transaction amount + And Admin does charge-off the loan on "01 March 2024" + And Admin waives charge + 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 | Waived | Outstanding | + | | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | | | + | 1 | 31 | 01 February 2024 | 01 February 2024 | 83.59 | 16.41 | 0.59 | 5.0 | 0.0 | 22.0 | 22.0 | 0.0 | 0.0 | 0.0 | 0.0 | + | 2 | 29 | 01 March 2024 | | 67.05 | 16.54 | 0.46 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 3 | 31 | 01 April 2024 | | 50.05 | 17.0 | 0.0 | 3.0 | 0.0 | 20.0 | 0.0 | 0.0 | 0.0 | 3.0 | 17.0 | + | 4 | 30 | 01 May 2024 | | 33.05 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 5 | 31 | 01 June 2024 | | 16.05 | 17.0 | 0.0 | 0.0 | 0.0 | 17.0 | 0.0 | 0.0 | 0.0 | 0.0 | 17.0 | + | 6 | 30 | 01 July 2024 | | 0.0 | 16.05 | 0.0 | 0.0 | 0.0 | 16.05 | 0.0 | 0.0 | 0.0 | 0.0 | 16.05 | + Then Loan Repayment schedule has the following data in Total row: + | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Waived | Outstanding | + | 100 | 1.05 | 8 | 0 | 109.05 | 22.0 | 0 | 0 | 3.0 | 84.05 | + 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 | 22.0 | 16.41 | 0.59 | 5.0 | 0.0 | 83.59 | false | false | + | 01 March 2024 | Waive loan charges | 3.0 | 0.0 | 0.0 | 0.0 | 0.0 | 83.59 | false | false | + | 01 March 2024 | Charge-off | 84.05 | 83.59 | 0.46 | 0.0 | 0.0 | 0.0 | false | true | + Scenario: Charge-off on due date when loan behaviour is zero-interest and interestRecalculation = false When Admin sets the business date to "1 March 2023" And Admin creates a client with random data @@ -2461,7 +2771,7 @@ Feature: Charge-off | 15 July 2023 | Charge-off | 102.03 | 100.0 | 2.03 | 0.0 | 0.0 | 0.0 | Scenario: Charge-off when charge is added before the charge-off date, loan behaviour is zero-interest and interestRecalculation = false - When Admin sets the business date to "1 March 2023" + When Admin sets the business date to "1 January 2023" And Admin creates a client with random data When Admin creates a new zero charge-off Loan without interest recalculation and with date: "1 January 2023" Then Loan Repayment schedule has 6 periods, with the following data for periods: @@ -2479,6 +2789,7 @@ Feature: Charge-off And Admin successfully approves the loan on "1 January 2023" with "100" amount and expected disbursement date on "1 January 2023" And Admin successfully disburse the loan on "1 January 2023" with "100" EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "27 February 2023" due date and 3 EUR transaction amount + When Admin sets the business date to "28 February 2023" And Admin does charge-off the loan on "28 February 2023" 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 | @@ -2498,7 +2809,7 @@ Feature: Charge-off | 28 February 2023 | Charge-off | 104.02 | 100.0 | 1.02 | 3.0 | 0.0 | 0.0 | Scenario: Charge-off when charge is added on charge-off date, loan behaviour is zero-interest and interestRecalculation = false - When Admin sets the business date to "1 March 2023" + When Admin sets the business date to "1 January 2023" And Admin creates a client with random data When Admin creates a new zero charge-off Loan without interest recalculation and with date: "1 January 2023" Then Loan Repayment schedule has 6 periods, with the following data for periods: @@ -2516,6 +2827,7 @@ Feature: Charge-off And Admin successfully approves the loan on "1 January 2023" with "100" amount and expected disbursement date on "1 January 2023" And Admin successfully disburse the loan on "1 January 2023" with "100" EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "28 February 2023" due date and 3 EUR transaction amount + When Admin sets the business date to "28 February 2023" And Admin does charge-off the loan on "28 February 2023" 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 | @@ -2535,7 +2847,7 @@ Feature: Charge-off | 28 February 2023 | Charge-off | 104.02 | 100.0 | 1.02 | 3.0 | 0.0 | 0.0 | Scenario: Charge-off when charge is added after the charge off date, loan behaviour is zero-interest and interestRecalculation = false - When Admin sets the business date to "1 March 2023" + When Admin sets the business date to "1 January 2023" And Admin creates a client with random data When Admin creates a new zero charge-off Loan without interest recalculation and with date: "1 January 2023" Then Loan Repayment schedule has 6 periods, with the following data for periods: @@ -2553,6 +2865,7 @@ Feature: Charge-off And Admin successfully approves the loan on "1 January 2023" with "100" amount and expected disbursement date on "1 January 2023" And Admin successfully disburse the loan on "1 January 2023" with "100" EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "1 March 2023" due date and 3 EUR transaction amount + When Admin sets the business date to "28 February 2023" And Admin does charge-off the loan on "28 February 2023" 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 | @@ -4039,7 +4352,7 @@ Feature: Charge-off 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 When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 5 EUR transaction amount - When Admin sets the business date to "29 February 2024" + When Admin sets the business date to "15 February 2024" And Admin adds an NSF fee because of payment bounce with "29 February 2024" transaction date 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 | @@ -4057,14 +4370,13 @@ Feature: Charge-off | 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 | - When Admin sets the business date to "15 February 2024" And Admin does charge-off the loan on "15 February 2024" Then Loan Repayment schedule has 3 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 | 14 | 15 February 2024 | | 0.0 | 83.57 | 0.24 | 0.0 | 0.0 | 83.81 | 0.0 | 0.0 | 0.0 | 83.81 | - | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 10.0 | 15.0 | 0.0 | 0.0 | 0.0 | 15.0 | + | 2 | 14 | 15 February 2024 | | 0.0 | 83.57 | 0.24 | 0.0 | 10.0 | 93.81 | 0.0 | 0.0 | 0.0 | 93.81 | + | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 5.0 | 0.0 | 0.0 | 0.0 | 5.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 | 0.82 | 5.0 | 10.0 | 115.82 | 17.01 | 0.0 | 0.0 | 98.81 | @@ -4072,7 +4384,7 @@ Feature: Charge-off | 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 | - | 15 February 2024 | Charge-off | 88.81 | 83.57 | 0.24 | 5.0 | 0.0 | 0.0 | false | false | + | 15 February 2024 | Charge-off | 98.81 | 83.57 | 0.24 | 5.0 | 10.0 | 0.0 | false | false | Scenario: Verify accelerate maturity to charge-off date when interest recalculation is enabled - case when fee and penalty charges due dates is after charge-off date, and one charge is waived after charge-off When Admin sets the business date to "01 January 2024" @@ -4100,7 +4412,7 @@ Feature: Charge-off 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 When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 5 EUR transaction amount - When Admin sets the business date to "29 February 2024" + When Admin sets the business date to "15 February 2024" And Admin adds an NSF fee because of payment bounce with "29 February 2024" transaction date 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 | @@ -4118,14 +4430,13 @@ Feature: Charge-off | 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 | - When Admin sets the business date to "15 February 2024" And Admin does charge-off the loan on "15 February 2024" Then Loan Repayment schedule has 3 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 | 14 | 15 February 2024 | | 0.0 | 83.57 | 0.24 | 0.0 | 0.0 | 83.81 | 0.0 | 0.0 | 0.0 | 83.81 | - | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 10.0 | 15.0 | 0.0 | 0.0 | 0.0 | 15.0 | + | 2 | 14 | 15 February 2024 | | 0.0 | 83.57 | 0.24 | 0.0 | 10.0 | 93.81 | 0.0 | 0.0 | 0.0 | 93.81 | + | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 5.0 | 0.0 | 0.0 | 0.0 | 5.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 | 0.82 | 5.0 | 10.0 | 115.82 | 17.01 | 0.0 | 0.0 | 98.81 | @@ -4133,23 +4444,23 @@ Feature: Charge-off | 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 | - | 15 February 2024 | Charge-off | 88.81 | 83.57 | 0.24 | 5.0 | 0.0 | 0.0 | false | false | - And Admin waives due date charge + | 15 February 2024 | Charge-off | 98.81 | 83.57 | 0.24 | 5.0 | 10.0 | 0.0 | false | false | + And Admin waives charge Then Loan Repayment schedule has 3 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 | 14 | 15 February 2024 | | 0.0 | 83.57 | 0.24 | 0.0 | 0.0 | 83.81 | 0.0 | 0.0 | 0.0 | 83.81 | - | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 10.0 | 15.0 | 0.0 | 0.0 | 0.0 | 15.0 | + | 2 | 14 | 15 February 2024 | | 0.0 | 83.57 | 0.24 | 0.0 | 10.0 | 93.81 | 0.0 | 0.0 | 0.0 | 83.81 | + | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 5.0 | 0.0 | 0.0 | 0.0 | 5.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 | 0.82 | 5.0 | 10.0 | 115.82 | 17.01 | 0.0 | 0.0 | 98.81 | + | 100.0 | 0.82 | 5.0 | 10.0 | 115.82 | 17.01 | 0.0 | 0.0 | 88.81 | 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 | - | 15 February 2024 | Charge-off | 88.81 | 83.57 | 0.24 | 5.0 | 0.0 | 0.0 | false | false | - | 15 February 2024 | Waive loan charges | 5.0 | 0.0 | 0.0 | 0.0 | 0.0 | 83.57 | false | false | + | 15 February 2024 | Waive loan charges | 10.0 | 0.0 | 0.0 | 0.0 | 0.0 | 83.57 | false | false | + | 15 February 2024 | Charge-off | 88.81 | 83.57 | 0.24 | 5.0 | 0.0 | 0.0 | false | true | Scenario: Verify accelerate maturity to charge-off date when interest recalculation is disabled - case when one fee charge due date is before charge-off date When Admin sets the business date to "01 January 2024" @@ -4534,7 +4845,7 @@ Feature: Charge-off When Admin sets the business date to "01 February 2024" And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.00 EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 5 EUR transaction amount - When Admin sets the business date to "29 February 2024" + When Admin sets the business date to "15 February 2024" And Admin adds an NSF fee because of payment bounce with "29 February 2024" transaction date 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 | @@ -4552,7 +4863,6 @@ Feature: Charge-off | 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.0 | 16.41 | 0.59 | 0.0 | 0.0 | 83.59 | false | false | - When Admin sets the business date to "15 February 2024" And Admin does charge-off the loan on "15 February 2024" Then Loan Repayment schedule has 3 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 | @@ -4593,7 +4903,7 @@ Feature: Charge-off When Admin sets the business date to "01 February 2024" And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.00 EUR transaction amount When Admin adds "LOAN_SNOOZE_FEE" due date charge with "05 March 2024" due date and 5 EUR transaction amount - When Admin sets the business date to "29 February 2024" + When Admin sets the business date to "15 February 2024" And Admin adds an NSF fee because of payment bounce with "29 February 2024" transaction date 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 | @@ -4611,7 +4921,6 @@ Feature: Charge-off | 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.0 | 16.41 | 0.59 | 0.0 | 0.0 | 83.59 | false | false | - When Admin sets the business date to "15 February 2024" And Admin does charge-off the loan on "15 February 2024" Then Loan Repayment schedule has 3 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 | @@ -4627,21 +4936,21 @@ Feature: Charge-off | 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false | | 01 February 2024 | Repayment | 17.0 | 16.41 | 0.59 | 0.0 | 0.0 | 83.59 | false | false | | 15 February 2024 | Charge-off | 98.81 | 83.59 | 0.22 | 5.0 | 10.0 | 0.0 | false | false | - And Admin waives due date charge + And Admin waives charge Then Loan Repayment schedule has 3 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.59 | 16.41 | 0.59 | 0.0 | 0.0 | 17.0 | 17.0 | 0.0 | 0.0 | 0.0 | - | 2 | 14 | 15 February 2024 | | 0.0 | 83.59 | 0.22 | 0.0 | 0.0 | 83.81 | 0.0 | 0.0 | 0.0 | 83.81 | - | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 10.0 | 15.0 | 0.0 | 0.0 | 0.0 | 15.0 | + | 2 | 14 | 15 February 2024 | | 0.0 | 83.59 | 0.22 | 0.0 | 10.0 | 93.81 | 0.0 | 0.0 | 0.0 | 83.81 | + | 3 | 19 | 05 March 2024 | | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | 5.0 | 0.0 | 0.0 | 0.0 | 5.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 | 0.81 | 5.0 | 10.0 | 115.81 | 17.0 | 0.0 | 0.0 | 98.81 | + | 100.0 | 0.81 | 5.0 | 10.0 | 115.81 | 17.0 | 0.0 | 0.0 | 88.81 | 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.0 | 16.41 | 0.59 | 0.0 | 0.0 | 83.59 | false | false | - | 15 February 2024 | Waive loan charges | 5.0 | 0.0 | 0.0 | 0.0 | 0.0 | 83.59 | false | false | + | 15 February 2024 | Waive loan charges | 10.0 | 0.0 | 0.0 | 0.0 | 0.0 | 83.59 | false | false | | 15 February 2024 | Charge-off | 88.81 | 83.59 | 0.22 | 5.0 | 0.0 | 0.0 | false | true | @TestRailId:C3352 @AdvancedPaymentAllocation diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java index e0fa02d6f..0ce2a3473 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/Loan.java @@ -3581,4 +3581,17 @@ public class Loan extends AbstractAuditableWithUTCDateTimeCustom { return (chargeOffTransaction == null) ? false : (chargeOffTransaction.getDateOf().compareTo(onDate) <= 0); } + public boolean hasMonetaryActivityAfter(final LocalDate transactionDate) { + for (LoanTransaction transaction : this.getLoanTransactions()) { + if (transaction.getTransactionDate().isAfter(transactionDate) && !transaction.isNonMonetaryTransaction()) { + return true; + } + } + for (LoanCharge loanCharge : this.getLoanCharges()) { + if (!loanCharge.determineIfFullyPaid() && loanCharge.getSubmittedOnDate().isAfter(transactionDate)) { + return true; + } + } + return false; + } } diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java index 9058b7f77..c1bb2743c 100644 --- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java +++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanCharge.java @@ -511,7 +511,7 @@ public class LoanCharge extends AbstractAuditableWithUTCDateTimeCustom { return this.dueDate; // TODO delete duplicated method } - private boolean determineIfFullyPaid() { + public boolean determineIfFullyPaid() { if (this.amount == null) { return true; } diff --git a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java index 263e5c02c..b089fab99 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java +++ b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java @@ -3201,6 +3201,12 @@ public class LoanWritePlatformServiceJpaRepositoryImpl implements LoanWritePlatf transactionDate); } + if (loan.hasMonetaryActivityAfter(transactionDate)) { + throw new GeneralPlatformDomainRuleException("error.msg.loan.monetary.transactions.after.charge.off", + "Loan: " + loanId + " charge-off cannot be executed. Loan has monetary activity after the charge-off transaction date!", + loanId); + } + businessEventNotifierService.notifyPreBusinessEvent(new LoanChargeOffPreBusinessEvent(loan)); if (command.hasParameter(LoanApiConstants.chargeOffReasonIdParamName)) { diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java index 59f48876f..609e2396f 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/ClientLoanIntegrationTest.java @@ -6135,7 +6135,7 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest { globalConfigurationHelper.updateGlobalConfiguration(GlobalConfigurationConstants.ENABLE_BUSINESS_DATE, new PutGlobalConfigurationsRequest().enabled(true)); BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) - .date("30 September 2022").dateFormat(DATETIME_PATTERN).locale("en")); + .date("04 September 2022").dateFormat(DATETIME_PATTERN).locale("en")); final Account assetAccount = ACCOUNT_HELPER.createAssetAccount(); final Account incomeAccount = ACCOUNT_HELPER.createIncomeAccount(); final Account expenseAccount = ACCOUNT_HELPER.createExpenseAccount(); @@ -6271,6 +6271,9 @@ public class ClientLoanIntegrationTest extends BaseLoanIntegrationTest { assertEquals(403, exception.getResponse().code()); assertTrue(exception.getMessage().contains("error.msg.loan.is.not.charged.off")); + BUSINESS_DATE_HELPER.updateBusinessDate(new BusinessDateRequest().type(BusinessDateType.BUSINESS_DATE.getName()) + .date("08 September 2022").dateFormat(DATETIME_PATTERN).locale("en")); + PostLoansLoanIdTransactionsResponse loanRepaymentResponse = LOAN_TRANSACTION_HELPER.makeLoanRepayment((long) loanID, new PostLoansLoanIdTransactionsRequest().dateFormat(DATETIME_PATTERN).transactionDate("05 September 2022").locale("en") .transactionAmount(5.0)); diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java index 25e22e48f..1f7c02ab8 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanAccountChargeOffWithAdvancedPaymentAllocationTest.java @@ -147,64 +147,66 @@ public class LoanAccountChargeOffWithAdvancedPaymentAllocationTest extends BaseL // Charge-off accounting and balances @Test public void loanChargeOffWithAdvancedPaymentStrategyTest() { - String loanExternalIdStr = UUID.randomUUID().toString(); - final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingAndAdvancedPaymentAllocationStrategy(); - final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue(); - final Integer loanId = createLoanAccount(clientId, loanProductID, loanExternalIdStr); + runAt("10 September 2022", () -> { + String loanExternalIdStr = UUID.randomUUID().toString(); + final Integer loanProductID = createLoanProductWithPeriodicAccrualAccountingAndAdvancedPaymentAllocationStrategy(); + final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue(); + final Integer loanId = createLoanAccount(clientId, loanProductID, loanExternalIdStr); - // apply charges - Integer feeCharge = ChargesHelper.createCharges(requestSpec, responseSpec, - ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", false)); + // apply charges + Integer feeCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", false)); - LocalDate targetDate = LocalDate.of(2022, 9, 5); - final String feeCharge1AddedDate = DATE_FORMATTER.format(targetDate); - Integer feeLoanChargeId = loanTransactionHelper.addChargesForLoan(loanId, - LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge), feeCharge1AddedDate, "10")); + LocalDate targetDate = LocalDate.of(2022, 9, 5); + final String feeCharge1AddedDate = DATE_FORMATTER.format(targetDate); + Integer feeLoanChargeId = loanTransactionHelper.addChargesForLoan(loanId, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge), feeCharge1AddedDate, "10")); - // apply penalty - Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec, - ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", true)); + // apply penalty + Integer penalty = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", true)); - final String penaltyCharge1AddedDate = DATE_FORMATTER.format(targetDate); + final String penaltyCharge1AddedDate = DATE_FORMATTER.format(targetDate); - Integer penalty1LoanChargeId = this.loanTransactionHelper.addChargesForLoan(loanId, - LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), penaltyCharge1AddedDate, "10")); + Integer penalty1LoanChargeId = this.loanTransactionHelper.addChargesForLoan(loanId, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty), penaltyCharge1AddedDate, "10")); - // make Repayment - final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, - new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("9 September 2022").locale("en") - .transactionAmount(10.0)); + // make Repayment + final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("9 September 2022").locale("en") + .transactionAmount(10.0)); - GetLoansLoanIdResponse loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); + GetLoansLoanIdResponse loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); - // set loan as chargeoff - String randomText = Utils.randomStringGenerator("en", 5) + Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5); - Integer chargeOffReasonId = CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1); - String transactionExternalId = UUID.randomUUID().toString(); - PostLoansLoanIdTransactionsResponse chargeOffTransaction = this.loanTransactionHelper.chargeOffLoan((long) loanId, - new PostLoansLoanIdTransactionsRequest().transactionDate("10 September 2022").locale("en").dateFormat("dd MMMM yyyy") - .externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId)); + // set loan as chargeoff + String randomText = Utils.randomStringGenerator("en", 5) + Utils.randomNumberGenerator(6) + + Utils.randomStringGenerator("is", 5); + Integer chargeOffReasonId = CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1); + String transactionExternalId = UUID.randomUUID().toString(); + PostLoansLoanIdTransactionsResponse chargeOffTransaction = this.loanTransactionHelper.chargeOffLoan((long) loanId, + new PostLoansLoanIdTransactionsRequest().transactionDate("10 September 2022").locale("en").dateFormat("dd MMMM yyyy") + .externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId)); - loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); - assertTrue(loanDetails.getChargedOff()); + loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); + assertTrue(loanDetails.getChargedOff()); - // verify amounts for charge-off transaction - verifyTransaction(LocalDate.of(2022, 9, 10), 1010.0f, 1000.0f, 0.0f, 10.0f, 0.0f, loanId, "chargeoff"); - // verify journal entries - GetJournalEntriesTransactionIdResponse journalEntriesForChargeOff = journalEntryHelper - .getJournalEntries("L" + chargeOffTransaction.getResourceId().toString()); + // verify amounts for charge-off transaction + verifyTransaction(LocalDate.of(2022, 9, 10), 1010.0f, 1000.0f, 0.0f, 10.0f, 0.0f, loanId, "chargeoff"); + // verify journal entries + GetJournalEntriesTransactionIdResponse journalEntriesForChargeOff = journalEntryHelper + .getJournalEntries("L" + chargeOffTransaction.getResourceId().toString()); - assertNotNull(journalEntriesForChargeOff); - - List journalEntries = journalEntriesForChargeOff.getPageItems(); - assertEquals(4, journalEntries.size()); - verifyJournalEntry(journalEntries.get(3), 1000.0, LocalDate.of(2022, 9, 10), loansReceivable, "CREDIT"); - verifyJournalEntry(journalEntries.get(2), 10.0, LocalDate.of(2022, 9, 10), interestFeeReceivable, "CREDIT"); - verifyJournalEntry(journalEntries.get(1), 1000.0, LocalDate.of(2022, 9, 10), creditLossBadDebt, "DEBIT"); - verifyJournalEntry(journalEntries.get(0), 10.0, LocalDate.of(2022, 9, 10), feeChargeOff, "DEBIT"); + assertNotNull(journalEntriesForChargeOff); + List journalEntries = journalEntriesForChargeOff.getPageItems(); + assertEquals(4, journalEntries.size()); + verifyJournalEntry(journalEntries.get(3), 1000.0, LocalDate.of(2022, 9, 10), loansReceivable, "CREDIT"); + verifyJournalEntry(journalEntries.get(2), 10.0, LocalDate.of(2022, 9, 10), interestFeeReceivable, "CREDIT"); + verifyJournalEntry(journalEntries.get(1), 1000.0, LocalDate.of(2022, 9, 10), creditLossBadDebt, "DEBIT"); + verifyJournalEntry(journalEntries.get(0), 10.0, LocalDate.of(2022, 9, 10), feeChargeOff, "DEBIT"); + }); } // Reverse Replay of Charge-Off diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java index 5f9e29a6f..6def38cea 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargeOffAccountingTest.java @@ -105,7 +105,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { @Test public void loanChargeOffAccountingTreatmentTestForPeriodicAccrualAccounting() { - runAt("12 September 2022", () -> { + runAt("6 September 2022", () -> { // Loan ExternalId String loanExternalIdStr = UUID.randomUUID().toString(); @@ -161,6 +161,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6 September 2022", new JournalEntry(20, JournalEntry.TransactionType.DEBIT)); + updateBusinessDate("12 September 2022"); // make Repayment final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("7 September 2022").locale("en") @@ -261,7 +262,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { @Test public void loanChargeOffFraudAccountingTreatmentTestForCashBasedAccounting() { - runAt("12 September 2022", () -> { + runAt("6 September 2022", () -> { // Loan ExternalId String loanExternalIdStr = UUID.randomUUID().toString(); @@ -330,6 +331,8 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6 September 2022", new JournalEntry(20, JournalEntry.TransactionType.DEBIT)); + updateBusinessDate("12 September 2022"); + // make Repayment final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("7 September 2022").locale("en") @@ -494,7 +497,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { @Test public void loanAccountingTreatmentTestForGoodwillCreditPeriodicAccrualAccounting_ChargeOff() { - runAt("12 September 2022", () -> { + runAt("6 September 2022", () -> { // Loan ExternalId String loanExternalIdStr = UUID.randomUUID().toString(); @@ -550,6 +553,8 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6 September 2022", new JournalEntry(20, JournalEntry.TransactionType.DEBIT)); + updateBusinessDate("12 September 2022"); + // Goodwill Credit final PostLoansLoanIdTransactionsResponse goodwillCredit_1 = loanTransactionHelper.makeGoodwillCredit((long) loanId, new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("08 September 2022").locale("en") @@ -633,7 +638,7 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { @Test public void loanAccountingTreatmentTestForCashBasedAccounting_ChargeOff() { - runAt("12 September 2022", () -> { + runAt("6 September 2022", () -> { // Loan ExternalId String loanExternalIdStr = UUID.randomUUID().toString(); @@ -694,6 +699,8 @@ public class LoanChargeOffAccountingTest extends BaseLoanIntegrationTest { this.journalEntryHelper.checkJournalEntryForIncomeAccount(incomeAccount, "6 September 2022", new JournalEntry(20, JournalEntry.TransactionType.DEBIT)); + updateBusinessDate("12 September 2022"); + // Goodwill Credit final PostLoansLoanIdTransactionsResponse goodwillCredit_1 = loanTransactionHelper.makeGoodwillCredit((long) loanId, new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("10 September 2022").locale("en") diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java index ae34f6d59..fd7bfe377 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanPostChargeOffScenariosTest.java @@ -72,7 +72,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(LoanTestLifecycleExtension.class) -public class LoanPostChargeOffScenariosTest { +public class LoanPostChargeOffScenariosTest extends BaseLoanIntegrationTest { private static final DateTimeFormatter DATE_FORMATTER = new DateTimeFormatterBuilder().appendPattern("dd MMMM yyyy").toFormatter(); private ResponseSpecification responseSpec; @@ -143,172 +143,177 @@ public class LoanPostChargeOffScenariosTest { @Test public void postChargeOffAddBackdatedTransactionTest() { - String loanExternalIdStr = UUID.randomUUID().toString(); - final Integer loanProductID = createLoanProductWithPeriodicAccrualAccounting(); - final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue(); - final Integer loanId = createLoanAccount(clientId, loanProductID, loanExternalIdStr); + runAt("14 September 2022", () -> { + String loanExternalIdStr = UUID.randomUUID().toString(); + final Integer loanProductID = createLoanProductWithPeriodicAccrualAccounting(); + final Integer clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue(); + final Integer loanId = createLoanAccount(clientId, loanProductID, loanExternalIdStr); - // apply charges - Integer feeCharge = ChargesHelper.createCharges(requestSpec, responseSpec, - ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", false)); + // apply charges + Integer feeCharge = ChargesHelper.createCharges(requestSpec, responseSpec, + ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, "10", false)); - LocalDate targetDate = LocalDate.of(2022, 9, 5); - final String feeCharge1AddedDate = DATE_FORMATTER.format(targetDate); - Integer feeLoanChargeId = loanTransactionHelper.addChargesForLoan(loanId, - LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge), feeCharge1AddedDate, "10")); + LocalDate targetDate = LocalDate.of(2022, 9, 5); + final String feeCharge1AddedDate = DATE_FORMATTER.format(targetDate); + Integer feeLoanChargeId = loanTransactionHelper.addChargesForLoan(loanId, + LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(feeCharge), feeCharge1AddedDate, "10")); - // set loan as chargeoff - String randomText = Utils.randomStringGenerator("en", 5) + Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5); - Integer chargeOffReasonId = CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1); - String transactionExternalId = UUID.randomUUID().toString(); - PostLoansLoanIdTransactionsResponse chargeOffTransaction = loanTransactionHelper.chargeOffLoan((long) loanId, - new PostLoansLoanIdTransactionsRequest().transactionDate("14 September 2022").locale("en").dateFormat("dd MMMM yyyy") - .externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId)); + // set loan as chargeoff + String randomText = Utils.randomStringGenerator("en", 5) + Utils.randomNumberGenerator(6) + + Utils.randomStringGenerator("is", 5); + Integer chargeOffReasonId = CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText, 1); + String transactionExternalId = UUID.randomUUID().toString(); + PostLoansLoanIdTransactionsResponse chargeOffTransaction = loanTransactionHelper.chargeOffLoan((long) loanId, + new PostLoansLoanIdTransactionsRequest().transactionDate("14 September 2022").locale("en").dateFormat("dd MMMM yyyy") + .externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId)); - GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); - assertTrue(loanDetails.getChargedOff()); + GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); + assertTrue(loanDetails.getChargedOff()); - // verify Journal Entries For ChargeOff Transaction - GetJournalEntriesTransactionIdResponse journalEntriesForChargeOff = journalEntryHelper - .getJournalEntries("L" + chargeOffTransaction.getResourceId().toString()); + // verify Journal Entries For ChargeOff Transaction + GetJournalEntriesTransactionIdResponse journalEntriesForChargeOff = journalEntryHelper + .getJournalEntries("L" + chargeOffTransaction.getResourceId().toString()); - assertNotNull(journalEntriesForChargeOff); - List journalEntries = journalEntriesForChargeOff.getPageItems(); - assertEquals(4, journalEntries.size()); + assertNotNull(journalEntriesForChargeOff); + List journalEntries = journalEntriesForChargeOff.getPageItems(); + assertEquals(4, journalEntries.size()); - assertEquals(1000, journalEntries.get(3).getAmount()); - assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(3).getTransactionDate()); - assertEquals(loansReceivable.getAccountID().longValue(), journalEntries.get(3).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(3).getEntryType().getValue()); + assertEquals(1000, journalEntries.get(3).getAmount()); + assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(3).getTransactionDate()); + assertEquals(loansReceivable.getAccountID().longValue(), journalEntries.get(3).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(3).getEntryType().getValue()); - assertEquals(10, journalEntries.get(2).getAmount()); - assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(2).getTransactionDate()); - assertEquals(interestFeeReceivable.getAccountID().longValue(), journalEntries.get(2).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(2).getEntryType().getValue()); + assertEquals(10, journalEntries.get(2).getAmount()); + assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(2).getTransactionDate()); + assertEquals(interestFeeReceivable.getAccountID().longValue(), journalEntries.get(2).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(2).getEntryType().getValue()); - assertEquals(1000, journalEntries.get(1).getAmount()); - assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(1).getTransactionDate()); - assertEquals(creditLossBadDebt.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); - assertEquals("DEBIT", journalEntries.get(1).getEntryType().getValue()); + assertEquals(1000, journalEntries.get(1).getAmount()); + assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(1).getTransactionDate()); + assertEquals(creditLossBadDebt.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); + assertEquals("DEBIT", journalEntries.get(1).getEntryType().getValue()); - assertEquals(10, journalEntries.get(0).getAmount()); - assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(0).getTransactionDate()); - assertEquals(feeChargeOff.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); - assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); + assertEquals(10, journalEntries.get(0).getAmount()); + assertEquals(LocalDate.of(2022, 9, 14), journalEntries.get(0).getTransactionDate()); + assertEquals(feeChargeOff.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); + assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); - // make Repayment before chargeoff date - final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, - new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("7 September 2022").locale("en") - .transactionAmount(100.0)); + // make Repayment before chargeoff date + final PostLoansLoanIdTransactionsResponse repaymentTransaction = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("7 September 2022").locale("en") + .transactionAmount(100.0)); - loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); - assertTrue(loanDetails.getChargedOff()); + loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); + assertTrue(loanDetails.getChargedOff()); - // verify Journal Entries for Repayment transaction + // verify Journal Entries for Repayment transaction - GetJournalEntriesTransactionIdResponse journalEntriesForRepayment = journalEntryHelper - .getJournalEntries("L" + repaymentTransaction.getResourceId().toString()); - assertNotNull(journalEntriesForRepayment); + GetJournalEntriesTransactionIdResponse journalEntriesForRepayment = journalEntryHelper + .getJournalEntries("L" + repaymentTransaction.getResourceId().toString()); + assertNotNull(journalEntriesForRepayment); - journalEntries = journalEntriesForRepayment.getPageItems(); - assertEquals(3, journalEntries.size()); + journalEntries = journalEntriesForRepayment.getPageItems(); + assertEquals(3, journalEntries.size()); - assertEquals(90, journalEntries.get(2).getAmount()); - assertEquals(LocalDate.of(2022, 9, 7), journalEntries.get(2).getTransactionDate()); - assertEquals(loansReceivable.getAccountID().longValue(), journalEntries.get(2).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(2).getEntryType().getValue()); + assertEquals(90, journalEntries.get(2).getAmount()); + assertEquals(LocalDate.of(2022, 9, 7), journalEntries.get(2).getTransactionDate()); + assertEquals(loansReceivable.getAccountID().longValue(), journalEntries.get(2).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(2).getEntryType().getValue()); - assertEquals(10, journalEntries.get(1).getAmount()); - assertEquals(LocalDate.of(2022, 9, 7), journalEntries.get(1).getTransactionDate()); - assertEquals(interestFeeReceivable.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); + assertEquals(10, journalEntries.get(1).getAmount()); + assertEquals(LocalDate.of(2022, 9, 7), journalEntries.get(1).getTransactionDate()); + assertEquals(interestFeeReceivable.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); - assertEquals(100, journalEntries.get(0).getAmount()); - assertEquals(LocalDate.of(2022, 9, 7), journalEntries.get(0).getTransactionDate()); - assertEquals(suspenseClearingAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); - assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); + assertEquals(100, journalEntries.get(0).getAmount()); + assertEquals(LocalDate.of(2022, 9, 7), journalEntries.get(0).getTransactionDate()); + assertEquals(suspenseClearingAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); + assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); - // Goodwill Credit before chargeoff date - final PostLoansLoanIdTransactionsResponse goodwillCredit = loanTransactionHelper.makeGoodwillCredit((long) loanId, - new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("10 September 2022").locale("en") - .transactionAmount(100.0)); + // Goodwill Credit before chargeoff date + final PostLoansLoanIdTransactionsResponse goodwillCredit = loanTransactionHelper.makeGoodwillCredit((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("10 September 2022").locale("en") + .transactionAmount(100.0)); - loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); - assertTrue(loanDetails.getChargedOff()); + loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); + assertTrue(loanDetails.getChargedOff()); - // verify Journal Entries for Goodwill Credit - GetJournalEntriesTransactionIdResponse journalEntriesForGoodWillCredit = journalEntryHelper - .getJournalEntries("L" + goodwillCredit.getResourceId().toString()); - assertNotNull(journalEntriesForGoodWillCredit); + // verify Journal Entries for Goodwill Credit + GetJournalEntriesTransactionIdResponse journalEntriesForGoodWillCredit = journalEntryHelper + .getJournalEntries("L" + goodwillCredit.getResourceId().toString()); + assertNotNull(journalEntriesForGoodWillCredit); - journalEntries = journalEntriesForGoodWillCredit.getPageItems(); - assertEquals(2, journalEntries.size()); + journalEntries = journalEntriesForGoodWillCredit.getPageItems(); + assertEquals(2, journalEntries.size()); - assertEquals(100, journalEntries.get(1).getAmount()); - assertEquals(LocalDate.of(2022, 9, 10), journalEntries.get(1).getTransactionDate()); - assertEquals(loansReceivable.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); + assertEquals(100, journalEntries.get(1).getAmount()); + assertEquals(LocalDate.of(2022, 9, 10), journalEntries.get(1).getTransactionDate()); + assertEquals(loansReceivable.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); - assertEquals(100, journalEntries.get(0).getAmount()); - assertEquals(LocalDate.of(2022, 9, 10), journalEntries.get(0).getTransactionDate()); - assertEquals(goodwillExpenseAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); - assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); + assertEquals(100, journalEntries.get(0).getAmount()); + assertEquals(LocalDate.of(2022, 9, 10), journalEntries.get(0).getTransactionDate()); + assertEquals(goodwillExpenseAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); + assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); - // make Repayment after chargeoff date - final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, - new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("15 September 2022").locale("en") - .transactionAmount(100.0)); + updateBusinessDate("16 September 2022"); - loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); - assertTrue(loanDetails.getChargedOff()); + // make Repayment after chargeoff date + final PostLoansLoanIdTransactionsResponse repaymentTransaction_1 = loanTransactionHelper.makeLoanRepayment(loanExternalIdStr, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("15 September 2022").locale("en") + .transactionAmount(100.0)); - // verify Journal Entries for Repayment transaction - journalEntriesForRepayment = journalEntryHelper.getJournalEntries("L" + repaymentTransaction_1.getResourceId().toString()); + loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); + assertTrue(loanDetails.getChargedOff()); - assertNotNull(journalEntriesForRepayment); + // verify Journal Entries for Repayment transaction + journalEntriesForRepayment = journalEntryHelper.getJournalEntries("L" + repaymentTransaction_1.getResourceId().toString()); - journalEntries = journalEntriesForRepayment.getPageItems(); - assertEquals(2, journalEntries.size()); + assertNotNull(journalEntriesForRepayment); - assertEquals(100, journalEntries.get(1).getAmount()); - assertEquals(LocalDate.of(2022, 9, 15), journalEntries.get(1).getTransactionDate()); - assertEquals(recoveries.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); + journalEntries = journalEntriesForRepayment.getPageItems(); + assertEquals(2, journalEntries.size()); - assertEquals(100, journalEntries.get(0).getAmount()); - assertEquals(LocalDate.of(2022, 9, 15), journalEntries.get(0).getTransactionDate()); - assertEquals(suspenseClearingAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); - assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); + assertEquals(100, journalEntries.get(1).getAmount()); + assertEquals(LocalDate.of(2022, 9, 15), journalEntries.get(1).getTransactionDate()); + assertEquals(recoveries.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); - // Goodwill Credit after chargeoff date - final PostLoansLoanIdTransactionsResponse goodwillCredit_1 = loanTransactionHelper.makeGoodwillCredit((long) loanId, - new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("16 September 2022").locale("en") - .transactionAmount(100.0)); + assertEquals(100, journalEntries.get(0).getAmount()); + assertEquals(LocalDate.of(2022, 9, 15), journalEntries.get(0).getTransactionDate()); + assertEquals(suspenseClearingAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); + assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); - loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); - assertTrue(loanDetails.getStatus().getActive()); - assertTrue(loanDetails.getChargedOff()); + // Goodwill Credit after chargeoff date + final PostLoansLoanIdTransactionsResponse goodwillCredit_1 = loanTransactionHelper.makeGoodwillCredit((long) loanId, + new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM yyyy").transactionDate("16 September 2022").locale("en") + .transactionAmount(100.0)); - // verify Journal Entries for Goodwill Credit - journalEntriesForGoodWillCredit = journalEntryHelper.getJournalEntries("L" + goodwillCredit_1.getResourceId().toString()); - assertNotNull(journalEntriesForGoodWillCredit); + loanDetails = loanTransactionHelper.getLoanDetails((long) loanId); + assertTrue(loanDetails.getStatus().getActive()); + assertTrue(loanDetails.getChargedOff()); - journalEntries = journalEntriesForGoodWillCredit.getPageItems(); - assertEquals(2, journalEntries.size()); + // verify Journal Entries for Goodwill Credit + journalEntriesForGoodWillCredit = journalEntryHelper.getJournalEntries("L" + goodwillCredit_1.getResourceId().toString()); + assertNotNull(journalEntriesForGoodWillCredit); - assertEquals(100, journalEntries.get(1).getAmount()); - assertEquals(LocalDate.of(2022, 9, 16), journalEntries.get(1).getTransactionDate()); - assertEquals(recoveries.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); - assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); + journalEntries = journalEntriesForGoodWillCredit.getPageItems(); + assertEquals(2, journalEntries.size()); - assertEquals(100, journalEntries.get(0).getAmount()); - assertEquals(LocalDate.of(2022, 9, 16), journalEntries.get(0).getTransactionDate()); - assertEquals(goodwillExpenseAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); - assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); + assertEquals(100, journalEntries.get(1).getAmount()); + assertEquals(LocalDate.of(2022, 9, 16), journalEntries.get(1).getTransactionDate()); + assertEquals(recoveries.getAccountID().longValue(), journalEntries.get(1).getGlAccountId().longValue()); + assertEquals("CREDIT", journalEntries.get(1).getEntryType().getValue()); + + assertEquals(100, journalEntries.get(0).getAmount()); + assertEquals(LocalDate.of(2022, 9, 16), journalEntries.get(0).getTransactionDate()); + assertEquals(goodwillExpenseAccount.getAccountID().longValue(), journalEntries.get(0).getGlAccountId().longValue()); + assertEquals("DEBIT", journalEntries.get(0).getEntryType().getValue()); + }); } @Test diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionInterestPaymentWaiverTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionInterestPaymentWaiverTest.java index 8c79e7f2c..4abc345e9 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionInterestPaymentWaiverTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionInterestPaymentWaiverTest.java @@ -1353,7 +1353,7 @@ public class LoanTransactionInterestPaymentWaiverTest extends BaseLoanIntegratio // reverse 4 - 1 Interest Payment Waiver transactions @Test public void testInterestPaymentWaiverTransactionAccountingAccuralForInterestPenaltyFeeOverpaymentChargeOFFLoan() { - runAt("15 May 2023", () -> { + runAt("2 January 2023", () -> { final String disbursementDay = "01 January 2023"; final String repaymentPeriod1DueDate = "01 February 2023"; @@ -1385,6 +1385,8 @@ public class LoanTransactionInterestPaymentWaiverTest extends BaseLoanIntegratio new PostLoansLoanIdTransactionsRequest().transactionDate("2 January 2023").locale("en").dateFormat("dd MMMM yyyy") .externalId(transactionExternalId).chargeOffReasonId((long) chargeOffReasonId)); + updateBusinessDate("15 May 2023"); + GetLoansLoanIdResponse loanDetails = loanTransactionHelper.getLoanDetails(loanId); validateLoanSummaryBalances(loanDetails, 1260.0, 0.0, 1000.0, 0.0, null); validateRepaymentPeriod(loanDetails, 1, LocalDate.of(2023, 2, 1), 250.0, 0.0, 250.0, 40.0, 0.0, 40.0, 30.0, 0.0, 30.0, 20.0,