Skip to main content

Teller Deposit Transaction

Customer deposits funds via teller counter (Cash or Cheque).

Overview

Teller deposits allow customers to credit funds to their deposit accounts through physical cash or cheque presented at the teller counter. The transaction increases both the customer's account balance and the teller till balance (for cash deposits).

Key Features:

  • Supports both Cash and Cheque deposits
  • Till balance tracking for cash transactions
  • Cheque clearing cycle management
  • Account activation on first deposit
  • Approval workflow for large amounts
  • Concurrent transaction safety with impact tracking

Transaction Flow

Cash Deposit Flow

Cheque Deposit Flow


Entities Impacted

Cash Deposit Scenario

Command: DepositToTellerTillCommand (BPMCore)

ImpactedEntities:
[
{
entityType: "DepositAccount",
entityId: 12345,
fieldName: "AvailableBalance",
oldValue: 100000.00,
newValue: 105000.00,
deltaAmount: +5000.00
},
{
entityType: "DepositAccount",
entityId: 12345,
fieldName: "BookBalance",
oldValue: 100000.00,
newValue: 105000.00,
deltaAmount: +5000.00
},
{
entityType: "TellerTill",
entityId: 789,
fieldName: "CashBalance",
oldValue: 50000.00,
newValue: 55000.00,
deltaAmount: +5000.00
},
{
entityType: "TellerTill",
entityId: 789,
fieldName: "TransactionCount",
oldValue: 42,
newValue: 43,
deltaAmount: +1
},
{
entityType: "GLAccount",
entityKey: "1001-CUSTOMER-DEPOSITS",
fieldName: "DebitAmount",
deltaAmount: +5000.00
},
{
entityType: "GLAccount",
entityKey: "1050-CASH-IN-TILL",
fieldName: "CreditAmount",
deltaAmount: +5000.00
}
]
```text
### Cheque Deposit Scenario

**Command**: `InitiateDepositCommand` (with `cashOrCheque=Cheque`)

```typescript
ImpactedEntities:
[
{
entityType: "DepositAccount",
entityId: 12345,
fieldName: "BookBalance",
oldValue: 100000.00,
newValue: 110000.00,
deltaAmount: +10000.00 // Provisional credit
},
{
entityType: "ChequeClearingTransaction",
entityId: 999,
fieldName: "State",
oldValue: null,
newValue: "PENDING_CLEARING",
deltaAmount: 0
},
{
entityType: "ChequeClearingTransaction",
entityId: 999,
fieldName: "Amount",
oldValue: 0,
newValue: 10000.00,
deltaAmount: +10000.00
},
{
entityType: "GLAccount",
entityKey: "1200-CHEQUE-SUSPENSE",
fieldName: "DebitAmount",
deltaAmount: +10000.00
},
{
entityType: "GLAccount",
entityKey: "1001-CUSTOMER-DEPOSITS",
fieldName: "CreditAmount",
deltaAmount: +10000.00
}
]
```text
---

## Implementation

### Cash Deposit Implementation

**BPMCore Command**: `DepositToTellerTillCommand`

:::warning[Code Removed]
**Implementation details removed for security.**

Contact support for implementation guidance.
:::text
### Cheque Deposit Implementation

**Command**: `InitiateDepositCommand` (with `cashOrCheque=Cheque`)

:::warning[Code Removed]
**Implementation details removed for security.**

Contact support for implementation guidance.
:::text
---

## Validation Rules

### Till Validation

| Rule | Check | Error Message |
|------|-------|---------------|
| **Till Exists** | Till found by `TillId` or `EncodedKey` | "Till not found" |
| **Till State** | `TillAccountState == OPENED` | "Till {TillId} is not opened" |
| **Till Type** | `TillType == TellerTill` | "Invalid till type" |
| **Currency Match** | Till currency == Account currency | "Currency mismatch" |
| **Maximum Balance** | `Balance + Amount <= MaximumBalance` (if Hard constraint) | "Transaction will exceed till maximum balance by {excess}" |
| **Branch Open** | Branch is open for today | "Branch is closed" |

### Account Validation

| Rule | Check | Error Message |
|------|-------|---------------|
| **Account Exists** | Account found by `AccountNumber` or `EncodedKey` | "Account not found" |
| **Account Active** | `DepositState == ACTIVE` or `APPROVED` | "Account is not active" |
| **Not Locked** | `DepositState != LOCKED` | "Account is locked" |
| **Not Closed** | `DepositState != CLOSED` | "Account is closed" |
| **Amount Valid** | `Amount > 0` | "Amount must be greater than zero" |

### Cheque Validation (if applicable)

| Rule | Check | Error Message |
|------|-------|---------------|
| **Cheque Number** | Cheque number provided when `CashOrCheque == Cheque` | "Cheque number is required" |
| **Cheque Format** | Valid cheque number format | "Invalid cheque number format" |
| **Duplicate Check** | Cheque number not already deposited | "Duplicate cheque number" |

---

## GL Account Postings

### Cash Deposit

| Account | Debit (Dr) | Credit (Cr) | Description |
|---------|------------|-------------|-------------|
| **Customer Deposits Liability** | Amount | - | Increase customer liability |
| **Cash-in-Till Asset** | - | Amount | Increase till cash balance |

**Example** (₦5,000 deposit):
```text
DR: 2001-Customer-Deposits-Liability ₦5,000
CR: 1050-Cash-in-Till ₦5,000
```text
### Cheque Deposit

| Account | Debit (Dr) | Credit (Cr) | Description |
|---------|------------|-------------|-------------|
| **Cheque Suspense Asset** | Amount | - | Pending clearing |
| **Customer Deposits Liability** | - | Amount | Provisional credit |

**On Clearing**:
```text
DR: 1001-Customer-Deposits-Liability ₦10,000
CR: 1200-Cheque-Suspense ₦10,000
```text
---

## Testing

### Test Scenario 1: Cash Deposit - Auto-Approve

**Setup**:
- Account: Active Savings Account (₦100,000 balance)
- Till: TELLER-01 (₦50,000 balance, max ₦100,000)
- Amount: ₦5,000 (below approval limit)

**Expected Results**:
```typescript
DepositAccount:
AvailableBalance: 100000 → 105000 ✓
BookBalance: 100000 → 105000 ✓
LastTransactionDate: Updated ✓

TellerTill:
Balance: 50000 → 55000 ✓
TransactionCount: +1 ✓

Transaction:
State: PENDING → APPROVED → COMPLETED ✓

GLEntries:
DR: Customer-Deposits: ₦5,000 ✓
CR: Cash-in-Till: ₦5,000 ✓
```text
### Test Scenario 2: Cheque Deposit - Pending Clearing

**Setup**:
- Account: Active Current Account (₦50,000 balance)
- Cheque Number: CHQ-123456
- Amount: ₦10,000

**Expected Results**:
```typescript
DepositAccount:
AvailableBalance: 50000 (NO CHANGE) ✓
BookBalance: 50000 → 60000 ✓

ChequeClearingTransaction:
State: PENDING_CLEARING ✓
Amount: ₦10,000 ✓
ChequeNumber: CHQ-123456 ✓

Transaction:
CashOrCheque: CHEQUE ✓
State: COMPLETED ✓

GLEntries:
DR: Cheque-Suspense: ₦10,000 ✓
CR: Customer-Deposits: ₦10,000 ✓
```text
### Test Scenario 3: Approval Workflow

**Setup**:
- Amount: ₦500,000 (above approval limit of ₦100,000)

**Expected Results**:
```typescript
Transaction:
State: PENDING ✓
RequiresApproval: true ✓

DepositAccount:
AvailableBalance: NO CHANGE (pending approval) ✓
BookBalance: NO CHANGE (pending approval) ✓

After Approval:
State: APPROVED → COMPLETED ✓
Balances updated ✓
```text
### Test Scenario 4: Account Activation

**Setup**:
- Account State: APPROVED (new account, never funded)
- First deposit: ₦10,000

**Expected Results**:
```typescript
DepositAccount:
DepositState: APPROVED → ACTIVE ✓
ActivationDate: Set to current date ✓
AvailableBalance: 0 → 10000 ✓
BookBalance: 0 → 10000 ✓
```text
### Test Scenario 5: Till Maximum Balance Constraint

**Setup**:
- Till Balance: ₦95,000
- Till MaximumBalance: ₦100,000
- Till Constraint: HARD
- Deposit Amount: ₦10,000

**Expected Results**:
```typescript
Validation:
Error: "Transaction will exceed till maximum balance by ₦5,000" ✓
Transaction: REJECTED ✓

Till Balance: 95000 (NO CHANGE) ✓
Account Balance: NO CHANGE ✓
```text
---

## Concurrent Transaction Safety

### Scenario: Simultaneous Deposits

Two tellers deposit to the same account at the same time:

**Teller A**: Deposit ₦5,000
**Teller B**: Deposit ₦3,000

**Initial State**:
- Account Balance: ₦100,000

**Delta-Based Tracking**:
```typescript
Transaction A Impact:
OldValue: 100000
NewValue: 105000
Delta: +5000

Transaction B Impact:
OldValue: 100000 // Same starting point
NewValue: 103000
Delta: +3000

Final Balance: 100000 + 5000 + 3000 = 108000 ✓

Both deltas are preserved, ensuring accurate final balance even with concurrent execution.


V2 API Commands

BankLingo V2 provides BPMCore-compatible commands for teller deposit transactions.

Architecture Overview

The V2 teller deposit uses the core deposit command with till tracking:

  • V2 Command: InitiateDepositCommand (with tillId parameter)
  • BPM Integration: Accepts parameters via BpmUtil.GetPropertyValue()
  • Impact Tracking: Tracks account + till changes via TransactionImpactTracker
  • State Management: PENDING → APPROVED → SETTLED
  • Till Integration: Automatically updates till balance for cash deposits

Implementation: CB.Administration.Api/Commands/BPMCore/DepositWithdrawal/AdministrationCoreDepositTransactionCommandHandlers.cs


InitiateDepositCommand (Teller Context)

Purpose: Process customer deposit via teller counter (cash or cheque)

Command: InitiateDepositCommand

Key Parameters for Teller Context:

{
"commandName": "InitiateDepositCommand",
"data": {
"accountEncodedKey": "string (mandatory)",
"amount": "decimal (mandatory)",
"tillId": "string (optional - for cash deposits)",
"chequeNo": "string (optional - for cheque deposits)",
"isCash": "boolean (optional)",
"referenceId": "string (optional)",
"remarks": "string (optional)"
}
}

Teller-Specific Behavior

Cash Deposit (with tillId):

  • ✅ Account balance increased
  • ✅ Till balance increased
  • ✅ GL: DR Customer Deposits, CR Cash-in-Till

Cheque Deposit (with chequeNo):

  • ⚠️ Account balance NOT immediately increased (awaits clearing)
  • ✅ UnclearedChequeAmount tracked
  • ✅ Cheque clearing cycle initiated

Example: Cash Deposit via Teller

Request:

{
"commandName": "InitiateDepositCommand",
"data": {
"accountEncodedKey": "8a8080827f23dep017f23abc123",
"amount": 50000.00,
"tillId": "TILL-001",
"isCash": true,
"remarks": "Cash deposit at teller counter"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-DEP-20251229-0001",
"transactionState": "SETTLED",
"message": "Deposit processed successfully",
"data": {
"accountEncodedKey": "8a8080827f23dep017f23abc123",
"amount": 50000.00,
"accountBalance": {
"previousBalance": 100000.00,
"newBalance": 150000.00
},
"tillBalance": {
"tillId": "TILL-001",
"previousBalance": 300000.00,
"newBalance": 350000.00
},
"impactRecords": 6
}
}

Example: Cheque Deposit via Teller

Request:

{
"commandName": "InitiateDepositCommand",
"data": {
"accountEncodedKey": "8a8080827f23dep017f23abc123",
"amount": 75000.00,
"tillId": "TILL-002",
"chequeNo": "CHQ-2025-001234",
"isCash": false,
"remarks": "Cheque deposit - awaiting clearing"
}
}

Response:

{
"isSuccessful": true,
"transactionId": "TXN-CHQDEP-20251229-0002",
"transactionState": "PENDING",
"message": "Cheque deposit posted (awaiting clearing)",
"data": {
"accountEncodedKey": "8a8080827f23dep017f23abc123",
"amount": 75000.00,
"chequeNo": "CHQ-2025-001234",
"accountBalance": {
"previousBalance": 150000.00,
"newBalance": 150000.00
},
"unclearedChequeAmount": 75000.00,
"clearingStatus": "PENDING",
"expectedClearingDate": "2026-01-02"
}
}

Till Integration Details

When tillId is provided:

  1. Validation: Till must be OPENED and belong to authorized teller
  2. Balance Update: Till cash balance increased by deposit amount
  3. Impact Tracking: Both account and till changes tracked
  4. GL Posting: Includes till-specific GL accounts
  5. Concurrent Safety: Uses locking on both account and till

Benefits:

  • ✅ Real-time till balance tracking
  • ✅ Automated till reconciliation
  • ✅ Teller performance metrics
  • ✅ Cash position monitoring

Developer Resources

For API implementation details, see: