diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java index 0b4cd0672be..d9351deee71 100644 --- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java +++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccrualBasedAccountingProcessorForLoan.java @@ -1104,13 +1104,13 @@ private void createJournalEntriesForLoanCreditBalanceRefund(final LoanDTO loanDT if (principalAmount != null && principalAmount.compareTo(BigDecimal.ZERO) > 0) { totalAmount = totalAmount.add(principalAmount); - journalAmountHolders.add( - new JournalAmountHolder(determineAccrualAccount(isMarkedChargeOff, isMarkedFraud, false, isReversal), principalAmount)); + journalAmountHolders + .add(new JournalAmountHolder(determineAccrualAccountForCBR(isMarkedChargeOff, isMarkedFraud, false), principalAmount)); } if (overpaymentAmount != null && overpaymentAmount.compareTo(BigDecimal.ZERO) > 0) { totalAmount = totalAmount.add(overpaymentAmount); - journalAmountHolders.add(new JournalAmountHolder(determineAccrualAccount(isMarkedChargeOff, isMarkedFraud, true, isReversal), - overpaymentAmount)); + journalAmountHolders + .add(new JournalAmountHolder(determineAccrualAccountForCBR(isMarkedChargeOff, isMarkedFraud, true), overpaymentAmount)); } JournalAmountHolder totalAmountHolder = new JournalAmountHolder(AccrualAccountsForLoan.FUND_SOURCE.getValue(), totalAmount); @@ -1119,16 +1119,16 @@ private void createJournalEntriesForLoanCreditBalanceRefund(final LoanDTO loanDT } - private Integer determineAccrualAccount(boolean isMarkedChargeOff, boolean isMarkedFraud, boolean isOverpayment, boolean isReversal) { - if (isMarkedChargeOff && isReversal) { - if (isMarkedFraud) { - return AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(); - } else { - return AccrualAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(); - } + private Integer determineAccrualAccountForCBR(boolean isMarkedChargeOff, boolean isMarkedFraud, boolean isOverpayment) { + if (isOverpayment) { + return AccrualAccountsForLoan.OVERPAYMENT.getValue(); } else { - if (isOverpayment) { - return AccrualAccountsForLoan.OVERPAYMENT.getValue(); + if (isMarkedChargeOff) { + if (isMarkedFraud) { + return AccrualAccountsForLoan.CHARGE_OFF_FRAUD_EXPENSE.getValue(); + } else { + return AccrualAccountsForLoan.CHARGE_OFF_EXPENSE.getValue(); + } } else { return AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(); } diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java index 7340699763c..f73ff45a34b 100644 --- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java +++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionReverseReplayTest.java @@ -37,6 +37,7 @@ import org.apache.fineract.client.models.BusinessDateRequest; import org.apache.fineract.client.models.GetLoanProductsProductIdResponse; import org.apache.fineract.client.models.GetLoansLoanIdResponse; +import org.apache.fineract.client.models.GetLoansLoanIdTransactions; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsRequest; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsResponse; import org.apache.fineract.client.models.PostLoansLoanIdTransactionsTransactionIdRequest; @@ -305,37 +306,55 @@ public void loanTransactionReverseReplayWithChargeOffAndCBR() { new PostLoansLoanIdTransactionsTransactionIdRequest().transactionDate("06 October 2022").locale("en") .dateFormat(DATE_PATTERN).transactionAmount(0.0)); + // check if the original CBR got reversed + journalEntriesForCBR = journalEntryHelper + .getJournalEntriesByTransactionId("L" + cbrTransactionResponse.getResourceId().toString()); + assertNotNull(journalEntriesForCBR); + cbrExpenseJournalEntries = journalEntriesForCBR.stream() // + .filter(journalEntry -> assetAccount.getAccountID().equals(journalEntry.get("glAccountId"))) // + .toList(); + + cbrAssetJournalEntries = journalEntriesForCBR.stream() // + .filter(journalEntry -> overpaymentAccount.getAccountID().equals(journalEntry.get("glAccountId"))) // + .toList(); + + assertEquals(2, cbrExpenseJournalEntries.size()); + assertEquals(2, cbrAssetJournalEntries.size()); + inlineLoanCOBHelper.executeInlineCOB(List.of(loanId.longValue())); loansLoanIdResponse = loanTransactionHelper.getLoanDetails(loanExternalIdStr); lastTransactionIndex = loansLoanIdResponse.getTransactions().size() - 1; assertEquals(500.0, loansLoanIdResponse.getTransactions().get(lastTransactionIndex).getAmount()); - journalEntriesForCBR = journalEntryHelper - .getJournalEntriesByTransactionId("L" + cbrTransactionResponse.getResourceId().toString()); + // replayed CBR transaction + GetLoansLoanIdTransactions newCBRTransaction = loansLoanIdResponse.getTransactions().stream() + .filter(transaction -> transaction.getType().getCreditBalanceRefund()).findFirst().orElse(null); + + assertNotNull(newCBRTransaction); + + Long newCBRTransactionId = newCBRTransaction.getId(); + + journalEntriesForCBR = journalEntryHelper.getJournalEntriesByTransactionId("L" + newCBRTransactionId); ArrayList journalEntriesForChargeOff = journalEntryHelper .getJournalEntriesByTransactionId("L" + chargeOffResponse.getResourceId().toString()); assertNotNull(journalEntriesForCBR); assertNotNull(journalEntriesForChargeOff); - String expenseGlAccountCodeAfterReversal = (String) journalEntriesForChargeOff.get(0).get("glAccountCode"); - String assetGlAccountCodeAfterReversal = (String) journalEntriesForChargeOff.get(1).get("glAccountCode"); + String expenseGlAccountCodeForChargeOff = (String) journalEntriesForChargeOff.get(0).get("glAccountCode"); + String assetGlAccountCodeForChargeOff = (String) journalEntriesForChargeOff.get(1).get("glAccountCode"); cbrExpenseJournalEntries = journalEntriesForCBR.stream() // - .filter(journalEntry -> expenseGlAccountCodeAfterReversal.equals(journalEntry.get("glAccountCode"))) // + .filter(journalEntry -> expenseGlAccountCodeForChargeOff.equals(journalEntry.get("glAccountCode")) + && expenseAccount.getAccountID().equals(journalEntry.get("glAccountId"))) // .toList(); cbrAssetJournalEntries = journalEntriesForCBR.stream() // - .filter(journalEntry -> assetGlAccountCodeAfterReversal.equals(journalEntry.get("glAccountCode"))) // - .toList(); - - List cbrExpenseJournalEntriesAfterReversal = journalEntriesForCBR.stream() // - .filter(journalEntry -> expenseGlAccountCodeAfterReversal.equals(journalEntry.get("glAccountCode")) // - && expenseAccount.getAccountID().equals(journalEntry.get("glAccountId"))) // + .filter(journalEntry -> assetGlAccountCodeForChargeOff.equals(journalEntry.get("glAccountCode")) + && assetAccount.getAccountID().equals(journalEntry.get("glAccountId"))) // .toList(); assertEquals(1, cbrExpenseJournalEntries.size()); - assertEquals(1, cbrExpenseJournalEntriesAfterReversal.size()); - assertEquals(2, cbrAssetJournalEntries.size()); + assertEquals(1, cbrAssetJournalEntries.size()); } finally { GlobalConfigurationHelper.updateIsBusinessDateEnabled(requestSpec, responseSpec, Boolean.FALSE); }