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 be9e44fa44 FINERACT-2215: Exclude reversed transactions from
hasMonetaryActivityAfter check
be9e44fa44 is described below
commit be9e44fa447fc8e6603a81762ceeff88cd7ef4d2
Author: Abhinav Cillanki <[email protected]>
AuthorDate: Sat Mar 29 20:29:09 2025 +0530
FINERACT-2215: Exclude reversed transactions from hasMonetaryActivityAfter
check
---
.../portfolio/loanaccount/domain/Loan.java | 3 +-
.../LoanUndoChargeOffReverseExternalIdTest.java | 62 ++++++++++++++++++++++
2 files changed, 64 insertions(+), 1 deletion(-)
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 95550bbb08..37d8e17c9d 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
@@ -3529,7 +3529,8 @@ public class Loan extends
AbstractAuditableWithUTCDateTimeCustom<Long> {
public boolean hasMonetaryActivityAfter(final LocalDate transactionDate) {
for (LoanTransaction transaction : this.getLoanTransactions()) {
- if (transaction.getTransactionDate().isAfter(transactionDate) &&
!transaction.isNonMonetaryTransaction()) {
+ if (transaction.getTransactionDate().isAfter(transactionDate) &&
transaction.isNotReversed()
+ && !transaction.isNonMonetaryTransaction()) {
return true;
}
}
diff --git
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanUndoChargeOffReverseExternalIdTest.java
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanUndoChargeOffReverseExternalIdTest.java
index 5d7e89d44f..c61cd75e36 100644
---
a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanUndoChargeOffReverseExternalIdTest.java
+++
b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanUndoChargeOffReverseExternalIdTest.java
@@ -120,6 +120,68 @@ public class LoanUndoChargeOffReverseExternalIdTest {
assertEquals(reverseTransactionExternalId,
chargeOffTransactionDetails.getReversalExternalId());
}
+ /**
+ * Test scenario: - Charge-off is performed. - Charge-off is then undone.
- A new charge-off is performed with an
+ * earlier transaction date. This verifies that reversed transactions are
properly excluded so that the new
+ * charge-off is allowed.
+ */
+ @Test
+ public void loanChargeOffAfterUndoWithEarlierDateTest() {
+ // Loan ExternalId
+ String loanExternalIdStr = UUID.randomUUID().toString();
+
+ final Integer loanProductID =
createLoanProductWithPeriodicAccrualAccounting(assetAccount, incomeAccount,
expenseAccount,
+ overpaymentAccount);
+ final Integer clientId =
clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId().intValue();
+ final Integer loanId = createLoanAccount(clientId, loanProductID,
loanExternalIdStr);
+
+ // make Repayment
+ final PostLoansLoanIdTransactionsResponse repaymentTransaction =
loanTransactionHelper.makeLoanRepayment(loanExternalIdStr,
+ new PostLoansLoanIdTransactionsRequest().dateFormat("dd MMMM
yyyy").transactionDate("28 March 2025").locale("en")
+ .transactionAmount(100.0));
+
+ GetLoansLoanIdResponse loanDetails =
this.loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+
+ // Perform first charge-off with date "29 March 2025"
+ String randomText1 = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
+ Integer chargeOffReasonId1 =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText1, 1);
+ String transactionExternalId1 = UUID.randomUUID().toString();
+ loanTransactionHelper.chargeOffLoan((long) loanId, new
PostLoansLoanIdTransactionsRequest().transactionDate("29 March 2025")
+ .locale("en").dateFormat("dd MMMM
yyyy").externalId(transactionExternalId1).chargeOffReasonId((long)
chargeOffReasonId1));
+
+ loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // Undo the charge-off
+ String reverseTransactionExternalId = UUID.randomUUID().toString();
+ PostLoansLoanIdTransactionsResponse undoChargeOffTxResponse =
loanTransactionHelper.undoChargeOffLoan((long) loanId,
+ new
PostLoansLoanIdTransactionsRequest().reversalExternalId(reverseTransactionExternalId));
+ assertNotNull(undoChargeOffTxResponse);
+
+ loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
+ assertTrue(loanDetails.getStatus().getActive());
+ assertFalse(loanDetails.getChargedOff());
+
+ // Perform a new charge-off with an earlier date ("28 March 2025")
than the first charge-off
+ String randomText2 = Utils.randomStringGenerator("en", 5) +
Utils.randomNumberGenerator(6) + Utils.randomStringGenerator("is", 5);
+ Integer chargeOffReasonId2 =
CodeHelper.createChargeOffCodeValue(requestSpec, responseSpec, randomText2, 1);
+ String transactionExternalId2 = UUID.randomUUID().toString();
+ loanTransactionHelper.chargeOffLoan((long) loanId, new
PostLoansLoanIdTransactionsRequest().transactionDate("28 March 2025")
+ .locale("en").dateFormat("dd MMMM
yyyy").externalId(transactionExternalId2).chargeOffReasonId((long)
chargeOffReasonId2));
+
+ loanDetails = loanTransactionHelper.getLoanDetails((long) loanId);
+ // After the new charge-off, the loan should be charged off
+ assertTrue(loanDetails.getStatus().getActive());
+ assertTrue(loanDetails.getChargedOff());
+
+ // Verify the new charge-off transaction details
+ GetLoansLoanIdTransactionsTransactionIdResponse
newChargeOffTransactionDetails = loanTransactionHelper
+ .getLoanTransactionDetails((long) loanId,
transactionExternalId2);
+ assertNotNull(newChargeOffTransactionDetails);
+ }
+
private Integer createLoanAccount(final Integer clientID, final Integer
loanProductID, final String externalId) {
String loanApplicationJSON = new
LoanApplicationTestBuilder().withPrincipal("1000").withLoanTermFrequency("1")