# Stage Controller Documentation

**File**: `/controllers/stageController.php`  
**Purpose**: Manages production stages/workflows with operation sequencing and timing  
**Last Updated**: December 21, 2024  
**Total Functions**: 6  
**Lines of Code**: ~421

---

## 📋 Overview

The Stage Controller is a production management module designed for manufacturing workflow control. It manages production stages that define sequences of operations required to manufacture products. The system handles:
- Multi-step production stage creation
- Operation sequencing and timing
- Product-specific workflow definitions
- Stage validation and dependency checking
- Soft delete functionality with recovery
- Operation step management
- Total production time calculations
- User audit tracking

This controller is essential for:
- Manufacturing planning and scheduling
- Production workflow standardization
- Time estimation for production processes
- Quality control checkpoints
- Resource planning and allocation

### Primary Functions
- [x] Create production stages with operation sequences
- [x] Manage stage steps and operation ordering
- [x] Edit existing stages and modify operations
- [x] Soft delete/restore stages with validation
- [x] Permanent deletion with dependency checking
- [x] Calculate total production hours
- [x] Operation sequence management
- [x] Product association tracking

### Related Controllers
- [productController.php](#) - Product management
- [settingoperationController.php](#) - Operation definitions
- [productionController.php](#) - Production scheduling
- [qualityController.php](#) - Quality control

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **stage** | Production stage definitions | stageId, stagename, productId, totalhour, conditions, date, userid |
| **stagestep** | Operation sequences within stages | stagestepId, stageId, operationId, stepno |
| **settingoperation** | Available operations | settingoperationId, operationname, realTime |
| **product** | Products requiring production stages | productid, productname |

### Supporting Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **youtubelink** | Tutorial video links | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **Default Action** - Add Stage Form
**Location**: Line 109  
**Purpose**: Display stage creation form with product and operation data

**Process Flow**:
1. Include authentication check
2. Load all products for selection dropdown
3. Load all available operations for stage building
4. Display stage creation template

**Data Loading**:
```php
$allproduct = loadproduct();      // Available products
$alloperation = loadopration();   // Available operations
$smarty->assign("allproduct", $allproduct);
$smarty->assign("alloperation", $alloperation);
```

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

---

### 2. **add()** - Create New Production Stage
**Location**: Line 239  
**Purpose**: Create production stage with multiple operation steps

**Function Signature**:
```php
function add() {
    global $StagestepDAO, $Stagestep;
    global $StageDAO, $Stage;
}
```

**Process Flow**:
1. Extract stage details from POST data
2. Create stage master record
3. Process dynamic operation sequence from form
4. Insert each operation step with sequence numbers
5. Calculate total production hours

**Stage Creation**:
```php
$Stage->conditions = 0;                    // Active status
$Stage->date = date("Y-m-d");
$Stage->userid = $_SESSION['userid'];
$Stage->productId = $productid;
$Stage->stagename = $stagename;
$Stage->totalhour = $stagehour;

$stageno = $StageDAO->insert($Stage);      // Returns new stage ID
```

**Dynamic Operation Processing**:
```php
$operationitr = $_POST["operationitr"];    // Number of operations

for ($h = 1; $h <= $operationitr; $h++) {
    $operationname = $_POST['oprationname' . $h . ''];
    $no = $_POST['no' . $h . ''];          // Step sequence number
    
    if (isset($operationname) && $operationname != -1) {
        $Stagestep->operationId = $operationname;
        $Stagestep->stageId = $stageno;
        $Stagestep->stepno = $no;
        
        $StagestepDAO->insert($Stagestep);
    }
}
```

---

### 3. **show** - Display Stages with Operation Counts
**Location**: Line 116  
**Purpose**: Show all stages with operation count summaries

**Process Flow**:
1. Load YouTube tutorial links
2. Query all stages from database
3. For each stage, count associated operations
4. Assign enhanced stage data to template

**Operation Count Enhancement**:
```php
$allstage = $StageDAO->queryAll();
foreach ($allstage as $newstage) {
    $totaloperation = $StagestepDAO->queryByStageId($newstage->stageId);
    $newstage->countoperation = count($totaloperation);  // Add operation count
}
$smarty->assign("allstage", $allstage);
```

**Template**: `stageview/show.html`

---

### 4. **update()** - Edit Existing Stage
**Location**: Line 278  
**Purpose**: Update stage details and reorganize operation sequence

**Process Flow**:
1. Update stage master record with new details
2. Delete all existing stage steps for clean rebuild
3. Process new operation sequence from form
4. Re-insert operations with updated sequence
5. Handle both new and existing step IDs

**Stage Update**:
```php
$Stage->conditions = 0;
$Stage->date = date("Y-m-d");
$Stage->userid = $_SESSION['userid'];
$Stage->productId = $productid;
$Stage->stagename = $stagename;
$Stage->totalhour = $stagehour;
$Stage->stageId = $stageid;

$StageDAO->update($Stage);
```

**Operation Sequence Rebuild**:
```php
$StagestepDAO->deleteByStageId($stageid);  // Clean slate

$operationitr = $_POST["operationitr"];
for ($h = 1; $h <= $operationitr; $h++) {
    $operationname = $_POST['oprationname' . $h . ''];
    $no = $_POST['no' . $h . ''];
    $stagestepid = $_POST['stagestep' . $h . ''];    // Existing step ID
    
    if (!empty($operationname) && $operationname != '-1' && !empty($no)) {
        $Stagestep->operationId = $operationname;
        $Stagestep->stageId = $stageid;
        $Stagestep->stepno = $no;
        $Stagestep->stagestepId = $stagestepid;
        
        if (isset($stagestepid) && $stagestepid > 0) {
            $StagestepEX->insertwithid($Stagestep);    // Preserve ID
        } else {
            $StagestepDAO->insert($Stagestep);         // New step
        }
    }
}
```

---

### 5. **delete()** - Permanent Deletion with Validation
**Location**: Line 389  
**Purpose**: Permanently delete stage after dependency validation

**Function Signature**:
```php
function delete($stageId) {
    global $StagestepDAO, $StageDAO, $StageEX;
}
```

**Process Flow**:
1. Check for associated operations/dependencies
2. If no dependencies exist, allow deletion
3. If dependencies found, prevent deletion
4. Return status code for UI handling

**Dependency Validation**:
```php
$alloperation = $StagestepDAO->queryByStageId($stageId);
if (count($alloperation) <= 0) {
    $operationdeleteValid = 0;          // Safe to delete
    $StageDAO->delete($stageId);
    $note = "success";
} else {
    $operationdeleteValid = 1;          // Has dependencies
    $note = "لا يمكن حذف هذه المرحله";    // Arabic: Cannot delete this stage
}

return array($note, $operationdeleteValid);
```

---

### 6. **Soft Delete Functions** - Hide/Restore Operations
**Locations**: Lines 331, 360  
**Purpose**: Temporarily hide stages without losing data

**deletetemp() - Hide Stage**:
```php
function deletetemp($stageId) {
    global $Stage, $StageEX;
    
    $Stage->conditions = 1;             // Mark as hidden
    $Stage->date = date("Y-m-d");
    $Stage->userid = $_SESSION["userid"];
    $Stage->stageId = $stageId;
    
    $StageEX->updateConditions($Stage);
}
```

**returndelete() - Restore Stage**:
```php
function returndelete($stageId) {
    global $Stage, $StageEX;
    
    $Stage->conditions = 0;             // Mark as active
    $Stage->date = date("Y-m-d");
    $Stage->userid = $_SESSION["userid"];
    $Stage->stageId = $stageId;
    
    $StageEX->updateConditions($Stage);
}
```

---

## 🔄 Workflows

### Workflow 1: Production Stage Creation
```
┌─────────────────────────────────────────────────────────────┐
│              START: Create Production Stage                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Stage Creation Form                             │
│     - Load available products                               │
│     - Load available operations                             │
│     - Set up dynamic operation sequence builder             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Configure Stage Details                                 │
│     - Select target product                                 │
│     - Enter stage name/description                          │
│     - Add operations in sequence                            │
│     - Set step numbers for ordering                         │
│     - Calculate total production hours                      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Execute add() Function                                  │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ A. Create Stage Master Record                       │ │
│     │    - Insert into stage table                        │ │
│     │    - Get new stage ID                               │ │
│     │    - Set metadata (user, date)                      │ │
│     └─────────────────────────────────────────────────────┘ │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ B. Process Operation Sequence                       │ │
│     │    - Loop through dynamic form fields               │ │
│     │    - Validate operation selections                  │ │
│     │    - Insert each step with sequence number          │ │
│     └─────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Validate and Finalize                                  │
│     - Verify all operations added successfully             │
│     - Calculate total stage time                            │
│     - Redirect to success page                             │
└─────────────────────────────────────────────────────────────┘
```

### Workflow 2: Stage Update and Operation Management
```
┌─────────────────────────────────────────────────────────────┐
│               START: Edit Production Stage                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Existing Stage Data                               │
│     - Query stage master record                             │
│     - Load current operation sequence                       │
│     - Calculate operation counts and times                  │
│     - Populate edit form with existing data                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Modify Stage Configuration                              │
│     - Update stage name/product association                 │
│     - Add/remove/reorder operations                         │
│     - Adjust step sequence numbers                          │
│     - Recalculate production timing                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Execute update() Function                               │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ A. Update Master Record                             │ │
│     │    - Modify stage table entry                       │ │
│     │    - Update metadata fields                         │ │
│     └─────────────────────────────────────────────────────┘ │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ B. Rebuild Operation Sequence                       │ │
│     │    - Delete all existing steps                      │ │
│     │    - Process new operation configuration            │ │
│     │    - Re-insert steps with new sequence              │ │
│     │    - Preserve step IDs where possible               │ │
│     └─────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Validate Changes and Update Display                    │
│     - Verify operation sequence integrity                   │
│     - Update stage listing with new data                    │
│     - Display success confirmation                          │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default | Display stage creation form |
| `do=add` | `add()` | Process new stage creation |
| `do=show` | Display listing | Show all stages with operation counts |
| `do=edit` | Edit form | Display stage edit form with existing data |
| `do=update` | `update()` | Process stage modifications |
| `do=delete` | `delete()` | Permanently delete stage (with validation) |
| `do=deletetemp` | `deletetemp()` | Soft delete (hide) stage |
| `do=returndelete` | `returndelete()` | Restore soft deleted stage |
| `do=sucess` | Success page | Display operation success message |
| `do=error` | Error page | Display operation error message |

### Required Parameters by Action

**Add Stage** (`do=add`):
- `setoperation` - Stage name/description
- `productname` - Product ID association
- `totaloperationhour1` - Total production hours
- `operationitr` - Number of operations in sequence
- `oprationname{N}` - Operation ID for step N
- `no{N}` - Step sequence number for operation N

**Edit Stage** (`do=edit`):
- `stageId` - Stage ID to edit
- `operationid` - Product ID (in POST)

**Update Stage** (`do=update`):
- `stageid` - Stage ID
- `setoperation` - Updated stage name
- `productname` - Updated product ID
- `totaloperationhour1` - Updated total hours
- `operationitr` - Number of operations
- `oprationname{N}` - Operation ID for step N
- `no{N}` - Step sequence number
- `stagestep{N}` - Existing step ID (for updates)

**Delete Stage** (`do=delete`, `do=deletetemp`, `do=returndelete`):
- `stageId` - Stage ID to delete/modify

---

## 🧮 Calculation Methods

### Operation Count Calculation
```php
// Count operations per stage for display
foreach ($allstage as $newstage) {
    $totaloperation = $StagestepDAO->queryByStageId($newstage->stageId);
    $newstage->countoperation = count($totaloperation);
}
```

### Dynamic Form Processing
```php
// Process variable number of operations
$operationitr = $_POST["operationitr"];    // Total operations to process

for ($h = 1; $h <= $operationitr; $h++) {
    $operationname = $_POST['oprationname' . $h . ''];   // Dynamic field name
    $no = $_POST['no' . $h . ''];                        // Step sequence
    
    if (isset($operationname) && $operationname != -1) {
        // Process this operation step
    }
}
```

### Total Hour Calculation
```php
// Stage total hours (from form input)
$stagehour = $_POST['totaloperationhour1'];
$Stage->totalhour = $stagehour;

// Individual operation times loaded from settingoperation table
$steprow = $SettingoperationEX->loadByopertaionid($new->operationId);
$new->newstage = $steprow->realTime;  // Individual operation time
```

### Dependency Validation
```php
// Check if stage can be safely deleted
$alloperation = $StagestepDAO->queryByStageId($stageId);
if (count($alloperation) <= 0) {
    $operationdeleteValid = 0;      // No dependencies
    $StageDAO->delete($stageId);    // Safe to delete
} else {
    $operationdeleteValid = 1;      // Has dependencies
    // Prevent deletion
}
```

---

## 🔒 Security & Permissions

### Authentication Requirements
- All actions require authentication via `include_once("../public/authentication.php")`
- Session-based user validation
- User ID tracking for all modifications

### Input Validation
```php
// Direct POST access - framework-level sanitization expected
$stagename = $_POST['setoperation'];
$productid = $_POST['productname'];
$stagehour = $_POST['totaloperationhour1'];

// Dynamic field processing with loop validation
for ($h = 1; $h <= $operationitr; $h++) {
    if (isset($operationname) && $operationname != -1) {
        // Only process valid operations
    }
}
```

### Data Integrity
```php
// Audit trail with user tracking
$Stage->userid = $_SESSION['userid'];
$Stage->date = date("Y-m-d");

// Soft delete preserves data
$Stage->conditions = 1;  // Hide instead of hard delete

// Dependency checking prevents data corruption
if (count($alloperation) <= 0) {
    // Safe to delete
} else {
    // Prevent deletion
}
```

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Indexes Required**:
   - `stage(productId)` for product-based filtering
   - `stage(conditions)` for active/deleted filtering
   - `stagestep(stageId)` for operation lookups
   - `stagestep(operationId)` for reverse lookups
   - `stage(userid)` for user-based queries

2. **Query Optimization**:
   - Operation counts calculated at display time
   - Efficient DAO-based operations
   - Minimal recursive queries

3. **Update Strategy**:
   - Delete/rebuild approach for operation sequences
   - May be inefficient for large operation lists
   - Consider differential update for production systems

### Known Performance Issues
```php
// Delete/rebuild approach in update()
$StagestepDAO->deleteByStageId($stageid);  // Delete all steps
// Then rebuild all steps - inefficient for minor changes

// Operation count queries in loop
foreach ($allstage as $newstage) {
    $totaloperation = $StagestepDAO->queryByStageId($newstage->stageId);
    // Separate query for each stage - N+1 problem
}
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **Operation Sequence Inconsistencies**
**Issue**: Step numbers don't reflect actual sequence  
**Cause**: Manual step numbering without validation

**Debug**:
```sql
-- Check for duplicate step numbers
SELECT stageId, stepno, COUNT(*) 
FROM stagestep 
GROUP BY stageId, stepno 
HAVING COUNT(*) > 1;

-- Check for gaps in sequence
SELECT stageId, stepno FROM stagestep 
WHERE stageId = ? ORDER BY stepno;
```

### 2. **Edit Form Data Loading Issues**
**Issue**: Existing operations not loading in edit form  
**Cause**: Complex data preparation for dynamic forms

**Debug**:
```php
// Verify stage step loading
$stagerow = $StagestepDAO->queryByStageId($stageId);
foreach ($stagerow as $new) {
    echo "Step: " . $new->stepno . " Operation: " . $new->operationId . "<br>";
}
```

### 3. **Dynamic Form Processing Failures**
**Issue**: Some operations not saving during add/update  
**Cause**: JavaScript form generation vs PHP processing mismatch

**Fix**:
```php
// Debug dynamic form processing
$operationitr = $_POST["operationitr"];
echo "Processing $operationitr operations:<br>";

for ($h = 1; $h <= $operationitr; $h++) {
    $operationname = $_POST['oprationname' . $h . ''];
    echo "Operation $h: $operationname<br>";
    
    if (!isset($operationname) || $operationname == -1) {
        echo "Skipping invalid operation $h<br>";
    }
}
```

### 4. **Delete Validation Logic**
**Issue**: Deletion prevention not working correctly  
**Cause**: Complex dependency checking logic

**Enhancement**:
```php
// Improve delete validation
function canDeleteStage($stageId) {
    global $StagestepDAO;
    
    $dependencies = array();
    
    // Check stage steps
    $steps = $StagestepDAO->queryByStageId($stageId);
    if (count($steps) > 0) {
        $dependencies[] = "Has " . count($steps) . " operation steps";
    }
    
    // Check production schedules, work orders, etc.
    // Add other dependency checks here
    
    return $dependencies;
}
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Stage Creation
```
1. Access stage creation form
2. Select product "Widget ABC"
3. Enter stage name "Assembly Process"
4. Add 3 operations in sequence:
   - Step 1: Preparation (10 min)
   - Step 2: Assembly (30 min) 
   - Step 3: Quality Check (15 min)
5. Set total hours to 55 minutes
6. Submit and verify database records
```

### Test Case 2: Complex Stage Update
```
1. Edit existing 3-operation stage
2. Remove middle operation
3. Add new operation at end
4. Reorder remaining operations
5. Verify sequence integrity
6. Check operation count updates
```

### Test Case 3: Delete Validation
```
1. Create stage with operations
2. Attempt permanent deletion
3. Verify prevention due to dependencies
4. Test soft delete functionality
5. Verify restore capability
6. Remove all operations, then test permanent delete
```

### Test Case 4: Dynamic Form Processing
```
1. Create stage with maximum operations (test limits)
2. Use JavaScript to add/remove operations dynamically
3. Verify form submission handles variable operation count
4. Test with gaps in operation sequence
5. Validate step numbering consistency
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [Production Management](#) - Overall production system
- [Operation Management](#) - Individual operation definitions
- [Product Management](#) - Product-stage associations

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When production workflow requirements change