# Maintenance Receipts Controller Documentation

**File**: `/controllers/maintenancereceipts.php`  
**Purpose**: Manages maintenance receipt processing, policy management, and maintenance procedure tracking  
**Last Updated**: December 20, 2024  
**Total Functions**: 7  
**Lines of Code**: ~310

---

## 📋 Overview

The Maintenance Receipts Controller is the central hub for processing maintenance receipts and managing maintenance policies. It handles the workflow from initial receipt creation to processing individual maintenance items, including cost calculations, procedure assignments, and status transitions. This controller manages the complex business logic of maintenance service operations and integrates with external maintenance companies.

### Primary Functions
- [x] Create and manage maintenance policies (batches)
- [x] Process individual maintenance items within policies
- [x] Assign maintenance procedures and costs
- [x] Calculate shipping and service charges
- [x] Track maintenance progression through case statuses
- [x] Manage external maintenance company relationships
- [x] Handle maintenance policy receipts and dispatching
- [x] Dynamic maintenance item loading and updates

### Related Controllers
- [maintenanceclients.php](maintenanceclients.md) - Client management
- [maintenancedeliverys.php](maintenancedeliverys.md) - Delivery processing
- [maintenanceproducts.php](maintenanceproducts.md) - Product management
- [externalMaintenanceGoReport.php](externalMaintenanceGoReport.md) - Reporting

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **maintenancepolicys** | Maintenance policy/batch records | id, supplierid, maintenancecompanieid, sendorreceipt, bpolicydate, bpolicynumber, bpolicystatement, bshippingvalue |
| **maintenances** | Individual maintenance items | id, maintenancepolicyid, clientid, productid, supplierid, maintenancecaseid, sendorreceipt, maintenanceprocedureid |
| **maintenanceprocedures** | Maintenance procedures catalog | id, procedurename, maintenanceproceduredate, userid, conditions |

### Cost & Status Fields in maintenances
| Field | Purpose | Data Type |
|-------|---------|-----------|
| **bshipprice** | Backward shipping price | DECIMAL |
| **bshipcharge** | Backward shipping charge | DECIMAL |
| **factoringnumber** | Factoring/tracking number | VARCHAR |
| **maintenanceprice** | Service price | DECIMAL |
| **maintenancecost** | Service cost | DECIMAL |
| **statementprocedure** | Procedure statement | TEXT |
| **totalcost** | Total calculated cost | DECIMAL |
| **requiredcustomer** | Amount required from customer | DECIMAL |
| **paidlater** | Amount for later payment | DECIMAL |
| **paidall** | Total amount paid | DECIMAL |
| **residual** | Remaining balance | DECIMAL |

### Reference Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **supplier** | Service suppliers | supplierid, suppliername |
| **maintenancecompanies** | External maintenance companies | id, companyname |
| **client** | Customers | clientid, clientname |
| **product** | Products for maintenance | productId, productName |
| **user** | System users | userid, employeename |

---

## 🔑 Key Functions

### 1. **Default Action (Empty $do)** - Add Receipt Form
**Location**: Lines 18-23  
**Purpose**: Display the maintenance receipt creation form

**Process Flow**:
1. Set username from session
2. Display header template
3. Load `maintenancereceiptview/add.html` template
4. Set maintenance flag to 1
5. Display footer template

**Template**: `maintenancereceiptview/add.html`

---

### 2. **show** - Display Receipt Grid
**Location**: Lines 23-31  
**Purpose**: Show maintenance receipt policies in a data table

**Process Flow**:
1. Include authentication check
2. Load YouTube tutorial links
3. Assign data to template
4. Display `maintenancereceiptview/show.html` template
5. Set maintenance flag to 1

**Security**: Requires authentication

---

### 3. **edit** - Edit Receipt Policy
**Location**: Lines 31-55  
**Purpose**: Display receipt policy editing form with associated maintenance items

**Function Signature**:
```php
$id = filter_input(INPUT_GET, 'id');
$del = filter_input(INPUT_GET, 'del');
```

**Process Flow**:
1. Include authentication check
2. Load maintenance policy data by ID
3. Load associated maintenance items (case > 2)
4. Process product names for display
5. Assign all data to template
6. Display `maintenancereceiptview/edit.html` template

**Complex Product Name Processing**:
```php
$maintenances = R::getAll('SELECT maintenances.* ,suppliername FROM `maintenances` 
    LEFT JOIN supplier ON maintenances.supplierid = supplier.supplierid 
    WHERE maintenances.maintenancecaseid > 2 and maintenances.conditions = 0 and maintenances.maintenancepolicyid = '.$id);
    
foreach($maintenances as $maintenance){
    $products = R::getAll("SELECT productName FROM product WHERE productId in (".$maintenance->productid.")");
    $productName = '';
    foreach($products as $product){
        $productName .= $product['productName']. ' / ';
    }
    $maintenance->productName = $productName;
}
```

---

### 4. **maintenancepolicyget** - AJAX Load Maintenance Items
**Location**: Lines 63-81  
**Purpose**: Dynamically load maintenance items for a specific policy

**Function Signature**:
```php
$maintenancepolicyid = filter_input(INPUT_POST, 'maintenancepolicyid');
```

**Process Flow**:
1. Get policy ID from POST data
2. Query maintenance items with case ID = 2 (under service)
3. Load supplier information via JOIN
4. Process product names for each maintenance item
5. Assign data to template
6. Display `maintenancereceiptview/get.html` template

**Key Filter**: Only loads items with `maintenancecaseid = 2` (under service)

---

### 5. **saveprocedure()** - Save Maintenance Procedure
**Location**: Lines 86-110  
**Purpose**: Create or update maintenance procedure definitions

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

**Input Parameters**:
- `procedurename` - Procedure name/description
- `maintenanceprocedureid` - Procedure ID (for updates)
- `selectitr` - Form iteration selector

**Process Flow**:
1. Get session data (userid, datetime)
2. Filter input parameters
3. **INSERT** (New Procedure):
   ```php
   $maintenanceprocedures = R::dispense('maintenanceprocedures');
   $maintenanceprocedures->maintenanceproceduredate = $today;  
   $maintenanceprocedures->conditions = 0;
   $maintenanceprocedures->userid = $userid;
   ```
4. **UPDATE** (Existing Procedure):
   ```php
   $maintenanceprocedures = R::load('maintenanceprocedures',$maintenanceprocedureid);
   $maintenanceprocedures->euserid = $userid;
   ```
5. Save procedure name and return JSON response

---

### 6. **savedata()** - Process Receipt Policy
**Location**: Lines 112-176  
**Purpose**: Handle receipt policy creation and maintenance item processing

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

**Input Parameters**:
- Policy fields: `policydate`, `policynumber`, `policystatement`, `shippingvalue`
- Company: `maintenancecompanies` (external maintenance company)
- Dynamic maintenance items: `maintenanceid_N`, `bshipprice_N`, `bshipcharge_N`, etc.
- `maintenanceitr` - Number of maintenance items to process

**Process Flow**:
1. Load and update maintenance policy:
   ```php
   $maintenancepolicys = R::load('maintenancepolicys',$maintenancepolicyid);
   $maintenancepolicys->sendorreceipt = 2;  // Set receipt status
   $maintenancepolicys->bmaintenancepolicydate = $today;
   $maintenancepolicys->buserid = $userid;
   ```

2. **Reset all items in policy**:
   ```sql
   UPDATE `maintenances` SET `bshipprice`= ' ', `bshipcharge`= ' ', `sendorreceipt`= 1, maintenancecaseid = 2, maintenancepolicyid = 0 
   WHERE conditions = 0 and maintenancepolicyid = $maintenancepolicyid
   ```

3. **Process each maintenance item**:
   ```php
   for ($i = 1; $i <= $maintenanceitr; $i++) {
       $maintenanceid = filter_input(INPUT_POST, 'maintenanceid_' . $i);
       // Get all item-specific fields
       $bshipprice = filter_input(INPUT_POST, 'bshipprice_' . $i);
       $maintenancecost = filter_input(INPUT_POST, 'maintenancecost_' . $i);
       // ... process each item
   }
   ```

4. **Calculate totals**:
   ```php
   $maintenances->totalcost = $maintenances->bshipcharge + $maintenances->shipcharge + $maintenances->maintenancecost;
   $maintenances->requiredcustomer = $maintenances->totalcost - $maintenances->prepaid;
   $maintenances->residual = $maintenances->totalcost - $maintenances->prepaid;
   ```

5. **Update status**:
   ```php
   $maintenances->maintenancecaseid = 3;  // Completed
   $maintenances->maintenancepolicyid = $maintenancepolicyid;
   ```

---

### 7. **showajax()** - AJAX Data Grid
**Location**: Lines 179-286  
**Purpose**: Server-side DataTables processing for receipt policies

**Filter Parameters**:
- `start_date` / `end_date` - Policy date range
- `del` - Deletion status
- `data1` - Supplier filter
- `data2` - Maintenance company filter
- `data3` - Policy ID filter

**Main Query**:
```sql
SELECT maintenancepolicys.* ,employeename ,suppliername , companyname 
FROM `maintenancepolicys` 
LEFT JOIN user ON maintenancepolicys.buserid = user.userid 
LEFT JOIN supplier ON maintenancepolicys.supplierid = supplier.supplierid
LEFT JOIN maintenancecompanies ON maintenancepolicys.maintenancecompanieid = maintenancecompanies.id  
WHERE 1 [FILTERS]
```

**Action Buttons Based on Status**:
```php
if($row["conditions"] == 0 && $row["sendorreceipt"] == 2){  
    // Active receipt policy
    $sub_array[] = '<a href="maintenancereceipts.php?do=edit&id='. $row["id"] .'&del=0" class="btn btn-default btn-lg editicon"></a>';
    $sub_array[] = '<a href="javascript:;" data-id="'. $row["id"] .'" class="btn btn-default btn-lg deleteicon removeteble"></a>';
}else{
    // Inactive or processed policy
    $sub_array[] = '<a href="maintenancereceipts.php?do=edit&id='. $row["id"] .'&del=1" class="btn btn-default btn-lm">تفاصيل</a>';
    $sub_array[] = '--------';
}
```

---

### 8. **changecondition()** - Update Connection Status
**Location**: Lines 288-310  
**Purpose**: Update maintenance connection conditions

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

**Process**: Updates `maintenanceconects` table and related maintenance policy assignments.

---

## 🔄 Workflows

### Workflow 1: Receipt Policy Creation & Processing
```
┌─────────────────────────────────────────────────────────────┐
│           START: Create Receipt Policy                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Policy Setup                                           │
│     - Set policy date and number                           │
│     - Select external maintenance company                  │
│     - Enter policy statement                               │
│     - Set shipping value                                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Load Maintenance Items                                  │
│     - Query items with caseid = 2 (under service)         │
│     - Load via maintenancepolicyget AJAX                  │
│     - Display items ready for processing                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Individual Items                               │
│     FOR EACH maintenance item:                             │
│       │                                                     │
│       ├─→ Set factoring/tracking number                   │
│       │                                                     │
│       ├─→ Assign maintenance procedure                     │
│       │                                                     │
│       ├─→ Calculate costs:                                 │
│       │   ├─ Backward shipping price                       │
│       │   ├─ Backward shipping charge                      │
│       │   ├─ Maintenance cost                              │
│       │   └─ Total = charges + cost                        │
│       │                                                     │
│       ├─→ Set payment calculations:                        │
│       │   ├─ Required from customer                        │
│       │   ├─ Payment later amount                          │
│       │   └─ Residual balance                              │
│       │                                                     │
│       └─→ Update case status to 3 (completed)             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Finalize Receipt Policy                                │
│     - Set policy sendorreceipt = 2                        │
│     - Update policy dates and user                        │
│     - Link all items to policy                            │
│     - Ready for delivery processing                       │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Maintenance Item Status Progression
```
┌─────────────────────────────────────────────────────────────┐
│        Maintenance Item Lifecycle                          │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│  Case 1: Initial Receipt                                    │
│     - Item received from customer                           │
│     - Basic information recorded                            │
│     - Assigned to maintenance workflow                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Case 2: Under Service                                      │
│     - Item assigned to external company                     │
│     - Maintenance work in progress                          │
│     - Available for receipt processing                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Case 3: Service Completed (THIS CONTROLLER)               │
│     - Maintenance work finished                             │
│     - Costs calculated and assigned                         │
│     - Procedures documented                                 │
│     - Ready for customer delivery                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Case 4: Delivered                                          │
│     - Item returned to customer                             │
│     - Final payments processed                              │
│     - Maintenance cycle complete                            │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default display | Show receipt creation form |
| `do=show` | show action | Display receipt policies grid |
| `do=edit` | edit action | Show receipt policy edit form |
| `do=savedata` | `savedata()` | Process receipt policy and items |
| `do=showajax` | `showajax()` | DataTables AJAX endpoint |
| `do=savecompany` | (not implemented) | Save maintenance company |
| `do=changecondition` | `changecondition()` | Update connection conditions |
| `do=maintenancepolicyget` | AJAX action | Load policy maintenance items |
| `do=saveprocedure` | `saveprocedure()` | Save maintenance procedure |

### Required Parameters by Action

**Receipt Creation** (empty `do`):
- No parameters required

**Show Receipts** (`do=show`):
- Authentication required
- No additional parameters

**Edit Receipt** (`do=edit`):
- `id` - Maintenance policy ID
- `del` - Deletion status flag

**Save Receipt** (`do=savedata`):
- `maintenancepolicys` - Policy ID (required)
- `policydate`, `policynumber`, `policystatement` - Policy details
- `maintenancecompanies` - External company ID
- `shippingvalue` - Shipping value
- `maintenanceitr` - Number of items
- Dynamic fields: `maintenanceid_N`, `bshipprice_N`, `maintenancecost_N`, etc.

**Load Policy Items** (`do=maintenancepolicyget`):
- `maintenancepolicyid` - Policy ID to load items for

**Save Procedure** (`do=saveprocedure`):
- `procedurename` - Procedure name
- `maintenanceprocedureid` - For updates (optional)

---

## 🧮 Calculation Methods

### 1. **Total Cost Calculation**
```php
$maintenances->totalcost = $maintenances->bshipcharge + $maintenances->shipcharge + $maintenances->maintenancecost;
```

### 2. **Customer Payment Calculations**
```php
// Amount required from customer
$maintenances->requiredcustomer = $maintenances->totalcost - $maintenances->prepaid;

// Payment structure
$maintenances->paidlater = 0;  // Reset deferred payment
$maintenances->paidall = $maintenances->paidlater + $maintenances->prepaid;

// Remaining balance
$maintenances->residual = $maintenances->totalcost - $maintenances->prepaid;
```

### 3. **Status Transition Logic**
```php
// Reset all items first
UPDATE `maintenances` SET 
    `sendorreceipt`= 1, 
    maintenancecaseid = 2, 
    maintenancepolicyid = 0 
WHERE conditions = 0 and maintenancepolicyid = $maintenancepolicyid

// Then update processed items
$maintenances->maintenancecaseid = 3;  // Completed
$maintenances->maintenancepolicyid = $maintenancepolicyid;  // Re-assign
```

### 4. **Product Name Concatenation**
```php
$products = R::getAll("SELECT productName FROM product WHERE productId in (".$maintenance->productid.")");
$productName = '';
foreach($products as $product){
    $productName .= $product['productName']. ' / ';
}
$maintenance->productName = $productName;
```

---

## 🔒 Security & Permissions

### Authentication Requirements
- **show** and **edit** actions require authentication
- **savedata**, **showajax**, and other AJAX endpoints should include authentication

### Input Sanitization
```php
// Properly filtered inputs
$policydate = filter_input(INPUT_POST, 'policydate');
$policynumber = filter_input(INPUT_POST, 'policynumber');
$maintenancecost = filter_input(INPUT_POST, 'maintenancecost_' . $i);
```

### SQL Injection Prevention
- Uses RedBeanPHP ORM for most operations
- **POTENTIAL ISSUE**: Complex UPDATE query uses string concatenation

### Business Logic Security
- Status transitions are properly controlled
- Policy items reset before reprocessing prevents data inconsistency

---

## 📊 Performance Considerations

### Database Optimization
1. **Critical Indexes**:
   - `maintenancepolicys(id, sendorreceipt)` - Status filtering
   - `maintenances(maintenancepolicyid)` - Policy relationships
   - `maintenances(maintenancecaseid)` - Status filtering
   - `maintenanceprocedures(id, conditions)` - Procedure lookups

2. **Complex Queries**:
   - Product name concatenation could be optimized
   - Dynamic item processing in loops
   - Multiple JOIN operations in display queries

### Performance Issues
- **N+1 Query Problem**: Product name loading in loops
- **Large Batches**: Processing many maintenance items at once
- **Complex JOINs**: Multiple table relationships in grid display

---

## 🐛 Common Issues & Troubleshooting

### 1. **Cost Calculation Errors**
**Issue**: Total costs don't match component costs  
**Cause**: Missing shipping charges or calculation errors

**Debug**:
```sql
SELECT 
    id,
    bshipcharge,
    shipcharge, 
    maintenancecost,
    totalcost,
    (bshipcharge + shipcharge + maintenancecost) as calculated_total
FROM maintenances 
WHERE maintenancepolicyid = [POLICY_ID];
```

### 2. **Status Transition Problems**
**Issue**: Items stuck in wrong case status  
**Cause**: Incomplete status updates or failed transactions

**Debug**:
```sql
SELECT 
    maintenancecaseid,
    sendorreceipt,
    maintenancepolicyid,
    COUNT(*) as item_count
FROM maintenances 
WHERE maintenancepolicyid = [POLICY_ID]
GROUP BY maintenancecaseid, sendorreceipt;
```

### 3. **Policy Item Loading Issues**
**Issue**: No items appear when loading policy  
**Cause**: Incorrect caseid filtering or policy assignments

**Fix**:
```sql
-- Check items available for policy
SELECT COUNT(*) FROM maintenances 
WHERE maintenancecaseid = 2 
AND conditions = 0 
AND maintenancepolicyid = [POLICY_ID];
```

### 4. **Product Name Display Issues**
**Issue**: Product names not showing correctly  
**Cause**: Invalid productid values or missing products

**Debug**:
```php
// Add validation in product name processing
if (!empty($maintenance->productid)) {
    $products = R::getAll("SELECT productName FROM product WHERE productId in (".$maintenance->productid.")");
    // Check if products found
    if (empty($products)) {
        error_log("No products found for productid: " . $maintenance->productid);
    }
}
```

---

## 🧪 Testing Scenarios

### Test Case 1: Complete Receipt Processing
```
1. Create maintenance policy with items in case 2
2. Load policy edit form and verify items appear
3. Fill in all cost and procedure details
4. Submit policy processing
5. Verify all items transition to case 3
6. Check cost calculations are correct
```

### Test Case 2: Dynamic Item Loading
```
1. Create policy with multiple maintenance items
2. Use maintenancepolicyget AJAX to load items
3. Verify all items display with correct data
4. Test with policies having no items
5. Check product name concatenation works
```

### Test Case 3: Procedure Management
```
1. Create new maintenance procedure
2. Edit existing procedure
3. Assign procedures to maintenance items
4. Verify procedure data saves correctly
5. Test procedure selection in forms
```

### Test Case 4: Grid Functionality
```
1. Create multiple receipt policies
2. Test filtering by supplier, company, dates
3. Verify search functionality across fields
4. Check action buttons based on status
5. Test pagination with large datasets
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [maintenancedeliverys.md](maintenancedeliverys.md) - Next stage (delivery processing)
- [maintenanceclients.md](maintenanceclients.md) - Client management
- [maintenanceproducts.md](maintenanceproducts.md) - Product management
- [Database Schema Documentation](#) - Maintenance workflow tables

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Complex Features**: Policy management, item processing, cost calculations  
**Next Review**: When workflow changes occur