# Daily Entry Functions Controller Documentation

**File**: `/controllers/dailyentryfun.php`  
**Purpose**: Core accounting utility functions for managing daily journal entries, accounts tree, and accounting operations  
**Last Updated**: December 20, 2024  
**Total Functions**: 25+  
**Lines of Code**: ~858

---

## 📋 Overview

The Daily Entry Functions Controller serves as the backbone of the accounting system, providing essential utility functions for:
- Daily journal entry management (debit/credit transactions)
- Chart of accounts (accounts tree) management  
- Account balance calculations and updates
- Double-entry bookkeeping enforcement
- Transaction reversal and correction
- Cost center detail tracking
- Account value affection based on account type

### Primary Functions
- [x] Insert complex journal entries with multiple debits/credits
- [x] Manage accounts tree structure (add/delete/restore elements)
- [x] Enforce accounting equation balance (debits = credits)
- [x] Reverse journal entries by ID or comment
- [x] Calculate running account balances
- [x] Handle cost center allocations
- [x] Support transaction rollback on errors
- [x] Validate unique account names within parent groups
- [x] Automatic account value updates based on account type

### Related Controllers
- [dailyentrymany.php](dailyentrymany.md) - Bulk daily entry creation
- [sellbillController.php](sellbillController.md) - Sales transaction entries
- [buyBillController.php](buyBillController.md) - Purchase transaction entries
- [clientPayedDeptController.php](#) - Customer payment entries
- [expensesController.php](#) - Expense transaction entries

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **accountstree** | Chart of accounts master | id, name, parent, itemtype, itemtype2, theValue, userid, reportid |
| **dailyentry** | Journal entry headers | id, totalcreditor, totaldebtor, thedate, userid, entryComment, operationId |
| **dailyentrycreditor** | Credit side entries | id, dailyentryid, accountstreeid, value, dComment, costcenterid |
| **dailyentrydebtor** | Debit side entries | id, dailyentryid, accountstreeid, value, dComment, costcenterid |
| **costcenter** | Cost center master data | id, name, description |
| **costcenterdetail** | Cost center allocations | id, costcenterid, costamount, modelid, tablename, type |

### Account Types (itemtype)
| Type | Description | Nature |
|------|-------------|---------|
| **0** | مصروفات (Expenses) | Debit balance |
| **1** | خصوم (Liabilities) | Credit balance |
| **2** | إيرادات (Income) | Credit balance |
| **3** | أصول (Assets) | Debit balance |
| **4** | حقوق الملكية (Equity) | Credit balance |
| **5** | مسحوبات (Drawings) | Debit balance |

---

## 🔑 Key Functions

### 1. **addTreeElement()** - Add Account to Chart
**Location**: Line 94  
**Purpose**: Add new account to the chart of accounts with validation

**Function Signature**:
```php
function addTreeElement($name, $parent, $itemtype, $itemfrom, $itemtype2, $notes = '', $theOrder = 0, $theValue = 0, $reportid = 0)
```

**Parameters**:
- `$name` - Account name (required, must be unique within parent)
- `$parent` - Parent account ID (0 = root level)
- `$itemtype` - Account type (0-5, see table above)
- `$itemfrom` - Source (0=program, 1=tree only)
- `$itemtype2` - Level (0=parent, 1=leaf account)
- `$notes` - Optional description
- `$theOrder` - Display order
- `$theValue` - Initial balance (for leaf accounts)
- `$reportid` - Report group ID

**Return Values**:
- `{id}` - Success, returns new account ID
- `-1` - Error, duplicate name

**Validation**:
- Checks name uniqueness within parent using `isUniqueName()`
- Inherits parent's account nature and list ID
- Sets default report ID (2 for expenses/income)

---

### 2. **insertEntery()** - Create Journal Entry
**Location**: Line 337  
**Purpose**: Insert complete double-entry journal transaction with validation

**Function Signature**:
```php
function insertEntery($dailyEntryObj = NULL, $dailyEntryDebtorArray, $dailyEntryCreditorArray, $stopEntryTransaction = 0, $operationId = 0, $operationDetailLink = '')
```

**Process Flow**:
1. **Validation**: Ensure total debits = total credits and ≠ 0
2. **Entry Header**: Create dailyentry record with totals and metadata
3. **Debit Entries**: Process each debit line item
   - Insert dailyentrydebtor record
   - Update account balance via `affectAccount()`
   - Handle cost center allocation if specified
   - Execute plugin effects if fromFlag = 2
4. **Credit Entries**: Process each credit line item (same pattern)
5. **Transaction Control**: Commit on success, rollback on failure

**Return Values**:
- `[1, {entryId}]` - Success with new entry ID
- `[-1, 0]` - Error: debits ≠ credits or zero amount
- `[-2, 0]` - Error: database exception

**Features**:
- Automatic transaction wrapping (unless nested)
- Cost center detail creation
- Plugin system integration
- Account balance updates
- Branch assignment from session

---

### 3. **reverseEntryWithItsID()** - Reverse Journal Entry
**Location**: Line 495  
**Purpose**: Create reversing entry to cancel out original transaction

**Function Signature**:
```php
function reverseEntryWithItsID($id, $stopEntryTransaction = 0)
```

**Process Flow**:
1. Load original entry and validate not already reversed
2. Mark original entry as reversed (reverseofid = -10)
3. Create new entry with reversed debits/credits:
   - Original debits → new credits
   - Original credits → new debits
4. Update account balances with reversed amounts
5. Set comment: "تم عكس القيد رقم {id}"

**Reversal Status Codes**:
- `0` - Normal entry
- `{positive}` - This entry reverses entry #{positive}
- `-9` - Manually marked as reversed  
- `-10` - Automatically reversed by system

---

### 4. **affectAccount()** - Update Account Balance
**Location**: Line 759  
**Purpose**: Update account balance based on transaction type and account nature

**Function Signature**:
```php
function affectAccount($CreditorOrDebtorObj, $type)
```

**Account Effect Logic**:
```php
// For Assets (3), Expenses (0), Drawings (5):
if ($type == 0) { // Debit side
    $operation = 'increase'; // Normal balance side
} else { // Credit side
    $operation = 'decrease'; // Contra balance side  
}

// For Liabilities (1), Income (2), Equity (4):
if ($type == 0) { // Debit side
    $operation = 'decrease'; // Contra balance side
} else { // Credit side  
    $operation = 'increase'; // Normal balance side
}
```

**Parameters**:
- `$CreditorOrDebtorObj` - Entry line object with accountstreeid, value
- `$type` - 0=debit entry, 1=credit entry

---

### 5. **insertCostCenterDetail()** - Track Cost Allocations
**Location**: Line 820  
**Purpose**: Record cost center allocation for management reporting

**Function Signature**:
```php
function insertCostCenterDetail($Costcenterid, $val, $dailyentryid, $comment, $controllerName, $costCenterType = -1)
```

**Purpose**: Links specific amounts to cost centers for:
- Project cost tracking
- Department expense analysis
- Activity-based costing
- Management reporting

---

## 🔄 Workflows

### Workflow 1: Complete Journal Entry Creation
```
┌─────────────────────────────────────────────────────────────┐
│           START: Prepare Entry Data Arrays                 │
│   - $dailyEntryDebtorArray (from accounts)                 │
│   - $dailyEntryCreditorArray (to accounts)                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Validation Phase                                        │
│     - Calculate total debits: sum($dailyEntryDebtorArray)   │
│     - Calculate total credits: sum($dailyEntryCreditorArray)│
│     - Verify: debits = credits AND ≠ 0                     │
│     - FAIL → Return [-1, 0]                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Entry Header (dailyentry)                       │
│     - totalcreditor = calculated total                     │
│     - totaldebtor = calculated total                       │
│     - thedate = today OR specified date                    │
│     - userid = $_SESSION['userid']                         │
│     - entryComment = description                           │
│     - branchid = $_SESSION['branchId']                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Debit Entries                                   │
│     FOR EACH debit in $dailyEntryDebtorArray:              │
│       │                                                     │
│       ├─→ Insert dailyentrydebtor record                   │
│       │   ├─ Link to main entry ID                         │
│       │   └─ Store account, amount, comment                │
│       │                                                     │
│       ├─→ Update Account Balance                           │
│       │   ├─ Load account from accountstree                │
│       │   ├─ Determine operation (increase/decrease)       │
│       │   └─ Update account theValue                       │
│       │                                                     │
│       ├─→ Handle Cost Center (if specified)                │
│       │   └─ Insert costcenterdetail record                │
│       │                                                     │
│       └─→ Execute Plugin Effects (if fromFlag = 2)         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Process Credit Entries                                  │
│     FOR EACH credit in $dailyEntryCreditorArray:           │
│       │                                                     │
│       ├─→ Insert dailyentrycreditor record                 │
│       ├─→ Update Account Balance (opposite direction)       │
│       ├─→ Handle Cost Center (if specified)                │
│       └─→ Execute Plugin Effects (if fromFlag = 2)         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Transaction Finalization                               │
│     - Commit transaction (if managing transaction)         │
│     - Return [1, $dailyEntryId]                            │
│                                                             │
│  ERROR HANDLING:                                            │
│     - Rollback transaction on any exception                │
│     - Return [-2, 0] with error message                    │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Account Tree Management
```
┌─────────────────────────────────────────────────────────────┐
│               START: Add New Account                       │
│   Parameters: name, parent, type, etc.                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Name Validation                                         │
│     - Check isUniqueName(name, parent)                     │
│     - Search both 'name' and 'customName' fields          │
│     - Within same parent group only                        │
│                                                             │
│     IF DUPLICATE FOUND:                                     │
│       ├─→ Check if soft-deleted (del = 1)                  │
│       ├─→ If yes: restore it (del = 0)                     │
│       └─→ If no: return -1 (error)                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Inherit Parent Properties                               │
│     - Load parent account data                              │
│     - Inherit: accountNature, listId, reportid             │
│     - Set default reportid = 2 for expenses/income         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Create Account Record                                   │
│     - name = specified name                                 │
│     - customName = name (can be changed later)             │
│     - parent = parent account ID                            │
│     - itemtype = account type (0-5)                        │
│     - itemtype2 = 1 for leaf, 0 for parent                │
│     - theValue = initial balance (if leaf)                 │
│     - userid = $_SESSION['userid']                         │
│     - sysdate = current timestamp                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Success Response                                        │
│     - Insert into accountstree table                       │
│     - Return new account ID                                 │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 Usage Examples

### Example 1: Simple Expense Entry
```php
// Record office supplies expense paid from cash
$dailyEntry = new Dailyentry();
$dailyEntry->entryComment = 'Office supplies purchase';

// Debit: Office Supplies Expense
$debitEntry = new Dailyentrydebtor();
$debitEntry->accountstreeid = 150; // Office Supplies account
$debitEntry->value = 500.00;
$debitEntry->dComment = 'Printer paper and pens';

// Credit: Cash Account  
$creditEntry = new Dailyentrycreditor();
$creditEntry->accountstreeid = 101; // Cash account
$creditEntry->value = 500.00;
$creditEntry->dComment = 'Payment for supplies';

$result = insertEntery($dailyEntry, [$debitEntry], [$creditEntry]);
// Returns: [1, 1234] where 1234 is the new entry ID
```

### Example 2: Sales Transaction Entry
```php
// Record cash sale with multiple accounts affected
$dailyEntry = new Dailyentry();
$dailyEntry->entryComment = 'Cash sale - invoice #12345';
$dailyEntry->operationId = 12345;
$dailyEntry->operationDetailLink = 'sellbillController.php?id=12345';

// Debit entries
$debitEntries = [];

// Cash received
$cashDebit = new Dailyentrydebtor();
$cashDebit->accountstreeid = 101; // Cash
$cashDebit->value = 1150.00;
$debitEntries[] = $cashDebit;

// Credit entries  
$creditEntries = [];

// Sales revenue
$salesCredit = new Dailyentrycreditor();
$salesCredit->accountstreeid = 201; // Sales Revenue
$salesCredit->value = 1000.00;
$creditEntries[] = $salesCredit;

// Sales tax
$taxCredit = new Dailyentrycreditor();
$taxCredit->accountstreeid = 210; // Sales Tax Payable
$taxCredit->value = 150.00;
$creditEntries[] = $taxCredit;

$result = insertEntery($dailyEntry, $debitEntries, $creditEntries);
```

---

## 🔒 Security & Permissions

### User Access Control
- All functions respect `$_SESSION['userid']` for audit trail
- Account access controlled by user permissions
- Branch-level data separation via `$_SESSION['branchId']`

### Data Validation
- Account name uniqueness enforced within parent groups
- Numeric validation on amounts (no negative values in core functions)
- Account tree integrity maintained (parent-child relationships)
- Double-entry validation (debits = credits) strictly enforced

### Transaction Safety
- Database transactions wrap multi-table operations
- Automatic rollback on any failure
- Reversal entries maintain audit trail
- No direct balance updates without journal entries

---

## 📊 Performance Considerations

### Database Optimization
1. **Indexes Required**:
   - `accountstree(parent, del, name)`
   - `accountstree(parent, del, customName)`
   - `dailyentry(operationId)`
   - `dailyentrycreditor(dailyentryid)`
   - `dailyentrydebtor(dailyentryid)`

2. **Query Patterns**:
   - Frequent parent-child traversal in accounts tree
   - Entry detail lookups by dailyentryid
   - Account balance updates (single row updates)

### Memory Management
- Large journal entries with many line items require adequate PHP memory
- Cost center processing adds overhead for each line item
- Plugin system execution can be resource-intensive

---

## 🐛 Common Issues & Troubleshooting

### 1. **"لابد ان يكون مجموع مدين يساوى مجموع دائن" Error**
**Issue**: Debits don't equal credits validation failure  
**Cause**: Rounding errors or incorrect amount calculation

**Debug**:
```php
$totalDebits = getTotal($dailyEntryDebtorArray);
$totalCredits = getTotal($dailyEntryCreditorArray);
echo "Debits: $totalDebits, Credits: $totalCredits";
```

### 2. **"اسم العنصر مكرر" Error**
**Issue**: Account name already exists in parent group  
**Cause**: Trying to create duplicate account name

**Fix**:
```php
// Check before creating
$isUnique = isUniqueName($accountName, $parentId);
if (!$isUnique) {
    // Handle duplicate - maybe append suffix or use different name
}
```

### 3. **Account Balance Calculation Errors**
**Issue**: Account balances don't match expected values  
**Cause**: Missing entries or incorrect account type logic

**Debug**:
```php
// Check account type and recent entries
$account = $accountsTreeDAO->load($accountId);
echo "Account Type: " . $account->itemtype;
echo "Current Balance: " . $account->theValue;

// Check recent entries affecting this account
$recentDebits = $dailyEntryDebtorDAO->queryByAccountstreeid($accountId);
$recentCredits = $dailyEntryCreditorDAO->queryByAccountstreeid($accountId);
```

### 4. **Transaction Rollback Issues**
**Issue**: Partial entries created despite errors  
**Cause**: Nested transaction handling or missing try-catch

**Fix**:
```php
// Always use transaction wrapper
$transaction = new Transaction();
try {
    // Your journal entry operations
    insertEntery($entry, $debits, $credits, 1); // stopEntryTransaction = 1
    $transaction->commit();
} catch (Exception $e) {
    $transaction->rollback();
    // Handle error appropriately
}
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Double-Entry Validation
```
1. Create entry with unbalanced debits/credits
2. Verify function returns [-1, 0]  
3. Create entry with balanced amounts
4. Verify function returns [1, {id}]
5. Check database for correct entry creation
```

### Test Case 2: Account Tree Hierarchy
```
1. Create parent account (itemtype2 = 0)
2. Create child accounts under parent
3. Test name uniqueness within parent
4. Verify inheritance of parent properties
5. Test account deletion and restoration
```

### Test Case 3: Reversal Functionality  
```
1. Create normal journal entry
2. Record original entry ID
3. Reverse the entry using reverseEntryWithItsID()
4. Verify original marked as reversed (reverseofid = -10)
5. Verify new reversing entry created
6. Check account balances return to pre-entry state
```

### Test Case 4: Cost Center Integration
```
1. Create entry with cost center assignments
2. Verify costcenterdetail records created
3. Check cost allocation amounts match entry amounts
4. Test cost center reporting accuracy
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [dailyentrymany.md](dailyentrymany.md) - Bulk entry operations
- [Database Schema Documentation](#) - Complete table relationships
- [Accounting Principles Guide](#) - Double-entry bookkeeping rules

---

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