Skip to content

Commit 72b9748

Browse files
FINERACT-2389: Fix undo repayment with linked chargeback error handling
1 parent 2e38343 commit 72b9748

File tree

6 files changed

+86
-29
lines changed

6 files changed

+86
-29
lines changed

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanRepaymentStepDef.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,36 @@ private void adjustNthRepaymentWithExternalOwnerCheck(String nthItemStr, String
679679
loanTransactionAdjustmentDataV1 -> loanTransactionAdjustmentDataV1.getNewTransactionDetail().getExternalOwnerId())
680680
.isEqualTo(externalOwnerId);
681681
}
682+
}
683+
684+
@Then("Customer undo {string}th transaction made on {string} results a {int} error and {string} error message")
685+
public void undoTransactionResultsError(final String nthItemStr, final String transactionDate, final int errorCodeExpected,
686+
final String errorMessageCode) {
687+
eventStore.reset();
688+
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
689+
final PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
690+
assert loanResponse != null;
691+
final long loanId = loanResponse.getLoanId();
692+
final List<GetLoansLoanIdTransactions> transactions = ok(
693+
() -> fineractClient.loans().retrieveLoan(loanId, Map.<String, Object>of("associations", "transactions")))
694+
.getTransactions();
682695

696+
final int nthItem = Integer.parseInt(nthItemStr) - 1;
697+
assert transactions != null;
698+
final GetLoansLoanIdTransactions targetTransaction = transactions.stream().filter(t -> {
699+
assert t.getDate() != null;
700+
return transactionDate.equals(formatter.format(t.getDate()));
701+
}).toList().get(nthItem);
702+
703+
final PostLoansLoanIdTransactionsTransactionIdRequest transactionUndoRequest = LoanRequestFactory.defaultTransactionUndoRequest()
704+
.transactionDate(transactionDate);
705+
706+
final CallFailedRuntimeException exception = fail(() -> fineractClient.loanTransactions().adjustLoanTransaction(loanId,
707+
targetTransaction.getId(), transactionUndoRequest, Map.of()));
708+
709+
assertThat(exception.getStatus()).as(ErrorMessageHelper.wrongErrorCode(exception.getStatus(), errorCodeExpected))
710+
.isEqualTo(errorCodeExpected);
711+
assertThat(exception.getDeveloperMessage())
712+
.as(ErrorMessageHelper.wrongErrorMessage(exception.getDeveloperMessage(), errorMessageCode)).contains(errorMessageCode);
683713
}
684714
}

fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef/loan/LoanStepDef.java

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3319,26 +3319,6 @@ public void writeOffLoan(String transactionDate, String writeOffReason) {
33193319
testContext().set(TestContextKey.LOAN_WRITE_OFF_RESPONSE, writeOffResponse);
33203320
}
33213321

3322-
@Then("Admin fails to undo {string}th transaction made on {string}")
3323-
public void undoTransaction(String nthTransaction, String transactionDate) {
3324-
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
3325-
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);
3326-
long loanId = loanResponse.getLoanId();
3327-
List<GetLoansLoanIdTransactions> transactions = ok(() -> fineractClient.loans().retrieveLoan(loanId,
3328-
Map.of("staffInSelectedOfficeOnly", "false", "associations", "transactions"))).getTransactions();
3329-
3330-
int nthItem = Integer.parseInt(nthTransaction) - 1;
3331-
GetLoansLoanIdTransactions targetTransaction = transactions.stream()
3332-
.filter(t -> transactionDate.equals(formatter.format(t.getDate()))).toList().get(nthItem);
3333-
3334-
PostLoansLoanIdTransactionsTransactionIdRequest transactionUndoRequest = LoanRequestFactory.defaultTransactionUndoRequest()
3335-
.transactionDate(transactionDate);
3336-
3337-
CallFailedRuntimeException exception = fail(() -> fineractClient.loanTransactions().adjustLoanTransaction(loanId,
3338-
targetTransaction.getId(), transactionUndoRequest, Map.of()));
3339-
assertThat(exception.getStatus()).as(ErrorMessageHelper.dateFailureErrorCodeMsg()).isEqualTo(503);
3340-
}
3341-
33423322
@Then("Loan {string} repayment transaction on {string} with {double} EUR transaction amount results in error")
33433323
public void loanTransactionWithErrorCheck(String repaymentType, String transactionDate, double transactionAmount) {
33443324
PostLoansResponse loanResponse = testContext().get(TestContextKey.LOAN_CREATE_RESPONSE);

fineract-e2e-tests-runner/src/test/resources/features/LoanRepayment.feature

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6704,3 +6704,50 @@ Feature: LoanRepayment
67046704
| 27 October 2025 | Repayment | 0.4 | 0.4 | 0.0 | 0.0 | 0.0 | 0.0 | false | false |
67056705
Then Loan is closed with zero outstanding balance and it's all installments have obligations met
67066706

6707+
@TestRailId:C4648
6708+
Scenario: Verify repayment undo with linked chargeback fails with proper error
6709+
When Admin sets the business date to "01 January 2024"
6710+
When Admin creates a client with random data
6711+
When Admin creates a fully customized loan with the following data:
6712+
| 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 |
6713+
| LP2_ADV_PYMNT_INTEREST_DAILY_INTEREST_RECALC_EMI_360_30_CHARGEBACK_INTEREST_PENALTY_FEE_PRINCIPAL | 01 January 2024 | 100 | 7 | DECLINING_BALANCE | DAILY | EQUAL_INSTALLMENTS | 6 | MONTHS | 1 | MONTHS | 6 | 0 | 0 | 0 | ADVANCED_PAYMENT_ALLOCATION |
6714+
And Admin successfully approves the loan on "01 January 2024" with "100" amount and expected disbursement date on "01 January 2024"
6715+
When Admin successfully disburse the loan on "01 January 2024" with "100" EUR transaction amount
6716+
Then Loan Repayment schedule has 6 periods, with the following data for periods:
6717+
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
6718+
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
6719+
| 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 |
6720+
| 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 |
6721+
| 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 |
6722+
| 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 |
6723+
| 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 |
6724+
| 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 |
6725+
Then Loan Repayment schedule has the following data in Total row:
6726+
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
6727+
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 0.0 | 0.0 | 0.0 | 102.05 |
6728+
Then Loan Transactions tab has the following data:
6729+
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted |
6730+
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false |
6731+
When Admin sets the business date to "01 February 2024"
6732+
And Customer makes "AUTOPAY" repayment on "01 February 2024" with 17.01 EUR transaction amount
6733+
Then Loan Repayment schedule has 6 periods, with the following data for periods:
6734+
| Nr | Days | Date | Paid date | Balance of loan | Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
6735+
| | | 01 January 2024 | | 100.0 | | | 0.0 | | 0.0 | 0.0 | | | |
6736+
| 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 |
6737+
| 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 |
6738+
| 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 |
6739+
| 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 |
6740+
| 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 |
6741+
| 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 |
6742+
Then Loan Repayment schedule has the following data in Total row:
6743+
| Principal due | Interest | Fees | Penalties | Due | Paid | In advance | Late | Outstanding |
6744+
| 100.0 | 2.05 | 0.0 | 0.0 | 102.05 | 17.01 | 0.0 | 0.0 | 85.04 |
6745+
Then Loan Transactions tab has the following data:
6746+
| Transaction date | Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance | Reverted | Replayed |
6747+
| 01 January 2024 | Disbursement | 100.0 | 0.0 | 0.0 | 0.0 | 0.0 | 100.0 | false | false |
6748+
| 01 February 2024 | Repayment | 17.01 | 16.43 | 0.58 | 0.0 | 0.0 | 83.57 | false | false |
6749+
When Admin sets the business date to "15 March 2024"
6750+
When Admin makes "REPAYMENT_ADJUSTMENT_CHARGEBACK" chargeback with 17.01 EUR transaction amount
6751+
Then Customer undo "1"th transaction made on "01 February 2024" results a 403 error and "update not allowed as loan transaction is linked to other transactions" error message
6752+
When Loan Pay-off is made on "15 March 2024"
6753+
Then Loan is closed with zero outstanding balance and it's all installments have obligations met

fineract-e2e-tests-runner/src/test/resources/features/LoanWriteOff.feature

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
And Admin does write-off the loan on "29 January 2023"
1717
Then Loan status will be "CLOSED_WRITTEN_OFF"
1818
Then Loan Transactions tab has a transaction with date: "29 January 2023", and with the following data:
19-
| Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
19+
| Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
2020
| Close (as written-off) | 650.0 | 650.0 | 0.0 | 0.0 | 0.0 | 0.0 |
21-
Then Admin fails to undo "1"th transaction made on "22 January 2023"
21+
Then Customer undo "1"th transaction made on "22 January 2023" results a 403 error and "update not allowed as loan status is written off" error message
2222

2323

2424
@TestRailId:C2935
@@ -56,9 +56,9 @@
5656
And Admin does write-off the loan on "29 January 2023"
5757
Then Loan status will be "CLOSED_WRITTEN_OFF"
5858
Then Loan Transactions tab has a transaction with date: "29 January 2023", and with the following data:
59-
| Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
59+
| Transaction Type | Amount | Principal | Interest | Fees | Penalties | Loan Balance |
6060
| Close (as written-off) | 650.0 | 650.0 | 0.0 | 0.0 | 0.0 | 0.0 |
61-
Then Admin fails to undo "1"th transaction made on "29 January 2023"
61+
Then Customer undo "1"th transaction made on "29 January 2023" results a 403 error and "update not allowed as loan status is written off" error message
6262

6363
@TestRailId:C4006
6464
Scenario: Verify accounting journal entries are not duplicated during write-off in case the cumulative loan was already charged-off

fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/service/LoanWritePlatformServiceJpaRepositoryImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1195,16 +1195,16 @@ public CommandProcessingResult adjustLoanTransaction(final Long loanId, final Lo
11951195
businessEventNotifierService.notifyPreBusinessEvent(
11961196
new LoanAdjustTransactionBusinessEvent(new LoanAdjustTransactionBusinessEvent.Data(transactionToAdjust)));
11971197
if (this.accountTransfersReadPlatformService.isAccountTransfer(transactionId, PortfolioAccountType.LOAN)) {
1198-
throw new PlatformServiceUnavailableException("error.msg.loan.transfer.transaction.update.not.allowed",
1198+
throw new GeneralPlatformDomainRuleException("error.msg.loan.transfer.transaction.update.not.allowed",
11991199
"Loan transaction: " + transactionId + " update not allowed as it involves in account transfer", transactionId);
12001200
}
12011201
if (loan.isClosedWrittenOff()) {
1202-
throw new PlatformServiceUnavailableException("error.msg.loan.written.off.update.not.allowed",
1202+
throw new GeneralPlatformDomainRuleException("error.msg.loan.written.off.update.not.allowed",
12031203
"Loan transaction: " + transactionId + " update not allowed as loan status is written off", transactionId);
12041204
}
12051205

12061206
if (transactionToAdjust.hasChargebackLoanTransactionRelations()) {
1207-
throw new PlatformServiceUnavailableException("error.msg.loan.transaction.update.not.allowed",
1207+
throw new GeneralPlatformDomainRuleException("error.msg.loan.transaction.update.not.allowed",
12081208
"Loan transaction: " + transactionId + " update not allowed as loan transaction is linked to other transactions",
12091209
transactionId);
12101210
}

integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanWriteOffWithAdvancedPaymentAllocationTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public void loanUndoRepaymentAfterWriteOffShouldGiveErrorTest() {
148148
new PostLoansLoanIdTransactionsTransactionIdRequest().transactionDate("9 September 2022").locale("en")
149149
.dateFormat("dd MMMM yyyy").transactionAmount(0.0)));
150150

151-
assertEquals(503, exception.getResponse().code());
151+
assertEquals(403, exception.getResponse().code());
152152
assertTrue(exception.getMessage().contains("error.msg.loan.written.off.update.not.allowed"));
153153
}
154154

@@ -221,7 +221,7 @@ public void loanUndoWriteOffShouldGiveErrorTest() {
221221
new PostLoansLoanIdTransactionsTransactionIdRequest().transactionDate("8 September 2022").locale("en")
222222
.dateFormat("dd MMMM yyyy").transactionAmount(0.0)));
223223

224-
assertEquals(503, exception.getResponse().code());
224+
assertEquals(403, exception.getResponse().code());
225225
assertTrue(exception.getMessage().contains("error.msg.loan.written.off.update.not.allowed"));
226226
}
227227

0 commit comments

Comments
 (0)