# Cash Transfer Controller Documentation

**File**: `/controllers/cashTransferController.php`  
**Purpose**: Manage cash transfers between bank accounts and cash registers with full transaction tracking  
**Last Updated**: December 20, 2024  
**Total Functions**: 8+  
**Lines of Code**: ~664

---

## 📋 Overview

The Cash Transfer Controller manages cash movements between bank accounts and cash registers, providing complete transaction tracking and accounting integration. It handles:
- Bank-to-cash register transfers (withdrawals)
- Cash register-to-bank transfers (deposits)
- Account balance updates with transaction history
- Daily entry accounting integration
- Transaction reversal and cancellation
- Batch operation processing
- Print-friendly transfer receipts
- Multi-user permission support

### Primary Functions
- [x] Process cash transfers between banks and registers
- [x] Update bank account and cash register balances
- [x] Create corresponding accounting entries
- [x] Track transaction history with audit trail
- [x] Support transaction reversal and cancellation
- [x] Generate transfer reports and receipts
- [x] Handle batch transfer operations
- [x] Integrate with daily entry accounting system

### Related Controllers
- [saveController.php](saveController.md) - Cash register management
- [bankaccountController.php](bankaccountController.md) - Bank account operations
- [dailyentry.php](dailyentry.md) - Accounting integration
- [savedailyController.php](savedailyController.md) - Cash transaction history

---

## 🗄️ Database Tables

### Primary Transaction Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **cashtransfer** | Cash transfer records | cashtransferid, bankaccountid, saveid, cashtransferamount, type, conditions, dailyentryid |
| **accountmovement** | Bank account movements | accountmovementid, accountid, accountmovementamount, accountmovementtype, processname |
| **savedaily** | Cash register history | savedailyid, saveid, savedailychangeamount, savedailychangetype, processname |

### Account Management Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **bankaccount** | Bank account master | accountid, bankid, accountnumber, accountbeginingbalance, treeId |
| **save** | Cash registers | saveid, savename, savecurrentvalue, treeId |
| **bank** | Bank information | bankid, bankname |

### Accounting Integration
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **dailyentry** | Journal entry headers | id, dDateTime, entryComment |
| **dailyentrydebtor** | Debit entries | id, dailyentryid, accountstreeid, value |
| **dailyentrycreditor** | Credit entries | id, dailyentryid, accountstreeid, value |
| **accountstree** | Chart of accounts | id, customName, parent |

### Support Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **youtubelink** | Tutorial videos | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **add()** - Create Cash Transfer
**Location**: Line 254  
**Purpose**: Process new cash transfer with complete transaction handling

**Function Signature**:
```php
function add()
```

**Process Flow**:
1. Extract and validate form parameters
2. Determine transfer type and direction
3. Create cash transfer record
4. Update cash register balance
5. Update bank account balance
6. Create transaction history records
7. Generate accounting entries
8. Commit transaction with safety

**Transfer Types**:
```php
if ($transfer == 1) { // Bank to Cash Register
    $type = 1;
    $processname = "تحويل نقدي من البنك إلى الخزنة";
    $savedailychangetype = 0; // Cash increase
    $accountmovementtype = 1; // Bank decrease
} else if ($transfer == 2) { // Cash Register to Bank
    $type = 2;
    $processname = "تحويل نقدي من الخزنة إلى البنك";
    $savedailychangetype = 1; // Cash decrease
    $accountmovementtype = 0; // Bank increase
}
```

**Cash Register Balance Update**:
```php
$savesData = $saveExt->loadForUpdateEx($saveId);
$saveBefore = $savesData->savecurrentvalue;

if ($transfer == 1) { // Bank to Cash
    $saveAfter = ($savesData->savecurrentvalue + $amount);
} else if ($transfer == 2) { // Cash to Bank
    $saveAfter = ($savesData->savecurrentvalue - $amount);
}

$save->savecurrentvalue = $saveAfter;
$save->saveid = $saveId;
$saveExt->updateSaveValue($save);
```

**Bank Account Balance Update**:
```php
$accoundatat = $accountDAO->load($accountid);
$accountBefore = $accoundatat->accountbeginingbalance;

if ($accountmovementtype == 1) { // Bank decrease
    $account->accountbeginingbalance = $accountBefore - $amount;
    $accountmovementafter = $accountBefore - $amount;
} elseif ($accountmovementtype == 0) { // Bank increase
    $account->accountbeginingbalance = $accountBefore + $amount;
    $accountmovementafter = $accountBefore + $amount;
}

$accountExt->updateacount($account);
```

---

### 2. **Accounting Integration**
**Location**: Line 385-414  
**Purpose**: Create double-entry accounting records for cash transfers

**Process Flow**:
1. Determine debit and credit accounts based on transfer direction
2. Create daily entry header
3. Set up debtor and creditor arrays
4. Call accounting integration function
5. Update transfer record with daily entry ID

**Account Determination Logic**:
```php
$baccountData = $accountDAO->load($accountid);
$accountTreeId = $baccountData->treeId;

$saveData = $savesDAO->load($saveId);
$saveTreeId = $saveData->treeId;

if ($transfer == 1) { // Bank to Cash: Debit=Cash, Credit=Bank
    $dailyEntryDebtor->accountstreeid = $saveTreeId;
    $dailyEntryCreditor->accountstreeid = $accountTreeId;
} else { // Cash to Bank: Debit=Bank, Credit=Cash
    $dailyEntryDebtor->accountstreeid = $accountTreeId;
    $dailyEntryCreditor->accountstreeid = $saveTreeId;
}
```

**Daily Entry Creation**:
```php
$dailyEntry->dDateTime = date('Y-m-d H:i:s');
$dailyEntry->entryComment = $processname;

$dailyEntryDebtor->value = $amount;
$dailyEntryCreditor->value = $amount;

$returnedData = insertEntery($dailyEntry, $dailyEntryDebtorArray, 
                           $dailyEntryCreditorArray, 1, $cashTransferId, 
                           'cashTransferController.php?do=editprint&id=' . $cashTransferId);
```

---

### 3. **show()** - Transfer History Display
**Location**: Line 459  
**Purpose**: Display transfer history with flexible filtering options

**Function Signature**:
```php
function show()
```

**Filtering Options**:
1. **Date Range Filter**: Show transfers between specified dates
2. **Cash Register Filter**: Show transfers for specific register
3. **Default View**: Show today's transfers

**Filter Logic**:
```php
if (isset($to) && $to != "" && isset($from) && $from != "") {
    // Date range filter
    $shownData = $cashTransferExt->queryCashTransferBydate($from, $to);
    $message = "عرض التحويلات النقدية من تاريخ : " . $from . "  الى تاريخ  " . $to;
    
} elseif (isset($saveid) && $saveid != "-1") {
    // Cash register filter
    $saveData = $savesDAO->load($saveid);
    $shownData = $cashTransferExt->queryCashTransferBySaveId($saveid);
    $message = "عرض التحويلات النقدية من وإلى الخزنة : " . $saveData->savename;
    
} else {
    // Default: today's transfers
    $shownData = $cashTransferExt->queryCashTransferBydate(date("Y-m-d"), date("Y-m-d"));
    $message = "عرض التحويلات النقدية من تاريخ : " . date("Y-m-d") . "  الى تاريخ :   " . date("Y-m-d");
}
```

---

### 4. **delete()** - Transfer Reversal
**Location**: Line 493  
**Purpose**: Reverse cash transfer with complete transaction rollback

**Function Signature**:
```php
function delete($id)
```

**Process Flow**:
1. Load original transfer data
2. Reverse cash register balance changes
3. Reverse bank account balance changes
4. Create reversal transaction history
5. Mark transfer as cancelled
6. Reverse accounting entries
7. Commit all changes

**Cash Register Reversal**:
```php
if ($type == 1) { // Original was bank to cash, so reverse: decrease cash
    $saveAfter = ($savedata->savecurrentvalue - $amount);
    $savedailychangetype = 1;
    $processname = "إلغاء تحويل نقدي من البنك إلى الخزنة";
} else if ($type == 2) { // Original was cash to bank, so reverse: increase cash
    $saveAfter = ($savedata->savecurrentvalue + $amount);
    $savedailychangetype = 0;
    $processname = "إلغاء تحويل نقدي من الخزنة إلى البنك";
}
```

**Bank Account Reversal**:
```php
if ($type == 1) { // Reverse bank decrease
    $accountAfter = $accountBefore + $cashtransferamount;
    $accountmovementtype = 0;
} else if ($type == 2) { // Reverse bank increase
    $accountAfter = $accountBefore - $cashtransferamount;
    $accountmovementtype = 1;
}
```

---

### 5. **execute()** - Batch Operations
**Location**: Line 612  
**Purpose**: Process batch transfer operations with error handling

**Function Signature**:
```php
function execute()
```

**Process Flow**:
1. Parse operation type and selected transfers
2. Iterate through selected transfer IDs
3. Validate operation permissions
4. Execute operation (currently only deletion supported)
5. Track success/failure for each operation
6. Display consolidated results

**Batch Processing Logic**:
```php
foreach ($choosedItemArr as $checkId) {
    $checkdata = $cashTransferDAO->load($checkId);
    $conditions = $checkdata->conditions;
    
    if ($operationType == '1' && $conditions == 0) { // Delete if not cancelled
        try {
            $note = delete($checkId);
            if ($note != "sucess") {
                $outputString .= $cashtransfernumber . ": " . $note . "<br/>";
            } else {
                $outputString .= $cashtransfernumber . ": تمت العملية بنجاح <br/>";
            }
        } catch (Exception $e) {
            // Error handling
        }
    } else {
        $outputString .= $cashtransfernumber . ": لا يمكن الغاء هذا الشيك لانه ملغى سابقا<br/>";
    }
}
```

---

### 6. **edit()** - Transfer Receipt Display
**Location**: Line 444  
**Purpose**: Display transfer details for printing

**Function Signature**:
```php
function edit()
```

**Process Flow**:
1. Get transfer ID from URL
2. Load extended transfer data
3. Display via print template

---

### 7. **getSaves()** - Cash Register List
**Location**: Line 247  
**Purpose**: Load available cash registers for selection

**Function Signature**:
```php
function getSaves()
```

**Returns**: Array of active cash register records

---

## 🔄 Workflows

### Workflow 1: Cash Transfer Processing
```
┌─────────────────────────────────────────────────────────────┐
│                START: Initiate Cash Transfer               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Select Transfer Parameters                             │
│     - Transfer direction (1=Bank→Cash, 2=Cash→Bank)       │
│     - Source bank account                                  │
│     - Target cash register                                │
│     - Transfer amount                                      │
│     - Notes and reference number                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Validate Transfer Parameters                           │
│     - Check account balances                               │
│     - Verify user permissions                              │
│     - Validate amount > 0                                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Create Transfer Record                                 │
│     - Insert into cashtransfer table                      │
│     - Set initial status (conditions = 0)                 │
│     - Record user and timestamp                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Update Cash Register Balance                           │
│     - Load current cash register value                    │
│     - Calculate new balance based on direction            │
│     - Update save table with new amount                   │
│     - Create savedaily history record                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Update Bank Account Balance                            │
│     - Load current bank account balance                   │
│     - Calculate new balance based on direction            │
│     - Update bankaccount table                            │
│     - Create accountmovement history record               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Create Accounting Entries                              │
│     - Determine debit and credit accounts                 │
│     - Create dailyentry header record                     │
│     - Create dailyentrydebtor record                      │
│     - Create dailyentrycreditor record                    │
│     - Link transfer to daily entry                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  7. Commit Transaction                                     │
│     - Verify all operations successful                    │
│     - Commit database transaction                         │
│     - Generate success message                            │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Transfer Reversal Process
```
┌─────────────────────────────────────────────────────────────┐
│              START: Reverse Cash Transfer                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Original Transfer Data                            │
│     - Get transfer record by ID                           │
│     - Extract amount, accounts, and type                  │
│     - Verify transfer can be reversed (conditions = 0)    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Reverse Cash Register Changes                          │
│     - Load current cash register balance                  │
│     - Apply opposite of original change                   │
│     - Create reversal savedaily record                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Reverse Bank Account Changes                           │
│     - Load current bank account balance                   │
│     - Apply opposite of original change                   │
│     - Create reversal accountmovement record              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Mark Transfer as Cancelled                             │
│     - Update conditions field to 1                        │
│     - Preserve original record for audit trail            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Reverse Accounting Entries                             │
│     - Call reverseEntryWithItsID() function               │
│     - Create offsetting journal entries                   │
│     - Maintain accounting balance                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Commit Reversal Transaction                            │
│     - Verify all reversals successful                     │
│     - Commit database changes                             │
│     - Generate success/failure message                    │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Show form | Display transfer creation interface |
| `do=add` | `add()` | Process new cash transfer |
| `do=show` | `show()` | Display transfer history with filters |
| `do=editprint` | `edit()` | Show printable transfer receipt |
| `do=executeOperation` | `execute()` | Process batch operations |
| `do=delete` | `delete()` | Reverse individual transfer |
| `do=details` | Show details | Display transfer details view |
| `do=sucess` | Show template | Display success message |
| `do=error` | Show template | Display error message |

### Required Parameters by Action

**Transfer Creation** (`do=add`):
- `transfer` - Direction (1=bank to cash, 2=cash to bank)
- `save` - Cash register ID
- `accountid` - Bank account ID
- `txtAmount` - Transfer amount
- `textNote` - Transfer notes
- `txtcheckNum` - Reference number
- `txtUser` - User name
- `ddlBank` - Bank ID

**Transfer History** (`do=show`):
- `saveid` - Cash register filter (optional)
- `from` - Start date filter (optional)
- `to` - End date filter (optional)

**Batch Operations** (`do=executeOperation`):
- `operation` - Operation type (1=delete)
- `choosedItem[]` - Array of transfer IDs
- `dailyentryid[]` - Array of accounting entry IDs

**Transfer Reversal** (`do=delete`):
- `transferId` - Transfer ID to reverse
- `action` - Daily entry ID for reversal

---

## 🧮 Balance Calculation Logic

### Cash Register Balance Updates
```php
// For Bank→Cash transfers (type 1)
$saveAfter = $saveBefore + $amount;
$savedailychangetype = 0; // Increase

// For Cash→Bank transfers (type 2)  
$saveAfter = $saveBefore - $amount;
$savedailychangetype = 1; // Decrease
```

### Bank Account Balance Updates
```php
// For Bank→Cash transfers (decrease bank)
$accountAfter = $accountBefore - $amount;
$accountmovementtype = 1; // Withdrawal

// For Cash→Bank transfers (increase bank)
$accountAfter = $accountBefore + $amount;
$accountmovementtype = 0; // Deposit
```

### Accounting Entry Logic
```php
// Bank→Cash: Debit Cash Account, Credit Bank Account
if ($transfer == 1) {
    $dailyEntryDebtor->accountstreeid = $saveTreeId;    // Cash register
    $dailyEntryCreditor->accountstreeid = $accountTreeId; // Bank account
}

// Cash→Bank: Debit Bank Account, Credit Cash Account
else {
    $dailyEntryDebtor->accountstreeid = $accountTreeId;   // Bank account
    $dailyEntryCreditor->accountstreeid = $saveTreeId;    // Cash register
}
```

---

## 📊 Transaction Safety Features

### Database Transactions
```php
$cashTransactions = new Transaction();
try {
    // All operations here
    $cashTransactions->commit();
    $message = 'تمت العملية بنجاح';
} catch (Exception $ex) {
    $cashTransactions->rollback();
    $message = 'عفوا لقد حدث خطأ';
}
```

### Audit Trail Maintenance
- Original records preserved during reversals
- Complete transaction history in movement tables
- Accounting entries maintain double-entry integrity
- User and timestamp tracking for all operations

### Error Recovery
- Automatic transaction rollback on failures
- Graceful error handling with user feedback
- Batch operation continues despite individual failures

---

## 🔒 Security & Validation

### Access Control
```php
include_once("../public/authentication.php");
```

### Input Validation
- Amount validation (positive numbers)
- Account existence validation
- Balance sufficiency checks
- User permission validation

### Transaction Integrity
- Atomic operations with rollback support
- Balance consistency validation
- Duplicate prevention mechanisms

---

## 🐛 Common Issues & Troubleshooting

### 1. **Balance Inconsistencies**
**Issue**: Cash register and bank balances don't match transaction history  
**Cause**: Interrupted transactions or rollback failures

**Debug**:
```sql
-- Check balance vs. transaction sum
SELECT s.savename, s.savecurrentvalue,
       SUM(CASE WHEN sd.savedailychangetype = 0 THEN sd.savedailychangeamount ELSE -sd.savedailychangeamount END) as calculated
FROM save s
LEFT JOIN savedaily sd ON sd.saveid = s.saveid
GROUP BY s.saveid;
```

### 2. **Accounting Entry Mismatches**
**Issue**: Daily entries don't balance  
**Cause**: Incorrect debit/credit assignment

**Fix**: Verify account tree IDs and transfer direction logic

### 3. **Transfer Reversal Failures**
**Issue**: Cannot reverse completed transfers  
**Cause**: Missing daily entry ID or permissions

**Solution**: Verify dailyentryid is populated and user has reversal permissions

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [saveController.md](saveController.md) - Cash register management
- [bankaccountController.md](bankaccountController.md) - Bank account operations
- [dailyentry.md](dailyentry.md) - Accounting integration

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur