Expense Exchange Controller Documentation
File: /controllers/expenseexchange.php
Purpose: Manages project-related expense transactions with supplier payments, supervision costs, and financial accounting
Last Updated: December 20, 2024
Total Functions: 8+
Lines of Code: ~943
---
๐ Overview
The Expense Exchange Controller is a specialized financial management module that handles project-based expenses with complex supplier interactions and supervision cost tracking. It provides:
- โข Project expense recording with supplier payment integration
- โข Supervision cost allocation and tracking
- โข Multi-source payment handling (save accounts, bank accounts, suppliers)
- โข Automatic accounting entry generation
- โข Image attachment support for expense documentation
- โข Real-time client debt adjustment for project expenses
- โข Cost center allocation for project tracking
Primary Functions
- โ Record project expenses with supplier allocation
- โ Handle supervision cost calculations
- โ Process multi-source payments (cash/bank/supplier)
- โ Generate automatic accounting entries
- โ Update client debt for project costs
- โ Support image documentation
- โ Serial number generation for tracking
- โ Integration with expense and payment systems
Related Controllers
- โข expensesController.php - General expense management
- โข expensesTypeController.php - Expense categorization
- โข supplierPayedDeptController.php - Supplier payment processing
- โข dailyentryajax.php - Accounting entry management
- โข clientController.php - Client management
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **expenseexchange** | Project expense transactions | id, serialno, projectid, expensefrom, expenseid, thevalue, expensetype, supplierid, supervision_amount, finalsupervision | |
| **project** | Project master data | projectid, name, clientid | |
| **expensestype** | Expense category definitions | expensestypeid, expensestypename, treeId |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **save** | Cash registers/safes | saveid, savename, treeId | |
| **bankaccount** | Bank account details | bankaccountid, accountname, bankid, treeId | |
| **bank** | Bank master data | bankid, bankname |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **supplier** | Supplier information | supplierid, suppliername, suppliercurrentDebt | |
| **supplierdebtchange** | Supplier debt transactions | supplierdebtchangeid, supplierid, payedDept, comment | |
| **client** | Client master data | clientid, clientname, clientdebt, treeId | |
| **costcenter** | Cost center allocation | id, name, description |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **accountstree** | Chart of accounts | id, name, parent, customName | |
| **dailyentry** | Journal entries | id, entryComment, thedate | |
| **dailyentrydebtor** | Debit entries | id, dailyentryid, accountstreeid, value | |
| **dailyentrycreditor** | Credit entries | id, dailyentryid, accountstreeid, value |
๐ Key Functions
1. Default Action - Add Form Display
Location: Line 184
Purpose: Display expense exchange form with initialization data
Process Flow:
1. Load supplier dropdown data
2. Configure save accounts based on user permissions
3. Load bank accounts with filtering
4. Generate unique serial number
5. Display form template with validation settings
Template Variables:
- โข
$serialno- Generated expense serial number - โข
$supplierData- Supplier dropdown options - โข
$saves- Available save accounts - โข
$banks- Available bank accounts - โข
$projectValidation- Form validation flag
---
2. add() - Create Expense Transaction
Location: Line 485
Purpose: Process new expense exchange with complex payment and accounting logic
Function Signature:
function add($id = null)
Process Flow:
1. Input Processing:
- Parse form data (amounts, dates, comments)
- Handle image uploads with existing image preservation
- Determine payment source (save/bank/supplier)
2. Payment Source Handling:
if ($expensefrom == 0) {
// Save account payment
$expenseid = $_POST['saveid'];
$EFrom = $saveDAO->load($expenseid);
} elseif ($expensefrom == 1) {
// Bank account payment
$expenseid2 = $_POST['bankaccountid'];
$EFrom = $bankAccountDAO->load($expenseid2);
} elseif ($expensefrom == 2) {
// Supplier payment
$expenseid = $supplierid;
}
```
3. **Cost Center Assignment**:
```php
$projectData = $ProjectDAO->load($projectid);
$costCenter = $CostcenterDAO->queryByName($projectData->name);
```
4. **Database Insert**:
- Insert main expense exchange record
- Support custom ID for updates
5. **Supplier Payment Processing** (if applicable):
```php
if (isset($supplierid) && $supplierid > 1) {
$data_arr = array(
'supplierid' => $supplierdata->supplierid,
'payedDept' => $thevalue,
'comment' => $supplierdata->suppliername . 'ุตุฑู ู
ุตุฑูู' . $ET->expensestypename
);
CURL_Request($data_arr, 'supplierPayedDeptController.php?do=add', 0, 1, '', 'POST');
}
```
6. **Expense Registration**:
```php
$data_arr = array(
'supplier' => $supplierid,
'expensevalue' => $thevalue,
'expensecomment' => $expenseexcomment . ' / ' . $projectName
);
CURL_Request($data_arr, 'expensesController.php?do=add', 0, 1, '', 'POST');
```
7. **Client Debt Adjustment**:
```php
$data_arr = array(
'E_parent1' => $clientData->treeId,
'valueFrom1' => $thevalue + $finalsupervision,
'E_parent2' => 159,
'valueTo2' => $thevalue,
'E_parent3' => 431,
'valueTo3' => $finalsupervision
);
CURL_Request($data_arr, 'dailyentryajax.php?do=add', 0, 1, '', 'POST');
```
---
### 3. **show()** - Display Expense Reports
**Location**: Line 258
**Purpose**: Generate filtered expense exchange reports
**Process Flow**:
1. **Filter Processing**:
```php
$projectid = filter_input(INPUT_POST, "projectname");
$saveid = filter_input(INPUT_POST, "saveid");
$expensetype = filter_input(INPUT_POST, "expensetype");
$datefrom = filter_input(INPUT_POST, "datefrom");
$dateto = filter_input(INPUT_POST, "dateto");
```
2. **Query Building**:
- Apply project filtering with permission checks
- Date range filtering
- Expense type filtering
- Serial number search
3. **Total Calculation**:
```php
$total = 0;
foreach ($alldata as $value) {
$total += $value->thevalue;
}
```
**Permission Logic**:
php
if ($_SESSION['projectids'] != 0) {
$queryString .= ' AND expenseexchange.projectid in (' . $_SESSION['projectids'] . ')';
}
---
### 4. **edit()** - Load Expense for Editing
**Location**: Line 357
**Purpose**: Load expense exchange data for modification
**Process Flow**:
1. Load expense exchange record
2. Parse attached images
3. Load related project data
4. Configure form with existing data
5. Populate dropdowns with current selections
**Image Handling**:
php
$editelement->allimages = explode(',', $editelement->images);
---
### 5. **update()** - Modify Expense Transaction
**Location**: Line 789
**Purpose**: Update existing expense exchange using delete/recreate pattern
**Implementation**:
php
function update() {
$editid = filter_input(INPUT_POST, 'editid', FILTER_DEFAULT);
delete($editid);
add($editid);
}
**Note**: Uses delete-then-recreate pattern to ensure accounting consistency
---
### 6. **delete()** - Remove Expense Transaction
**Location**: Line 795
**Purpose**: Delete expense exchange and reverse accounting entries
**Process Flow**:
1. Load expense exchange data
2. Reconstruct account tree IDs
3. Reverse journal entries
4. Delete expense exchange record
**Accounting Reversal**:
php
$entryid = entryinsert_data_reverse($oldEntryID, 12);
---
### 7. **getserails()** - Generate Serial Numbers
**Location**: Line 858
**Purpose**: Create unique serial numbers for expense tracking
**Implementation**:
php
function generateRandomString($length = 4) {
$newnum = substr(str_shuffle("0123456789"), 0, $length);
return date("Y") . '' . $newnum;
}
**Duplicate Prevention**:
php
$checkifthere = $expenseExchangeEX->queryAllbyserialno($number);
if (count($checkifthere) > 0) {
$number = generateRandomString();
}
---
## ๐ Workflows
### Workflow 1: Complete Expense Transaction Processing
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Expense Transaction โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Form Input Validation โ
โ - Project selection โ
โ - Expense amount and type โ
โ - Payment source (save/bank/supplier) โ
โ - Supervision costs โ
โ - Supporting images โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Generate Serial Number โ
โ - Create unique tracking number โ
โ - Verify no duplicates exist โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Process Payment Source โ
โ IF Save Account (expensefrom = 0): โ
โ โโ Load save account details โ
โ โโ Get/create tree ID for accounting โ
โ ELIF Bank Account (expensefrom = 1): โ
โ โโ Load bank account details โ
โ โโ Create combined tree element โ
โ ELIF Supplier Payment (expensefrom = 2): โ
โ โโ Set supplier as payment source โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Cost Center Assignment โ
โ - Load project details โ
โ - Find/create matching cost center โ
โ - Link expense to project cost structure โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. Insert Expense Exchange Record โ
โ - Save main transaction data โ
โ - Store expense details and images โ
โ - Record payment source information โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 6. Process Supplier Payment (if applicable) โ
โ IF Supplier Payment: โ
โ โโ Update supplier debt โ
โ โโ Create supplier payment record โ
โ โโ Generate payment voucher โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 7. Register General Expense โ
โ - Create expense record in main system โ
โ - Link to expense type and cost center โ
โ - Include supervision costs โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 8. Generate Accounting Entry โ
โ DEBIT: Client Account (project cost) โ
โ CREDIT: Expense Account (actual expense) โ
โ CREDIT: Supervision Account (if applicable) โ
โ - Amount: expense + supervision โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 9. Update Client Debt โ
โ - Increase client debt by total amount โ
โ - Record debt change transaction โ
โ - Link to expense exchange record โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
### Workflow 2: Expense Update Process
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Update Expense โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Delete Existing Record โ
โ - Reverse all accounting entries โ
โ - Remove expense exchange record โ
โ - Clear supplier payment links โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Recreate with New Data โ
โ - Process updated form data โ
โ - Maintain original ID if provided โ
โ - Follow complete add workflow โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
## ๐ URL Routes & Actions
| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display expense exchange form |
| `do=add` | `add()` | Process new expense transaction |
| `do=show` | Default with filtering | Display expense reports with filters |
| `do=shownew` | Project-specific view | Show expenses for specific project |
| `do=edit` | `edit()` | Load expense for editing |
| `do=update` | `update()` | Update existing expense |
| `do=delete` | `delete()` | Delete expense transaction |
### Required Parameters by Action
**Add Expense** (`do=add`):
- `projectname` - Project ID
- `expensefrom` - Payment source (0=save, 1=bank, 2=supplier)
- `thevalue` - Expense amount
- `expensetype` - Expense category ID
- `supplierid` - Supplier ID (optional)
- `supervision_amount` - Supervision cost (optional)
**Show Reports** (`do=show`):
- `projectname` - Project filter (optional)
- `saveid` - Save account filter (optional)
- `expensetype` - Expense type filter (optional)
- `datefrom` - Start date (optional)
- `dateto` - End date (optional)
**Edit/Delete** (`do=edit`, `do=delete`):
- `id` - Expense exchange ID
---
## ๐งฎ Calculation Methods
### Supervision Cost Processing
php
$supervision_type = filter_input(INPUT_POST, 'supervision_type', FILTER_DEFAULT);
$supervision_amount = filter_input(INPUT_POST, 'supervision_amount', FILTER_DEFAULT);
$finalsupervision = filter_input(INPUT_POST, 'finalsupervision', FILTER_DEFAULT);
// Total project cost includes supervision
$totalProjectCost = $thevalue + $finalsupervision;
### Client Debt Adjustment
php
// Accounting entry for project expense
'E_parent1' => $clientData->treeId, // Client account (debit)
'valueFrom1' => $thevalue + $finalsupervision, // Total amount
'E_parent2' => 159, // Expense account (credit)
'valueTo2' => $thevalue, // Actual expense
'E_parent3' => 431, // Supervision account (credit)
'valueTo3' => $finalsupervision, // Supervision amount
### Serial Number Generation
php
function generateRandomString($length = 4) {
$newnum = substr(str_shuffle("0123456789"), 0, $length);
return date("Y") . '' . $newnum; // Format: 2024XXXX
}
---
## ๐ Security & Permissions
### User Permission Checks
php
include_once("../public/authentication.php");
### Save Account Filtering
php
if ($_SESSION['saveids'] == 0) {
$saves = $saveDAO->queryAll();
} else {
$queryString = ' and saveid in (' . $_SESSION['saveids'] . ')';
$saves = $SaveExt->queryWithConditionWithQueryString($queryString);
}
### Project Access Control
php
if ($_SESSION['projectids'] != 0) {
$queryString .= ' AND expenseexchange.projectid in (' . $_SESSION['projectids'] . ')';
}
### Input Sanitization
- All POST data filtered through `filter_input()`
- SQL injection prevention via DAO parameterized queries
- File upload validation for image attachments
- Amount validation for financial calculations
---
## ๐ Performance Considerations
### Database Optimization Tips
1. **Indexes Required**:
- `expenseexchange(projectid, expensedate)`
- `expenseexchange(serialno)` - Unique
- `expenseexchange(supplierid, sysdate)`
2. **Query Optimization**:
- Use of JOIN queries in extended DAO classes
- Efficient filtering with permission-based WHERE clauses
- Proper date range indexing
3. **Memory Management**:
- Image processing with existing file preservation
- Efficient CURL request handling for integration
- Transaction rollback on errors
---
## ๐ Common Issues & Troubleshooting
### 1. **Missing Serial Number Generation**
**Issue**: Duplicate or missing serial numbers
**Cause**: Concurrent transactions or failed generation
**Debug**:
sql
SELECT serialno, COUNT(*) FROM expenseexchange
GROUP BY serialno HAVING COUNT(*) > 1;
### 2. **Accounting Entry Failures**
**Issue**: Incomplete journal entries
**Cause**: Missing tree IDs or invalid account structure
**Debug**:
php
// Check tree ID existence
$treeExists = $accountsTreeDAO->load($treeId);
if (empty($treeExists)) {
echo "Missing tree element: " . $treeId;
}
### 3. **Supplier Payment Integration Errors**
**Issue**: Failed CURL requests to supplier payment system
**Cause**: Network issues or invalid supplier data
**Debug**:
php
// Enable CURL debugging
$rs = CURL_Request($data_arr, 'supplierPayedDeptController.php?do=add', 0, 1, '', 'POST');
error_log("Supplier payment response: " . print_r($rs, true));
### 4. **Image Upload Problems**
**Issue**: Failed file uploads or storage issues
**Cause**: Permission problems or disk space
**Fix**:
bash
Check upload directory permissions
chmod 755 /Applications/AMPPS/www/erp19/upload/expenseexchange
chown www-data:www-data /Applications/AMPPS/www/erp19/upload/expenseexchange
---
## ๐งช Testing Scenarios
### Test Case 1: Basic Expense Transaction
1. Create expense with save account payment
2. Verify serial number generation
3. Check accounting entry creation
4. Confirm client debt adjustment
5. Validate expense registration
### Test Case 2: Supplier Payment Integration
1. Create expense with supplier payment
2. Verify supplier debt reduction
3. Check payment voucher creation
4. Confirm expense type linkage
5. Test supervision cost allocation
### Test Case 3: Bank Account Payment
1. Select bank account as payment source
2. Verify bank account tree ID creation
3. Check accounting entry accuracy
4. Test cost center assignment
5. Validate project linkage
### Debug Mode Enable
php
// Add at top of controller for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Debug CURL requests
function debug_curl($data_arr, $url) {
echo "CURL Request to: " . $url . "
";
echo "Data: " . print_r($data_arr, true) . "
";
}
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข expensesController.md - General expense management
- โข projectController.md - Project management
- โข supplierController.md - Supplier management
- โข accountstree.md - Chart of accounts
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur