# Spare Part Controller Documentation

**File**: `/controllers/sparePartController.php`  
**Purpose**: Manages spare parts inventory with quantity tracking and audit reporting  
**Last Updated**: December 21, 2024  
**Total Functions**: 9  
**Lines of Code**: ~442

---

## 📋 Overview

The Spare Part Controller is an inventory management module specifically designed for spare parts operations. It provides comprehensive functionality for:
- Spare part creation and management
- Quantity tracking and stock control
- Store detail management with location tracking
- Audit reporting for all inventory changes
- Bulk operations for efficiency
- Soft delete functionality with recovery options
- Pagination for large inventories
- User tracking and audit trails

### Primary Functions
- [x] Create spare parts with initial stock quantities
- [x] Edit spare part details and adjust quantities
- [x] Soft delete/restore spare parts (conditions-based)
- [x] Permanent deletion with validation
- [x] Bulk operations (hide/show/delete multiple items)
- [x] Inventory audit reporting
- [x] Paginated display for performance
- [x] Store detail integration

### Related Controllers
- [storeController.php](#) - Main inventory management
- [inventoryController.php](#) - General inventory operations
- [productController.php](#) - Product management
- [auditController.php](#) - System audit trails

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **sparepart** | Spare part master data | sparepartid, sparepartname, sparepartprice, sparepartnotes, conditions, userid, sparepartdate |
| **sparepartstoredetail** | Inventory quantities by store | sparepartstoredetailid, sparepartid, sparepartstoreId, partquantity, sparepartstoredetaildate, userid |
| **sparepartstorereport** | Audit trail for all changes | sparepartstorereportid, sparepartid, partbefore, partafter, partquantity, processname, storereporttype, tablename, storereportdate |

### Supporting Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **sparepartstore** | Store locations | sparepartstoreId, storename |

---

## 🔑 Key Functions

### 1. **Default Action** - Add Form Display
**Location**: Line 78  
**Purpose**: Display spare part creation form

**Process Flow**:
1. Include authentication check
2. Display spare part add form template

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

---

### 2. **add()** - Create New Spare Part
**Location**: Line 175  
**Purpose**: Create spare part with initial inventory and audit tracking

**Function Signature**:
```php
function add() {
    global $sparePart, $sparePartDAO;
    global $sparePartDetail, $sparePartDetailDAO;
    global $sparePartReport, $sparePartReportDAO;
}
```

**Process Flow**:
1. Extract POST data for spare part details
2. Create spare part master record
3. Insert initial store detail quantity record
4. Create audit report entry for the addition
5. Link all records through spare part ID

**Master Record Creation**:
```php
$sparePart->conditions = 0;                    // Active
$sparePart->sparepartdate = date("Y-m-d");
$sparePart->sparepartname = $sparepartname;
$sparePart->sparepartnotes = $sparepartnotes;
$sparePart->sparepartprice = $sparepartprice;
$sparePart->userid = $_SESSION["userid"];

$sparepartid = $sparePartDAO->insert($sparePart);
```

**Initial Quantity Setup**:
```php
$sparePartDetail->partquantity = $partquantity;
$sparePartDetail->sparepartid = $sparepartid;
$sparePartDetail->sparepartstoredetaildate = date("Y-m-d");
$sparePartDetail->sparepartstoreId = 1;        // Default store
$sparePartDetail->userid = $_SESSION["userid"];
```

**Audit Trail Creation**:
```php
$sparePartReport->partafter = $partquantity;
$sparePartReport->partbefore = 0;
$sparePartReport->partquantity = $partquantity;
$sparePartReport->processname = "إضافة قطع غيار";   // Arabic: "Add spare parts"
$sparePartReport->storereporttype = 0;            // Addition type
$sparePartReport->tablename = "sparePartController.php";
```

---

### 3. **show()** - Display Spare Parts with Pagination
**Location**: Line 226  
**Purpose**: Show paginated spare parts listing with quantity details

**Function Signature**:
```php
function show() {
    global $sparePartExt, $sparePartDetailDAO, $sparePartDetailExt;
    global $smarty;
}
```

**Process Flow**:
1. Initialize SmartyPaginate for performance
2. Set pagination limit (25 items per page)
3. Query total count for pagination calculation
4. Query limited results for current page
5. Assign data and pagination controls to template

**Pagination Implementation**:
```php
$paginate = new SmartyPaginate;
$paginate->connect();
$paginate->setLimit(25);                           // 25 items per page

$allColums = $sparePartExt->queryAllExt();        // Get total count
$paginate->setTotal(count($allColums));

$sparePartsData = $sparePartExt->queryAllExtLimited(
    $paginate->getCurrentIndex(), 
    $paginate->getLimit()
);
```

---

### 4. **update()** - Edit Spare Part with Quantity Tracking
**Location**: Line 328  
**Purpose**: Update spare part details and track quantity changes

**Function Signature**:
```php
function update() {
    global $sparePart, $sparePartDAO;
    global $sparePartDetail, $sparePartDetailDAO, $sparePartDetailExt;
    global $sparePartReport, $sparePartReportDAO;
}
```

**Process Flow**:
1. Update spare part master record
2. Find and update existing store detail record
3. Calculate quantity difference (increase/decrease)
4. Create audit report for the change
5. Track before/after values for compliance

**Quantity Change Tracking**:
```php
$h_partquantity = $_POST['h_partquantity'];    // Original quantity
$partquantity = $_POST['partquantity'];        // New quantity

if ($h_partquantity > $partquantity) {
    $sparePartReport->storereporttype = 1;      // Decrease
    $sparePartReport->partquantity = $h_partquantity - $partquantity;
} else {
    $sparePartReport->storereporttype = 0;      // Increase  
    $sparePartReport->partquantity = $partquantity - $h_partquantity;
}

$sparePartReport->partafter = $partquantity;
$sparePartReport->partbefore = $h_partquantity;
$sparePartReport->processname = "تعديل قطع غيار";  // Arabic: "Edit spare parts"
```

---

### 5. **deletetemp()** - Soft Delete Spare Part
**Location**: Line 268  
**Purpose**: Temporarily hide spare part from active use (soft delete)

**Function Signature**:
```php
function deletetemp($sparePartId) {
    global $sparePart, $sparePartExt;
}
```

**Process Flow**:
1. Set conditions flag to 1 (hidden)
2. Update system date and user tracking
3. Use extended DAO for conditions update
4. Return success/error status

**Soft Delete Logic**:
```php
$sparePart->conditions = 1;                    // Mark as deleted
$sparePart->sparepartdate = date("Y-m-d");
$sparePart->userid = $_SESSION["userid"];
$sparePart->sparepartid = $sparePartId;

$sparePartExt->updateConditions($sparePart);
```

---

### 6. **returndelete()** - Restore Soft Deleted Item
**Location**: Line 293  
**Purpose**: Restore previously hidden spare part to active status

**Function Signature**:
```php
function returndelete($sparePartId) {
    global $sparePart, $sparePartExt;
}
```

**Process Flow**:
1. Set conditions flag to 0 (active)
2. Update system metadata
3. Restore item to visible state

**Restore Logic**:
```php
$sparePart->conditions = 0;                    // Mark as active
$sparePart->sparepartdate = date("Y-m-d");
$sparePart->userid = $_SESSION["userid"];
$sparePart->sparepartid = $sparePartId;

$sparePartExt->updateConditions($sparePart);
```

---

### 7. **executeOperation()** - Bulk Operations Handler
**Location**: Line 394  
**Purpose**: Perform bulk operations on multiple selected spare parts

**Function Signature**:
```php
function executeOperation() {
    global $sparePartDAO, $smarty;
}
```

**Process Flow**:
1. Get operation type from POST (1=hide, 2=show, 3=delete)
2. Process array of selected spare part IDs
3. Execute appropriate operation for each item
4. Collect and display operation results
5. Handle error reporting for failed operations

**Operation Types**:
```php
$operationType = $_POST['operation'];
$choosedItemArr = $_POST['choosedItem'];

foreach ($choosedItemArr as $sparePartId) {
    if ($operationType == '1') {
        $note = deletetemp($sparePartId);        // Hide
    } elseif ($operationType == "2") {
        $note = returndelete($sparePartId);      // Show
    } elseif ($operationType == "3") {
        $note = delete($sparePartId);            // Permanent delete
    }
}
```

---

## 🔄 Workflows

### Workflow 1: Spare Part Creation Process
```
┌─────────────────────────────────────────────────────────────┐
│              START: Create New Spare Part                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Add Form                                        │
│     - Load spare part creation template                     │
│     - Set up form fields (name, price, quantity, notes)    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Process Form Submission                                 │
│     - Extract spare part details                            │
│     - Validate required fields                              │
│     - Prepare for database insertion                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Execute add() Function                                  │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ A. Create Master Record                             │ │
│     │    - Insert into sparepart table                   │ │
│     │    - Get new spare part ID                          │ │
│     └─────────────────────────────────────────────────────┘ │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ B. Create Store Detail                             │ │
│     │    - Insert initial quantity                       │ │
│     │    - Link to default store (ID=1)                  │ │
│     └─────────────────────────────────────────────────────┘ │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ C. Create Audit Entry                              │ │
│     │    - Record addition in report table               │ │
│     │    - Track user and timestamp                      │ │
│     └─────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Handle Success/Error                                    │
│     - Redirect to success page on completion               │
│     - Show error page if exception occurs                  │
└─────────────────────────────────────────────────────────────┘
```

### Workflow 2: Bulk Operations Process
```
┌─────────────────────────────────────────────────────────────┐
│               START: Bulk Operations                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Display Spare Parts Listing                            │
│     - Show paginated list with checkboxes                  │
│     - Provide operation selection (Hide/Show/Delete)       │
│     - Enable multi-select functionality                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. User Selects Items and Operation                       │
│     - Check multiple spare parts                           │
│     - Choose operation type (1/2/3)                        │
│     - Submit bulk operation request                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Execute executeOperation() Function                     │
│     FOR EACH selected spare part:                          │
│     ┌─────────────────┬───────────────┬─────────────────┐   │
│     │   Operation 1   │  Operation 2   │  Operation 3    │   │
│     │  (Hide/Temp     │   (Show/       │  (Permanent     │   │
│     │   Delete)       │    Restore)    │   Delete)       │   │
│     │                 │                │                 │   │
│     │ ┌─────────────┐ │ ┌────────────┐ │ ┌─────────────┐ │   │
│     │ │deletetemp() │ │ │returndelete│ │ │delete()     │ │   │
│     │ │conditions=1 │ │ │conditions=0│ │ │Hard delete  │ │   │
│     │ └─────────────┘ │ └────────────┘ │ └─────────────┘ │   │
│     └─────────────────┴───────────────┴─────────────────┘   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Collect and Display Results                             │
│     - Show success/error for each item                     │
│     - Display updated spare parts listing                   │
│     - Provide operation summary                             │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default | Display spare part creation form |
| `do=add` | `add()` | Process new spare part creation |
| `do=show` | `show()` | Display paginated spare parts listing |
| `do=edit` | `edit()` | Display spare part edit form |
| `do=update` | `update()` | Process spare part modifications |
| `do=delete` | `delete()` | Permanently delete spare part |
| `do=deletetemp` | `deletetemp()` | Soft delete (hide) spare part |
| `do=returndelete` | `returndelete()` | Restore soft deleted spare part |
| `do=executeOperation` | `executeOperation()` | Perform bulk operations |
| `do=sucess` | Success page | Display operation success message |
| `do=error` | Error page | Display operation error message |

### Required Parameters by Action

**Add Spare Part** (`do=add`):
- `sparepartname` - Part name/description
- `sparepartprice` - Unit price
- `partquantity` - Initial quantity
- `sparepartnotes` - Optional notes

**Edit Spare Part** (`do=edit`):
- `id` - Spare part ID to edit

**Update Spare Part** (`do=update`):
- `sparepartid` - Part ID
- `sparepartname` - Updated name
- `sparepartprice` - Updated price  
- `partquantity` - New quantity
- `sparepartnotes` - Updated notes
- `delete` - Conditions flag
- `h_partquantity` - Original quantity (for audit)

**Bulk Operations** (`do=executeOperation`):
- `operation` - Operation type (1=hide, 2=show, 3=delete)
- `choosedItem[]` - Array of selected spare part IDs

---

## 🧮 Calculation Methods

### Quantity Change Tracking
```php
// Determine if quantity increased or decreased
$h_partquantity = $_POST['h_partquantity'];    // Original
$partquantity = $_POST['partquantity'];        // New

if ($h_partquantity > $partquantity) {
    $sparePartReport->storereporttype = 1;      // Decrease
    $sparePartReport->partquantity = $h_partquantity - $partquantity;
} else {
    $sparePartReport->storereporttype = 0;      // Increase
    $sparePartReport->partquantity = $partquantity - $h_partquantity;
}
```

### Pagination Mathematics
```php
$paginate = new SmartyPaginate;
$paginate->setLimit(25);                       // Items per page
$allColums = $sparePartExt->queryAllExt();     // Total items
$paginate->setTotal(count($allColums));

// Current page items
$sparePartsData = $sparePartExt->queryAllExtLimited(
    $paginate->getCurrentIndex(),               // Offset
    $paginate->getLimit()                      // Limit
);
```

### Audit Trail Calculations
```php
// Initial addition audit
$sparePartReport->partafter = $partquantity;   // Final quantity
$sparePartReport->partbefore = 0;              // No previous stock
$sparePartReport->partquantity = $partquantity; // Change amount

// Update audit
$sparePartReport->partafter = $partquantity;
$sparePartReport->partbefore = $h_partquantity;
$sparePartReport->partquantity = abs($partquantity - $h_partquantity);
```

---

## 🔒 Security & Permissions

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

### Input Sanitization
```php
// Direct POST access - relies on framework-level sanitization
$sparepartname = $_POST['sparepartname'];
$sparepartprice = $_POST['sparepartprice'];
$partquantity = $_POST['partquantity'];

// ID validation for operations
$sparepartid = $_GET['id'];  // Should be validated as integer
```

### Access Control
- No role-based permissions implemented
- All authenticated users have full access
- Audit trail maintains accountability

### Data Integrity
```php
// Soft delete preserves data
$sparePart->conditions = 1;  // Hide instead of delete

// Audit trail for all changes
$sparePartReport->userid = $_SESSION['userid'];
$sparePartReport->storereportdate = date("Y-m-d");
```

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Indexes Required**:
   - `sparepart(conditions)` for active/deleted filtering
   - `sparepartstoredetail(sparepartid)` for quantity lookups
   - `sparepartstorereport(sparepartid, storereportdate)` for audit queries
   - `sparepart(userid)` for user-based filtering

2. **Pagination Benefits**:
   - Limits result set to 25 items per page
   - Reduces memory usage for large inventories
   - Improves page load times

3. **Query Optimization**:
   - Extended DAOs handle complex joins
   - Efficient pagination implementation
   - Audit queries can be archived for performance

### Known Performance Issues
```php
// Bulk operations process items sequentially
foreach ($choosedItemArr as $sparePartId) {
    // Individual database operations for each item
    // Could be optimized with batch operations
}

// No bulk delete/update capabilities
// Consider implementing batch SQL for large operations
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **Quantity Synchronization Issues**
**Issue**: Store detail quantities don't match audit totals  
**Cause**: Failed updates or missing audit entries

**Debug**:
```sql
-- Verify quantity consistency
SELECT 
    sp.sparepartname,
    sd.partquantity as current_quantity,
    SUM(CASE WHEN sr.storereporttype = 0 THEN sr.partquantity ELSE -sr.partquantity END) as audit_total
FROM sparepart sp
JOIN sparepartstoredetail sd ON sp.sparepartid = sd.sparepartid  
LEFT JOIN sparepartstorereport sr ON sp.sparepartid = sr.sparepartid
GROUP BY sp.sparepartid
HAVING current_quantity != audit_total;
```

### 2. **Pagination Navigation Issues**
**Issue**: Page navigation not working properly  
**Cause**: SmartyPaginate configuration or URL parameter issues

**Fix**:
```php
// Ensure proper pagination URL setup
$paginate->setUrl('sparePartController.php?do=show&');

// Check if pagination variables are assigned
$paginate->assign($smarty);
```

### 3. **Bulk Operation Failures**
**Issue**: Some items in bulk operations fail silently  
**Cause**: Exception handling masks individual failures

**Enhancement**:
```php
// Improve error reporting in executeOperation()
foreach ($choosedItemArr as $sparePartId) {
    try {
        $note = deletetemp($sparePartId);
        if ($note != "success") {
            $outputString .= $sparepartname . ": " . $note . "<br/>";
        }
    } catch (Exception $e) {
        $outputString .= $sparepartname . ": Exception - " . $e->getMessage() . "<br/>";
    }
}
```

### 4. **Soft Delete Recovery**
**Issue**: No interface to view and recover soft-deleted items  
**Cause**: Show function only displays active items (conditions = 0)

**Solution**:
```php
// Add view for soft-deleted items
$deletedItems = $sizeColorDAO->queryByConditions(1);  // conditions = 1
// Provide restore interface
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Spare Part Creation
```
1. Access spare part add form
2. Fill name: "Oil Filter XYZ"
3. Set price: 15.50
4. Set initial quantity: 100
5. Add notes: "Compatible with Model ABC"
6. Submit and verify database records
7. Check audit trail entry
```

### Test Case 2: Quantity Update with Audit
```
1. Edit existing spare part
2. Change quantity from 100 to 85 (decrease)
3. Verify audit record shows:
   - partbefore: 100
   - partafter: 85  
   - partquantity: 15
   - storereporttype: 1 (decrease)
```

### Test Case 3: Bulk Operations
```
1. Create 5 test spare parts
2. Select 3 items for bulk hide operation
3. Verify all selected items marked with conditions = 1
4. Test bulk restore operation
5. Confirm items return to active status
```

### Test Case 4: Pagination Performance
```
1. Create 100+ spare parts
2. Verify pagination shows 25 items per page
3. Test page navigation functionality
4. Check total count accuracy
5. Verify query performance with large datasets
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [Store Management](#) - Main inventory system
- [Audit Trail System](#) - System-wide audit functionality
- [DAO Pattern](#) - Database access layer documentation

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When inventory management requirements change