This is an automated email from the ASF dual-hosted git repository.
adamsaghy pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git
The following commit(s) were added to refs/heads/develop by this push:
new 69317d62c FINERACT-2205: Add tests when charge is added after the
charge off date and forbid backdated charge-off transactions in the middle of
the monetary activity.
69317d62c is described below
commit 69317d62c8b9f822e4f642f16731f0fed678f965
Author: mariiaKraievska <[email protected]>
AuthorDate: Thu Jan 30 15:13:11 2025 +0200
FINERACT-2205: Add tests when charge is added after the charge off date and
forbid backdated charge-off transactions in the middle of the monetary activity.
---
.../test/stepdef/loan/LoanChargeStepDef.java | 1 +
.../fineract/test/stepdef/loan/LoanStepDef.java | 19 ++
.../test/resources/features/LoanChargeOff.feature | 373 +++++++++++++++++++--
.../portfolio/loanaccount/domain/Loan.java | 13 +
.../portfolio/loanaccount/domain/LoanCharge.java | 2 +-
.../LoanWritePlatformServiceJpaRepositoryImpl.java | 6 +
.../ClientLoanIntegrationTest.java | 5 +-
...ChargeOffWithAdvancedPaymentAllocationTest.java | 94 +++---
.../LoanChargeOffAccountingTest.java | 15 +-
.../LoanPostChargeOffScenariosTest.java | 337 ++++++++++---------
.../LoanTransactionInterestPaymentWaiverTest.java | 4 +-
11 files changed, 618 insertions(+), 251 deletions(-)
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<PostLoansResponse> 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<PostLoansLoanIdTransactionsResponse> 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<PostLoansResponse> 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<Long> {
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<Long> {
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);
-
- // apply charges
- Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
+ 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);
- 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 charges
+ Integer feeCharge = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", false));
- // apply penalty
- Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
-
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
+ 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"));
- final String penaltyCharge1AddedDate =
DATE_FORMATTER.format(targetDate);
+ // apply penalty
+ Integer penalty = ChargesHelper.createCharges(requestSpec,
responseSpec,
+
ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT,
"10", true));
- Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
-
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
+ final String penaltyCharge1AddedDate =
DATE_FORMATTER.format(targetDate);
- // make Repayment
- final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
- new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("9 September 2022").locale("en")
- .transactionAmount(10.0));
+ Integer penalty1LoanChargeId =
this.loanTransactionHelper.addChargesForLoan(loanId,
+
LoanTransactionHelper.getSpecifiedDueDateChargesForLoanAsJSON(String.valueOf(penalty),
penaltyCharge1AddedDate, "10"));
- GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
+ // make Repayment
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd
MMMM yyyy").transactionDate("9 September 2022").locale("en")
+ .transactionAmount(10.0));
- // 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));
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
- loanDetails = this.loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
+ // 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));
- // 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());
+ loanDetails = this.loanTransactionHelper.getLoanDetails((long)
loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
- assertNotNull(journalEntriesForChargeOff);
+ // 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());
- List<JournalEntryTransactionItem> 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<JournalEntryTransactionItem> 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);
-
- // 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"));
-
- // 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());
-
- // verify Journal Entries For ChargeOff Transaction
- GetJournalEntriesTransactionIdResponse journalEntriesForChargeOff =
journalEntryHelper
- .getJournalEntries("L" +
chargeOffTransaction.getResourceId().toString());
-
- assertNotNull(journalEntriesForChargeOff);
- List<JournalEntryTransactionItem> 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(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(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));
-
- loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Repayment transaction
-
- GetJournalEntriesTransactionIdResponse journalEntriesForRepayment =
journalEntryHelper
- .getJournalEntries("L" +
repaymentTransaction.getResourceId().toString());
- assertNotNull(journalEntriesForRepayment);
-
- 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(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());
-
- // 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());
-
- // verify Journal Entries for Goodwill Credit
- GetJournalEntriesTransactionIdResponse journalEntriesForGoodWillCredit
= journalEntryHelper
- .getJournalEntries("L" +
goodwillCredit.getResourceId().toString());
- assertNotNull(journalEntriesForGoodWillCredit);
-
- 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(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));
+ 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));
+
+ 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));
+
+ 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());
+
+ assertNotNull(journalEntriesForChargeOff);
+ List<JournalEntryTransactionItem> 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(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(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));
+
+ loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Repayment transaction
+
+ GetJournalEntriesTransactionIdResponse journalEntriesForRepayment
= journalEntryHelper
+ .getJournalEntries("L" +
repaymentTransaction.getResourceId().toString());
+ assertNotNull(journalEntriesForRepayment);
+
+ 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(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());
+
+ // 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());
+
+ // verify Journal Entries for Goodwill Credit
+ GetJournalEntriesTransactionIdResponse
journalEntriesForGoodWillCredit = journalEntryHelper
+ .getJournalEntries("L" +
goodwillCredit.getResourceId().toString());
+ assertNotNull(journalEntriesForGoodWillCredit);
+
+ 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(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());
+
+ updateBusinessDate("16 September 2022");
+
+ // 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));
+
+ loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Repayment transaction
+ journalEntriesForRepayment =
journalEntryHelper.getJournalEntries("L" +
repaymentTransaction_1.getResourceId().toString());
+
+ assertNotNull(journalEntriesForRepayment);
+
+ journalEntries = journalEntriesForRepayment.getPageItems();
+ assertEquals(2, journalEntries.size());
+
+ 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());
+
+ 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());
+
+ // 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));
+
+ loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // verify Journal Entries for Goodwill Credit
+ journalEntriesForGoodWillCredit =
journalEntryHelper.getJournalEntries("L" +
goodwillCredit_1.getResourceId().toString());
+ assertNotNull(journalEntriesForGoodWillCredit);
+
+ journalEntries = journalEntriesForGoodWillCredit.getPageItems();
+ assertEquals(2, journalEntries.size());
- loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Repayment transaction
- journalEntriesForRepayment = journalEntryHelper.getJournalEntries("L"
+ repaymentTransaction_1.getResourceId().toString());
-
- assertNotNull(journalEntriesForRepayment);
-
- journalEntries = journalEntriesForRepayment.getPageItems();
- assertEquals(2, journalEntries.size());
-
- 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());
-
- 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());
-
- // 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));
-
- loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
- assertTrue(loanDetails.getStatus().getActive());
- assertTrue(loanDetails.getChargedOff());
-
- // verify Journal Entries for Goodwill Credit
- journalEntriesForGoodWillCredit =
journalEntryHelper.getJournalEntries("L" +
goodwillCredit_1.getResourceId().toString());
- assertNotNull(journalEntriesForGoodWillCredit);
-
- journalEntries = journalEntriesForGoodWillCredit.getPageItems();
- assertEquals(2, journalEntries.size());
-
- 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());
+ 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,