# Asset Controller Documentation

**File**: `/controllers/assetController.php`  
**Purpose**: Comprehensive asset management with accounting integration and multiple payment methods  
**Last Updated**: December 20, 2024  
**Total Functions**: 25+ (CRUD operations, accounting, payments)  
**Lines of Code**: ~1,733

---

## 📋 Overview

The Asset Controller is a comprehensive fixed asset management system that handles the complete lifecycle of assets with full accounting integration. It manages:
- Asset creation with new/old asset distinction
- Multiple payment methods (cash, check, supplier credit)
- Depreciation tracking and accounting entries
- Asset sales and disposal
- Integration with accounting tree and daily entries
- Supplier relationship management
- Bank account and check processing
- Asset categorization and reporting

### Primary Functions
- [x] Asset registration (new and old assets)
- [x] Multiple payment method support (cash, check, supplier)
- [x] Automatic accounting entries generation
- [x] Depreciation calculation and tracking
- [x] Asset sales processing
- [x] Asset modification and deletion
- [x] Integration with accounting tree structure
- [x] Supplier debt management
- [x] Bank account transaction processing
- [x] Asset categorization and filtering

### Related Controllers
- [assetTypeController.php](assetTypeController.md) - Asset category management
- [supplierController.php](#) - Supplier management
- [bankController.php](#) - Banking operations
- [dailyentryController.php](#) - Accounting entries

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **assets** | Fixed assets master data | assetId, assetsName, assetsValue, type, conditions, depreciation, treeId, dailyentryid, paytype, supplierid |
| **assetssale** | Asset sales transactions | assetssaleid, assetsid, assetssaleclient, assetssaleval, assetssaledate |
| **assetscat** | Asset categories | assetscatid, cattitel, treeId |

### Financial Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **save** | Cash registers/safes | saveid, savecurrentvalue, treeId |
| **savedaily** | Cash transaction log | savedailyid, saveid, savedailychangeamount, savedailychangetype, processname |
| **checkwithdrawal** | Check payments | checkwithdrawalid, bankaccountid, checkwithdrawalamount, checkwithdrawalnumber |
| **bankaccount** | Bank accounts | accountid, bankid, accountbeginingbalance, treeId |
| **accountmovement** | Bank transaction log | accountmovementid, accountid, accountmovementamount, accountmovementtype |

### Accounting Integration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **dailyentry** | Journal entries | dailyentryid, entryComment, reverseofid |
| **dailyentrycreditor** | Credit side entries | dailyentrycreditorid, dailyentryid, accountstreeid, value |
| **dailyentrydebtor** | Debit side entries | dailyentrydebtorigid, dailyentryid, accountstreeid, value |
| **accountstree** | Chart of accounts | id, name, customName, parent, theValue |

### Supplier Integration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **supplier** | Supplier master data | supplierid, suppliername, suppliercurrentDebt, treeId |
| **supplierdebtchange** | Supplier debt tracking | supplierdebtchangeid, supplierid, supplierdebtchangeamount, supplierdebtchangetype |

### Reference Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **client** | Customer data | clientid, clientname |
| **checkcontroller** | Check control records | checkid, controllerid, type |
| **youtubelink** | Tutorial videos | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **Default Action** - Asset Entry Form
**Location**: Lines 224-254  
**Purpose**: Display asset entry form with type selection (new vs old asset)

**Function Signature**:
```php
// Triggered when: empty($do)
$type = $_GET["type"]; // 0 = old asset, 1 = new asset
```

**Process Flow**:
1. Load bank accounts and save data
2. Load suppliers for payment options
3. Load asset categories
4. Determine asset type and display appropriate form

**Template Selection**:
```php
if ($type != 0) {
    $smarty->display("assetsview/add.html");    // New asset form
} else {
    $smarty->display("assetsview/addold.html"); // Old asset form
}
```

---

### 2. **add()** - Asset Creation with Accounting Integration
**Location**: Lines 472-841  
**Purpose**: Create new asset with full accounting integration and payment processing

**Function Signature**:
```php
function add()
// Uses $_POST data for asset information and payment details
```

**Key Parameters**:
- `$assetName` - Asset name/description
- `$assetPrice` - Asset cost/value
- `$type` - Asset type (0=old, 1=new)
- `$paytype` - Payment method (0=cash, 1=check, 2=supplier)
- `$depreciation` - Depreciation amount for old assets
- `$supplierid` - Supplier ID if paid via supplier credit

**Process Flow**:
1. **Basic Asset Creation**:
   ```php
   $myAssets->assetsName = $assetName;
   $myAssets->assetsValue = $assetPrice;
   $myAssets->type = $type;
   $myAssets->paytype = $paytype;
   $modelid = $myAssetsRecord->insert($myAssets, $assetDescription);
   ```

2. **Payment Processing** (for new assets):
   - **Cash Payment** (`paytype = 0`):
     ```php
     getSaveValueAndMins($assetPrice, $saveid);
     updateSave($saveid, ($savebefor - $assetPrice));
     insertSavedaily(...);
     ```
   
   - **Check Payment** (`paytype = 1`):
     ```php
     addbanck($modelid); // Create check withdrawal record
     ```
   
   - **Supplier Credit** (`paytype = 2`):
     ```php
     // Update supplier debt
     $supplierDeptChange->supplierdebtchangeamount = $assetPrice;
     $supplierDeptChange->supplierdebtchangetype = 0; // Increase debt
     ```

3. **Accounting Entries Creation**:
   - **New Asset Entries**:
     ```php
     // Debit: Asset Account
     $dailyEntryDebtor->value = $assetPrice;
     $dailyEntryDebtor->accountstreeid = $aslId; // Asset tree ID
     
     // Credit: Cash/Bank/Supplier Account
     $dailyEntryCreditor->value = $assetPrice;
     $dailyEntryCreditor->accountstreeid = $paymentAccountId;
     ```

   - **Old Asset Entries** (dual entries):
     ```php
     // Entry 1: Asset recognition
     // Debit: Asset, Credit: Capital
     
     // Entry 2: Depreciation
     // Debit: Capital, Credit: Accumulated Depreciation
     ```

---

### 3. **show()** - Asset Listing and Management
**Location**: Lines 264-291  
**Purpose**: Display asset listing with search and pagination

**Process Flow**:
1. Load YouTube tutorials and reference data
2. Handle asset filtering by ID if specified
3. Call appropriate display function
4. Implement pagination for large datasets

**Asset Filtering**:
```php
$assetId = $_REQUEST['assetId'];
if (isset($assetId) && $assetId != "-1") {
    showByassetName(); // Filtered view
} else {
    showAll();        // All assets view
}
```

---

### 4. **delete()** - Asset Deletion with Reversal Logic
**Location**: Lines 1039-1215  
**Purpose**: Delete asset with proper accounting reversal and payment method handling

**Function Signature**:
```php
function delete($type, $assetId)
// $type: Asset type, $assetId: Asset to delete
```

**Deletion Process by Payment Type**:

**Cash Payment Reversal**:
```php
if ($assetdata->paytype == 0) {
    // Reverse cash transaction
    $savebefor = getSaveValueBefore($saveId);
    updateSave($saveId, ($savebefor + $assetdata->assetsValue));
    
    // Create reversal entry in savedaily
    insertSavedaily(..., 'الغاء وصل شراء اصل', ...);
    
    // Reverse accounting entry
    reverseEntryWithItsID($dailyEntryId);
}
```

**Check Payment Reversal**:
```php
elseif ($assetdata->paytype == 1) {
    // Update check status and bank account
    updateckeck($assetId);
    reverseEntryWithItsID($dailyEntryId);
}
```

**Supplier Payment Reversal**:
```php
elseif ($assetdata->paytype == 2) {
    // Decrease supplier debt
    $supplierDeptChange->supplierdebtchangeamount = $assetdata->assetsValue;
    $supplierDeptChange->supplierdebtchangetype = 1; // Decrease debt
    
    // Update supplier balance
    $supplier->suppliercurrentDebt = $debtAfter;
    $supplierExt->updatedept($supplier);
}
```

---

### 5. **assetsaleadd()** - Asset Sales Processing
**Location**: Lines 424-469  
**Purpose**: Process asset sales with cash register updates

**Process Flow**:
1. Record sale transaction details
2. Update cash register with sale proceeds
3. Set asset value to zero (mark as sold)
4. Create cash register transaction log

**Key Operations**:
```php
// Record sale
$myAssetssale->assetssaleval = $assetssaleval;
$myAssetssale->assetsid = $assetsid;
$myAssetssaleDAO->insert($myAssetssale);

// Update cash register
R::exec("UPDATE save SET savecurrentvalue = savecurrentvalue + $assetssaleval WHERE saveid = $assetssalesave");

// Mark asset as sold
R::exec("UPDATE assets SET assetsValue = 0 WHERE assetId = $assetsid");
```

---

### 6. **addbanck()** - Check Payment Processing
**Location**: Lines 844-927  
**Purpose**: Process check payments with bank account integration

**Process Flow**:
1. Create check withdrawal record
2. Update bank account balance
3. Create account movement log
4. Link check to asset via checkcontroller

**Bank Account Update**:
```php
$accountBefore = $accoundatat->accountbeginingbalance;
if ($accountBefore >= $checkwithdrawalamount) {
    $account->accountbeginingbalance = $accountBefore - $checkwithdrawalamount;
}
$accountExtDAO->updateacount($account);
```

---

### 7. **Supplier Integration Functions** - Debt Management
**Location**: Lines 1695-1724  
**Purpose**: Handle supplier debt synchronization and locking

**Key Functions**:
- `getSupplierDataFromSupplierInUseSP()` - Get supplier with locking
- `markSupplierAsNOTInUse()` - Release supplier lock

**Supplier Locking Logic**:
```php
while ($supplier_data->suppliercurrentDebt == 'in_use') {
    sleep(1);
    $noOfTries++;
    if ($noOfTries > 15) {
        // Force unlock after 15 seconds
        R::exec('UPDATE supplier SET inUse = 0 where supplierid = ' . $supplier);
    }
    $supplier_data = $supplierExt->callSupplierInUseSP($supplier);
}
```

---

## 🔄 Workflows

### Workflow 1: New Asset Creation with Cash Payment
```
┌─────────────────────────────────────────────────────────────┐
│               START: New Asset Creation                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Asset Data Entry                                        │
│     - Asset name and description                            │
│     - Asset value/cost                                      │
│     - Asset category selection                              │
│     - Payment method selection                              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Asset Record                                     │
│     - Insert into assets table                              │
│     - Generate asset ID                                     │
│     - Set asset metadata                                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Cash Payment                                    │
│     - Check cash register balance                           │
│     - Deduct asset cost from register                       │
│     - Update cash register current value                    │
│     - Create cash register transaction log                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Create Accounting Tree Entry                            │
│     - Add asset to chart of accounts                        │
│     - Link to appropriate parent category                   │
│     - Set asset value in accounting tree                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Generate Journal Entries                                │
│     - Debit: Asset Account (new tree element)              │
│     - Credit: Cash Account (from selected register)        │
│     - Create dailyentry with comment                        │
│     - Link journal entry to asset record                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Update Asset with Generated IDs                         │
│     - Update dailyentryid in asset record                   │
│     - Update treeId in asset record                         │
│     - Complete asset creation process                       │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Asset Purchase via Supplier Credit
```
┌─────────────────────────────────────────────────────────────┐
│            START: Asset Purchase via Supplier              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Supplier Selection and Validation                       │
│     - Select supplier from dropdown                         │
│     - Lock supplier record for transaction                  │
│     - Get current supplier debt balance                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Asset Record                                     │
│     - Insert asset with supplier reference                  │
│     - Set paytype = 2 (supplier payment)                   │
│     - Generate asset ID for linking                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Update Supplier Debt                                    │
│     - Calculate new debt balance                            │
│     - Create supplier debt change record                    │
│     - Update supplier current debt                          │
│     - Release supplier lock                                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Generate Accounting Entries                             │
│     - Debit: Asset Account                                  │
│     - Credit: Supplier Account (from supplier treeId)      │
│     - Create journal entry with asset reference             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Complete Asset Registration                             │
│     - Update asset with accounting references               │
│     - Link to accounting tree structure                     │
│     - Mark transaction as completed                         │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 3: Old Asset Registration with Depreciation
```
┌─────────────────────────────────────────────────────────────┐
│              START: Old Asset Registration                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Asset Information Entry                                 │
│     - Asset name and current value                          │
│     - Original cost and accumulated depreciation            │
│     - Asset category and details                            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Asset Record                                     │
│     - Insert asset with type = 0 (old asset)               │
│     - Set depreciation amount                               │
│     - Mark as existing asset                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. First Journal Entry - Asset Recognition                 │
│     - Debit: Asset Account (current value)                 │
│     - Credit: Capital Account (121)                        │
│     - Create journal entry for asset recognition            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Second Journal Entry - Accumulated Depreciation         │
│     - Debit: Capital Account (121)                         │
│     - Credit: Accumulated Depreciation (8)                 │
│     - Record depreciation amount                            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Update Asset with Journal Entry IDs                     │
│     - Store both journal entry IDs (comma-separated)       │
│     - Link asset to accounting tree                         │
│     - Complete old asset registration                       │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default form | Asset entry form selection |
| `do=add` | `add()` | Create new asset |
| `do=show` | Asset listing | Display assets with pagination |
| `do=delete` | `delete()` | Delete asset with reversals |
| `do=edit` | `edit()` | Edit asset information |
| `do=update` | `update()` | Update asset after edit |
| `do=assetsaleadd` | `assetsaleadd()` | Process asset sale |
| `do=executeOperation` | `execute()` | Batch operations on assets |
| `do=editprint` | Print view | Asset details for printing |

### Required Parameters by Action

**Asset Creation** (`do=add`):
- `assetname` - Asset name/description
- `assetprice` - Asset value/cost
- `type` - Asset type (0=old, 1=new)
- `paytype` - Payment method (0=cash, 1=check, 2=supplier)
- `assetscatid` - Asset category ID
- `saveid` - Cash register ID (for cash payments)
- `supplierid` - Supplier ID (for supplier payments)
- `depreciation` - Depreciation amount (for old assets)

**Asset Sale** (`do=assetsaleadd`):
- `assetsidm` - Asset ID to sell
- `assetssaleval` - Sale value
- `assetssalesave` - Cash register to receive payment
- `assetssaleclient` - Client purchasing the asset

**Check Payment** (via `addbanck()`):
- `accountid` - Bank account ID
- `txtAmount` - Check amount
- `txtcheckNum` - Check number
- `ddlBank` - Bank ID

---

## 🧮 Calculation Methods

### Depreciation Calculation (Old Assets)
```php
// For old assets, two journal entries are created:
// 1. Asset recognition at current value
// 2. Depreciation adjustment

$assetValue = $_POST['assetprice'];     // Current book value
$depreciation = $_POST['depreciation']; // Accumulated depreciation

// Original cost = Current value + Accumulated depreciation
$originalCost = $assetValue + $depreciation;
```

### Cash Register Balance Updates
```php
// Cash payment (asset purchase)
$saveValueAfter = $saveValueBefore - $assetPrice;

// Cash receipt (asset sale)
$saveValueAfter = $saveValueBefore + $assetSaleValue;
```

### Bank Account Balance Updates
```php
// Check payment
$accountAfter = $accountBefore - $checkAmount;

// Check reversal (asset deletion)
$accountAfter = $accountBefore + $checkAmount;
```

### Supplier Debt Calculations
```php
// Asset purchase on credit
$supplierDebtAfter = $supplierDebtBefore + $assetPrice;

// Asset purchase reversal
$supplierDebtAfter = $supplierDebtBefore - $assetPrice;
```

---

## 🔒 Security & Permissions

### Authentication Requirements
```php
include_once("../public/authentication.php");
```

### Session-Based Access Control
- All operations require valid user session
- User ID is recorded in all transactions
- Branch-specific data isolation (implied through session)

### Supplier Locking Mechanism
```php
// Prevent concurrent supplier debt modifications
$supplier_data = $supplierExt->callSupplierInUseSP($supplier);
// Automatic timeout and force unlock after 15 seconds
```

### Input Validation
- Asset prices are cast to numeric values
- Asset types are validated (0 or 1)
- Payment types are restricted to valid options (0, 1, 2)
- Supplier IDs are validated before debt operations

---

## 📊 Performance Considerations

### Database Optimization Tips

1. **Indexes Required**:
   ```sql
   -- Asset management
   CREATE INDEX idx_assets_conditions ON assets(conditions);
   CREATE INDEX idx_assets_type ON assets(type);
   CREATE INDEX idx_assets_category ON assets(assetscatid);
   
   -- Financial tracking
   CREATE INDEX idx_savedaily_saveid_date ON savedaily(saveid, savedailydate);
   CREATE INDEX idx_accountmovement_accountid ON accountmovement(accountid);
   
   -- Supplier integration
   CREATE INDEX idx_supplierdebtchange_supplier ON supplierdebtchange(supplierid);
   ```

2. **Transaction Management**:
   - Asset creation involves multiple table inserts
   - Use database transactions for consistency
   - Implement proper rollback on failures

3. **Large Dataset Considerations**:
   - Pagination implemented for asset listings (2500 items per page)
   - Consider archiving old/deleted assets
   - Optimize asset search queries

### Known Performance Issues

1. **N+1 Query Patterns**:
   - Asset listing loads category data individually
   - Consider JOIN or batch loading

2. **Large Transaction Logs**:
   - `savedaily` and `accountmovement` tables grow rapidly
   - Consider partitioning by date

3. **Supplier Locking**:
   - Polling approach for supplier locks may cause delays
   - Consider event-based or message queue approach

---

## 🐛 Common Issues & Troubleshooting

### 1. **Asset Creation Fails**
**Issue**: Asset creation succeeds but accounting entries fail  
**Cause**: Missing accounting tree elements or invalid tree structure

**Debug**:
```sql
-- Check accounting tree integrity
SELECT * FROM accountstree WHERE id = [TREE_ID];

-- Verify parent categories exist
SELECT * FROM assetscat WHERE assetscatid = [CATEGORY_ID];
```

**Fix**:
```php
// Verify tree element creation
$aslId = addTreeElement($assetName, $treeId, 3, 0, 1, '', 0, 0);
if ($aslId === false) {
    throw new Exception("Failed to create accounting tree element");
}
```

### 2. **Check Payment Processing Fails**
**Issue**: Check payment creates record but doesn't update bank balance  
**Cause**: Insufficient bank account balance or invalid account ID

**Debug**:
```sql
-- Check bank account status
SELECT * FROM bankaccount WHERE accountid = [ACCOUNT_ID];

-- Verify balance sufficiency
SELECT accountbeginingbalance FROM bankaccount WHERE accountid = [ACCOUNT_ID];
```

### 3. **Supplier Debt Synchronization Issues**
**Issue**: Supplier debt becomes out of sync or locked permanently  
**Cause**: Transaction failures or improper lock release

**Fix**:
```sql
-- Force release supplier locks
UPDATE supplier SET inUse = 0 WHERE supplierid = [SUPPLIER_ID];

-- Recalculate supplier debt
SELECT SUM(CASE WHEN supplierdebtchangetype = 0 THEN supplierdebtchangeamount 
               ELSE -supplierdebtchangeamount END) 
FROM supplierdebtchange WHERE supplierid = [SUPPLIER_ID];
```

### 4. **Asset Deletion Reversal Issues**
**Issue**: Asset deletion doesn't properly reverse financial transactions  
**Cause**: Missing or invalid journal entry references

**Debug**:
```php
// Check journal entry existence
$dailyEntryId = $assetdata->dailyentryid;
if (empty($dailyEntryId)) {
    echo "Asset has no associated journal entries";
}

// For old assets, check comma-separated IDs
$entryIds = explode(',', $dailyEntryId);
foreach ($entryIds as $id) {
    // Verify each entry exists and can be reversed
}
```

---

## 🧪 Testing Scenarios

### Test Case 1: New Asset Creation with Cash Payment
```
1. Create new asset with valid category
2. Select cash payment method with sufficient balance
3. Verify asset record creation
4. Verify cash register deduction
5. Verify accounting entries creation
6. Check asset appears in listing
```

### Test Case 2: Old Asset Registration with Depreciation
```
1. Register old asset with depreciation amount
2. Verify dual journal entries creation
3. Check asset value vs depreciation calculation
4. Verify accounting tree integration
```

### Test Case 3: Asset Purchase via Supplier Credit
```
1. Select supplier with valid debt capacity
2. Create asset on supplier credit
3. Verify supplier debt increase
4. Check supplier debt change records
5. Verify proper lock release
```

### Test Case 4: Asset Sale Processing
```
1. Sell existing asset to client
2. Verify sale record creation
3. Check cash register increase
4. Verify asset value set to zero
5. Check client can be associated with sale
```

### Test Case 5: Asset Deletion with Reversals
```
1. Delete asset with each payment type
2. Verify financial reversals for cash payments
3. Check supplier debt decrease for supplier payments
4. Verify accounting entry reversals
5. Check bank account restoration for check payments
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [assetTypeController.md](assetTypeController.md) - Asset category management
- [Accounting Integration](#) - Daily entry and tree management
- [Supplier Management](#) - Supplier debt tracking
- [Banking Module](#) - Check processing and bank accounts

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When asset management workflows change