# Save Daily Controller Documentation

**File**: `/controllers/savedailyController.php`  
**Purpose**: Generates comprehensive daily treasury reports and cash flow tracking for cash registers and bank accounts  
**Last Updated**: December 20, 2024  
**Total Functions**: 13+  
**Lines of Code**: ~2,050

---

## 📋 Overview

The Save Daily Controller is a critical treasury reporting module that provides detailed daily cash register reports, cash flow analysis, and transaction tracking. It handles:
- Daily cash register transaction reports
- Multi-cash register consolidated reports
- Bank payment tracking and analysis
- Process-based filtering and search capabilities
- User privilege-based data access
- Royal/external system integration for payment data
- Real-time cash flow calculations
- Transaction type categorization and analysis

### Primary Functions
- [x] Generate daily cash register reports
- [x] Track cash inflow/outflow transactions
- [x] Multi-register consolidated reporting
- [x] Process-based filtering (sales, payments, expenses)
- [x] User-specific cash register access control
- [x] Bank payment integration
- [x] Date range reporting with time zone support
- [x] Real-time balance calculations
- [x] External system API integration
- [x] Transaction linking to source documents

### Related Controllers
- [cashflowsController.php](cashflowsController.md) - Cash flow summary
- [saveController.php](saveController.md) - Cash register management
- [sellbillController.php](sellbillController.md) - Sales operations
- [buyBillController.php](buyBillController.md) - Purchase operations
- [expensesController.php](expensesController.md) - Expense management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **savedaily** | Daily cash register transactions | savedailyid, saveid, savedailychangeamount, savedailychangetype, savedailydate, processname, tablename |
| **save** | Cash registers/safes master data | saveid, savename, savecurrentvalue, userid, conditions |
| **accountmovement** | Bank account movements | accountmovementid, accountid, amount, movementtype, movementdate |

### Transaction Source Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **sellbill** | Sales transactions | sellbillid, sellbillclientid, sellbilltotalpayed, sellbilldate |
| **buybill** | Purchase transactions | buybillid, buybillsupplierid, buybilltotalpayed, buybilldate |
| **expenses** | Expense transactions | expensesid, expensesValue, expensesdate, saveid |
| **income** | Income transactions | incomeid, incomeValue, incomedate, saveid |
| **bills** | Service bills | billid, clientid, finalnetbillvalue, billdate |
| **clientdebtchange** | Customer debt changes | clientdebtchangeid, clientid, clientdebtchangeamount, clientdebtchangetype |

### Configuration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **usergroup** | User group settings | usergroupid, savedailydate, usergroupname |
| **programsettings** | System configuration | programsettingsid, reportsPlusHours, settingkey, settingvalue |
| **user** | System users | userid, username, usergroupid |
| **branch** | Business branches | branchid, branchname, branchcode |

### Reference Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **client** | Customer master data | clientid, clientname, clientdebt |
| **supplier** | Supplier master data | supplierid, suppliername |
| **youtubelink** | Tutorial links | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **show() / Default Action** - Daily Treasury Report
**Location**: Line 303  
**Purpose**: Generate comprehensive daily cash register report with filtering capabilities

**Function Signature**:
```php
// Triggered when: do=show or empty $do
$saveId = $_REQUEST['saveId'];     // Cash register ID
$userId = $_REQUEST['userId'];     // User filter
$startDate = $_REQUEST['from'];    // Start date
$endDate = $_REQUEST['to'];        // End date  
$processid = $_REQUEST['processid']; // Process type filter
```

**Process Flow**:
1. Load cash registers based on user privileges
2. Load process types for filtering
3. Parse date parameters with timezone handling
4. Apply search filters or default to today's data
5. Call `search()` with parameters
6. Handle CURL/API requests for external systems
7. Display via `show.html` template

**Features**:
- User privilege-based cash register access
- Process type filtering (sales, payments, expenses)
- Date range with timezone support
- Real-time vs historical reporting
- External API integration

---

### 2. **search()** - Core Search and Data Processing
**Location**: Line 1150  
**Purpose**: Query and process cash register transactions with comprehensive filtering

**Function Signature**:
```php
function search($saveid, $processid, $startDate, $endDate, $userId = 0)
```

**Process Flow**:
1. Build dynamic WHERE clause based on filters
2. Apply user privilege restrictions
3. Query `savedaily` table with filters
4. Process each transaction record:
   - Link to source documents
   - Load related party information
   - Calculate running totals
   - Categorize transaction types
5. Calculate summary statistics
6. Return structured data arrays

**Transaction Processing Logic**:
```php
foreach ($savedailyData as $data) {
    // Generate document links
    if ($data->tablename == 'bills.php' || $data->tablename == 'billsreturn.php') {
        $data->link = $data->tablename . '?do=details&id=' . $data->savedailymodelid;
    } else {
        $data->link = $data->tablename . '?do=editprint&id=' . $data->savedailymodelid;
    }
    
    // Calculate running totals
    if ($data->savedailychangetype == 0) { // Income
        $changeAmountSum += $data->savedailychangeamount;
    } else { // Expense
        $changeAmountSum -= $data->savedailychangeamount;
    }
}
```

---

### 3. **loadSaveByUserPrivileg()** - User-Based Cash Register Loading
**Location**: Line 1021  
**Purpose**: Load cash registers based on user privileges and session settings

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

**Process Flow**:
1. Check session setting `searchinonesave`
2. If restricted (=1): Load only user's assigned cash register
3. If unrestricted (=0): Load all active cash registers
4. Return filtered cash register array

**Access Control Logic**:
```php
if ($_SESSION['searchinonesave'] == 1) {
    // Restricted: user's cash register only
    $saveData = $mySaveRecord->queryByUserid($_SESSION['userid']);
} else {
    // Full access: all cash registers
    $saveData = $mySaveRecord->queryByConditions(0);
}
```

---

### 4. **getRoyalData()** - External System Integration
**Location**: Line 2031  
**Purpose**: Format transaction data for Royal/external system API consumption

**Function Signature**:
```php
function getRoyalData($savedailyData, $allMovements)
```

**Process Flow**:
1. Process cash register transactions
2. Format for external API compatibility
3. Include bank movement data
4. Return JSON-formatted response

**API Response Format**:
```php
return array(
    "savePayments" => $savedailyData,    // Cash transactions
    "bankPayments" => $allMovements      // Bank transactions
);
```

---

### 5. **getOpticData()** - Specialized Optical System Report
**Location**: Line 1818  
**Purpose**: Generate reports for optical/medical businesses with insurance integration

**Function Signature**:
```php
function getOpticData($saveId, $startDate, $endDate, $cash, $insurance, $network)
```

**Process Flow**:
1. Query sales bills within date range
2. Filter by payment method (cash/insurance/network)
3. Calculate totals and commissions
4. Format for optical business requirements

---

### 6. **operationName()** - Transaction Type Identification
**Location**: Line 2031  
**Purpose**: Standardize transaction type names for consistent reporting

**Function Signature**:
```php
function operationName($data)
```

**Process Flow**:
1. Analyze `processname` field
2. Map to standardized operation categories
3. Return localized operation name

**Operation Mapping**:
```php
switch ($data->processname) {
    case 'sellbillController.php':
        return 'مبيعات نقدي';
    case 'clientPayedDeptController.php':
        return 'تحصيل من عميل';
    case 'expensesController.php':
        return 'مصروف';
    // ... additional mappings
}
```

---

### 7. **Helper Functions**

**sumCredit()** - Calculate total across all cash registers  
**sumCreditById($id)** - Calculate total for specific cash register  
**loadSave()** - Load all active cash registers  
**loadprocess()** - Load process types for filtering  
**showDetail()** - Load detailed transaction records

---

## 🔄 Workflows

### Workflow 1: Daily Treasury Report Generation
```
┌─────────────────────────────────────────────────────────────┐
│                START: Access Daily Report                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Check User Privileges                                   │
│     - Load accessible cash registers                        │
│     - Apply session restrictions                            │
│     - Load user-specific data                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Process Date/Filter Parameters                          │
│     - Parse date range with timezone                        │
│     - Apply process type filters                            │
│     - Handle default "today" scenario                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Execute Search Query                                    │
│     - Build dynamic WHERE clause                            │
│     - Query savedaily table                                 │
│     - Apply user access restrictions                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Process Transaction Records                             │
│     FOR EACH transaction:                                   │
│       │                                                     │
│       ├─→ Identify transaction source                      │
│       │                                                     │
│       ├─→ Load related party information                   │
│       │   ├─ Customer/supplier names                       │
│       │   ├─ Employee information                          │
│       │   └─ Bill details                                  │
│       │                                                     │
│       ├─→ Generate document links                          │
│       │                                                     │
│       ├─→ Calculate running totals                         │
│       │   ├─ Income transactions (+)                       │
│       │   └─ Expense transactions (-)                      │
│       │                                                     │
│       └─→ Categorize transaction types                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Generate Report Output                                  │
│     - Calculate summary totals                              │
│     - Format for display/API                                │
│     - Include bank movement data                            │
│     - Display via template or return JSON                   │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: External System API Integration
```
┌─────────────────────────────────────────────────────────────┐
│             START: API Request (CURL)                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Detect CURL Request                                     │
│     - Check $_POST['curlpost'] == 1                        │
│     - Skip header display                                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Process Search Request                                  │
│     - Execute normal search() function                      │
│     - Get cash and bank transaction data                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Format for External System                             │
│     - Call getRoyalData() for formatting                   │
│     - Structure as API response                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Return JSON Response                                    │
│     - Output savePayments array                             │
│     - Include bankPayments array                            │
│     - Exit without footer display                           │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) or `do=show` | Default action | Daily treasury report |
| `do=showByDay` | `showByDay()` | Single day summary view |
| `do=opticdata` | `getOpticData()` | Optical business report |

### Required Parameters

**Daily Report** (`do=show`):
- `saveId` - Cash register ID (-1 for all)
- `userId` - User filter (0 for all users)
- `from` - Start date (YYYY-MM-DD)
- `to` - End date (YYYY-MM-DD)
- `processid` - Process type filter
- `search` - Search type ("dateOnly" for date-only filtering)

**API Integration**:
- `curlpost` - Set to 1 for API requests
- All standard report parameters

---

## 🧮 Calculation Methods

### Running Balance Calculation
```php
$changeAmountSum = 0;
$changeAmountSumplus = 0; 
$changeAmountminus = 0;

foreach ($savedailyData as $data) {
    if ($data->savedailychangetype == 0) { // Income
        $changeAmountSum += $data->savedailychangeamount;
        $changeAmountSumplus += $data->savedailychangeamount;
    } else { // Expense  
        $changeAmountSum -= $data->savedailychangeamount;
        $changeAmountminus += $data->savedailychangeamount;
    }
}
```

### Timezone-Aware Date Processing
```php
if (isset($Programsetting->reportsPlusHours) && !empty($Programsetting->reportsPlusHours)) {
    $reportsPlusHours = $Programsetting->reportsPlusHours + 24;
    $endDate = date('Y-m-d H:i:s', strtotime('+' . $reportsPlusHours . ' hour +0 minutes', strtotime($endDate)));
    $startDate = date('Y-m-d H:i:s', strtotime('+' . $Programsetting->reportsPlusHours . ' hour +0 minutes', strtotime($startDate)));
} else {
    $endDate = $endDate . ' 23:59:59';
    $startDate = $startDate . " 00:00:00";
}
```

---

## 🔒 Security & Permissions

### User Access Control
```php
// Cash register access control
if ($_SESSION['searchinonesave'] == 1) {
    // User restricted to specific cash register
    $saveData = $mySaveRecord->queryByUserid($_SESSION['userid']);
} else {
    // User has access to all cash registers
    $saveData = $mySaveRecord->queryByConditions(0);
}
```

### Input Sanitization
- Cash register IDs validated as integers
- Date strings validated before SQL inclusion
- Process filters sanitized through array checking
- All DAO operations use parameterized queries

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Critical Indexes**:
   - `savedaily(saveid, savedailydate)`
   - `savedaily(savedailychangetype, processname)`
   - `save(userid, conditions)`

2. **Query Optimization**:
   - Date range filtering with proper timezone handling
   - User-based filtering to reduce dataset size
   - Process type filtering for focused reports

3. **Memory Management**:
   - Large date ranges may return thousands of records
   - User privilege filtering reduces memory usage
   - Transaction linking optimized for batch processing

---

## 🐛 Common Issues & Troubleshooting

### 1. **Incorrect Balance Calculations**
**Issue**: Running totals don't match expected values  
**Cause**: Mixed transaction types or timezone issues

**Debug**:
```sql
SELECT 
    SUM(CASE WHEN savedailychangetype = 0 THEN savedailychangeamount ELSE 0 END) as income,
    SUM(CASE WHEN savedailychangetype = 1 THEN savedailychangeamount ELSE 0 END) as expenses
FROM savedaily WHERE saveid = [ID] AND savedailydate BETWEEN '[DATE1]' AND '[DATE2]';
```

### 2. **Missing Transaction Links**
**Issue**: Transaction shows "#" link instead of document link  
**Cause**: `savedailymodelid = -1` or unrecognized `tablename`

### 3. **User Access Issues**
**Issue**: User cannot see expected cash registers  
**Cause**: Session variable `searchinonesave` restrictions

**Fix**: Check user group settings and cash register assignments

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Daily Report
```
1. Select cash register with recent transactions
2. Set today's date range
3. Verify transaction count and totals
4. Check transaction links work properly
```

### Test Case 2: Multi-Register Report
```
1. Select "All Cash Registers" option
2. Set date range covering multiple registers
3. Verify totals are properly segregated
4. Check user access restrictions
```

### Test Case 3: API Integration
```
1. Send CURL request with curlpost=1
2. Verify JSON response format
3. Check data accuracy vs web interface
4. Test error handling for invalid parameters
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [cashflowsController.md](cashflowsController.md) - Cash flow reports
- [saveController.md](saveController.md) - Cash register management
- [Database Schema Documentation](#) - Table relationships

---

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