# Production Equation Controller Documentation

**File**: `/controllers/productionEquationController.php`  
**Purpose**: Manages production equations/formulas defining raw material requirements for manufacturing finished products  
**Last Updated**: December 20, 2024  
**Total Functions**: 9  
**Lines of Code**: ~613

---

## 📋 Overview

The Production Equation Controller manages manufacturing formulas that define the precise raw material composition needed to produce finished goods. This is essential for:
- Bill of Materials (BOM) management
- Production cost calculation
- Raw material requirement planning
- Manufacturing recipe definition
- Inventory planning for production

### Primary Functions
- [x] Create production equations with material percentages
- [x] Manage raw material to finished product ratios
- [x] Excel import for bulk equation setup
- [x] Product size/color variant support
- [x] Production rate formula validation (must equal 100%)
- [x] Edit and update existing formulas
- [x] Activate/deactivate production equations
- [x] Delete equation records with cascading rules

### Related Controllers
- [productionRateController.php](productionRateController.md) - Production rates and timing
- [productionOutController.php](productionOutController.md) - Simple manufacturing
- [productionExecutionController.php](#) - Advanced production execution
- [productController.php](#) - Product master data

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **productionrate** | Production equation headers | productionRateId, name, finalName, sizeid, colorid, conditions, thedate, userId |
| **productionrateproduct** | Raw material components | productionRateProductId, productionRateId, productId, sizeid, colorid, quantity, rate, unitId |

### Referenced Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **product** | Product master data | productId, productName, productCatId, productBuyPrice |
| **productcat** | Product categories | productCatId, productCatName |
| **productunit** | Product units and conversions | productunitid, productid, unitname, productnumber |
| **programsettings** | System configuration | programsettingsid, settingkey, settingvalue |
| **youtubelink** | Tutorial links | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **Default Action** - Add Production Equation Form
**Location**: Line 113  
**Purpose**: Display form for creating new production equations

**Function Signature**:
```php
// Triggered when: do=showadd or empty $do
```

**Process Flow**:
1. Check user authentication
2. Load program settings for display
3. Assign template variables
4. Display add form template

**Features**:
- Program settings integration
- Custom production equation flag
- Raw materials data loading (commented)

---

### 2. **add()** - Create Production Equation
**Location**: Line 376  
**Purpose**: Validate and save new production equations with raw material components

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

**Process Flow**:
1. Extract final product information (handle size/color variants)
2. Validate that total percentages equal 100%
3. Create production rate header record
4. Call `addproductionrateproducts()` for components
5. Return percentage total for validation

**Validation Logic**:
```php
$totalpercentage = 0;
for ($i = 1; $i <= $rowitr; $i++) {
    if (isset($_POST["input" . $i . ""]) && !empty($_POST["input" . $i . ""])) {
        $Productionrateproduct->rate = $_POST["input" . $i . ""];
    } else {
        $Productionrateproduct->rate = 0;
    }
    $totalpercentage += $Productionrateproduct->rate;
}

if ($totalpercentage == 100) {
    // Process equation creation
}
```

**Size/Color Handling**:
```php
if (strpos($productId, "hasSizeColor") !== false) {
    $productIdComplex = explode('-', str_replace("hasSizeColor", "", $productId));
    $productId = $productIdComplex[0];
    $sizeId = $productIdComplex[1];
    $colorId = $productIdComplex[2];
}
```

---

### 3. **addproductionrateproducts()** - Add Raw Material Components
**Location**: Line 318  
**Purpose**: Save individual raw material entries for a production equation

**Function Signature**:
```php
function addproductionrateproducts($productionrateid)
```

**Process Flow**:
1. Loop through posted row data
2. Extract product ID (handle size/color encoding)
3. Validate product and unit selections
4. Insert or update production rate product records
5. Handle quantity and percentage data

**Component Validation**:
```php
if (isset($_POST["product" . $i . ""]) && !empty($_POST["product" . $i . ""]) && $_POST["product" . $i . ""] != -1) {
    if (isset($_POST["unitId" . $i . ""]) && !empty($_POST["unitId" . $i . ""]) && $_POST["unitId" . $i . ""] != -1) {
        // Process component
    }
}
```

---

### 4. **edit()** - Edit Production Equation
**Location**: Line 149  
**Purpose**: Load existing equation for modification

**Process Flow**:
1. Load production rate and associated products
2. Build display names with category/size/color info
3. Load product unit data for dropdowns
4. Assign data to edit template
5. Display edit form

**Display Name Building**:
```php
$oldfinalproductname = $product->productName . '/ ' . $productCat->productCatName;
if (!empty($product->sizeName))
    $oldfinalproductname .= '/ ' . $product->sizeName;
if (!empty($product->colorName))
    $oldfinalproductname .= '/ ' . $product->colorName;
```

---

### 5. **update()** - Update Production Equation
**Location**: Line 520  
**Purpose**: Modify existing production equations with validation

**Process Flow**:
1. Re-validate percentage totals
2. Update header record
3. Delete existing component records
4. Re-insert updated components
5. Handle size/color variants

**Update Logic**:
```php
//delete old ones in data base
$ProductionrateproductDAO->deleteByProductionRateId($productionrate->productionRateId);

//insert
addproductionrateproducts($productionrate->productionRateId);
```

---

### 6. **addFromExcel()** - Excel Import
**Location**: Line 428  
**Purpose**: Bulk import production equations from Excel files

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

**Process Flow**:
1. Upload and process Excel file
2. Read worksheet starting from row 4
3. Extract equation name and final product ID
4. Validate product existence by barcode
5. Process up to 6 raw material components per equation
6. Insert valid equations with transaction control

**Excel Format Expected**:
- Column A: Equation name
- Column B: Final product barcode
- Columns C-N: Alternating product ID and quantity (6 products max)

**Validation Logic**:
```php
if (!empty($name) && !empty($finalProductId)) {
    $checkName = $productionrateDAO->queryByName($name);
    $checkFinalProduct = $productDAO->queryByParcode($finalProductId);
    if (count($checkName) == 0 && isset($checkFinalProduct[0]->productId) && $checkFinalProduct[0]->productId > 0) {
        // Process equation
    }
}
```

---

### 7. **details()** - View Equation Details
**Location**: Line 221  
**Purpose**: Display read-only view of production equation

**Process Flow**:
1. Load equation and component data
2. Load product unit information
3. Build display names
4. Assign to details template

---

### 8. **show()** - List All Equations
**Location**: Line 257  
**Purpose**: Display paginated list of production equations

**Features**:
- YouTube tutorial links
- All equations listing
- Action buttons for edit/delete/details

---

### 9. **stop_active()** - Toggle Equation Status
**Location**: Line 587  
**Purpose**: Activate or deactivate production equations

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

**Toggle Logic**:
```php
if ($productionrate->conditions == 0) {
    $productionrate->conditions = 1;
} elseif ($productionrate->conditions == 1) {
    $productionrate->conditions = 0;
}
```

---

### 10. **delete()** - Delete Production Equation
**Location**: Line 603  
**Purpose**: Remove equation and all associated components

**Process Flow**:
1. Delete all component records
2. Delete header record
3. Cascading deletion ensures data integrity

---

## 🔄 Workflows

### Workflow 1: Creating Production Equation
```
┌─────────────────────────────────────────────────────────────┐
│                START: Create Production Equation           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Select Final Product                                    │
│     - Choose manufactured product                           │
│     - Handle size/color variants                            │
│     - Set equation name                                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Define Raw Material Components                         │
│     FOR EACH raw material:                                 │
│       │                                                    │
│       ├─→ Select product                                   │
│       ├─→ Choose unit of measure                           │
│       ├─→ Set quantity required                            │
│       └─→ Set percentage in formula                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Validate Formula                                        │
│     - Check total percentages = 100%                       │
│     - Validate all required fields                         │
│     - Ensure product/unit selections                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Save Production Equation                               │
│     - Insert header record                                  │
│     - Insert component records                             │
│     - Set active status                                     │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Excel Import Process
```
┌─────────────────────────────────────────────────────────────┐
│              START: Excel Import                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Upload Excel File                                       │
│     - Validate file format                                  │
│     - Read worksheet data                                   │
│     - Start from row 4                                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Process Each Row                                        │
│     FOR EACH row in Excel:                                  │
│       │                                                     │
│       ├─→ Extract equation name                             │
│       ├─→ Lookup final product by barcode                  │
│       ├─→ Validate equation name uniqueness                │
│       └─→ Process up to 6 raw materials                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Import Valid Equations                                  │
│     - Insert equation header                                │
│     - Insert raw material components                        │
│     - Use transaction control                               │
│     - Skip invalid/duplicate entries                        │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|-----------------|-------------|
| `do=` (empty) or `do=showadd` | Default action | Display add equation form |
| `do=add` | `add()` | Create new production equation |
| `do=edit&id={id}` | Edit display | Load equation for modification |
| `do=update` | `update()` | Update existing equation |
| `do=details&id={id}` | Details view | Display equation components |
| `do=show` | `show()` | List all production equations |
| `do=stop&id={id}` | `stop_active()` | Toggle equation active status |
| `do=delete&id={id}` | `delete()` | Delete equation and components |
| `do=addexcel` | Excel form | Show Excel upload form |
| `do=addfromexcel` | `addFromExcel()` | Process Excel import |

### Required Parameters by Action

**Add Equation** (`do=add`):
- `name` - Equation name
- `finalProductId` - Final product (may include hasSizeColor encoding)
- `rowitr` - Number of raw material rows
- `product{i}` - Raw material product IDs
- `unitId{i}` - Unit of measure IDs
- `inputt{i}` - Quantities required
- `input{i}` - Percentage rates

**Excel Import** (`do=addfromexcel`):
- `pEquationSheet` - Uploaded Excel file

---

## 🧮 Calculation Methods

### Percentage Validation
```php
$totalpercentage = 0;
for ($i = 1; $i <= $rowitr; $i++) {
    if (isset($_POST["input" . $i . ""]) && !empty($_POST["input" . $i . ""])) {
        $Productionrateproduct->rate = $_POST["input" . $i . ""];
    } else {
        $Productionrateproduct->rate = 0;
    }
    $totalpercentage += $Productionrateproduct->rate;
}

// Must equal 100%
if ($totalpercentage == 100) {
    // Proceed with equation creation
}
```

### Size/Color Variant Parsing
```php
if (strpos($productId, "hasSizeColor") !== false) {
    $productIdComplex = explode('-', str_replace("hasSizeColor", "", $productId));
    $productId = $productIdComplex[0];
    $sizeId = $productIdComplex[1];
    $colorId = $productIdComplex[2];
}
```

---

## 🔒 Security & Permissions

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

### Input Validation
- Percentage totals must equal 100%
- Product IDs validated against database
- Unit IDs must be valid for selected products
- Excel import validates product existence by barcode
- Duplicate equation names prevented

### Transaction Control (Excel Import)
```php
$mytransactions = new Transaction();
try {
    // Import operations
    $mytransactions->commit();
} catch (Exception $e) {
    $mytransactions->rollback();
}
```

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Indexes Required**:
   - `productionrate(finalName, sizeid, colorid)`
   - `productionrateproduct(productionRateId)`
   - `productionrateproduct(productId)`

2. **Query Optimization**:
   - Batch deletion for updates
   - Efficient Excel processing with validation
   - Product lookup optimization

### Memory Management
- Large Excel files processed row by row
- Component arrays built incrementally
- Transaction control prevents partial imports

---

## 🐛 Common Issues & Troubleshooting

### 1. **Percentage Validation Errors**
**Issue**: "لابد ان يكون مجموع النسب يساوى 100" (Total percentages must equal 100%)  
**Cause**: Raw material percentages don't sum to exactly 100%

**Debug**:
```php
// Check percentage calculation
$totalpercentage = 0;
for ($i = 1; $i <= $rowitr; $i++) {
    echo "Row $i: " . $_POST["input" . $i . ""] . "<br>";
    $totalpercentage += (float)$_POST["input" . $i . ""];
}
echo "Total: $totalpercentage";
```

### 2. **Excel Import Failures**
**Issue**: Excel equations not importing correctly  
**Cause**: Format mismatch or invalid product barcodes

**Debug**:
```sql
-- Check product existence by barcode
SELECT productId, productName FROM product WHERE productParcode = 'BARCODE123';

-- Check equation name uniqueness
SELECT COUNT(*) FROM productionrate WHERE name = 'EQUATION_NAME';
```

### 3. **Size/Color Variant Issues**
**Issue**: Products with variants not saving correctly  
**Cause**: Incorrect hasSizeColor encoding

**Fix**:
```php
// Proper encoding format: "hasSizeColor{productId}-{sizeId}-{colorId}"
if (strpos($productId, "hasSizeColor") !== false) {
    $productIdComplex = explode('-', str_replace("hasSizeColor", "", $productId));
    if (count($productIdComplex) == 3) {
        $productId = $productIdComplex[0];
        $sizeId = $productIdComplex[1]; 
        $colorId = $productIdComplex[2];
    }
}
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Equation Creation
```
1. Create equation with 3 raw materials
2. Set percentages: 60%, 30%, 10%
3. Verify total equals 100%
4. Save and verify database records
5. Check equation appears in listing
```

### Test Case 2: Excel Import Validation
```
1. Prepare Excel file with valid equations
2. Include duplicate names (should skip)
3. Include invalid product barcodes (should skip)
4. Import and verify only valid equations created
5. Check transaction rollback on errors
```

### Test Case 3: Size/Color Variant Handling
```
1. Create equation for product with size/color variants
2. Verify hasSizeColor encoding works
3. Check edit form loads variants correctly
4. Update equation and verify variants preserved
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [productionRateController.md](productionRateController.md) - Production timing rates
- [productionOutController.md](productionOutController.md) - Simple manufacturing
- [productController.md](#) - Product master data

---

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