feat(cashier): remove GL entries for vault-to-cashier transfers (Option A)

ALLOCATE (vault→cashier) and SETTLE (cashier→vault) no longer post
DR CASH_AT_TELLER / CR CASH_AT_MAINVAULT journal entries.

Rationale: Cash transfer between vault and teller drawer is an internal
physical movement — the denomination/amount is already tracked operationally
via m_cash_transfer and m_cash_settlement tables. A single Cash in Hand GL
(CASH_AT_MAINVAULT) covers all bank cash. GL entries now only occur on
actual customer deposit/withdrawal transactions (SAVINGS_REFERENCE ↔
SAVINGS_CONTROL), keeping the GL clean and RBI-compliant.

Removed unused imports and field injections:
  JournalEntryRepository, FinancialActivityAccountRepositoryWrapper,
  FinancialActivity, FinancialActivityAccount, GLAccount,
  JournalEntry, JournalEntryType

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jaanu423
2026-06-02 07:13:48 +05:30
co-authored by Claude Sonnet 4.6
parent 8bf28a8033
commit 6bdcac7b77
@@ -24,13 +24,6 @@ import java.util.Set;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils; import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.fineract.accounting.common.AccountingConstants.FinancialActivity;
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccount;
import org.apache.fineract.accounting.financialactivityaccount.domain.FinancialActivityAccountRepositoryWrapper;
import org.apache.fineract.accounting.glaccount.domain.GLAccount;
import org.apache.fineract.accounting.journalentry.domain.JournalEntry;
import org.apache.fineract.accounting.journalentry.domain.JournalEntryRepository;
import org.apache.fineract.accounting.journalentry.domain.JournalEntryType;
import org.apache.fineract.infrastructure.core.api.JsonCommand; import org.apache.fineract.infrastructure.core.api.JsonCommand;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResult; import org.apache.fineract.infrastructure.core.data.CommandProcessingResult;
import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder; import org.apache.fineract.infrastructure.core.data.CommandProcessingResultBuilder;
@@ -70,8 +63,6 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
private final StaffRepository staffRepository; private final StaffRepository staffRepository;
private final CashierRepository cashierRepository; private final CashierRepository cashierRepository;
private final CashierTransactionRepository cashierTxnRepository; private final CashierTransactionRepository cashierTxnRepository;
private final JournalEntryRepository glJournalEntryRepository;
private final FinancialActivityAccountRepositoryWrapper financialActivityAccountRepositoryWrapper;
private final CashierTransactionDataValidator cashierTransactionDataValidator; private final CashierTransactionDataValidator cashierTransactionDataValidator;
@Override @Override
@@ -385,53 +376,10 @@ public class TellerWritePlatformServiceJpaImpl implements TellerWritePlatformSer
this.cashierTxnRepository.save(cashierTxn); this.cashierTxnRepository.save(cashierTxn);
// Pass the journal entries // GL entries skipped for vault-to-cashier (ALLOCATE) and cashier-to-vault (SETTLE)
FinancialActivityAccount mainVaultFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper // transfers. Cash is internal bank physical movement — denomination tracking is
.findByFinancialActivityTypeWithNotFoundDetection(FinancialActivity.CASH_AT_MAINVAULT.getValue()); // handled operationally via m_cash_transfer / m_cash_settlement tables.
FinancialActivityAccount tellerCashFinancialActivityAccount = this.financialActivityAccountRepositoryWrapper // GL impact happens only on customer deposit/withdrawal transactions.
.findByFinancialActivityTypeWithNotFoundDetection(FinancialActivity.CASH_AT_TELLER.getValue());
GLAccount creditAccount = null;
GLAccount debitAccount = null;
if (txnType.equals(CashierTxnType.ALLOCATE)) {
debitAccount = tellerCashFinancialActivityAccount.getGlAccount();
creditAccount = mainVaultFinancialActivityAccount.getGlAccount();
} else if (txnType.equals(CashierTxnType.SETTLE)) {
debitAccount = mainVaultFinancialActivityAccount.getGlAccount();
creditAccount = tellerCashFinancialActivityAccount.getGlAccount();
}
final Office cashierOffice = cashier.getTeller().getOffice();
final Long time = System.currentTimeMillis();
final String uniqueVal = String.valueOf(time) + currentUser.getId() + cashierOffice.getId();
final String transactionId = Long.toHexString(Long.parseLong(uniqueVal));
final JournalEntry debitJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
// detail
debitAccount, cashierTxn.getCurrencyCode(),
transactionId, false, // manual entry
cashierTxn.getTxnDate(), JournalEntryType.DEBIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number
null, null, null, null); // Loan
// and
// Savings
// Txn
final JournalEntry creditJournalEntry = JournalEntry.createNew(cashierOffice, null, // payment
// detail
creditAccount, cashierTxn.getCurrencyCode(),
transactionId, false, // manual entry
cashierTxn.getTxnDate(), JournalEntryType.CREDIT, cashierTxn.getTxnAmount(), cashierTxn.getTxnNote(), // Description
null, null, null, // entity Type, entityId, reference number
null, null, null, null); // Loan
// and
// Savings
// Txn
this.glJournalEntryRepository.saveAndFlush(debitJournalEntry);
this.glJournalEntryRepository.saveAndFlush(creditJournalEntry);
return new CommandProcessingResultBuilder() // return new CommandProcessingResultBuilder() //
.withCommandId(command.commandId()) // .withCommandId(command.commandId()) //