# Dollar Earnings Controller Documentation

**File**: `/controllers/dollarEarningsController.php`  
**Purpose**: Manages currency exchange transactions with multi-currency support, conversion tracking, and supplier integration  
**Last Updated**: December 20, 2024  
**Total Functions**: 12  
**Lines of Code**: ~779

---

## 📋 Overview

The Dollar Earnings Controller handles complex multi-currency financial transactions involving currency exchange between different safes/cash registers. It supports currency conversion with dynamic exchange rates, supplier integration for exchange commissions, daily entry accounting, and comprehensive audit trails.

### Primary Functions
- [x] Multi-currency money transfers between safes
- [x] Dynamic currency conversion with live rates
- [x] Supplier commission/expense tracking on exchanges
- [x] Automated daily entry accounting integration
- [x] Exchange transaction history and reporting
- [x] Currency factor management and updates
- [x] Safe balance validation before transactions
- [x] Comprehensive audit trail and reversal support

### Related Controllers
- [cashTransferController.php](#) - Simple cash transfers
- [saveController.php](#) - Safe/cash register management
- [supplierPayedDeptController.php](#) - Supplier payments
- [expensesController.php](#) - Expense management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **dollarearnings** | Exchange transaction records | id, saveidfrom, saveidto, transfermoneyvalueincurrencyfrom, transfermoneyvalueincurrencyto, exvalue, supplierid |
| **save** | Cash registers/safes | saveid, savename, savecurrentvalue, currencyId, treeId |
| **savedaily** | Safe transaction history | savedailyid, saveid, savedailychangeamount, savedailychangetype |

### Currency Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **currency** | Currency definitions | currencyId, currencyName, conversionFactor |
| **supplier** | Exchange suppliers/agents | supplierid, suppliername, suppliercurrentDebt, treeId |
| **supplierdebtchange** | Supplier debt tracking | supplierdebtchangeid, supplierid, supplierdebtchangeamount |

### Accounting Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **dailyentry** | Journal entries | dailyentryid, entryComment, reverseofid |
| **dailyentrycreditor** | Credit entries | dailyentrycreditorid, dailyentryid, accountstreeid, value |
| **dailyentrydebtor** | Debit entries | dailyentrydebttorid, dailyentryid, accountstreeid, value |
| **accountstree** | Chart of accounts | accountstreeid, accountstreeArabicname |

### Reference Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **programsettings** | System configuration | programsettingsid, dollarExType |
| **expensestype** | Expense categories | expensestypeid, expensestypename, treeId |

---

## 🔑 Key Functions

### 1. **Default Action** - Add Exchange Form
**Location**: Line 54  
**Purpose**: Display currency exchange form with safe and currency options

**Function Signature**:
```php
// Triggered when: empty($do)
```

**Process Flow**:
1. Check user permissions and save access rights
2. Load available safes based on user permissions
3. Load currency options
4. Load supplier list for exchange commissions
5. Display exchange form

**Permission Logic**:
```php
if ($_SESSION['searchinonesave'] == 0) {
    // User can access multiple safes
    if ($_SESSION['saveids'] == 0) {
        $saves = $mySaveEx->queryAllEX2(); // All safes
    } else {
        $queryString = ' and saveid in (' . $_SESSION['saveids'] . ')';
        $saves = $mySaveEx->queryAllEX2($queryString); // Permitted safes
    }
} else {
    // User restricted to specific safe
    $queryString = ' and saveid = ' . $_SESSION['saveid'] . ' ';
    $save = $mySaveEx->queryAllEXOne2($queryString);
}
```

---

### 2. **add** - Process Currency Exchange
**Location**: Line 282  
**Purpose**: Execute complex multi-currency exchange transaction

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

**Process Flow**:
1. Validate input parameters and conversion factors
2. Check source safe has sufficient balance
3. Update currency conversion factors
4. Process money transfer between safes
5. Create supplier expense if applicable
6. Generate daily entry accounting records
7. Return validation status and transaction ID

**Currency Conversion Logic**:
```php
$transfermoneyValueCurr = (float) $_POST['transfermoneyvalueCurr'];
$transfermoneyvalueInCurrencyto = (float) $_POST['transfermoneyvalueCurrSaveTo'];
$cFactorTo = (isset($_POST['cFactorTo']) && !empty($_POST['cFactorTo'])) ? (float) $_POST['cFactorTo'] : 1;
$cFactorFrom = (isset($_POST['cFactorFrom']) && !empty($_POST['cFactorFrom'])) ? (float) $_POST['cFactorFrom'] : 1;

// Update conversion factor if needed
if ($currencyIdSaveTo > 1) {
    $currencyEX->updateConversionFactor($cFactorTo, $currencyIdSaveTo);
}
```

**Balance Validation**:
```php
$saveFromValueBefore = $saveData[0];
$saveFromValueafterValid = $saveFromValueBefore - $transfermoneyValueInSaveCurr;
if ($saveFromValueafterValid >= 0) {
    $saveValuebeforeValid = 1; // Transaction allowed
} else {
    $saveValuebeforeValid = 0; // Insufficient funds
}
```

---

### 3. **show** - Display Exchange History
**Location**: Line 92  
**Purpose**: Show filtered exchange transaction history

**Function Signature**:
```php
$startDate = $_REQUEST['from'];
$endDate = $_REQUEST['to'];  
$id = (int) $_REQUEST['id'];
```

**Process Flow**:
1. Parse date range and ID filters
2. Apply user save permissions to query
3. Execute complex JOIN query for transaction details
4. Display results with safe names and supplier info

**Complex Query Structure**:
```sql
SELECT dollarearnings.*, savefrom.savename as savefromname, saveto.savename as savetoname, supplier.suppliername
FROM dollarearnings 
JOIN save savefrom ON dollarearnings.saveidfrom = savefrom.saveid 
JOIN save saveto ON dollarearnings.saveidto = saveto.saveid
LEFT JOIN supplier ON dollarearnings.supplierid = supplier.supplierid
WHERE savefrom.conditions = 0 and saveto.conditions = 0   
AND permission_filters
ORDER BY id desc
```

---

### 4. **delete** - Reverse Exchange Transaction
**Location**: Line 656  
**Purpose**: Reverse a currency exchange transaction

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

**Process Flow**:
1. Load original transaction data
2. Reverse the transaction by swapping from/to safes
3. Update safe balances in reverse
4. Reverse supplier debt changes
5. Reverse daily entry accounting records
6. Mark transaction as deleted (conditions = 2)

**Reversal Logic**:
```php
$saveidFrom = $rowDataold->saveidto;    // Swap source
$saveidTo = $rowDataold->saveidfrom;    // Swap destination  
$transfermoneyValueCurr = $rowDataold->transfermoneyvalueincurrencyto;
$transfermoneyvalueInCurrencyto = $rowDataold->transfermoneyvalueincurrencyfrom;
```

---

### 5. **getSaveValueAndMins/Plus** - Safe Balance Operations
**Location**: Lines 517-556  
**Purpose**: Safely update safe balances with currency conversion

**Function Signatures**:
```php
function getSaveValueAndPlus($saveid, $savevaluechanged, $saveConversionFactor = 0)
function getSaveValueAndMins($saveid, $savevaluechanged, $saveConversionFactor = 0)
```

**Process Flow**:
1. Load current save balance with row locking
2. Apply currency conversion if needed
3. Calculate new balance (plus/minus)
4. Return transaction data array

**Currency Conversion**:
```php
if ($saveConversionFactor == 0) {
    $saveConversionFactor = $saveData->conversionFactor;
}
$savevaluechanged = round(($savevaluechanged * $saveConversionFactor), 4);
```

---

### 6. **affectSupplierWithExpense** - Supplier Integration
**Location**: Line 597  
**Purpose**: Update supplier debt for exchange commissions

**Function Signature**:
```php
function affectSupplierWithExpense($supplier, $expensevalue, $suppRemainingVal, $dollarEarningId, $expensecomment, $operation)
```

**Process Flow**:
1. Validate expense parameters
2. Update supplier debt balance
3. Create supplier debt change record
4. Handle both add and delete operations

**Debt Calculation**:
```php
if ($operation == 'add') {
    $changeType = 0;
    $processName = 'اضافه حصيلة دولارية على مورد' . $expensecomment;
    $deptAfter = $deptBefore + $suppRemainingVal;
} elseif ($operation == 'del') {
    $changeType = 1;
    $processName = 'حذف حصيلة دولارية على مورد';
    $deptAfter = $deptBefore - $suppRemainingVal;
}
```

---

## 🔄 Workflows

### Workflow 1: Currency Exchange Transaction
```
┌─────────────────────────────────────────────────────────────┐
│              START: User Initiates Exchange                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Select Source and Destination                           │
│     - Choose source safe (with currency)                    │
│     - Choose destination safe (with currency)               │
│     - Enter amount in source currency                       │
│     - Enter conversion rate                                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Optional: Add Supplier Commission                       │
│     - Select exchange supplier/agent                        │
│     - Enter commission amount                               │
│     - Add commission comment                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Validate Transaction                                    │
│     - Check source safe has sufficient balance              │
│     - Validate currency conversion factors                  │
│     - Verify all required fields                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Execute Money Transfer                                  │
│     - Decrease source safe balance                          │
│     - Increase destination safe balance                     │
│     - Apply currency conversions                           │
│     - Create safe transaction records                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Process Supplier Commission (if applicable)             │
│     - Increase supplier debt                                │
│     - Create supplier debt change record                    │
│     - Generate expense accounting entry                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Generate Accounting Entries                             │
│     - Create daily entry for money transfer                 │
│     - Debit destination safe account                        │
│     - Credit source safe account                           │
│     - Create expense entry for commission                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  7. Complete Transaction                                    │
│     - Commit all database changes                          │
│     - Generate transaction confirmation                     │
│     - Update currency factors if needed                     │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Show exchange form |
| `do=add` | `add()` | Process exchange transaction |
| `do=show` | Show history | Display exchange history |
| `do=edit` | Edit form | Edit existing transaction |
| `do=update` | Update | Update existing transaction |
| `do=delete` | `delete()` | Reverse transaction |
| `do=editprint` | Print view | Print transaction details |

### Required Parameters by Action

**Add Exchange** (`do=add`):
- `saveidfrom` - Source safe ID
- `saveidto` - Destination safe ID  
- `transfermoneyvalueCurr` - Amount in source currency
- `transfermoneyvalueCurrSaveTo` - Amount in destination currency
- `cFactorFrom` - Source currency conversion factor
- `cFactorTo` - Destination currency conversion factor
- `supplierid` (optional) - Supplier for commission
- `exvalue` (optional) - Commission amount
- `comment` - Transaction comment

**Show History** (`do=show`):
- `from` - Start date
- `to` - End date  
- `id` (optional) - Specific transaction ID

---

## 🧮 Calculation Methods

### Currency Conversion
```php
// Convert to main currency
$transfermoneyValueInMainCurrency = $transfermoneyValueCurr;
if ($cFactorFrom != 1) {
    $transfermoneyValueInMainCurrency = $transfermoneyValueCurr / $cFactorFrom;
}

// Convert from main currency to destination
$transfermoneyvalueInDestCurrency = $transfermoneyValueInMainCurrency;
if ($cFactorTo != 1) {
    $transfermoneyvalueInDestCurrency = $transfermoneyValueInMainCurrency * $cFactorTo;
}
```

### Safe Balance Updates
```php
// Source safe (decrease)
$saveFromValueafter = $saveFromValuebefore - $transfermoneyValueCurr;

// Destination safe (increase)
$saveToValueafter = $saveToValuebefore + $transfermoneyvalueInCurrencyto;
```

### Supplier Debt Updates
```php
$deptAfter = $deptBefore + $suppRemainingVal; // Add commission debt
```

---

## 🔒 Security & Permissions

### User Save Access Control
```php
if ($_SESSION['searchinonesave'] == 0) {
    // Multiple save access
    if ($_SESSION['saveids'] != 0) {
        $queryString .= ' and ( dollarearnings.saveidfrom in (' . $_SESSION['saveids'] . ') 
                          or dollarearnings.saveidto in (' . $_SESSION['saveids'] . ') ) ';
    }
} else {
    // Single save access
    $queryString .= ' and ( dollarearnings.saveidfrom = ' . $_SESSION['saveid'] . ' 
                      or dollarearnings.saveidto = ' . $_SESSION['saveid'] . ' ) ';
}
```

### Input Validation
```php
$saveidFrom = $_POST['saveidfrom'];
$saveidTo = $_POST['saveidto'];
$exvalue = $_POST['exvalue'];
$cFactorTo = (isset($_POST['cFactorTo']) && !empty($_POST['cFactorTo'])) ? (float) $_POST['cFactorTo'] : 1;
```

### Transaction Safety
- Database transactions with rollback capability
- Balance validation before execution
- Row locking during balance updates

---

## 🐛 Common Issues & Troubleshooting

### 1. **Currency Conversion Errors**
**Issue**: Incorrect exchange amounts calculated  
**Cause**: Wrong conversion factors or missing currency data

**Debug**:
```sql
SELECT currencyId, conversionFactor FROM currency;
SELECT saveid, currencyId, savecurrentvalue FROM save WHERE saveid IN (?,?);
```

### 2. **Insufficient Balance Errors**
**Issue**: Transaction rejected due to insufficient funds  
**Cause**: Currency conversion not applied properly in balance check

**Debug**:
```php
echo "Source Balance: " . $saveFromValueBefore . "<br>";
echo "Amount to Transfer: " . $transfermoneyValueCurr . "<br>";  
echo "After Balance: " . ($saveFromValueBefore - $transfermoneyValueCurr) . "<br>";
```

### 3. **Accounting Entry Mismatches**
**Issue**: Daily entries don't balance  
**Cause**: Currency conversion in accounting entries

**Debug**:
```sql
SELECT de.entryComment, ded.value as debit, dec.value as credit
FROM dailyentry de
LEFT JOIN dailyentrydebtor ded ON de.dailyentryid = ded.dailyentryid  
LEFT JOIN dailyentrycreditor dec ON de.dailyentryid = dec.dailyentryid
WHERE de.dailyentryid = ?;
```

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Indexes Required**:
   - `dollarearnings(sysdate, saveidfrom, saveidto)`
   - `save(saveid, currencyId, conditions)`
   - `savedaily(saveid, savedailydate)`
   - `supplier(supplierid, conditions)`

2. **Query Optimization**:
   - Use proper JOIN types for optional suppliers
   - Index on sysdate for date range queries
   - Efficient permission filtering

3. **Transaction Management**:
   - Minimize transaction scope
   - Use row locking only when necessary
   - Proper rollback handling

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide  
- [saveController.php](#) - Safe/cash register management
- [currencyController.php](#) - Currency management
- [supplierController.php](#) - Supplier management
- [dailyentry.php](#) - Accounting entries

---

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