FINERACT-2042 Chargeback with credit allocation, accounting
diff --git a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
index 960ef61..1b737fe 100644
--- a/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
+++ b/fineract-loan/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransaction.java
@@ -35,6 +35,7 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import org.apache.fineract.infrastructure.core.domain.AbstractAuditableWithUTCDateTimeCustom;
 import org.apache.fineract.infrastructure.core.domain.ExternalId;
@@ -763,7 +764,14 @@
         thisTransactionData.put("currencyCode", currencyCode);
         thisTransactionData.put("amount", this.amount);
         thisTransactionData.put("netDisbursalAmount", this.loan.getNetDisbursalAmount());
-        thisTransactionData.put("principalPortion", this.principalPortion);
+
+        if (transactionType.isChargeback()
+                && (getLoan().getCreditAllocationRules() == null || getLoan().getCreditAllocationRules().size() == 0)) {
+            thisTransactionData.put("principalPortion", this.amount);
+        } else {
+            thisTransactionData.put("principalPortion", this.principalPortion);
+        }
+
         thisTransactionData.put("interestPortion", this.interestPortion);
         thisTransactionData.put("feeChargesPortion", this.feeChargesPortion);
         thisTransactionData.put("penaltyChargesPortion", this.penaltyChargesPortion);
@@ -790,6 +798,26 @@
             thisTransactionData.put("loanChargesPaid", loanChargesPaidData);
         }
 
+        if (transactionType.isChargeback() && this.overPaymentPortion != null && this.overPaymentPortion.compareTo(BigDecimal.ZERO) > 0) {
+            BigDecimal principalPaid = overPaymentPortion;
+            BigDecimal feePaid = BigDecimal.ZERO;
+            BigDecimal penaltyPaid = BigDecimal.ZERO;
+            if (getLoanTransactionToRepaymentScheduleMappings().size() > 0) {
+                principalPaid = getLoanTransactionToRepaymentScheduleMappings().stream()
+                        .map(mapping -> Optional.ofNullable(mapping.getPrincipalPortion()).orElse(BigDecimal.ZERO))
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                feePaid = getLoanTransactionToRepaymentScheduleMappings().stream()
+                        .map(mapping -> Optional.ofNullable(mapping.getFeeChargesPortion()).orElse(BigDecimal.ZERO))
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+                penaltyPaid = getLoanTransactionToRepaymentScheduleMappings().stream()
+                        .map(mapping -> Optional.ofNullable(mapping.getPenaltyChargesPortion()).orElse(BigDecimal.ZERO))
+                        .reduce(BigDecimal.ZERO, BigDecimal::add);
+            }
+            thisTransactionData.put("principalPaid", principalPaid);
+            thisTransactionData.put("feePaid", feePaid);
+            thisTransactionData.put("penaltyPaid", penaltyPaid);
+        }
+
         LoanTransactionRelation loanTransactionRelation = loanTransactionRelations.stream()
                 .filter(e -> LoanTransactionRelationTypeEnum.CHARGE_ADJUSTMENT.equals(e.getRelationType())).findAny().orElse(null);
         if (loanTransactionRelation != null) {
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
index bd9ebf2..07defb6 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/data/LoanTransactionDTO.java
@@ -60,4 +60,9 @@
 
     private final String chargeRefundChargeType;
     private final LoanChargeData loanChargeData;
+
+    /** In case chargeback and overpayment the below field contains the distribution payment **/
+    private final BigDecimal principalPaid;
+    private final BigDecimal feePaid;
+    private final BigDecimal penaltyPaid;
 }
diff --git a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
index 804184c..d3ca6da 100644
--- a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
+++ b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/AccountingProcessorHelper.java
@@ -156,9 +156,15 @@
                 isAccountTransfer = this.accountTransfersReadPlatformService.isAccountTransfer(Long.parseLong(transactionId),
                         PortfolioAccountType.LOAN);
             }
+
+            BigDecimal principalPaid = (BigDecimal) map.get("principalPaid");
+            BigDecimal feePaid = (BigDecimal) map.get("feePaid");
+            BigDecimal penaltyPaid = (BigDecimal) map.get("penaltyPaid");
+
             final LoanTransactionDTO transaction = new LoanTransactionDTO(transactionOfficeId, paymentTypeId, transactionId,
                     transactionDate, transactionType, amount, principal, interest, fees, penalties, overPayments, reversed,
-                    penaltyPaymentDetails, feePaymentDetails, isAccountTransfer, chargeRefundChargeType, loanChargeData);
+                    penaltyPaymentDetails, feePaymentDetails, isAccountTransfer, chargeRefundChargeType, loanChargeData, principalPaid,
+                    feePaid, penaltyPaid);
             Boolean isLoanToLoanTransfer = (Boolean) accountingBridgeData.get("isLoanToLoanTransfer");
             transaction.setLoanToLoanTransfer(isLoanToLoanTransfer != null && isLoanToLoanTransfer);
             newLoanTransactions.add(transaction);
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 f0ed03e..d92657b 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
@@ -430,25 +430,54 @@
         final BigDecimal overpaidAmount = Objects.isNull(loanTransactionDTO.getOverPayment()) ? BigDecimal.ZERO
                 : loanTransactionDTO.getOverPayment();
 
-        if (BigDecimal.ZERO.compareTo(overpaidAmount) == 0) { // when no overpay
-            helper.createJournalEntriesAndReversalsForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
-                    AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
-                    amount, isReversal);
-        } else if (overpaidAmount.compareTo(amount) >= 0) { // when the overpay amount is matching with the normal
-                                                            // amount
-            helper.createJournalEntriesAndReversalsForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
-                    AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
-                    amount, isReversal);
-        } else {
-            BigDecimal diff = amount.subtract(overpaidAmount);
-            helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
-                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, diff, isReversal);
-            helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, amount, isReversal);
+        final BigDecimal principalCredited = Objects.isNull(loanTransactionDTO.getPrincipal()) ? BigDecimal.ZERO
+                : loanTransactionDTO.getPrincipal();
+        final BigDecimal feeCredited = Objects.isNull(loanTransactionDTO.getFees()) ? BigDecimal.ZERO : loanTransactionDTO.getFees();
+        final BigDecimal penaltyCredited = Objects.isNull(loanTransactionDTO.getPenalties()) ? BigDecimal.ZERO
+                : loanTransactionDTO.getPenalties();
+
+        final BigDecimal principalPaid = Objects.isNull(loanTransactionDTO.getPrincipalPaid()) ? BigDecimal.ZERO
+                : loanTransactionDTO.getPrincipalPaid();
+        final BigDecimal feePaid = Objects.isNull(loanTransactionDTO.getFeePaid()) ? BigDecimal.ZERO : loanTransactionDTO.getFeePaid();
+        final BigDecimal penaltyPaid = Objects.isNull(loanTransactionDTO.getPenaltyPaid()) ? BigDecimal.ZERO
+                : loanTransactionDTO.getPenaltyPaid();
+
+        helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.FUND_SOURCE, loanProductId,
+                paymentTypeId, loanId, transactionId, transactionDate, amount, isReversal);
+
+        if (overpaidAmount.compareTo(BigDecimal.ZERO) > 0) {
             helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
                     loanProductId, paymentTypeId, loanId, transactionId, transactionDate, overpaidAmount, isReversal);
         }
 
+        if (principalCredited.compareTo(principalPaid) > 0) {
+            helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalCredited.subtract(principalPaid),
+                    isReversal);
+        } else if (principalCredited.compareTo(principalPaid) < 0) {
+            helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, principalPaid.subtract(principalCredited),
+                    isReversal);
+        }
+
+        if (feeCredited.compareTo(feePaid) > 0) {
+            helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(),
+                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, feeCredited.subtract(feePaid), isReversal);
+        } else if (feeCredited.compareTo(feePaid) < 0) {
+            helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(),
+                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, feePaid.subtract(feeCredited), isReversal);
+        }
+
+        if (penaltyCredited.compareTo(penaltyPaid) > 0) {
+            helper.createDebitJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(),
+                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, penaltyCredited.subtract(penaltyPaid),
+                    isReversal);
+        } else if (penaltyCredited.compareTo(penaltyPaid) < 0) {
+            helper.createCreditJournalEntryOrReversalForLoan(office, currencyCode, AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(),
+                    loanProductId, paymentTypeId, loanId, transactionId, transactionDate, penaltyPaid.subtract(penaltyCredited),
+                    isReversal);
+        }
+
     }
 
     /**
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
index d6cb8f4..aa1bd5e 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/AdvancedPaymentAllocationLoanRepaymentScheduleTest.java
@@ -3194,13 +3194,13 @@
             );
             // verify journal entries
             verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
                     journalEntry(50.0, overpaymentAccount, "CREDIT"), //
-                    journalEntry(150.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(150.0, fundSource, "DEBIT"), //
                     journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
                     journalEntry(50.0, overpaymentAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(100.0, fundSource, "CREDIT") //
             );
         });
     }
@@ -3273,12 +3273,12 @@
             );
             // verify journal entries
             verifyJournalEntries(loanResponse.getLoanId(), journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
                     journalEntry(50.0, overpaymentAccount, "CREDIT"), //
-                    journalEntry(150.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(150.0, fundSource, "DEBIT"), //
                     journalEntry(28.0, overpaymentAccount, "DEBIT"), //
-                    journalEntry(28.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(28.0, fundSource, "CREDIT") //
             );
         });
     }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
index fc4aaf2..bcd50f5 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/BaseLoanIntegrationTest.java
@@ -72,6 +72,7 @@
 import org.apache.fineract.integrationtests.common.BusinessDateHelper;
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
+import org.apache.fineract.integrationtests.common.SchedulerJobHelper;
 import org.apache.fineract.integrationtests.common.Utils;
 import org.apache.fineract.integrationtests.common.accounting.Account;
 import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
@@ -114,6 +115,7 @@
     protected final LoanProductHelper loanProductHelper = new LoanProductHelper();
     protected JournalEntryHelper journalEntryHelper = new JournalEntryHelper(requestSpec, responseSpec);
     protected ClientHelper clientHelper = new ClientHelper(requestSpec, responseSpec);
+    protected SchedulerJobHelper schedulerJobHelper = new SchedulerJobHelper(requestSpec);
     protected final InlineLoanCOBHelper inlineLoanCOBHelper = new InlineLoanCOBHelper(requestSpec, responseSpec);
 
     protected BusinessDateHelper businessDateHelper = new BusinessDateHelper();
@@ -123,18 +125,22 @@
     protected DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DATETIME_PATTERN);
 
     // asset
-    protected final Account loansReceivableAccount = accountHelper.createAssetAccount();
-    protected final Account interestFeeReceivableAccount = accountHelper.createAssetAccount();
-    protected final Account suspenseAccount = accountHelper.createAssetAccount();
+    protected final Account loansReceivableAccount = accountHelper.createAssetAccount("loanPortfolio");
+
+    protected final Account interestReceivableAccount = accountHelper.createAssetAccount("interestReceivable");
+    protected final Account feeReceivableAccount = accountHelper.createAssetAccount("feeReceivable");
+    protected final Account penaltyReceivableAccount = accountHelper.createAssetAccount("penaltyReceivable");
+    protected final Account suspenseAccount = accountHelper.createAssetAccount("suspense");
     // liability
-    protected final Account suspenseClearingAccount = accountHelper.createLiabilityAccount();
-    protected final Account overpaymentAccount = accountHelper.createLiabilityAccount();
+    protected final Account fundSource = accountHelper.createLiabilityAccount("fundSource");
+    protected final Account overpaymentAccount = accountHelper.createLiabilityAccount("overpayment");
     // income
-    protected final Account interestIncomeAccount = accountHelper.createIncomeAccount();
-    protected final Account feeIncomeAccount = accountHelper.createIncomeAccount();
-    protected final Account feeChargeOffAccount = accountHelper.createIncomeAccount();
-    protected final Account recoveriesAccount = accountHelper.createIncomeAccount();
-    protected final Account interestIncomeChargeOffAccount = accountHelper.createIncomeAccount();
+    protected final Account interestIncomeAccount = accountHelper.createIncomeAccount("interestIncome");
+    protected final Account feeIncomeAccount = accountHelper.createIncomeAccount("feeIncome");
+    protected final Account penaltyIncomeAccount = accountHelper.createIncomeAccount("penaltyIncome");
+    protected final Account feeChargeOffAccount = accountHelper.createIncomeAccount("feeChargeOff");
+    protected final Account recoveriesAccount = accountHelper.createIncomeAccount("recoveries");
+    protected final Account interestIncomeChargeOffAccount = accountHelper.createIncomeAccount("interestIncomeChargeOff");
     // expense
     protected final Account creditLossBadDebtAccount = accountHelper.createExpenseAccount();
     protected final Account creditLossBadDebtFraudAccount = accountHelper.createExpenseAccount();
@@ -159,6 +165,7 @@
                 .includeInBorrowerCycle(false)//
                 .currencyCode("USD")//
                 .digitsAfterDecimal(2)//
+                .inMultiplesOf(0)//
                 .installmentAmountInMultiplesOf(1)//
                 .useBorrowerCycle(false)//
                 .minPrincipal(100.0)//
@@ -207,24 +214,18 @@
                 .outstandingLoanBalance(10000.0)//
                 .charges(Collections.emptyList())//
                 .accountingRule(3)//
-                .fundSourceAccountId(suspenseClearingAccount.getAccountID().longValue())//
+                .fundSourceAccountId(fundSource.getAccountID().longValue())//
                 .loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
                 .transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
                 .interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
                 .incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())//
-                .incomeFromPenaltyAccountId(feeIncomeAccount.getAccountID().longValue())//
+                .incomeFromPenaltyAccountId(penaltyIncomeAccount.getAccountID().longValue())//
                 .incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())//
                 .writeOffAccountId(writtenOffAccount.getAccountID().longValue())//
                 .overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())//
-                .receivableInterestAccountId(interestFeeReceivableAccount.getAccountID().longValue())//
-                .receivableFeeAccountId(interestFeeReceivableAccount.getAccountID().longValue())//
-                .receivablePenaltyAccountId(interestFeeReceivableAccount.getAccountID().longValue())//
-                .dateFormat(DATETIME_PATTERN)//
-                .locale("en_GB")//
-                .disallowExpectedDisbursements(true)//
-                .allowApprovedDisbursedAmountsOverApplied(true)//
-                .overAppliedCalculationType("percentage")//
-                .overAppliedNumber(50)//
+                .receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())//
+                .receivableFeeAccountId(feeReceivableAccount.getAccountID().longValue())//
+                .receivablePenaltyAccountId(penaltyReceivableAccount.getAccountID().longValue())//
                 .goodwillCreditAccountId(goodwillExpenseAccount.getAccountID().longValue())//
                 .incomeFromGoodwillCreditInterestAccountId(interestIncomeChargeOffAccount.getAccountID().longValue())//
                 .incomeFromGoodwillCreditFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
@@ -233,7 +234,12 @@
                 .incomeFromChargeOffFeesAccountId(feeChargeOffAccount.getAccountID().longValue())//
                 .chargeOffExpenseAccountId(creditLossBadDebtAccount.getAccountID().longValue())//
                 .chargeOffFraudExpenseAccountId(creditLossBadDebtFraudAccount.getAccountID().longValue())//
-                .incomeFromChargeOffPenaltyAccountId(feeChargeOffAccount.getAccountID().longValue());
+                .incomeFromChargeOffPenaltyAccountId(feeChargeOffAccount.getAccountID().longValue()).dateFormat(DATETIME_PATTERN)//
+                .locale("en_GB")//
+                .disallowExpectedDisbursements(true)//
+                .allowApprovedDisbursedAmountsOverApplied(true)//
+                .overAppliedCalculationType("percentage")//
+                .overAppliedNumber(50);
     }
 
     protected PostLoanProductsRequest createOnePeriod30DaysLongNoInterestPeriodicAccrualProductWithAdvancedPaymentAllocation() {
@@ -344,7 +350,7 @@
                 boolean found = loanDetails.getTransactions().stream().anyMatch(item -> Objects.equals(item.getAmount(), tr.amount) //
                         && Objects.equals(item.getType().getValue(), tr.type) //
                         && Objects.equals(item.getDate(), LocalDate.parse(tr.date, dateTimeFormatter)) //
-                        && Objects.equals(item.getOutstandingLoanBalance(), tr.outstandingAmount) //
+                        && Objects.equals(item.getOutstandingLoanBalance(), tr.outstandingPrincipal) //
                         && Objects.equals(item.getPrincipalPortion(), tr.principalPortion) //
                         && Objects.equals(item.getInterestPortion(), tr.interestPortion) //
                         && Objects.equals(item.getFeeChargesPortion(), tr.feePortion) //
@@ -416,6 +422,18 @@
         });
     }
 
+    protected void verifyTRJournalEntries(Long transactionId, Journal... entries) {
+        GetJournalEntriesTransactionIdResponse journalEntriesForLoan = journalEntryHelper.getJournalEntries("L" + transactionId.toString());
+        Assertions.assertEquals(entries.length, journalEntriesForLoan.getPageItems().size());
+        Arrays.stream(entries).forEach(journalEntry -> {
+            boolean found = journalEntriesForLoan.getPageItems().stream()
+                    .anyMatch(item -> Objects.equals(item.getAmount(), journalEntry.amount)
+                            && Objects.equals(item.getGlAccountId(), journalEntry.account.getAccountID().longValue())
+                            && Objects.requireNonNull(item.getEntryType()).getValue().equals(journalEntry.type));
+            Assertions.assertTrue(found, "Required journal entry not found: " + journalEntry);
+        });
+    }
+
     protected Long addCharge(Long loanId, boolean isPenalty, double amount, String dueDate) {
         Integer chargeId = ChargesHelper.createCharges(requestSpec, responseSpec,
                 ChargesHelper.getLoanSpecifiedDueDateJSON(ChargesHelper.CHARGE_CALCULATION_TYPE_FLAT, String.valueOf(amount), isPenalty));
@@ -602,9 +620,10 @@
         return response.getResourceId();
     }
 
-    protected void addChargebackForLoan(Long loanId, Long transactionId, Double amount) {
-        loanTransactionHelper.chargebackLoanTransaction(loanId, transactionId,
+    protected Long addChargebackForLoan(Long loanId, Long transactionId, Double amount) {
+        PostLoansLoanIdTransactionsResponse response = loanTransactionHelper.chargebackLoanTransaction(loanId, transactionId,
                 new PostLoansLoanIdTransactionsTransactionIdRequest().locale("en").transactionAmount(amount).paymentTypeId(1L));
+        return response.getResourceId();
     }
 
     protected PostChargesResponse createCharge(Double amount) {
@@ -627,8 +646,22 @@
                 new BusinessDateRequest().type(BUSINESS_DATE.getName()).date(date).dateFormat(DATETIME_PATTERN).locale("en"));
     }
 
-    protected Journal journalEntry(double principalAmount, Account account, String type) {
-        return new Journal(principalAmount, account, type);
+    protected Long getTransactionId(Long loanId, String type, String date) {
+        GetLoansLoanIdResponse loan = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
+        return loan.getTransactions().stream().filter(tr -> Objects.equals(tr.getType().getValue(), type)
+                && Objects.equals(tr.getDate(), LocalDate.parse(date, dateTimeFormatter))).findAny().orElseThrow().getId();
+    }
+
+    protected Journal journalEntry(double amount, Account account, String type) {
+        return new Journal(amount, account, type);
+    }
+
+    protected Journal debit(Account account, double amount) {
+        return new Journal(amount, account, "DEBIT");
+    }
+
+    protected Journal credit(Account account, double amount) {
+        return new Journal(amount, account, "CREDIT");
     }
 
     protected Transaction transaction(double principalAmount, String type, String date) {
@@ -639,16 +672,16 @@
         return new Transaction(principalAmount, type, date, true);
     }
 
-    protected TransactionExt transaction(double amount, String type, String date, double outstandingAmount, double principalPortion,
+    protected TransactionExt transaction(double amount, String type, String date, double outstandingPrincipal, double principalPortion,
             double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion, double overpaymentPortion) {
-        return new TransactionExt(amount, type, date, outstandingAmount, principalPortion, interestPortion, feePortion, penaltyPortion,
+        return new TransactionExt(amount, type, date, outstandingPrincipal, principalPortion, interestPortion, feePortion, penaltyPortion,
                 unrecognizedIncomePortion, overpaymentPortion, false);
     }
 
-    protected TransactionExt transaction(double amount, String type, String date, double outstandingAmount, double principalPortion,
+    protected TransactionExt transaction(double amount, String type, String date, double outstandingPrincipal, double principalPortion,
             double interestPortion, double feePortion, double penaltyPortion, double unrecognizedIncomePortion, double overpaymentPortion,
             boolean reversed) {
-        return new TransactionExt(amount, type, date, outstandingAmount, principalPortion, interestPortion, feePortion, penaltyPortion,
+        return new TransactionExt(amount, type, date, outstandingPrincipal, principalPortion, interestPortion, feePortion, penaltyPortion,
                 unrecognizedIncomePortion, overpaymentPortion, reversed);
     }
 
@@ -765,7 +798,7 @@
         Double amount;
         String type;
         String date;
-        Double outstandingAmount;
+        Double outstandingPrincipal;
         Double principalPortion;
         Double interestPortion;
         Double feePortion;
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
index 63ae1b1..ccb3e1a 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanChargebackWithCreditAllocationsIntegrationTests.java
@@ -1011,6 +1011,455 @@
         });
     }
 
+    @Test
+    public void testAccountingChargebackOnPrincipal() {
+        runAt("01 January 2023", () -> {
+            // Create Client
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            // Create Loan Product
+            Long loanProductId = createLoanProduct(//
+                    createDefaultPaymentAllocation(), //
+                    chargebackAllocation("PENALTY", "FEE", "INTEREST", "PRINCIPAL")//
+            );
+            // Apply and Approve Loan
+            Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+            // Disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+            verifyRepaymentSchedule(loanId, //
+                    installment(0, null, "01 January 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") //
+            );
+
+            // Repayment #1
+            updateBusinessDate("01 February 2023");
+            Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0, "01 February 2023");
+
+            // Repayment #2
+            updateBusinessDate("01 March 2023");
+            Long repaymentTransaction2 = addRepaymentForLoan(loanId, 250.0, "01 March 2023");
+
+            // Repayment #3
+            updateBusinessDate("30 March 2023");
+            Long repaymentTransaction3 = addRepaymentForLoan(loanId, 250.0, "30 March 2023");
+
+            // Chargeback 250
+            Long chargeback = addChargebackForLoan(loanId, repaymentTransaction2, 250.0);
+
+            verifyTransactions(loanId, //
+                    transaction(750.0, "Disbursement", "01 January 2023", 750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 February 2023", 500.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 March 2023", 250.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "30 March 2023", 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Chargeback", "30 March 2023", 250, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0) //
+            );
+
+            // Verify GL entries
+            verifyTRJournalEntries(repaymentTransaction1, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250)//
+            );
+
+            verifyTRJournalEntries(repaymentTransaction2, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction3, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250)//
+            );
+
+            verifyTRJournalEntries(chargeback, //
+                    debit(loansReceivableAccount, 250), //
+                    credit(fundSource, 250) //
+            );
+
+        });
+    }
+
+    @Test
+    public void testAccountingChargebackOnPrincipalAndFees() {
+        runAt("01 January 2023", () -> {
+            // Create Client
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            // Create Loan Product
+            Long loanProductId = createLoanProduct(//
+                    createDefaultPaymentAllocation(), //
+                    chargebackAllocation("PENALTY", "FEE", "INTEREST", "PRINCIPAL")//
+            );
+            // Apply and Approve Loan
+            Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+            // Disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+            Long feeId = addCharge(loanId, false, 30, "15 February 2023");
+
+            verifyRepaymentSchedule(loanId, //
+                    installment(0, null, "01 January 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), //
+                    installment(250.0, 0, 30, 0, 280.0, false, "01 March 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") //
+            );
+
+            // Repayment #1
+            updateBusinessDate("01 February 2023");
+            Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0, "01 February 2023");
+
+            // Repayment #2
+            updateBusinessDate("01 March 2023");
+            Long repaymentTransaction2 = addRepaymentForLoan(loanId, 280.0, "01 March 2023");
+
+            // Run periodic accrual
+            schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions");
+
+            // Repayment #3
+            updateBusinessDate("30 March 2023");
+            Long repaymentTransaction3 = addRepaymentForLoan(loanId, 250.0, "30 March 2023");
+
+            // Chargeback 250
+            Long chargeback = addChargebackForLoan(loanId, repaymentTransaction2, 280.0);
+
+            verifyTransactions(loanId, //
+                    transaction(750.0, "Disbursement", "01 January 2023", 750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 February 2023", 500.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(280.0, "Repayment", "01 March 2023", 250.0, 250.0, 0.0, 30.0, 0.0, 0.0, 0.0), //
+                    transaction(30.0, "Accrual", "01 March 2023", 0.0, 0.0, 0.0, 30.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "30 March 2023", 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(280.0, "Chargeback", "30 March 2023", 250, 250.0, 0.0, 30.0, 0.0, 0.0, 0.0) //
+            );
+
+            // Verify GL entries
+            verifyTRJournalEntries(repaymentTransaction1, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction2, //
+                    debit(fundSource, 280), //
+                    credit(loansReceivableAccount, 250), //
+                    credit(feeReceivableAccount, 30)//
+            );
+
+            verifyTRJournalEntries(repaymentTransaction3, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250)//
+            );
+
+            verifyTRJournalEntries(chargeback, //
+                    debit(loansReceivableAccount, 250), //
+                    debit(feeReceivableAccount, 30), //
+                    credit(fundSource, 280) //
+            );
+
+        });
+    }
+
+    @Test
+    public void testAccountingChargebackOnPrincipalAndPenalties() {
+        runAt("01 January 2023", () -> {
+            // Create Client
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            // Create Loan Product
+            Long loanProductId = createLoanProduct(//
+                    createDefaultPaymentAllocation(), //
+                    chargebackAllocation("PENALTY", "FEE", "INTEREST", "PRINCIPAL")//
+            );
+            // Apply and Approve Loan
+            Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+            // Disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+            Long feeId = addCharge(loanId, true, 30, "15 February 2023");
+
+            verifyRepaymentSchedule(loanId, //
+                    installment(0, null, "01 January 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), //
+                    installment(250.0, 0, 0, 30.0, 280.0, false, "01 March 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") //
+            );
+
+            // Repayment #1
+            updateBusinessDate("01 February 2023");
+            Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0, "01 February 2023");
+
+            // Repayment #2
+            updateBusinessDate("01 March 2023");
+            Long repaymentTransaction2 = addRepaymentForLoan(loanId, 280.0, "01 March 2023");
+
+            // Run periodic accrual
+            schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions");
+
+            // Repayment #3
+            updateBusinessDate("30 March 2023");
+            Long repaymentTransaction3 = addRepaymentForLoan(loanId, 250.0, "30 March 2023");
+
+            // Chargeback 250
+            Long chargeback = addChargebackForLoan(loanId, repaymentTransaction2, 280.0);
+
+            verifyTransactions(loanId, //
+                    transaction(750.0, "Disbursement", "01 January 2023", 750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 February 2023", 500.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(280.0, "Repayment", "01 March 2023", 250.0, 250.0, 0.0, 0.0, 30.0, 0.0, 0.0), //
+                    transaction(30.0, "Accrual", "01 March 2023", 0.0, 0.0, 0.0, 0.0, 30.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "30 March 2023", 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(280.0, "Chargeback", "30 March 2023", 250, 250.0, 0.0, 0.0, 30.0, 0.0, 0.0) //
+            );
+
+            // Verify GL entries
+            verifyTRJournalEntries(repaymentTransaction1, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction2, //
+                    debit(fundSource, 280), //
+                    credit(loansReceivableAccount, 250), //
+                    credit(penaltyReceivableAccount, 30)//
+            );
+
+            verifyTRJournalEntries(repaymentTransaction3, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250)//
+            );
+
+            verifyTRJournalEntries(chargeback, //
+                    debit(loansReceivableAccount, 250), //
+                    debit(penaltyReceivableAccount, 30), //
+                    credit(fundSource, 280) //
+            );
+
+        });
+    }
+
+    @Test
+    public void testAccountingOverpaymentAmountIsSmallerThanChargeback() {
+        runAt("01 January 2023", () -> {
+            // Create Client
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            // Create Loan Product
+            Long loanProductId = createLoanProduct(//
+                    createDefaultPaymentAllocation(), //
+                    chargebackAllocation("PENALTY", "FEE", "INTEREST", "PRINCIPAL")//
+            );
+            // Apply and Approve Loan
+            Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+            // Disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+            verifyRepaymentSchedule(loanId, //
+                    installment(0, null, "01 January 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") //
+            );
+
+            // Repayment #1
+            updateBusinessDate("01 February 2023");
+            Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0, "01 February 2023");
+
+            // Repayment #2
+            updateBusinessDate("01 March 2023");
+            Long repaymentTransaction2 = addRepaymentForLoan(loanId, 250.0, "01 March 2023");
+
+            // Repayment #3
+            updateBusinessDate("30 March 2023");
+            Long repaymentTransaction3 = addRepaymentForLoan(loanId, 400.0, "30 March 2023");
+
+            // Chargeback 250
+            updateBusinessDate("31 March 2023");
+            Long chargeback = addChargebackForLoan(loanId, repaymentTransaction2, 250.0);
+
+            verifyTransactions(loanId, //
+                    transaction(750.0, "Disbursement", "01 January 2023", 750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 February 2023", 500.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 March 2023", 250.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(400.0, "Repayment", "30 March 2023", 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Chargeback", "31 March 2023", 100, 250.0, 0.0, 0.0, 0.0, 0.0, 150.0) //
+            );
+
+            // Verify GL entries
+            verifyTRJournalEntries(repaymentTransaction1, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction2, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction3, //
+                    debit(fundSource, 400), //
+                    credit(loansReceivableAccount, 250), //
+                    credit(overpaymentAccount, 150) //
+            );
+
+            verifyTRJournalEntries(chargeback, //
+                    debit(loansReceivableAccount, 100), //
+                    debit(overpaymentAccount, 150), //
+                    credit(fundSource, 250) //
+            );
+        });
+    }
+
+    @Test
+    public void testAccountingOverpaymentAmountIsBiggerThanChargeback() {
+        runAt("01 January 2023", () -> {
+            // Create Client
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            // Create Loan Product
+            Long loanProductId = createLoanProduct(//
+                    createDefaultPaymentAllocation(), //
+                    chargebackAllocation("PENALTY", "FEE", "INTEREST", "PRINCIPAL")//
+            );
+            // Apply and Approve Loan
+            Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+            // Disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+            verifyRepaymentSchedule(loanId, //
+                    installment(0, null, "01 January 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") //
+            );
+
+            // Repayment #1
+            updateBusinessDate("01 February 2023");
+            Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0, "01 February 2023");
+
+            // Repayment #2
+            updateBusinessDate("01 March 2023");
+            Long repaymentTransaction2 = addRepaymentForLoan(loanId, 250.0, "01 March 2023");
+
+            // Repayment #3
+            updateBusinessDate("30 March 2023");
+            Long repaymentTransaction3 = addRepaymentForLoan(loanId, 400.0, "30 March 2023");
+
+            // Chargeback 250
+            updateBusinessDate("31 March 2023");
+            Long chargeback = addChargebackForLoan(loanId, repaymentTransaction2, 100.0);
+
+            verifyTransactions(loanId, //
+                    transaction(750.0, "Disbursement", "01 January 2023", 750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 February 2023", 500.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 March 2023", 250.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(400.0, "Repayment", "30 March 2023", 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(100.0, "Chargeback", "31 March 2023", 0.0, 100.0, 0.0, 0.0, 0.0, 0.0, -50.0) //
+            );
+
+            // Verify GL entries
+            verifyTRJournalEntries(repaymentTransaction1, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction2, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction3, //
+                    debit(fundSource, 400), //
+                    credit(loansReceivableAccount, 250), //
+                    credit(overpaymentAccount, 150) //
+            );
+
+            verifyTRJournalEntries(chargeback, //
+                    debit(overpaymentAccount, 100), //
+                    credit(fundSource, 100) //
+            );
+        });
+    }
+
+    @Test
+    public void testAccountingOverpaidLoansWithFeesWhenOverpaymentAmountIsBiggerThanChargeback() {
+        runAt("01 January 2023", () -> {
+            // Create Client
+            Long clientId = clientHelper.createClient(ClientHelper.defaultClientCreationRequest()).getClientId();
+            // Create Loan Product
+            Long loanProductId = createLoanProduct(//
+                    createDefaultPaymentAllocation(), //
+                    chargebackAllocation("PENALTY", "FEE", "INTEREST", "PRINCIPAL")//
+            );
+            // Apply and Approve Loan
+            Long loanId = applyAndApproveLoan(clientId, loanProductId, 3);
+
+            // Disburse Loan
+            disburseLoan(loanId, BigDecimal.valueOf(750), "01 January 2023");
+
+            verifyRepaymentSchedule(loanId, //
+                    installment(0, null, "01 January 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 February 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 March 2023"), //
+                    installment(250.0, 0, 0, 0, 250.0, false, "01 April 2023") //
+            );
+
+            // Repayment #1
+            updateBusinessDate("01 February 2023");
+            Long repaymentTransaction1 = addRepaymentForLoan(loanId, 250.0, "01 February 2023");
+
+            // Add fee & Repayment #2
+            updateBusinessDate("01 March 2023");
+            Long feeId = addCharge(loanId, false, 30, "01 March 2023");
+            Long repaymentTransaction2 = addRepaymentForLoan(loanId, 280.0, "01 March 2023");
+            schedulerJobHelper.executeAndAwaitJob("Add Accrual Transactions");
+
+            // Repayment #3
+            updateBusinessDate("30 March 2023");
+            Long repaymentTransaction3 = addRepaymentForLoan(loanId, 400.0, "30 March 2023");
+
+            // Chargeback 250
+            updateBusinessDate("31 March 2023");
+            Long chargeback = addChargebackForLoan(loanId, repaymentTransaction2, 100.0);
+
+            verifyTransactions(loanId, //
+                    transaction(750.0, "Disbursement", "01 January 2023", 750.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(250.0, "Repayment", "01 February 2023", 500.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(280.0, "Repayment", "01 March 2023", 250.0, 250.0, 0.0, 30.0, 0.0, 0.0, 0.0), //
+                    transaction(30.0, "Accrual", "01 March 2023", 0.0, 0.0, 0.0, 30.0, 0.0, 0.0, 0.0), //
+                    transaction(400.0, "Repayment", "30 March 2023", 0.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
+                    transaction(100.0, "Chargeback", "31 March 2023", 0.0, 70.0, 0.0, 30.0, 0.0, 0.0, -50.0) //
+            );
+
+            // Verify GL entries
+            verifyTRJournalEntries(repaymentTransaction1, //
+                    debit(fundSource, 250), //
+                    credit(loansReceivableAccount, 250) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction2, //
+                    debit(fundSource, 280), //
+                    credit(loansReceivableAccount, 250), //
+                    credit(feeReceivableAccount, 30) //
+            );
+
+            verifyTRJournalEntries(getTransactionId(loanId, "Accrual", "01 March 2023"), //
+                    debit(feeReceivableAccount, 30), //
+                    credit(feeIncomeAccount, 30) //
+            );
+
+            verifyTRJournalEntries(repaymentTransaction3, //
+                    debit(fundSource, 400), //
+                    credit(loansReceivableAccount, 250), //
+                    credit(overpaymentAccount, 150) //
+            );
+
+            verifyTRJournalEntries(chargeback, //
+                    debit(overpaymentAccount, 100), //
+                    credit(fundSource, 100) //
+            );
+        });
+    }
+
     private void verifyLoanSummaryAmounts(Long loanId, double creditedPrincipal, double creditedFee, double creditedPenalty,
             double totalOutstanding) {
         GetLoansLoanIdResponse loanResponse = loanTransactionHelper.getLoan(requestSpec, responseSpec, loanId.intValue());
@@ -1023,10 +1472,10 @@
     }
 
     @Nullable
-    private Long applyAndApproveLoan(Long clientId, Long loanProductId) {
-        PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1250.0, 4)//
+    private Long applyAndApproveLoan(Long clientId, Long loanProductId, int numberOfRepayments) {
+        PostLoansRequest applicationRequest = applyLoanRequest(clientId, loanProductId, "01 January 2023", 1250.0, numberOfRepayments)//
                 .repaymentEvery(1)//
-                .loanTermFrequency(4)//
+                .loanTermFrequency(numberOfRepayments)//
                 .repaymentFrequencyType(RepaymentFrequencyType.MONTHS)//
                 .loanTermFrequencyType(RepaymentFrequencyType.MONTHS)//
                 .transactionProcessingStrategyCode("advanced-payment-allocation-strategy");
@@ -1036,8 +1485,12 @@
         PostLoansLoanIdResponse approvedLoanResult = loanTransactionHelper.approveLoan(postLoansResponse.getResourceId(),
                 approveLoanRequest(1250.0, "01 January 2023"));
 
-        Long loanId = approvedLoanResult.getLoanId();
-        return loanId;
+        return approvedLoanResult.getLoanId();
+    }
+
+    @Nullable
+    private Long applyAndApproveLoan(Long clientId, Long loanProductId) {
+        return applyAndApproveLoan(clientId, loanProductId, 4);
     }
 
     public Long createLoanProduct(AdvancedPaymentData defaultAllocation, CreditAllocationData creditAllocationData) {
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
index 17e05c2..2b8f7b0 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanDownPaymentTransactionChargebackTest.java
@@ -23,7 +23,6 @@
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 import java.math.BigDecimal;
-import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdTransactionsTransactionIdResponse;
 import org.apache.fineract.client.models.PostLoanProductsRequest;
@@ -88,15 +87,10 @@
             );
 
             // verify journal entries for chargeback transaction
-            GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper
-                    .getJournalEntries("L" + chargebackTransactionId.toString());
-            assertEquals(2L, journalEntries.getTotalFilteredRecords());
-            assertEquals(50.0, journalEntries.getPageItems().get(0).getAmount());
-            assertEquals("CREDIT", journalEntries.getPageItems().get(0).getEntryType().getValue());
-
-            assertEquals(50.0, journalEntries.getPageItems().get(1).getAmount());
-            assertEquals("DEBIT", journalEntries.getPageItems().get(1).getEntryType().getValue());
-
+            verifyTRJournalEntries(chargebackTransactionId, //
+                    credit(fundSource, 50.0), //
+                    debit(loansReceivableAccount, 50.0) //
+            );
         });
     }
 
@@ -152,15 +146,10 @@
             );
 
             // verify journal entries for chargeback transaction
-            GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper
-                    .getJournalEntries("L" + chargebackTransactionId.toString());
-            assertEquals(2L, journalEntries.getTotalFilteredRecords());
-            assertEquals(50.0, journalEntries.getPageItems().get(0).getAmount());
-            assertEquals("CREDIT", journalEntries.getPageItems().get(0).getEntryType().getValue());
-
-            assertEquals(50.0, journalEntries.getPageItems().get(1).getAmount());
-            assertEquals("DEBIT", journalEntries.getPageItems().get(1).getEntryType().getValue());
-
+            verifyTRJournalEntries(chargebackTransactionId, //
+                    credit(fundSource, 50.0), //
+                    debit(loansReceivableAccount, 50.0) //
+            );
         });
     }
 
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
index d9cf82d..9ef2a6a 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRepaymentScheduleWithDownPaymentTest.java
@@ -1252,10 +1252,11 @@
                     transaction(1000.0, "Disbursement", "03 March 2023", 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
                     transaction(250.0, "Down Payment", "03 March 2023", 750.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0) //
             );
-            verifyJournalEntries(loanResponse.getResourceId(), journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+            verifyJournalEntries(loanResponse.getResourceId(), //
+                    journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(250.0, fundSource, "DEBIT") //
             );
 
             loanTransactionHelper.makeLoanRepayment(loanResponse.getResourceId(), new PostLoansLoanIdTransactionsRequest()
@@ -1464,10 +1465,11 @@
                     transaction(1000.0, "Disbursement", "03 March 2023", 1000.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), //
                     transaction(250.0, "Down Payment", "03 March 2023", 750.0, 250.0, 0.0, 0.0, 0.0, 0.0, 0.0) //
             );
-            verifyJournalEntries(loanResponse.getResourceId(), journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+            verifyJournalEntries(loanResponse.getResourceId(), //
+                    journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(250.0, fundSource, "DEBIT") //
             );
 
             String externalId = UUID.randomUUID().toString();
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
index d54a60d..450553f 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanRescheduleTestWithDownpayment.java
@@ -74,9 +74,9 @@
 
             // verify journal entries
             verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
index 635a6c2..0fb211c 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/LoanTransactionChargebackTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.fineract.integrationtests;
 
+import static org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder.ACCRUAL_PERIODIC;
 import static org.apache.fineract.integrationtests.common.loans.LoanProductTestBuilder.DEFAULT_STRATEGY;
 import static org.apache.fineract.portfolio.loanaccount.domain.transactionprocessor.impl.AdvancedPaymentScheduleTransactionProcessor.ADVANCED_PAYMENT_ALLOCATION_STRATEGY;
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -39,7 +40,6 @@
 import org.apache.fineract.client.models.AdvancedPaymentData;
 import org.apache.fineract.client.models.GetDelinquencyBucketsResponse;
 import org.apache.fineract.client.models.GetDelinquencyRangesResponse;
-import org.apache.fineract.client.models.GetJournalEntriesTransactionIdResponse;
 import org.apache.fineract.client.models.GetLoanProductsProductIdResponse;
 import org.apache.fineract.client.models.GetLoansLoanIdRepaymentPeriod;
 import org.apache.fineract.client.models.GetLoansLoanIdRepaymentSchedule;
@@ -53,7 +53,6 @@
 import org.apache.fineract.integrationtests.common.ClientHelper;
 import org.apache.fineract.integrationtests.common.GlobalConfigurationHelper;
 import org.apache.fineract.integrationtests.common.Utils;
-import org.apache.fineract.integrationtests.common.accounting.Account;
 import org.apache.fineract.integrationtests.common.accounting.AccountHelper;
 import org.apache.fineract.integrationtests.common.accounting.JournalEntryHelper;
 import org.apache.fineract.integrationtests.common.loans.LoanApplicationTestBuilder;
@@ -72,7 +71,7 @@
 
 @Slf4j
 @ExtendWith(LoanTestLifecycleExtension.class)
-public class LoanTransactionChargebackTest {
+public class LoanTransactionChargebackTest extends BaseLoanIntegrationTest {
 
     private ResponseSpecification responseSpec;
     private ResponseSpecification responseSpecErr400;
@@ -139,14 +138,10 @@
 
         loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse, amount.doubleValue());
 
-        GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper
-                .getJournalEntries("L" + chargebackTransactionId.toString());
-        assertEquals(2L, journalEntries.getTotalFilteredRecords());
-        assertEquals(1000.0, journalEntries.getPageItems().get(0).getAmount());
-        assertEquals("CREDIT", journalEntries.getPageItems().get(0).getEntryType().getValue());
-
-        assertEquals(1000.0, journalEntries.getPageItems().get(1).getAmount());
-        assertEquals("DEBIT", journalEntries.getPageItems().get(1).getEntryType().getValue());
+        verifyTRJournalEntries(chargebackTransactionId, //
+                credit(fundSource, 1000.0), //
+                debit(loansReceivableAccount, 1000.0) //
+        );
 
         // Try to reverse a Loan Transaction charge back
         PostLoansLoanIdTransactionsResponse reverseTransactionResponse = loanTransactionHelper.reverseLoanTransaction(loanId,
@@ -431,17 +426,11 @@
         assertEquals(getLoansLoanIdResponse.getTimeline().getExpectedMaturityDate(),
                 getLoansLoanIdResponse.getTimeline().getActualMaturityDate());
 
-        GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper
-                .getJournalEntries("L" + chargebackTransactionId.toString());
-        assertEquals(3L, journalEntries.getTotalFilteredRecords());
-        assertEquals(100.0, journalEntries.getPageItems().get(0).getAmount());
-        assertEquals("DEBIT", journalEntries.getPageItems().get(0).getEntryType().getValue());
-
-        assertEquals(200.0, journalEntries.getPageItems().get(1).getAmount());
-        assertEquals("CREDIT", journalEntries.getPageItems().get(1).getEntryType().getValue());
-
-        assertEquals(100.0, journalEntries.getPageItems().get(2).getAmount());
-        assertEquals("DEBIT", journalEntries.getPageItems().get(2).getEntryType().getValue());
+        verifyTRJournalEntries(chargebackTransactionId, //
+                credit(fundSource, 200.0), //
+                debit(loansReceivableAccount, 100.0), //
+                debit(overpaymentAccount, 100.0) //
+        );
 
         final GetDelinquencyRangesResponse delinquencyRange = getLoansLoanIdResponse.getDelinquencyRange();
         assertNull(delinquencyRange);
@@ -525,14 +514,10 @@
 
         loanTransactionHelper.validateLoanPrincipalOustandingBalance(getLoansLoanIdResponse, Double.valueOf("0.00"));
 
-        GetJournalEntriesTransactionIdResponse journalEntries = journalEntryHelper
-                .getJournalEntries("L" + chargebackTransactionId.toString());
-        assertEquals(2L, journalEntries.getTotalFilteredRecords());
-        assertEquals(50.0, journalEntries.getPageItems().get(0).getAmount());
-        assertEquals("CREDIT", journalEntries.getPageItems().get(0).getEntryType().getValue());
-
-        assertEquals(50.0, journalEntries.getPageItems().get(1).getAmount());
-        assertEquals("DEBIT", journalEntries.getPageItems().get(1).getEntryType().getValue());
+        verifyTRJournalEntries(chargebackTransactionId, //
+                credit(fundSource, 50.0), //
+                debit(overpaymentAccount, 50.0) //
+        );
     }
 
     @ParameterizedTest
@@ -632,12 +617,20 @@
             final Integer delinquencyBucketId, final boolean withJournalEntries, LoanProductTestBuilder loanProductTestBuilder) {
         final HashMap<String, Object> loanProductMap;
         if (withJournalEntries) {
-            final Account assetAccount = accountHelper.createAssetAccount();
-            final Account expenseAccount = accountHelper.createExpenseAccount();
-            final Account incomeAccount = accountHelper.createIncomeAccount();
-            final Account overpaymentAccount = accountHelper.createLiabilityAccount();
             loanProductMap = loanProductTestBuilder
-                    .withAccountingRulePeriodicAccrual(new Account[] { assetAccount, expenseAccount, incomeAccount, overpaymentAccount })
+                    .withFullAccountingConfig(ACCRUAL_PERIODIC,
+                            LoanProductTestBuilder.FullAccountingConfig.builder().fundSourceAccountId(fundSource.getAccountID().longValue())//
+                                    .loanPortfolioAccountId(loansReceivableAccount.getAccountID().longValue())//
+                                    .transfersInSuspenseAccountId(suspenseAccount.getAccountID().longValue())//
+                                    .interestOnLoanAccountId(interestIncomeAccount.getAccountID().longValue())//
+                                    .incomeFromFeeAccountId(feeIncomeAccount.getAccountID().longValue())//
+                                    .incomeFromPenaltyAccountId(penaltyIncomeAccount.getAccountID().longValue())//
+                                    .incomeFromRecoveryAccountId(recoveriesAccount.getAccountID().longValue())//
+                                    .writeOffAccountId(writtenOffAccount.getAccountID().longValue())//
+                                    .overpaymentLiabilityAccountId(overpaymentAccount.getAccountID().longValue())//
+                                    .receivableInterestAccountId(interestReceivableAccount.getAccountID().longValue())//
+                                    .receivableFeeAccountId(interestReceivableAccount.getAccountID().longValue())//
+                                    .receivablePenaltyAccountId(interestReceivableAccount.getAccountID().longValue()).build())
                     .build(null, delinquencyBucketId);
         } else {
             loanProductMap = loanProductTestBuilder.build(null, delinquencyBucketId);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
index 6ecb979..20f4837 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/UndoLoanDisbursalWithDownPaymentIntegrationTest.java
@@ -69,9 +69,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -91,14 +91,14 @@
             verifyJournalEntries(loanId,
                     // original entries
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     // original entries reverted
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT")); //
+                    journalEntry(1000.0, fundSource, "DEBIT")); //
 
             verifyRepaymentSchedule(loanId, //
                     installment(1000.0, null, "01 January 2023"), //
@@ -139,9 +139,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // make a repayment
@@ -164,23 +164,23 @@
             verifyJournalEntries(loanId, //
                     // original entries down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // repayment entries
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
 
                     // original entries compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // repayment entries compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(250.0, fundSource, "CREDIT") //
             );
 
             verifyRepaymentSchedule(loanId, //
@@ -225,9 +225,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // undoDisbursal
@@ -240,15 +240,15 @@
             verifyJournalEntries(loanId, //
                     // original entries
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // original entries are compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(1000.0, fundSource, "DEBIT") //
             );
 
             // verify repayment entries are reverted
@@ -298,11 +298,11 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -322,23 +322,23 @@
             verifyJournalEntries(loanId, //
                     // original entries
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // original entries compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // manual partial repayment of the first installment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
 
                     // manual partial repayment of the first installment compensation after undoDisburse
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(100.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -381,9 +381,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -429,9 +429,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -476,9 +476,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -498,14 +498,14 @@
             verifyJournalEntries(loanId, //
                     // original entries
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     // original entries reverted
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(1000.0, fundSource, "DEBIT") //
             );
 
             // Verify Repayment Schedule
@@ -548,9 +548,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // make a repayment
@@ -573,23 +573,23 @@
             verifyJournalEntries(loanId,
                     // original entries down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // repayment entries
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
 
                     // original entries compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // repayment entries compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(250.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -635,9 +635,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // undoDisbursal
@@ -650,15 +650,15 @@
             verifyJournalEntries(loanId,
                     // original entries
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // original entries are compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(1000.0, fundSource, "DEBIT") //
             );
 
             // Verify Repayment Schedule
@@ -707,11 +707,11 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -731,23 +731,23 @@
             verifyJournalEntries(loanId,
                     // original entries
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // original entries compensated
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // manual partial repayment of the first installment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
 
                     // manual partial repayment of the first installment compensation after undoDisburse
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(100.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -787,9 +787,9 @@
 
             // verify journal entries
             verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -815,13 +815,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -846,21 +846,21 @@
             verifyJournalEntries(loanId,
                     // first disbursement + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // second disbursement + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // compensation of second disbursement + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(400.0, fundSource, "DEBIT") //
             );
 
             verifyRepaymentSchedule(loanId, //
@@ -901,9 +901,9 @@
 
             // verify journal entries
             verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -941,15 +941,15 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(300.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(300.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(300.0, fundSource, "DEBIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -975,25 +975,25 @@
             verifyJournalEntries(loanId,
                     // first disbursement + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // repayment
                     journalEntry(300.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(300.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(300.0, fundSource, "DEBIT"), //
 
                     // second disbursement + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // compensation of second disbursement + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(400.0, fundSource, "DEBIT") //
             );
 
             verifyRepaymentSchedule(loanId, //
@@ -1038,9 +1038,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1070,13 +1070,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1101,21 +1101,21 @@
             verifyJournalEntries(loanId,
                     // first disbursement + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // second disbursement + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // compensation of second disbursement + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(400.0, fundSource, "DEBIT") //
             );
 
             verifyRepaymentSchedule(loanId, //
@@ -1157,9 +1157,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1186,13 +1186,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1249,9 +1249,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1281,13 +1281,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1341,9 +1341,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1370,13 +1370,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1404,27 +1404,27 @@
             verifyJournalEntries(loanId,
                     // 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // compensation of the 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // compensation of the 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(400.0, fundSource, "DEBIT") //
             );
         });
     }
@@ -1463,9 +1463,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1495,13 +1495,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1529,27 +1529,27 @@
             verifyJournalEntries(loanId,
                     // 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // compensation of the 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // compensation of the 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT") //
+                    journalEntry(400.0, fundSource, "DEBIT") //
             );
         });
     }
@@ -1585,9 +1585,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1614,13 +1614,13 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1654,35 +1654,35 @@
             verifyJournalEntries(loanId,
                     // 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // manual repayment
                     journalEntry(50.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(50.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(50.0, fundSource, "DEBIT"), //
 
                     // compensation of the 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // compensation of the 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(400.0, fundSource, "DEBIT"), //
 
                     // compensation of repayment
                     journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(50.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(50.0, fundSource, "CREDIT") //
             );
         });
     }
@@ -1721,9 +1721,9 @@
             // verify journal entries
             verifyJournalEntries(loanId, //
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(1000.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1752,13 +1752,13 @@
 
             // verify journal entries
             verifyJournalEntries(loanId, journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(400.0, fundSource, "CREDIT") //
             );
 
             // Verify Repayment Schedule
@@ -1792,35 +1792,35 @@
             verifyJournalEntries(loanId,
                     // 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(250.0, fundSource, "DEBIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(1000.0, fundSource, "CREDIT"), //
 
                     // 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(100.0, fundSource, "DEBIT"), //
                     journalEntry(400.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(400.0, fundSource, "CREDIT"), //
 
                     // manual repayment
                     journalEntry(50.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(50.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(50.0, fundSource, "DEBIT"), //
 
                     // compensation of the 1st disbursal + down-payment
                     journalEntry(250.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(250.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(250.0, fundSource, "CREDIT"), //
                     journalEntry(1000.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(1000.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(1000.0, fundSource, "DEBIT"), //
 
                     // compensation of the 2nd disbursal + down-payment
                     journalEntry(100.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(100.0, suspenseClearingAccount, "CREDIT"), //
+                    journalEntry(100.0, fundSource, "CREDIT"), //
                     journalEntry(400.0, loansReceivableAccount, "CREDIT"), //
-                    journalEntry(400.0, suspenseClearingAccount, "DEBIT"), //
+                    journalEntry(400.0, fundSource, "DEBIT"), //
 
                     // compensation of repayment
                     journalEntry(50.0, loansReceivableAccount, "DEBIT"), //
-                    journalEntry(50.0, suspenseClearingAccount, "CREDIT") //
+                    journalEntry(50.0, fundSource, "CREDIT") //
             );
         });
     }
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
index 0d2a503..1004473 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/AccountHelper.java
@@ -42,35 +42,55 @@
     }
 
     public Account createAssetAccount() {
-        final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsAsset().build();
+        return this.createAssetAccount(null);
+    }
+
+    public Account createIncomeAccount() {
+        return this.createIncomeAccount(null);
+    }
+
+    public Account createExpenseAccount() {
+        return this.createExpenseAccount(null);
+    }
+
+    public Account createLiabilityAccount() {
+        return this.createLiabilityAccount(null);
+    }
+
+    public Account createEquityAccount() {
+        return this.createEquityAccount(null);
+    }
+
+    public Account createAssetAccount(String accountName) {
+        final String assetAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsAsset().build();
         final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
                 GL_ACCOUNT_ID_RESPONSE);
         return new Account(accountID, Account.AccountType.ASSET);
     }
 
-    public Account createIncomeAccount() {
-        final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsIncome().build();
+    public Account createIncomeAccount(String accountName) {
+        final String assetAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsIncome().build();
         final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
                 GL_ACCOUNT_ID_RESPONSE);
         return new Account(accountID, Account.AccountType.INCOME);
     }
 
-    public Account createExpenseAccount() {
-        final String assetAccountJSON = new GLAccountBuilder().withAccountTypeAsExpense().build();
+    public Account createExpenseAccount(String accountName) {
+        final String assetAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsExpense().build();
         final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, assetAccountJSON,
                 GL_ACCOUNT_ID_RESPONSE);
         return new Account(accountID, Account.AccountType.EXPENSE);
     }
 
-    public Account createLiabilityAccount() {
-        final String liabilityAccountJSON = new GLAccountBuilder().withAccountTypeAsLiability().build();
+    public Account createLiabilityAccount(String accountName) {
+        final String liabilityAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsLiability().build();
         final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, liabilityAccountJSON,
                 GL_ACCOUNT_ID_RESPONSE);
         return new Account(accountID, Account.AccountType.LIABILITY);
     }
 
-    public Account createEquityAccount() {
-        final String equityAccountJSON = new GLAccountBuilder().withAccountTypeAsAsEquity().build();
+    public Account createEquityAccount(String accountName) {
+        final String equityAccountJSON = new GLAccountBuilder().withName(accountName).withAccountTypeAsAsEquity().build();
         final Integer accountID = Utils.performServerPost(this.requestSpec, this.responseSpec, CREATE_GL_ACCOUNT_URL, equityAccountJSON,
                 GL_ACCOUNT_ID_RESPONSE);
         return new Account(accountID, Account.AccountType.EQUITY);
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
index 9edec63..9a675d1 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/accounting/GLAccountBuilder.java
@@ -21,6 +21,7 @@
 import com.google.gson.Gson;
 import java.util.Calendar;
 import java.util.HashMap;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.fineract.integrationtests.common.Utils;
 
 public class GLAccountBuilder {
@@ -86,6 +87,13 @@
         return this;
     }
 
+    public GLAccountBuilder withName(String name) {
+        if (StringUtils.isNotBlank(name)) {
+            this.name = Utils.uniqueRandomStringGenerator(name + "_", 5);
+        }
+        return this;
+    }
+
     public GLAccountBuilder withAccountUsageAsHeader() {
         accountUsage = ACCOUNT_USAGE_HEADER;
         return this;
diff --git a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
index a5973d5..7fd2529 100644
--- a/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
+++ b/integration-tests/src/test/java/org/apache/fineract/integrationtests/common/loans/LoanProductTestBuilder.java
@@ -25,6 +25,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+import lombok.Builder;
 import org.apache.fineract.client.models.AdvancedPaymentData;
 import org.apache.fineract.client.models.CreditAllocationData;
 import org.apache.fineract.integrationtests.common.Utils;
@@ -69,10 +71,10 @@
     public static final String RECALCULATION_COMPOUNDING_METHOD_FEE = "2";
     public static final String RECALCULATION_COMPOUNDING_METHOD_INTEREST_AND_FEE = "3";
 
-    private static final String NONE = "1";
-    private static final String CASH_BASED = "2";
-    private static final String ACCRUAL_PERIODIC = "3";
-    private static final String ACCRUAL_UPFRONT = "4";
+    public static final String NONE = "1";
+    public static final String CASH_BASED = "2";
+    public static final String ACCRUAL_PERIODIC = "3";
+    public static final String ACCRUAL_UPFRONT = "4";
 
     public static final String INTEREST_APPLICABLE_STRATEGY_REST_DATE = "2";
     public static final String INTEREST_APPLICABLE_STRATEGY_ON_PRE_CLOSE_DATE = "1";
@@ -157,6 +159,7 @@
     private Integer repaymentStartDateType = null;
     private String loanScheduleType = LoanScheduleType.CUMULATIVE.name();
     private String loanScheduleProcessingType = LoanScheduleProcessingType.HORIZONTAL.name();
+    private FullAccountingConfig fullAccountingConfig;
 
     public String build() {
         final HashMap<String, Object> map = build(null, null);
@@ -231,7 +234,9 @@
             map.put("outstandingLoanBalance", this.outstandingLoanBalance);
         }
 
-        if (this.accountingRule.equals(ACCRUAL_UPFRONT) || this.accountingRule.equals(ACCRUAL_PERIODIC)) {
+        if (this.fullAccountingConfig != null) {
+            map.putAll(this.fullAccountingConfig.toMap());
+        } else if (this.accountingRule.equals(ACCRUAL_UPFRONT) || this.accountingRule.equals(ACCRUAL_PERIODIC)) {
             map.putAll(getAccountMappingForAccrualBased(this.feeAndPenaltyAssetAccount));
         } else if (this.accountingRule.equals(CASH_BASED)) {
             map.putAll(getAccountMappingForCashBased());
@@ -487,6 +492,13 @@
         return this;
     }
 
+    public LoanProductTestBuilder withFullAccountingConfig(String accountingRule, FullAccountingConfig fullAccountingConfig) {
+        this.accountingRule = accountingRule;
+        this.fullAccountingConfig = fullAccountingConfig;
+        this.accountList = null;
+        return this;
+    }
+
     private Map<String, String> getAccountMappingForCashBased() {
         final Map<String, String> map = new HashMap<>();
         for (int i = 0; i < this.accountList.length; i++) {
@@ -768,4 +780,78 @@
         return transactionProcessingStrategyCode;
     }
 
+    @Builder
+    public static class FullAccountingConfig {
+
+        private final Long fundSourceAccountId;
+        private final Long loanPortfolioAccountId;
+        private final Long transfersInSuspenseAccountId;
+        private final Long interestOnLoanAccountId;
+        private final Long incomeFromFeeAccountId;
+        private final Long incomeFromPenaltyAccountId;
+        private final Long incomeFromRecoveryAccountId;
+        private final Long writeOffAccountId;
+        private final Long overpaymentLiabilityAccountId;
+        private final Long receivableInterestAccountId;
+        private final Long receivableFeeAccountId;
+        private final Long receivablePenaltyAccountId;
+        private final Long goodwillCreditAccountId;
+        private final Long incomeFromGoodwillCreditInterestAccountId;
+        private final Long incomeFromGoodwillCreditFeesAccountId;
+        private final Long incomeFromGoodwillCreditPenaltyAccountId;
+        private final Long incomeFromChargeOffInterestAccountId;
+        private final Long incomeFromChargeOffFeesAccountId;
+        private final Long chargeOffExpenseAccountId;
+        private final Long chargeOffFraudExpenseAccountId;
+        private final Long incomeFromChargeOffPenaltyAccountId;
+        private final Long accountingRule;
+
+        public Map<String, String> toMap() {
+            Map<String, String> map = new HashMap<>();
+            Optional.ofNullable(fundSourceAccountId)
+                    .ifPresent(fundSourceAccountId -> map.put("fundSourceAccountId", Long.toString(fundSourceAccountId)));
+            Optional.ofNullable(loanPortfolioAccountId)
+                    .ifPresent(loanPortfolioAccountId -> map.put("loanPortfolioAccountId", Long.toString(loanPortfolioAccountId)));
+            Optional.ofNullable(transfersInSuspenseAccountId).ifPresent(
+                    transfersInSuspenseAccountId -> map.put("transfersInSuspenseAccountId", Long.toString(transfersInSuspenseAccountId)));
+            Optional.ofNullable(interestOnLoanAccountId)
+                    .ifPresent(interestOnLoanAccountId -> map.put("interestOnLoanAccountId", Long.toString(interestOnLoanAccountId)));
+            Optional.ofNullable(incomeFromFeeAccountId)
+                    .ifPresent(incomeFromFeeAccountId -> map.put("incomeFromFeeAccountId", Long.toString(incomeFromFeeAccountId)));
+            Optional.ofNullable(incomeFromPenaltyAccountId).ifPresent(
+                    incomeFromPenaltyAccountId -> map.put("incomeFromPenaltyAccountId", Long.toString(incomeFromPenaltyAccountId)));
+            Optional.ofNullable(incomeFromRecoveryAccountId).ifPresent(
+                    incomeFromRecoveryAccountId -> map.put("incomeFromRecoveryAccountId", Long.toString(incomeFromRecoveryAccountId)));
+            Optional.ofNullable(writeOffAccountId)
+                    .ifPresent(writeOffAccountId -> map.put("writeOffAccountId", Long.toString(writeOffAccountId)));
+            Optional.ofNullable(overpaymentLiabilityAccountId).ifPresent(overpaymentLiabilityAccountId -> map
+                    .put("overpaymentLiabilityAccountId", Long.toString(overpaymentLiabilityAccountId)));
+            Optional.ofNullable(receivableInterestAccountId).ifPresent(
+                    receivableInterestAccountId -> map.put("receivableInterestAccountId", Long.toString(receivableInterestAccountId)));
+            Optional.ofNullable(receivableFeeAccountId)
+                    .ifPresent(receivableFeeAccountId -> map.put("receivableFeeAccountId", Long.toString(receivableFeeAccountId)));
+            Optional.ofNullable(receivablePenaltyAccountId).ifPresent(
+                    receivablePenaltyAccountId -> map.put("receivablePenaltyAccountId", Long.toString(receivablePenaltyAccountId)));
+            Optional.ofNullable(goodwillCreditAccountId)
+                    .ifPresent(goodwillCreditAccountId -> map.put("goodwillCreditAccountId", Long.toString(goodwillCreditAccountId)));
+            Optional.ofNullable(incomeFromGoodwillCreditInterestAccountId).ifPresent(incomeFromGoodwillCreditInterestAccountId -> map
+                    .put("incomeFromGoodwillCreditInterestAccountId", Long.toString(incomeFromGoodwillCreditInterestAccountId)));
+            Optional.ofNullable(incomeFromGoodwillCreditFeesAccountId).ifPresent(incomeFromGoodwillCreditFeesAccountId -> map
+                    .put("incomeFromGoodwillCreditFeesAccountId", Long.toString(incomeFromGoodwillCreditFeesAccountId)));
+            Optional.ofNullable(incomeFromGoodwillCreditPenaltyAccountId).ifPresent(incomeFromGoodwillCreditPenaltyAccountId -> map
+                    .put("incomeFromGoodwillCreditPenaltyAccountId", Long.toString(incomeFromGoodwillCreditPenaltyAccountId)));
+            Optional.ofNullable(incomeFromChargeOffInterestAccountId).ifPresent(incomeFromChargeOffInterestAccountId -> map
+                    .put("incomeFromChargeOffInterestAccountId", Long.toString(incomeFromChargeOffInterestAccountId)));
+            Optional.ofNullable(incomeFromChargeOffFeesAccountId).ifPresent(incomeFromChargeOffFeesAccountId -> map
+                    .put("incomeFromChargeOffFeesAccountId", Long.toString(incomeFromChargeOffFeesAccountId)));
+            Optional.ofNullable(chargeOffExpenseAccountId)
+                    .ifPresent(chargeOffExpenseAccountId -> map.put("chargeOffExpenseAccountId", Long.toString(chargeOffExpenseAccountId)));
+            Optional.ofNullable(chargeOffFraudExpenseAccountId).ifPresent(chargeOffFraudExpenseAccountId -> map
+                    .put("chargeOffFraudExpenseAccountId", Long.toString(chargeOffFraudExpenseAccountId)));
+            Optional.ofNullable(incomeFromChargeOffPenaltyAccountId).ifPresent(incomeFromChargeOffPenaltyAccountId -> map
+                    .put("incomeFromChargeOffPenaltyAccountId", Long.toString(incomeFromChargeOffPenaltyAccountId)));
+            return map;
+        }
+    }
+
 }