# Production Rate Controller Documentation

**File**: `/controllers/productionRateController.php`  
**Purpose**: Manages production rate formulas defining percentage-based raw material requirements for manufacturing  
**Last Updated**: December 20, 2024  
**Total Functions**: 8  
**Lines of Code**: ~467

---

## 📋 Overview

The Production Rate Controller manages percentage-based manufacturing formulas that define the exact proportional requirements of raw materials needed to produce finished goods. Unlike the Production Equation Controller which uses fixed quantities, this controller focuses on:
- Percentage-based material allocation (must total 100%)
- Production rate formulas for manufacturing
- Raw material ratio management
- Manufacturing recipe percentage validation
- Size/color variant support in formulas
- Production planning based on rates

### Primary Functions
- [x] Create production rate formulas with percentage allocations
- [x] Validate that material percentages sum to exactly 100%
- [x] Manage raw material to finished product ratios
- [x] Product size/color variant support in formulas
- [x] Edit and update existing rate formulas
- [x] Activate/deactivate production rate formulas
- [x] Delete rate records with cascading rules
- [x] Production rate listing and management

### Related Controllers
- [productionEquationController.php](productionEquationController.md) - Fixed quantity equations
- [productionOutController.php](productionOutController.md) - Simple manufacturing
- [productionExecutionController.php](#) - Production execution
- [productController.php](#) - Product master data

---

## 🗄️ Database Tables

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

### Referenced Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **product** | Product master data | productId, productName, productCatId |
| **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 Rate Form
**Location**: Line 108  
**Purpose**: Display form for creating new production rate formulas

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

**Process Flow**:
1. Check user authentication
2. Load program settings for display
3. Set production rate template flag
4. Display add form template

**Features**:
- Program settings integration
- Custom production rate flag
- Simple form interface for percentage-based formulas

---

### 2. **add()** - Create Production Rate Formula
**Location**: Line 330  
**Purpose**: Validate percentage totals and save new production rate formulas

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

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

**Percentage 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 rate formula creation
    $productionrateid = $productionrateDAO->insert($productionrate);
    addproductionrateproducts($productionrateid);
}

return $totalpercentage;
```

**Size/Color Variant 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 272  
**Purpose**: Save individual raw material percentage entries for a production rate formula

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

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

**Component Processing Logic**:
```php
for ($i = 1; $i <= $rowitr; $i++) {
    if (strlen($_POST["input" . $i . ""]) <= 0) {
        // Skip empty percentage entries
    } else {
        if (isset($_POST["product" . $i . ""]) && $_POST["product" . $i . ""] != -1) {
            if (isset($_POST["unitId" . $i . ""]) && !empty($_POST["unitId" . $i . ""])) {
                // Process valid component
                $Productionrateproduct->rate = $_POST["input" . $i . ""];
                $Productionrateproduct->quantity = $_POST["inputt" . $i . ""] ?? 0;
                
                if (isset($productionRateProductId) && $productionRateProductId > 0) {
                    $ProductionrateproductEX->insertwithid($Productionrateproduct);
                } else {
                    $ProductionrateproductDAO->insert($Productionrateproduct);
                }
            }
        }
    }
}
```

---

### 4. **edit()** - Edit Production Rate Formula
**Location**: Line 143  
**Purpose**: Load existing rate formula for modification

**Process Flow**:
1. Load production rate and associated product components
2. Build display names with category/size/color information
3. Load product unit data for each component
4. Handle size/color variant display encoding
5. Assign data to edit template

**Product Unit Loading**:
```php
$i = 1;
foreach ($Productionrateproduct as $p) {
    $productUnitData = $productUnitExt->queryWithProductId($p->productId);
    $smarty->assign("productUnitData" . $i, $productUnitData);
    
    $product = $productExt->loadSizeColor($p->productId, $p->sizeid, $p->colorid);
    $productCat = $productCatDAO->load($product->productCatId);
    $p->productName = $product->productName . '/' . $productCat->productCatName;
    
    if (!is_null($product->sizeName) && !empty($product->sizeName) && 
        !is_null($product->colorName) && !empty($product->colorName)) {
        $p->productId = "hasSizeColor" . $product->productId . "-" . $product->sizeid . "-" . $product->colorid;
        $p->productName .= '/' . $product->sizeName . '/' . $product->colorName;
    }
    $i++;
}
```

**Final Product Display**:
```php
$product = $productExt->loadSizeColor($productionrate->finalName, $productionrate->sizeid, $productionrate->colorid);
$productCat = $productCatDAO->load($product->productCatId);
$product->productName = $product->productName . '/' . $productCat->productCatName;

if (!is_null($product->sizeName) && !empty($product->sizeName) && 
    !is_null($product->colorName) && !empty($product->colorName)) {
    $productionrate->finalName = "hasSizeColor" . $product->productId . "-" . $product->sizeid . "-" . $product->colorid;
    $product->productName .= '/' . $product->sizeName . '/' . $product->colorName;
}
```

---

### 5. **update()** - Update Production Rate Formula
**Location**: Line 209  
**Purpose**: Modify existing production rate formulas with percentage validation

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

**Process Flow**:
1. Re-validate percentage totals (must equal 100%)
2. Update header record with new data
3. Delete existing component records
4. Re-insert updated components
5. Handle size/color variants

**Update Process**:
```php
// Re-validate percentages
$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) {
    // Update header
    $productionrateDAO->update($productionrate);
    
    // Delete and recreate components
    $ProductionrateproductDAO->deleteByProductionRateId($productionrate->productionRateId);
    addproductionrateproducts($productionrate->productionRateId);
}
```

---

### 6. **show()** - List All Production Rates
**Location**: Line 227  
**Purpose**: Display list of all production rate formulas

**Process Flow**:
1. Load all production rate records
2. Assign to template for display
3. Display listing template

**Simple listing functionality without filtering or search capabilities.**

---

### 7. **stop_active()** - Toggle Rate Formula Status
**Location**: Line 441  
**Purpose**: Activate or deactivate production rate formulas

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

**Toggle Logic**:
```php
$id = $_GET["id"];
$productionrate = $productionrateDAO->load($id);

if ($productionrate->conditions == 0) {
    $productionrate->conditions = 1; // Deactivate
} elseif ($productionrate->conditions == 1) {
    $productionrate->conditions = 0; // Activate
}
$productionrateDAO->update($productionrate);
```

---

### 8. **delete()** - Delete Production Rate Formula
**Location**: Line 457  
**Purpose**: Remove rate formula and all associated components

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

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

**Deletion Logic**:
```php
$id = $_GET["id"];
print_r($id); // Debug output
$ProductionrateproductDAO->deleteByProductionRateId($id);
$productionrateDAO->delete($id);
```

---

## 🔄 Workflows

### Workflow 1: Creating Percentage-Based Production Rate
```
┌─────────────────────────────────────────────────────────────┐
│            START: Create Production Rate Formula           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Define Final Product                                   │
│     - Select manufactured product                           │
│     - Handle size/color variants                            │
│     - Set formula name                                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Define Raw Material Percentages                       │
│     FOR EACH raw material component:                       │
│       │                                                     │
│       ├─→ Select raw material product                      │
│       ├─→ Choose unit of measure                           │
│       ├─→ Set optional quantity                            │
│       └─→ Set percentage in formula                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Validate Percentage Totals                            │
│     - Sum all component percentages                        │
│     - Check total equals exactly 100%                      │
│     - Reject if not equal to 100%                         │
│     - Display error message if invalid                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Save Production Rate Formula                           │
│     IF total == 100%:                                      │
│       │                                                     │
│       ├─→ Insert header record                             │
│       ├─→ Insert component records                         │
│       └─→ Set active status                                │
│     ELSE:                                                   │
│       └─→ Display error and return to form                 │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Editing Production Rate Formula
```
┌─────────────────────────────────────────────────────────────┐
│              START: Edit Production Rate                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Existing Formula                                  │
│     - Load rate header record                               │
│     - Load all component records                           │
│     - Load product unit data                               │
│     - Build display names                                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Present Edit Form                                      │
│     - Pre-populate final product                           │
│     - Show existing components with percentages            │
│     - Allow modification of all fields                     │
│     - Display current percentage totals                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Updates                                        │
│     - Re-validate percentage totals                        │
│     - Update header record                                 │
│     - Delete existing components                           │
│     - Insert updated components                            │
│     - Handle variant encoding                              │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|-----------------|-------------|
| `do=` (empty) or `do=showadd` | Default action | Display add rate formula form |
| `do=add` | `add()` | Create new production rate formula |
| `do=edit&id={id}` | Edit display | Load rate formula for modification |
| `do=update` | `update()` | Update existing rate formula |
| `do=show` | `show()` | List all production rate formulas |
| `do=stop&id={id}` | `stop_active()` | Toggle rate formula active status |
| `do=delete&id={id}` | `delete()` | Delete rate formula and components |

### Required Parameters by Action

**Add Rate Formula** (`do=add`):
- `name` - Formula name
- `finalProductId` - Final product (may include hasSizeColor encoding)
- `rowitr` - Number of raw material components
- `product{i}` - Raw material product IDs
- `unitId{i}` - Unit of measure IDs
- `inputt{i}` - Optional quantities
- `input{i}` - Percentage rates (must sum to 100%)

**Update Formula** (`do=update`):
- `productionrateid` - ID of formula to update
- Same parameters as add operation

---

## 🧮 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;
}

// Validation: Must equal exactly 100%
if ($totalpercentage == 100) {
    // Proceed with formula creation/update
} else {
    // Display error: "لابد ان يكون مجموع النسب يساوى 100"
    // (Total percentages must equal 100)
}
```

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

// Display name building
$product = $productExt->loadSizeColor($productId, $sizeId, $colorId);
$productCat = $productCatDAO->load($product->productCatId);
$displayName = $product->productName . '/' . $productCat->productCatName;

if (!is_null($product->sizeName) && !empty($product->sizeName) && 
    !is_null($product->colorName) && !empty($product->colorName)) {
    $displayName .= '/' . $product->sizeName . '/' . $product->colorName;
}
```

---

## 🔒 Security & Permissions

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

### Input Validation
- Percentage validation (must equal 100%)
- Product IDs validated against database
- Unit IDs must be valid for selected products
- Numeric values properly cast and validated
- Required field validation

### Data Integrity
- Cascading deletion for components
- Percentage total enforcement
- Product-unit relationship validation
- Size/color variant consistency

---

## 📊 Performance Considerations

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

2. **Query Optimization**:
   - Batch deletion for updates
   - Efficient product/unit data loading
   - Minimal database round trips

### Memory Management
- Component arrays processed incrementally
- Product unit data loaded per component
- Proper variable cleanup

---

## 🐛 Common Issues & Troubleshooting

### 1. **Percentage Validation Errors**
**Issue**: Error message "لابد ان يكون مجموع النسب يساوى 100" appears  
**Cause**: Component percentages don't sum to exactly 100%

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

// Exact match check
if ($totalpercentage == 100) {
    echo "Valid total";
} else {
    echo "Invalid total - must be exactly 100%";
}
```

### 2. **Size/Color Variant Issues**
**Issue**: Products with variants not displaying correctly in edit form  
**Cause**: Incorrect hasSizeColor encoding or null checks

**Fix**:
```php
// Proper null checking
if (!is_null($product->sizeName) && !empty($product->sizeName) && 
    !is_null($product->colorName) && !empty($product->colorName)) {
    $productId = "hasSizeColor" . $product->productId . "-" . $product->sizeid . "-" . $product->colorid;
    $displayName .= '/' . $product->sizeName . '/' . $product->colorName;
}
```

### 3. **Component Update Issues**
**Issue**: Components not updating correctly  
**Cause**: Delete-and-recreate pattern not working properly

**Debug**:
```sql
-- Check component deletion
SELECT COUNT(*) FROM productionrateproduct WHERE productionRateId = {id};

-- Verify re-insertion
SELECT * FROM productionrateproduct WHERE productionRateId = {id} ORDER BY productionRateProductId;
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Rate Formula Creation
```
1. Create rate formula with 3 components:
   - Material A: 60%
   - Material B: 30%
   - Material C: 10%
2. Verify total equals 100%
3. Save and check database records
4. Verify formula appears in listing
```

### Test Case 2: Percentage Validation
```
1. Create formula with invalid percentages:
   - Material A: 60%
   - Material B: 30%
   - Material C: 5%
2. Verify error message appears
3. Adjust to valid percentages (60%, 30%, 10%)
4. Verify successful save
```

### Test Case 3: Size/Color Variant Formula
```
1. Create formula for "Red Large Shirt"
2. Add components with variants
3. Verify hasSizeColor encoding
4. Edit formula and verify variants preserved
5. Check display names include variant info
```

### Test Case 4: Edit and Update Operations
```
1. Create rate formula
2. Edit with different percentages
3. Verify update process:
   - Old components deleted
   - New components inserted
   - Percentage validation applied
   - Header record updated
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [productionEquationController.md](productionEquationController.md) - Fixed quantity equations  
- [productionOutController.md](productionOutController.md) - Simple manufacturing
- [productController.md](#) - Product master data

---

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