# Affect Plugins Controller Documentation

**File**: `/controllers/affectplugins.php`  
**Purpose**: Core financial integration engine that affects accounting entities (save, bank, client, supplier, expenses) during transaction processing  
**Last Updated**: December 20, 2024  
**Total Functions**: 20+ complex functions  
**Lines of Code**: ~1,285

---

## 📋 Overview

The Affect Plugins Controller is the **core financial integration engine** of the ERP system. It acts as a central hub that automatically updates all affected financial entities when transactions occur. This controller handles:

- **Multi-entity Transaction Processing**: Affects save accounts, bank accounts, clients, suppliers, expenses, income, assets, and partners
- **Accounting Integration**: Links operational transactions to chart of accounts
- **Balance Management**: Maintains running balances across all financial entities
- **Audit Trails**: Creates detailed transaction logs for all affected accounts
- **Plugin Architecture**: Extensible system for adding new financial entity types
- **Daily Entry Integration**: Coordinates with journal entry system
- **Online Store Synchronization**: Updates external e-commerce platforms

### Primary Functions
- [x] Automatic financial entity updates during transactions
- [x] Save account balance management with audit trails
- [x] Bank account movement tracking and balance updates
- [x] Client debt management and change logging
- [x] Supplier debt tracking and payment processing
- [x] Expense and income categorization with cost centers
- [x] Partner account management and transfers
- [x] Asset value tracking and depreciation
- [x] Online store inventory synchronization
- [x] Multi-currency transaction handling

### Related Controllers
- [sellbillController.php](sellbillController.md) - Sales transaction processing
- [buyBillController.php](buyBillController.md) - Purchase transaction processing
- [dailyentry.php](dailyentry.md) - Journal entry system
- [saveController.php](saveController.md) - Save account management
- [bankController.php](bankController.md) - Bank account management
- [clientController.php](clientController.md) - Client management
- [supplierController.php](supplierController.md) - Supplier management

---

## 🗄️ Database Tables

### Financial Entity Tables (Direct Updates)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **save** | Cash registers/safes | saveid, savecurrentvalue, userid |
| **savedaily** | Save transaction log | savedailydate, savedailychangeamount, savedailychangetype, saveid, tablename |
| **bankaccount** | Bank accounts | accountid, accountbeginingbalance, bankid |
| **accountmovement** | Bank transaction log | accountmovementdate, accountmovementamount, accountmovementtype, accountid |
| **client** | Customer accounts | clientid, clientdebt, userid |
| **clientdebtchange** | Client debt change log | clientdebtchangedate, clientdebtchangeamount, clientdebtchangetype, clientid |
| **supplier** | Supplier accounts | supplierid, suppliercurrentDebt |
| **supplierdebtchange** | Supplier debt change log | supplierdebtchangedate, supplierdebtchangeamount, supplierdebtchangetype, supplierid |

### Accounting Integration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **accountstree** | Chart of accounts | id, customName, parent, del |
| **expenses** | Expense transactions | expensesid, expensesValue, expensestypeid, saveid, bankaccountid |
| **income** | Income transactions | incomeId, incomeValue, incomeTypeId, saveid |
| **assets** | Asset values | assetId, assetsValue, treeId |
| **capital** | Capital accounts | capitalamount |

### Partner Management Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **partner** | Business partners | partnerid, partnermoney, treeId |
| **partnertransferbetween** | Partner transfers | partneridfrom, partneridto, partnervalue |
| **partnerwithdrawal** | Partner withdrawals | partnerid, partnerwithdrawalvalue, partenrwithdrawaltype |
| **transfermoney** | Save-to-save transfers | saveidfrom, saveidto, transfermoneyvalue |

### Online Store Sync Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **onlinestoresetting** | E-commerce configuration | url, availableStores, updatetype |
| **onlinetempstoredetail** | Inventory sync queue | storeid, productid, quantity, edited |
| **onlinetempproduct** | Product sync queue | productid, edited |
| **onlinetemporder** | Order sync queue | orderid, edited |

---

## 🔑 Core Functions

### 1. **affectPlugin()** - Main Transaction Processor
**Location**: Lines 284-442  
**Purpose**: Central dispatcher that routes transactions to appropriate financial entity handlers

**Function Signature**:
```php
function affectPlugin($whatIsIt, $val, $id, $operation, $elementName, $comment, 
                     $controllerName, $costCenterID, $accountstreeid, 
                     $whichSideisIt, $dailyEntry, $AllDailyEntryDebtor, $AllDailyEntryCreditor)
```

**Parameters**:
- `$whatIsIt` - Entity type ('save', 'bank', 'client', 'supplier', 'expenses', etc.)
- `$val` - Transaction amount
- `$operation` - 'increase' or 'decrease'
- `$elementName` - Account/entity name
- `$whichSideisIt` - Debit (0) or Credit (1) side

**Process Flow**:
1. Identify entity type from chart of accounts
2. Route to appropriate handler function
3. Update entity balances
4. Create audit trail entries
5. Handle special cases (reversals, multi-entity transactions)

**Entity Handlers**:
```php
switch ($whatIsIt) {
    case 'save':     // Cash registers/safes
    case '3ohad':    // Government entities (Eohad)
        affectOtherSaveControllers(); // Handle transfers first
        // Then update save balance and create savedaily entry
        
    case 'bank':     // Bank accounts
        affectOtherBankControllers(); // Handle transfers first  
        // Then update bank balance and create accountmovement
        
    case 'client':   // Customer accounts
        updateClientDebt_f();
        insertClientdebtchange_f();
        
    case 'supplier': // Supplier accounts
        updateSupplierDebt_f();
        insertSupplierDebtChange_f();
        
    case 'expenses': // Expense categories
        insertEXpenseDaily_f();
        
    case 'income':   // Income categories
        insertIncomeDaily_f();
}
```

---

### 2. **whatIsIt()** - Entity Type Resolver
**Location**: Lines 444-461  
**Purpose**: Determine financial entity type from chart of accounts ID

**Process Flow**:
1. Check if account ID matches predefined plugin map
2. If not found, traverse up parent hierarchy
3. Match against known entity root accounts
4. Return entity type string

**Plugin Map Array**:
```php
$pluginMapArr = array(
    'save' => 40,           // Cash registers
    'bank' => 38,           // Bank accounts
    'client' => 57,         // Customer accounts
    'supplier' => 80,       // Supplier accounts
    'expenses' => 411,      // Expense categories
    'income' => 151,        // Income categories
    'partner' => 128        // Business partners
);
```

---

### 3. **Save Account Functions** - Cash Register Management

#### **getSaveValueAndPlus_f()** / **getSaveValueAndMins_f()**
**Location**: Lines 507-532  
**Purpose**: Calculate new save balance before/after transaction

#### **updateSave_f()**
**Location**: Lines 535-545  
**Purpose**: Update save current value

#### **insertSavedaily_f()**
**Location**: Lines 548-569  
**Purpose**: Create audit trail entry in savedaily table

**Process Flow for Save Operations**:
```php
// For increase operations
$saveData = getSaveValueAndPlus_f($saveid, $amount);
updateSave_f($saveId, $newBalance);
insertSavedaily_f($oldBalance, $amount, 0, $saveid, $comment, $id, $newBalance, $tablename);

// For decrease operations  
$saveData = getSaveValueAndMins_f($saveid, $amount);
updateSave_f($saveId, $newBalance);
insertSavedaily_f($oldBalance, $amount, 1, $saveid, $comment, $id, $newBalance, $tablename);
```

---

### 4. **Bank Account Functions** - Banking Operations

#### **getAccountBalanceAndPlus_f()** / **getAccountBalanceAndMins_f()**
**Location**: Lines 587-614  
**Purpose**: Calculate new bank account balance

#### **updateBankAccount_f()**
**Location**: Lines 617-629  
**Purpose**: Update bank account beginning balance

#### **insertAccountmovement_f()**
**Location**: Lines 632-662  
**Purpose**: Create bank transaction log entry

**Bank Transaction Logic**:
```php
// Extract account info from element name
$elementName = explode('/', $elementName); // Format: "AccountName/BankName"
$bankAccount = $bankAccountDAO->queryByAccountname($elementName[0]);

// Update balance
$data = getAccountBalanceAndPlus_f($accountid, $amount);
updateBankAccount_f($accountid, $newBalance);
insertAccountmovement_f($oldBalance, $amount, $type, $newBalance, ...);
```

---

### 5. **Client/Supplier Debt Management**

#### **updateClientDebt_f()** / **insertClientdebtchange_f()**
**Location**: Lines 667-702  
**Purpose**: Manage customer debt balances and audit trails

#### **updateSupplierDebt_f()** / **insertSupplierDebtChange_f()**
**Location**: Lines 707-740  
**Purpose**: Manage supplier debt balances and audit trails

**Debt Processing Logic**:
```php
// Client debt changes
$client = $clientDAO->queryByClientname($elementName);
$clientid = $client[0]->clientid;
$deptBefore = $client[0]->clientdebt;

if ($operation == 'increase') {
    $debtAfter = $deptBefore + $val;
    insertClientdebtchange_f($clientid, $deptBefore, $val, 0, ...); // Type 0 = debt increase
} else {
    $debtAfter = $deptBefore - $val;  
    insertClientdebtchange_f($clientid, $deptBefore, $val, 1, ...); // Type 1 = debt decrease
}
updateClientDebt_f($clientid, $debtAfter);
```

---

### 6. **Expense/Income Processing**

#### **insertEXpenseDaily_f()**
**Location**: Lines 745-794  
**Purpose**: Create expense entries with cost center and account linking

#### **insertIncomeDaily_f()**
**Location**: Lines 796-832  
**Purpose**: Create income entries with automatic sequencing

**Expense Entry Creation**:
```php
// Auto-generate unique expense name
$expenseName = $expensesname . R::getCell('SELECT AUTO_INCREMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = "expenses"');

// Link to save or bank account
$saveid = R::getCell('select saveid from save where treeId=' . $treeId);
if ($saveid < 1) {
    // Get bank account info instead
    $bankAccountData = $bankAccountDAO->queryByAccountname($accountName);
}

// Create expense record
$Expense->expensesValue = $expensevalue;
$Expense->expensestypeid = $expensetype;  
$Expense->costcenterid = $Costcenterid;
$Expense->dailyentryid = $dailyentryid;
```

---

### 7. **Complex Transaction Handlers**

#### **affectPartner()**
**Location**: Lines 942-1055  
**Purpose**: Handle partner transfers and withdrawals

**Process Logic**:
```php
// Determine transaction type
$whatIsItFrom = whatIsIt($AllDailyEntryDebtor[0]->accountstreeid);
$whatIsItTo = whatIsIt($AllDailyEntryCreditor[0]->accountstreeid);

if ($whatIsItFrom == $whatIsItTo && $whatIsItTo == "partner") {
    // This is partner-to-partner transfer
    handlePartnerTransfer($partnerfrom, $partnerto, $amount);
} else {
    // This is partner withdrawal/deposit
    handlePartnerWithdrawal($partner, $saveOrBank, $amount, $type);
}
```

#### **affectOtherSaveControllers()**
**Location**: Lines 1058-1172  
**Purpose**: Handle save-to-save transfers, cash transfers, and save adjustments

#### **affectOtherBankControllers()**
**Location**: Lines 1174-1284  
**Purpose**: Handle bank-to-bank transfers and account deficit adjustments

---

### 8. **Online Store Integration**

#### **onlineTempStoreDetailFunc()**
**Location**: Lines 838-857  
**Purpose**: Queue inventory updates for online store synchronization

#### **onlineTempProductFunc()**
**Location**: Lines 906-915  
**Purpose**: Queue product updates for online store

**Sync Process**:
```php
// Check if store is configured for sync
$onlineStoreSetting = getOrHandleOnlineStoreSetting();
$onlineStores = explode(',', $onlineStoreSetting->availableStores);

if (in_array($storeid, $onlineStores)) {
    // Queue update for external sync
    $obj->storeid = $storeid;
    $obj->productid = $productid;  
    $obj->quantity = $quantity;
    $obj->edited = $edited; // 0=not edited, 1=edited, 2=deleted
    $onlineTempStoreDetailEX->insertOrUpdateOnDuplicate($obj);
}
```

---

## 🔄 Complex Workflows

### Workflow 1: Sales Transaction Financial Impact
```
┌─────────────────────────────────────────────────────────────┐
│            START: Sales Bill Created in sellbillController │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Daily Entry Creation                                    │
│     - Journal entry created with debit/credit sides        │
│     - Customer account (debit) / Sales income (credit)     │
│     - Save account (debit) / Customer account (credit)     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. affectPlugin() Called for Each Side                    │
│     FOR EACH daily entry line:                             │
│       │                                                     │
│       ├─→ whatIsIt() determines entity type                │
│       │                                                     │
│       ├─→ Route to appropriate handler:                    │
│       │   ├─ client: Update customer debt                  │
│       │   ├─ save: Update cash register balance            │
│       │   ├─ income: Record sales income                   │
│       │   └─ expenses: Record cost of goods sold           │
│       │                                                     │
│       └─→ Create audit trail entries                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Multi-Entity Updates Complete                          │
│     - Customer debt increased by sale amount               │
│     - Save balance increased by cash payment               │
│     - Income recorded in appropriate category              │
│     - All changes logged with timestamps and references    │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Complex Transfer Transaction
```
┌─────────────────────────────────────────────────────────────┐
│          START: Money Transfer Between Save Accounts       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Identify Transaction Type                              │
│     - affectOtherSaveControllers() analyzes both sides    │ 
│     - Detects save-to-save transfer pattern               │
│     - Determines currency conversion if needed             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Transfer Record                                  │
│     - Insert into transfermoney table                      │
│     - Record source/destination save accounts              │
│     - Handle currency conversion factors                   │
│     - Link to daily entry for audit trail                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Update Both Save Accounts                              │
│     - Decrease source save balance                         │
│     - Increase destination save balance                    │
│     - Create savedaily entries for both accounts           │
│     - Maintain running balance integrity                   │
└─────────────────────────────────────────────────────────────┘
```

---

## 🧮 Financial Calculations

### Balance Update Patterns
```php
// Standard increase operation
$oldBalance = getCurrentBalance($accountId);
$newBalance = $oldBalance + $transactionAmount;
updateAccountBalance($accountId, $newBalance);
createAuditEntry($accountId, $oldBalance, $transactionAmount, INCREASE, $newBalance);

// Standard decrease operation  
$oldBalance = getCurrentBalance($accountId);
$newBalance = $oldBalance - $transactionAmount;
updateAccountBalance($accountId, $newBalance);
createAuditEntry($accountId, $oldBalance, $transactionAmount, DECREASE, $newBalance);
```

### Multi-Currency Handling
```php
// Currency conversion in transfers
$fromCurrency = R::getCell('select conversionFactor from currency where id = ?', [$fromCurrencyId]);
$toCurrency = R::getCell('select conversionFactor from currency where id = ?', [$toCurrencyId]);

$transferValue = $amount / $toCurrency; // Convert to base currency
$transfermoney->transfermoneyvalue = $transferValue;
$transfermoney->conversionFactor = $toCurrency;
$transfermoney->transfermoneyvalueInCurrency = $amount; // Original amount
```

---

## 🔒 Security & Data Integrity

### Transaction Atomicity
- All balance updates occur within database transactions
- Audit trails created simultaneously with balance changes
- Rollback capabilities through daily entry reversal system

### Audit Trail Requirements
- Every financial change creates corresponding log entry
- Entries link back to source transactions via `dailyentryid`
- User and timestamp recorded for all operations
- Change amounts and before/after balances preserved

### Reversal Handling
```php
// Transaction reversal logic
if ($dailyEntry->reverseofid > 0) {
    // This is a reversal entry - undo previous transaction
    $originalTransaction = R::getRow('select * from expenses where dailyentryid=' . $dailyEntry->reverseofid);
    $ExpenseDAO->delete($originalTransaction['expensesid']);
} else {
    // This is a new transaction - create new records
    $expenseId = $ExpenseDAO->insert($Expense);
}
```

---

## 📊 Performance Considerations

### Database Optimization
1. **Critical Indexes**:
   - `save(treeId)` for account lookups
   - `bankaccount(treeId, accountname)` for bank account resolution
   - `client(clientname)` for customer lookups
   - `accountstree(id, parent)` for hierarchy traversal

2. **Query Efficiency**:
   - Chart of accounts traversal can be expensive
   - Cache entity type mappings where possible
   - Batch operations when processing multiple transactions

### Memory Management
- Large transaction volumes require careful memory management
- Online store sync queues can grow large
- Consider periodic cleanup of temporary sync tables

---

## 🐛 Common Issues & Troubleshooting

### 1. **Balance Discrepancies**
**Issue**: Account balances don't match audit trail totals  
**Cause**: Failed transaction rollback or interrupted processing

**Debug**:
```sql
-- Verify save account integrity
SELECT 
    s.saveid,
    s.savecurrentvalue as current_balance,
    SUM(CASE WHEN sd.savedailychangetype = 0 THEN sd.savedailychangeamount ELSE 0 END) -
    SUM(CASE WHEN sd.savedailychangetype = 1 THEN sd.savedailychangeamount ELSE 0 END) as calculated_balance
FROM save s
LEFT JOIN savedaily sd ON s.saveid = sd.saveid
GROUP BY s.saveid;
```

### 2. **Entity Type Resolution Failures**
**Issue**: `whatIsIt()` returns empty string  
**Cause**: Account not properly linked to chart of accounts hierarchy

**Debug**:
```sql
-- Check account hierarchy
SELECT id, customName, parent FROM accountstree WHERE id = ?;
-- Verify parent chain leads to known plugin map entry
```

### 3. **Online Store Sync Issues** 
**Issue**: Inventory not updating in e-commerce platform  
**Cause**: Store not configured in available stores list

**Debug**:
```sql
SELECT * FROM onlinestoresetting WHERE id = 1;
-- Check availableStores contains target store ID
```

---

## 🧪 Testing Scenarios

### Test Case 1: Simple Save Transaction
```
1. Create save account with known balance
2. Process transaction through affectPlugin()
3. Verify save balance updated correctly
4. Confirm savedaily audit entry created
5. Check all fields populated correctly
```

### Test Case 2: Multi-Entity Transaction
```
1. Create sale transaction affecting customer and save
2. Process through daily entry system
3. Verify customer debt increased
4. Confirm save balance increased
5. Check both audit trails link to same daily entry
```

### Test Case 3: Partner Transfer
```  
1. Create two partner accounts with balances
2. Process partner-to-partner transfer
3. Verify both partner balances adjusted
4. Confirm partnertransferbetween record created
5. Check before/after balances recorded correctly
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [dailyentry.md](dailyentry.md) - Journal entry system integration
- [sellbillController.md](sellbillController.md) - Sales transaction processing
- [buyBillController.md](buyBillController.md) - Purchase transaction processing
- [Database Schema Documentation](#) - Financial entity relationships

---

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