This is an automated email from the ASF dual-hosted git repository.

arnold pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/fineract.git


The following commit(s) were added to refs/heads/develop by this push:
     new 23f672adb FINERACT-1706: Accounting for Chargeback
23f672adb is described below

commit 23f672adbcf843a1235e682710e407f488fc62a6
Author: Adam Saghy <[email protected]>
AuthorDate: Mon Aug 22 22:13:20 2022 +0200

    FINERACT-1706: Accounting for Chargeback
---
 .../service/AccountingProcessorHelper.java         |  37 +------
 .../AccrualBasedAccountingProcessorForLoan.java    |  88 +++++++++++------
 .../CashBasedAccountingProcessorForLoan.java       |  74 +++++++++-----
 .../loanaccount/data/LoanTransactionEnumData.java  |   7 ++
 .../loanaccount/domain/LoanTransactionType.java    | 106 ++++++---------------
 .../loanproduct/service/LoanEnumerations.java      |   2 +
 6 files changed, 149 insertions(+), 165 deletions(-)

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 59700c945..f052b3454 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
@@ -321,39 +321,6 @@ public class AccountingProcessorHelper {
 
     }
 
-    /**
-     * Convenience method that creates a pair of related Debits and Credits 
for Accrual Based accounting.
-     *
-     * The target accounts for debits and credits are switched in case of a 
reversal
-     *
-     * @param office
-     * @param accountTypeToBeDebited
-     *            Enum of the placeholder GLAccount to be debited
-     * @param accountTypeToBeCredited
-     *            Enum of the placeholder of the GLAccount to be credited
-     * @param loanProductId
-     * @param paymentTypeId
-     * @param loanId
-     * @param transactionId
-     * @param transactionDate
-     * @param amount
-     * @param isReversal
-     */
-    public void createAccrualBasedJournalEntriesAndReversalsForLoan(final 
Office office, final String currencyCode,
-            final Integer accountTypeToBeDebited, final Integer 
accountTypeToBeCredited, final Long loanProductId, final Long paymentTypeId,
-            final Long loanId, final String transactionId, final LocalDate 
transactionDate, final BigDecimal amount,
-            final Boolean isReversal) {
-        int accountTypeToDebitId = accountTypeToBeDebited;
-        int accountTypeToCreditId = accountTypeToBeCredited;
-        // reverse debits and credits for reversals
-        if (isReversal) {
-            accountTypeToDebitId = accountTypeToBeCredited;
-            accountTypeToCreditId = accountTypeToBeDebited;
-        }
-        createJournalEntriesForLoan(office, currencyCode, 
accountTypeToDebitId, accountTypeToCreditId, loanProductId, paymentTypeId, 
loanId,
-                transactionId, transactionDate, amount);
-    }
-
     /**
      * Convenience method that creates a pair of related Debits and Credits 
for Accrual Based accounting.
      *
@@ -382,7 +349,7 @@ public class AccountingProcessorHelper {
      * @param chargePaymentDTOs
      *            chargePaymentDTOs
      */
-    public void 
createAccrualBasedJournalEntriesAndReversalsForLoanCharges(final Office office, 
final String currencyCode,
+    public void createJournalEntriesAndReversalsForLoanCharges(final Office 
office, final String currencyCode,
             final Integer accountTypeToBeDebited, final Integer 
accountTypeToBeCredited, final Long loanProductId, final Long loanId,
             final String transactionId, final LocalDate transactionDate, final 
BigDecimal totalAmount, final Boolean isReversal,
             final List<ChargePaymentDTO> chargePaymentDTOs) {
@@ -476,7 +443,7 @@ public class AccountingProcessorHelper {
      * @param amount
      * @param isReversal
      */
-    public void createCashBasedJournalEntriesAndReversalsForLoan(final Office 
office, final String currencyCode,
+    public void createJournalEntriesAndReversalsForLoan(final Office office, 
final String currencyCode,
             final Integer accountTypeToBeDebited, final Integer 
accountTypeToBeCredited, final Long loanProductId, final Long paymentTypeId,
             final Long loanId, final String transactionId, final LocalDate 
transactionDate, final BigDecimal amount,
             final Boolean isReversal) {
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 968916d66..53623ed9b 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
@@ -27,7 +27,6 @@ import java.util.Map;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.accounting.closure.domain.GLClosure;
 import 
org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
-import 
org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
 import 
org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
 import org.apache.fineract.accounting.glaccount.domain.GLAccount;
 import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
@@ -96,9 +95,38 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
             else if 
(loanTransactionDTO.getTransactionType().isRefundForActiveLoans()) {
                 createJournalEntriesForRefundForActiveLoan(loanDTO, 
loanTransactionDTO, office);
             }
+            // Logic for Chargebacks
+            else if (loanTransactionDTO.getTransactionType().isChargeback()) {
+                createJournalEntriesForChargeback(loanDTO, loanTransactionDTO, 
office);
+            }
         }
     }
 
+    /**
+     * Handle chargeback journal entry creation
+     *
+     * @param loanDTO
+     * @param loanTransactionDTO
+     * @param office
+     */
+    private void createJournalEntriesForChargeback(LoanDTO loanDTO, 
LoanTransactionDTO loanTransactionDTO, Office office) {
+        // loan properties
+        final Long loanProductId = loanDTO.getLoanProductId();
+        final Long loanId = loanDTO.getLoanId();
+        final String currencyCode = loanDTO.getCurrencyCode();
+
+        // transaction properties
+        final String transactionId = loanTransactionDTO.getTransactionId();
+        final LocalDate transactionDate = 
loanTransactionDTO.getTransactionDate();
+        final BigDecimal amount = loanTransactionDTO.getAmount();
+        final boolean isReversal = loanTransactionDTO.isReversed();
+        final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
+
+        this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate, amount,
+                isReversal);
+    }
+
     /**
      * Debit loan Portfolio and credit Fund source for Disbursement.
      *
@@ -124,17 +152,17 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
         // create journal entries for the disbursement (or disbursement
         // reversal)
         if (loanTransactionDTO.isLoanToLoanTransfer()) {
-            
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, 
disbursalAmount, isReversed);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    FinancialActivity.ASSET_TRANSFER.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
+                    disbursalAmount, isReversed);
         } else if (loanTransactionDTO.isAccountTransfer()) {
-            
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, 
disbursalAmount, isReversed);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    FinancialActivity.LIABILITY_TRANSFER.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
+                    disbursalAmount, isReversed);
         } else {
-            
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
AccrualAccountsForLoan.FUND_SOURCE.getValue(), loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, 
disbursalAmount, isReversed);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    AccrualAccountsForLoan.FUND_SOURCE.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
+                    disbursalAmount, isReversed);
         }
 
     }
@@ -315,7 +343,7 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
         if (!(totalDebitAmount.compareTo(BigDecimal.ZERO) == 0)) {
             if (loanTransactionDTO.getTransactionType().isChargeRefund()) {
                 Integer incomeAccount = 
this.helper.getValueForFeeOrPenaltyIncomeAccount(loanTransactionDTO.getChargeRefundChargeType());
-                
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, incomeAccount,
+                this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, incomeAccount,
                         AccrualAccountsForLoan.FUND_SOURCE.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
                         totalDebitAmount, isReversal);
             }
@@ -341,7 +369,7 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
         final boolean isReversal = loanTransactionDTO.isReversed();
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
-        
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
+        this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
                 AccrualAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId,
                 transactionDate, amount, isReversal);
 
@@ -379,20 +407,20 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
 
         // create journal entries for recognizing interest (or reversal)
         if (interestAmount != null && 
!(interestAmount.compareTo(BigDecimal.ZERO) == 0)) {
-            
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(), 
AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(),
-                    loanProductId, paymentTypeId, loanId, transactionId, 
transactionDate, interestAmount, isReversed);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.INTEREST_RECEIVABLE.getValue(),
+                    AccrualAccountsForLoan.INTEREST_ON_LOANS.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId,
+                    transactionDate, interestAmount, isReversed);
         }
         // create journal entries for the fees application (or reversal)
         if (feesAmount != null && !(feesAmount.compareTo(BigDecimal.ZERO) == 
0)) {
-            
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoanCharges(office, 
currencyCode,
+            this.helper.createJournalEntriesAndReversalsForLoanCharges(office, 
currencyCode,
                     AccrualAccountsForLoan.FEES_RECEIVABLE.getValue(), 
AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(), loanProductId,
                     loanId, transactionId, transactionDate, feesAmount, 
isReversed, loanTransactionDTO.getFeePayments());
         }
         // create journal entries for the penalties application (or reversal)
         if (penaltiesAmount != null && 
!(penaltiesAmount.compareTo(BigDecimal.ZERO) == 0)) {
 
-            
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoanCharges(office, 
currencyCode,
+            this.helper.createJournalEntriesAndReversalsForLoanCharges(office, 
currencyCode,
                     AccrualAccountsForLoan.PENALTIES_RECEIVABLE.getValue(), 
AccrualAccountsForLoan.INCOME_FROM_PENALTIES.getValue(),
                     loanProductId, loanId, transactionId, transactionDate, 
penaltiesAmount, isReversed,
                     loanTransactionDTO.getPenaltyPayments());
@@ -413,12 +441,12 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
         if (loanTransactionDTO.isAccountTransfer()) {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
                     FinancialActivity.LIABILITY_TRANSFER.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
                     refundAmount, isReversal);
         } else {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
-                    CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate,
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.OVERPAYMENT.getValue(),
+                    AccrualAccountsForLoan.FUND_SOURCE.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
                     refundAmount, isReversal);
         }
     }
@@ -437,9 +465,9 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
         final boolean isReversal = loanTransactionDTO.isReversed();
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
-        
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
AccrualAccountsForLoan.OVERPAYMENT.getValue(), loanProductId,
-                paymentTypeId, loanId, transactionId, transactionDate, 
refundAmount, isReversal);
+        this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                AccrualAccountsForLoan.OVERPAYMENT.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate,
+                refundAmount, isReversal);
     }
 
     private void createJournalEntriesForRefundForActiveLoan(LoanDTO loanDTO, 
LoanTransactionDTO loanTransactionDTO, Office office) {
@@ -464,13 +492,13 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
 
         if (principalAmount != null && 
!(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
             totalDebitAmount = totalDebitAmount.add(principalAmount);
-            this.helper.createCreditJournalEntryOrReversalForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO, loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, 
principalAmount, !isReversal);
+            this.helper.createCreditJournalEntryOrReversalForLoan(office, 
currencyCode, AccrualAccountsForLoan.LOAN_PORTFOLIO,
+                    loanProductId, paymentTypeId, loanId, transactionId, 
transactionDate, principalAmount, !isReversal);
         }
 
         if (interestAmount != null && 
!(interestAmount.compareTo(BigDecimal.ZERO) == 0)) {
             totalDebitAmount = totalDebitAmount.add(interestAmount);
-            this.helper.createCreditJournalEntryOrReversalForLoan(office, 
currencyCode, CashAccountsForLoan.INTEREST_ON_LOANS,
+            this.helper.createCreditJournalEntryOrReversalForLoan(office, 
currencyCode, AccrualAccountsForLoan.INTEREST_ON_LOANS,
                     loanProductId, paymentTypeId, loanId, transactionId, 
transactionDate, interestAmount, !isReversal);
         }
 
@@ -486,7 +514,7 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
                         chargePaymentDTO.getLoanChargeId()));
             }
             
this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, 
currencyCode,
-                    CashAccountsForLoan.INCOME_FROM_FEES.getValue(), 
loanProductId, loanId, transactionId, transactionDate, feesAmount,
+                    AccrualAccountsForLoan.INCOME_FROM_FEES.getValue(), 
loanProductId, loanId, transactionId, transactionDate, feesAmount,
                     !isReversal, chargePaymentDTOs);
         }
 
@@ -502,18 +530,18 @@ public class AccrualBasedAccountingProcessorForLoan 
implements AccountingProcess
             }
 
             
this.helper.createCreditJournalEntryOrReversalForLoanCharges(office, 
currencyCode,
-                    CashAccountsForLoan.INCOME_FROM_PENALTIES.getValue(), 
loanProductId, loanId, transactionId, transactionDate,
+                    AccrualAccountsForLoan.INCOME_FROM_PENALTIES.getValue(), 
loanProductId, loanId, transactionId, transactionDate,
                     penaltiesAmount, !isReversal, chargePaymentDTOs);
         }
 
         if (overPaymentAmount != null && 
!(overPaymentAmount.compareTo(BigDecimal.ZERO) == 0)) {
             totalDebitAmount = totalDebitAmount.add(overPaymentAmount);
-            this.helper.createCreditJournalEntryOrReversalForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT, loanProductId,
+            this.helper.createCreditJournalEntryOrReversalForLoan(office, 
currencyCode, AccrualAccountsForLoan.OVERPAYMENT, loanProductId,
                     paymentTypeId, loanId, transactionId, transactionDate, 
overPaymentAmount, !isReversal);
         }
 
         /*** create a single debit entry (or reversal) for the entire amount 
**/
-        this.helper.createDebitJournalEntryOrReversalForLoan(office, 
currencyCode, CashAccountsForLoan.FUND_SOURCE.getValue(),
+        this.helper.createDebitJournalEntryOrReversalForLoan(office, 
currencyCode, AccrualAccountsForLoan.FUND_SOURCE.getValue(),
                 loanProductId, paymentTypeId, loanId, transactionId, 
transactionDate, totalDebitAmount, !isReversal);
 
     }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
index 1478ef188..530ec6f8f 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/accounting/journalentry/service/CashBasedAccountingProcessorForLoan.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
 import java.util.List;
 import lombok.RequiredArgsConstructor;
 import org.apache.fineract.accounting.closure.domain.GLClosure;
-import 
org.apache.fineract.accounting.common.AccountingConstants.AccrualAccountsForLoan;
 import 
org.apache.fineract.accounting.common.AccountingConstants.CashAccountsForLoan;
 import 
org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
 import org.apache.fineract.accounting.journalentry.data.ChargePaymentDTO;
@@ -91,7 +90,7 @@ public class CashBasedAccountingProcessorForLoan implements 
AccountingProcessorF
             else if (loanTransactionDTO.getTransactionType().isWriteOff()) {
                 final BigDecimal principalAmount = 
loanTransactionDTO.getPrincipal();
                 if (principalAmount != null && 
!(principalAmount.compareTo(BigDecimal.ZERO) == 0)) {
-                    
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
+                    
this.helper.createJournalEntriesAndReversalsForLoan(office, currencyCode,
                             CashAccountsForLoan.LOSSES_WRITTEN_OFF.getValue(), 
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), loanProductId,
                             paymentTypeId, loanId, transactionId, 
transactionDate, principalAmount, loanTransactionDTO.isReversed());
 
@@ -105,9 +104,38 @@ public class CashBasedAccountingProcessorForLoan 
implements AccountingProcessorF
             else if 
(loanTransactionDTO.getTransactionType().isRefundForActiveLoans()) {
                 createJournalEntriesForRefundForActiveLoan(loanDTO, 
loanTransactionDTO, office);
             }
+            // Logic for Chargebacks
+            else if (loanTransactionDTO.getTransactionType().isChargeback()) {
+                createJournalEntriesForChargeback(loanDTO, loanTransactionDTO, 
office);
+            }
         }
     }
 
+    /**
+     * Handle chargeback journal entry creation
+     *
+     * @param loanDTO
+     * @param loanTransactionDTO
+     * @param office
+     */
+    private void createJournalEntriesForChargeback(LoanDTO loanDTO, 
LoanTransactionDTO loanTransactionDTO, Office office) {
+        // loan properties
+        final Long loanProductId = loanDTO.getLoanProductId();
+        final Long loanId = loanDTO.getLoanId();
+        final String currencyCode = loanDTO.getCurrencyCode();
+
+        // transaction properties
+        final String transactionId = loanTransactionDTO.getTransactionId();
+        final LocalDate transactionDate = 
loanTransactionDTO.getTransactionDate();
+        final BigDecimal amount = loanTransactionDTO.getAmount();
+        final boolean isReversal = loanTransactionDTO.isReversed();
+        final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
+
+        this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate, amount,
+                isReversal);
+    }
+
     /**
      * Debit loan Portfolio and credit Fund source for a Disbursement <br/>
      *
@@ -132,17 +160,17 @@ public class CashBasedAccountingProcessorForLoan 
implements AccountingProcessorF
         final boolean isReversal = loanTransactionDTO.isReversed();
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
         if (loanTransactionDTO.isLoanToLoanTransfer()) {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
FinancialActivity.ASSET_TRANSFER.getValue(), loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, 
disbursalAmount, isReversal);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    FinancialActivity.ASSET_TRANSFER.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
+                    disbursalAmount, isReversal);
         } else if (loanTransactionDTO.isAccountTransfer()) {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
FinancialActivity.LIABILITY_TRANSFER.getValue(), loanProductId,
-                    paymentTypeId, loanId, transactionId, transactionDate, 
disbursalAmount, isReversal);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    FinancialActivity.LIABILITY_TRANSFER.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
+                    disbursalAmount, isReversal);
         } else {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, paymentTypeId,
-                    loanId, transactionId, transactionDate, disbursalAmount, 
isReversal);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate,
+                    disbursalAmount, isReversal);
         }
 
     }
@@ -171,11 +199,11 @@ public class CashBasedAccountingProcessorForLoan 
implements AccountingProcessorF
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
         if (loanTransactionDTO.isAccountTransfer()) {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
                     FinancialActivity.LIABILITY_TRANSFER.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
                     refundAmount, isReversal);
         } else {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.OVERPAYMENT.getValue(),
                     CashAccountsForLoan.FUND_SOURCE.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate,
                     refundAmount, isReversal);
         }
@@ -265,8 +293,8 @@ public class CashBasedAccountingProcessorForLoan implements 
AccountingProcessorF
         if (!(totalDebitAmount.compareTo(BigDecimal.ZERO) == 0)) {
             if (loanTransactionDTO.getTransactionType().isChargeRefund()) {
                 Integer incomeAccount = 
this.helper.getValueForFeeOrPenaltyIncomeAccount(loanTransactionDTO.getChargeRefundChargeType());
-                
this.helper.createAccrualBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, incomeAccount,
-                        AccrualAccountsForLoan.FUND_SOURCE.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
+                this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, incomeAccount,
+                        CashAccountsForLoan.FUND_SOURCE.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
                         totalDebitAmount, isReversal);
             }
         }
@@ -291,7 +319,7 @@ public class CashBasedAccountingProcessorForLoan implements 
AccountingProcessorF
         final boolean isReversal = loanTransactionDTO.isReversed();
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
-        this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.FUND_SOURCE.getValue(),
+        this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.FUND_SOURCE.getValue(),
                 CashAccountsForLoan.INCOME_FROM_RECOVERY.getValue(), 
loanProductId, paymentTypeId, loanId, transactionId, transactionDate,
                 amount, isReversal);
 
@@ -322,14 +350,14 @@ public class CashBasedAccountingProcessorForLoan 
implements AccountingProcessorF
         // final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
         if (loanTransactionDTO.getTransactionType().isInitiateTransfer()) {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), 
CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), loanProductId, null,
-                    loanId, transactionId, transactionDate, principalAmount, 
isReversal);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(),
+                    CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
loanProductId, null, loanId, transactionId, transactionDate,
+                    principalAmount, isReversal);
         } else if (loanTransactionDTO.getTransactionType().isApproveTransfer()
                 || 
loanTransactionDTO.getTransactionType().isWithdrawTransfer()) {
-            
this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode,
-                    CashAccountsForLoan.LOAN_PORTFOLIO.getValue(), 
CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), loanProductId, null,
-                    loanId, transactionId, transactionDate, principalAmount, 
isReversal);
+            this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+                    CashAccountsForLoan.TRANSFERS_SUSPENSE.getValue(), 
loanProductId, null, loanId, transactionId, transactionDate,
+                    principalAmount, isReversal);
         }
     }
 
@@ -347,7 +375,7 @@ public class CashBasedAccountingProcessorForLoan implements 
AccountingProcessorF
         final boolean isReversal = loanTransactionDTO.isReversed();
         final Long paymentTypeId = loanTransactionDTO.getPaymentTypeId();
 
-        this.helper.createCashBasedJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
+        this.helper.createJournalEntriesAndReversalsForLoan(office, 
currencyCode, CashAccountsForLoan.LOAN_PORTFOLIO.getValue(),
                 CashAccountsForLoan.OVERPAYMENT.getValue(), loanProductId, 
paymentTypeId, loanId, transactionId, transactionDate,
                 refundAmount, isReversal);
     }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
index 46633b57d..a0bbeae4c 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/data/LoanTransactionEnumData.java
@@ -50,6 +50,8 @@ public class LoanTransactionEnumData {
     private final boolean refundForActiveLoans;
     private final boolean creditBalanceRefund;
 
+    private final boolean chargeback;
+
     public LoanTransactionEnumData(final Long id, final String code, final 
String value) {
         this.id = id;
         this.code = code;
@@ -75,6 +77,7 @@ public class LoanTransactionEnumData {
         this.chargePayment = Long.valueOf(17).equals(this.id);
         this.refundForActiveLoans = Long.valueOf(18).equals(this.id);
         this.creditBalanceRefund = Long.valueOf(20).equals(this.id);
+        this.chargeback = Long.valueOf(25).equals(this.id);
     }
 
     public Long id() {
@@ -189,4 +192,8 @@ public class LoanTransactionEnumData {
         return this.creditBalanceRefund;
     }
 
+    public boolean isChargeback() {
+        return this.chargeback;
+    }
+
 }
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java
index 7c0e4ab84..1515d656e 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanaccount/domain/LoanTransactionType.java
@@ -56,7 +56,8 @@ public enum LoanTransactionType {
     MERCHANT_ISSUED_REFUND(21, "loanTransactionType.merchantIssuedRefund"), //
     PAYOUT_REFUND(22, "loanTransactionType.payoutRefund"), //
     GOODWILL_CREDIT(23, "loanTransactionType.goodwillCredit"), //
-    CHARGE_REFUND(24, "loanTransactionType.chargeRefund");
+    CHARGE_REFUND(24, "loanTransactionType.chargeRefund"), //
+    CHARGEBACK(25, "loanTransactionType.chargeback");
 
     private final Integer value;
     private final String code;
@@ -80,82 +81,33 @@ public enum LoanTransactionType {
             return LoanTransactionType.INVALID;
         }
 
-        LoanTransactionType loanTransactionType = null;
-        switch (transactionType) {
-            case 1:
-                loanTransactionType = LoanTransactionType.DISBURSEMENT;
-            break;
-            case 2:
-                loanTransactionType = LoanTransactionType.REPAYMENT;
-            break;
-            case 3:
-                loanTransactionType = LoanTransactionType.CONTRA;
-            break;
-            case 4:
-                loanTransactionType = LoanTransactionType.WAIVE_INTEREST;
-            break;
-            case 5:
-                loanTransactionType = 
LoanTransactionType.REPAYMENT_AT_DISBURSEMENT;
-            break;
-            case 6:
-                loanTransactionType = LoanTransactionType.WRITEOFF;
-            break;
-            case 7:
-                loanTransactionType = 
LoanTransactionType.MARKED_FOR_RESCHEDULING;
-            break;
-            case 8:
-                loanTransactionType = LoanTransactionType.RECOVERY_REPAYMENT;
-            break;
-            case 9:
-                loanTransactionType = LoanTransactionType.WAIVE_CHARGES;
-            break;
-            case 10:
-                loanTransactionType = LoanTransactionType.ACCRUAL;
-            break;
-            case 12:
-                loanTransactionType = LoanTransactionType.INITIATE_TRANSFER;
-            break;
-            case 13:
-                loanTransactionType = LoanTransactionType.APPROVE_TRANSFER;
-            break;
-            case 14:
-                loanTransactionType = LoanTransactionType.WITHDRAW_TRANSFER;
-            break;
-            case 15:
-                loanTransactionType = LoanTransactionType.REJECT_TRANSFER;
-            break;
-            case 16:
-                loanTransactionType = LoanTransactionType.REFUND;
-            break;
-            case 17:
-                loanTransactionType = LoanTransactionType.CHARGE_PAYMENT;
-            break;
-            case 18:
-                loanTransactionType = 
LoanTransactionType.REFUND_FOR_ACTIVE_LOAN;
-            break;
-            case 19:
-                loanTransactionType = LoanTransactionType.INCOME_POSTING;
-            break;
-            case 20:
-                loanTransactionType = 
LoanTransactionType.CREDIT_BALANCE_REFUND;
-            break;
-            case 21:
-                loanTransactionType = 
LoanTransactionType.MERCHANT_ISSUED_REFUND;
-            break;
-            case 22:
-                loanTransactionType = LoanTransactionType.PAYOUT_REFUND;
-            break;
-            case 23:
-                loanTransactionType = LoanTransactionType.GOODWILL_CREDIT;
-            break;
-            case 24:
-                loanTransactionType = LoanTransactionType.CHARGE_REFUND;
-            break;
-            default:
-                loanTransactionType = LoanTransactionType.INVALID;
-            break;
-        }
-        return loanTransactionType;
+        return switch (transactionType) {
+            case 1 -> LoanTransactionType.DISBURSEMENT;
+            case 2 -> LoanTransactionType.REPAYMENT;
+            case 3 -> LoanTransactionType.CONTRA;
+            case 4 -> LoanTransactionType.WAIVE_INTEREST;
+            case 5 -> LoanTransactionType.REPAYMENT_AT_DISBURSEMENT;
+            case 6 -> LoanTransactionType.WRITEOFF;
+            case 7 -> LoanTransactionType.MARKED_FOR_RESCHEDULING;
+            case 8 -> LoanTransactionType.RECOVERY_REPAYMENT;
+            case 9 -> LoanTransactionType.WAIVE_CHARGES;
+            case 10 -> LoanTransactionType.ACCRUAL;
+            case 12 -> LoanTransactionType.INITIATE_TRANSFER;
+            case 13 -> LoanTransactionType.APPROVE_TRANSFER;
+            case 14 -> LoanTransactionType.WITHDRAW_TRANSFER;
+            case 15 -> LoanTransactionType.REJECT_TRANSFER;
+            case 16 -> LoanTransactionType.REFUND;
+            case 17 -> LoanTransactionType.CHARGE_PAYMENT;
+            case 18 -> LoanTransactionType.REFUND_FOR_ACTIVE_LOAN;
+            case 19 -> LoanTransactionType.INCOME_POSTING;
+            case 20 -> LoanTransactionType.CREDIT_BALANCE_REFUND;
+            case 21 -> LoanTransactionType.MERCHANT_ISSUED_REFUND;
+            case 22 -> LoanTransactionType.PAYOUT_REFUND;
+            case 23 -> LoanTransactionType.GOODWILL_CREDIT;
+            case 24 -> LoanTransactionType.CHARGE_REFUND;
+            case 25 -> LoanTransactionType.CHARGEBACK;
+            default -> LoanTransactionType.INVALID;
+        };
     }
 
     public boolean isDisbursement() {
diff --git 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
index 92fa5df95..599dd7aba 100644
--- 
a/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
+++ 
b/fineract-provider/src/main/java/org/apache/fineract/portfolio/loanproduct/service/LoanEnumerations.java
@@ -287,6 +287,8 @@ public final class LoanEnumerations {
                     LoanTransactionType.GOODWILL_CREDIT.getCode(), "Goodwill 
Credit");
             case CHARGE_REFUND -> new 
LoanTransactionEnumData(LoanTransactionType.CHARGE_REFUND.getValue().longValue(),
                     LoanTransactionType.CHARGE_REFUND.getCode(), "Charge 
Refund");
+            case CHARGEBACK -> new 
LoanTransactionEnumData(LoanTransactionType.CHARGEBACK.getValue().longValue(),
+                    LoanTransactionType.CHARGEBACK.getCode(), "Chargeback");
         };
     }
 

Reply via email to