# Restaurant Raw Destruction Controller Documentation

**File**: `/controllers/restaurantRawDestruction.php`  
**Purpose**: Manages inventory destruction/wastage for restaurant raw materials with financial tracking  
**Last Updated**: December 21, 2024  
**Total Functions**: 7  
**Lines of Code**: ~668

---

## 📋 Overview

The Restaurant Raw Destruction Controller is a specialized inventory management module that handles destruction/wastage of raw materials in restaurant operations. It provides comprehensive tracking and financial reporting for inventory write-offs with integrated accounting features. The controller handles:

- Raw material destruction/wastage tracking
- Multi-store inventory destruction management  
- Automatic inventory quantity adjustments
- Financial impact calculation with multiple pricing strategies
- Daily entry (accounting) integration for cost tracking
- Store report generation for audit trails
- Size/color variant support for complex products
- User permission and store access control
- Operation numbering for batch tracking

### Primary Functions
- [x] Record inventory destruction/wastage operations
- [x] Update product quantities across stores
- [x] Calculate financial impact using multiple pricing strategies
- [x] Generate accounting entries for destroyed inventory
- [x] Track destruction operations with unique operation numbers
- [x] Support size/color product variants
- [x] Multi-store destruction management
- [x] Comprehensive audit trail generation

### Related Controllers
- [inventoryController.php](#) - General inventory management
- [storedetailController.php](#) - Store inventory details
- [dailyentryController.php](#) - Accounting entries
- [storereportController.php](#) - Inventory reports

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **restaurantrawdestruction** | Destruction records | restaurantrawdestructionid, storeid, productid, quantity, operationNum, sysdate |
| **storedetail** | Store inventory | storedetailid, productid, storeid, productquantity |
| **storereport** | Inventory audit trail | storereportid, productid, storeid, productquantity, processname, tablename |

### Product Management Tables  
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **product** | Product master data | productId, productName, productCatId, lastbuyprice, meanbuyprice |
| **productcat** | Product categories | productCatId, productCatName, productCatParent |
| **sizecolorstoredetail** | Size/color variants | sizeid, colorid, productid, storeid, quantity |

### Configuration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **store** | Store master data | storeId, storeName, treeId |
| **programsettings** | System configuration | programsettingsid, Inventoryevaluation, dailyEntryCostprice |
| **user** | User management | userid, employeename, usergroupid |
| **usergroup** | User permissions | usergroupid, groupname |

### Accounting Integration
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **accountstree** | Chart of accounts | id, name, parent |
| **dailyentry** | Journal entries | dailyentryid, entryComment, dDateTime |

---

## 🔑 Key Functions

### 1. **Default Action** - Destruction Interface
**Location**: Line 163  
**Purpose**: Display the raw material destruction interface with store selection and permissions

**Process Flow**:
1. Check user authentication
2. Load store data based on user permissions:
   - If `searchinonestore = 0`: Show multiple stores based on user access
   - If `searchinonestore = 1`: Show only user's assigned store
3. Apply store filtering based on user's `storeids` session
4. Display destruction interface template
5. Set up custom validation flags

**Permission Logic**:
```php
if ($_SESSION['searchinonestore'] == 0) {
    if ($_SESSION['storeids'] == 0) {
        $stores = $myStoreEx->queryByConditions();
    } else {
        $stores = $myStoreEx->queryByConditions(' and store.storeId in (' . $_SESSION['storeids'] . ')');
    }
} else {
    $storedef = $myStoreEx->queryByConditionsOne(' and store.storeId = ' . $_SESSION['storeid'] . ' ');
}
```

---

### 2. **show** - Display Destruction Reports
**Location**: Line 202  
**Purpose**: Generate and display destruction reports with filtering options

**Function Signature**:
```php
// Triggered by: do=show
$storeId = $_POST['storeId'];
$from = $_POST['from'];
$to = $_POST['to']; 
$showopnum = (int) $_POST['showopnum'];
```

**Process Flow**:
1. Parse request parameters for filtering
2. Load store data with user permissions
3. Call `getShowData()` with filters
4. Display results via show template
5. Support operation number grouping option

---

### 3. **add()** - Record Destruction Operations
**Location**: Line 434  
**Purpose**: Process multiple product destructions in a single operation with financial tracking

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

**Process Flow**:
1. Parse operation details (iteration count, estate information)
2. Generate unique operation number if not exists
3. For each product in the destruction:
   - Extract product details (handle size/color variants)
   - Validate and update inventory quantities
   - Create store report entries
   - Record destruction in `restaurantrawdestruction` table
   - Generate daily accounting entries
4. Return operation number for printing/reference

**Key Variables**:
- `$itr` - Number of products being destroyed
- `$operationNum` - Unique operation identifier
- `$decreaseQty` - Quantity being destroyed
- `$oldQty` - Previous inventory quantity
- `$actualQty` - New inventory quantity after destruction

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

**Inventory Update Logic**:
```php
$storeDetail = $storeDetailExt->getProductQuantity($productId, $storeid);
$oldQty = $storeDetail->productquantity;
$actualQty = $oldQty - $decreaseQty;

$storeDetail->productquantity = $actualQty;
$storeDetail->userid = $_SESSION['userid'];
$storeDetail->storeid = $storeid;
$storeDetail->storedetaildate = $today;
$storeDetailExt->updateProductquantity($storeDetail);
```

---

### 4. **getShowData()** - Report Data Generator
**Location**: Line 346  
**Purpose**: Generate comprehensive destruction report data with financial calculations

**Function Signature**:
```php
function getShowData($storeId, $from, $to, $showopnum, $operationNum)
```

**Process Flow**:
1. Build dynamic query string based on filters
2. Apply user store permissions
3. Execute query with grouping options
4. For each destruction record:
   - Load product information
   - Calculate destruction cost using configured pricing strategy
   - Format display data
5. Return formatted array for template display

**Pricing Strategy Logic**:
```php
switch ($Programsetting->Inventoryevaluation) {
    case "first":
        $buyprice = (float) $restVal->productBuyPrice;
        break;
    case "last":
        $buyprice = (float) $restVal->lastbuyprice;
        break;
    case "mean":
    case "generalPrice":
        $buyprice = (float) $restVal->meanbuyprice;
        break;
    case "last_discount":
        $buyprice = (float) $restVal->lastbuyprice_withDiscount;
        break;
    case "mean_discount":
        $buyprice = (float) $restVal->meanbuyprice_withDiscount;
        break;
    case "tax":
        $buyprice = (float) $restVal->lastbuyprice_withTax;
        break;
    case "mean_tax":
        $buyprice = (float) $restVal->meanbuyprice_withTax;
        break;
}
```

---

### 5. **getProductInStore()** - Product Information Retriever  
**Location**: Line 573  
**Purpose**: Retrieve detailed product information for destruction records

**Function Signature**:
```php
function getProductInStore($storeId, $productid, $sizeId, $colorId)
```

**Process Flow**:
1. Build query for specific product in store
2. Load product details via `querGroupProducts()`
3. Build category path for product display
4. Handle size/color variant information
5. Return enriched product data

**Category Path Building**:
```php
$parentId = $pro->productCatId;
$pathArr = fetch_recursive($parentId, $categories);
$pro->productName = $pro->productName . '/' . $pathArr;
```

**Size/Color Enhancement**:
```php
$sizeColor = $productExt->loadSizeColor($productid, $sizeId, $colorId);
if (!is_null($sizeColor->sizeName) && !empty($sizeColor->sizeName)) {
    $pro->productName .= '/' . $sizeColor->sizeName;
}
if (!is_null($sizeColor->colorName) && !empty($sizeColor->colorName)) {
    $pro->productName .= '/' . $sizeColor->colorName;
}
```

---

### 6. **doInventoryDailyEntry()** - Accounting Integration
**Location**: Line 605  
**Purpose**: Create automated accounting entries for inventory destruction costs

**Function Signature**:
```php
function doInventoryDailyEntry($storeId, $productId, $quantity, $newQty, $storeReport)
```

**Process Flow**:
1. Load store and product information
2. Determine cost price based on system configuration
3. Calculate total destruction cost
4. Create journal entry:
   - Debit: Raw Materials Wastage Account (Account 189)
   - Credit: Store Inventory Account (Store's Tree ID)
5. Link entry to store report for audit trail

**Cost Price Strategy**:
```php
switch ($dailyEntryCostprice) {
    case "first":
        $priceColName = 'productBuyPrice';
        break;
    case "last":
        $priceColName = 'lastbuyprice';
        break;
    case "mean":
        $priceColName = 'meanbuyprice';
        break;
    case "last_discount":
        $priceColName = 'lastbuyprice_withDiscount';
        break;
    // ... additional strategies
}
```

**Journal Entry Creation**:
```php
$dailyEntry->entryComment = 'تالف مواد تشغيل للمنتج : ' . $productName . 
                           ' فى مخزن : ' . $store['storeName'] . 
                           ' بالكمية : ' . $quantity;

// Debit: Wastage Account
$dailyEntryDebtor->accountstreeid = 189;
$dailyEntryDebtor->value = $productCost;

// Credit: Store Account  
$dailyEntryCreditor->accountstreeid = $store['treeId'];
$dailyEntryCreditor->value = $productCost;
```

---

### 7. **Supporting Functions** - Utility Operations
**Additional Functions**:

**getProductCatsForShow()** - Category hierarchy loading
**fetch_recursive()** - Recursive category path building  
**getStores()** - Store data loading

---

## 🔄 Workflows

### Workflow 1: Destruction Operation Processing
```
┌─────────────────────────────────────────────────────────────┐
│            START: Raw Material Destruction Request         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Parse Operation Parameters                              │
│     - Get iteration count for multiple products            │
│     - Extract estate/unit information                      │
│     - Initialize operation number                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Generate Unique Operation Number                        │
│     IF operationNum not provided:                           │
│       │                                                     │
│       ├─→ Get maximum existing operation number             │
│       └─→ Increment by 1 for new operation                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Each Product Destruction                        │
│     FOR i = 1 to iteration count:                          │
│       │                                                     │
│       ├─→ Extract product details from form                │
│       │   ├─ Product ID (handle size/color variants)       │
│       │   ├─ Destruction quantity                          │
│       │   ├─ Store details                                 │
│       │   └─ Notes                                          │
│       │                                                     │
│       ├─→ Validate inventory availability                  │
│       │   ├─ Get current product quantity                  │
│       │   └─ Ensure sufficient stock exists                │
│       │                                                     │
│       ├─→ Update Inventory Quantities                      │
│       │   ├─ Decrease main storedetail quantity            │
│       │   └─ Update size/color variants if applicable      │
│       │                                                     │
│       ├─→ Create Store Report Entry                        │
│       │   ├─ Record quantity before/after                  │
│       │   ├─ Link to operation and source table            │
│       │   └─ Set process name and dates                    │
│       │                                                     │
│       ├─→ Record Destruction Entry                         │
│       │   ├─ Store all pricing information                 │
│       │   ├─ Set operation number and dates                │
│       │   └─ Include size/color and notes                  │
│       │                                                     │
│       └─→ Generate Daily Accounting Entry                  │
│           ├─ Calculate destruction cost                    │
│           ├─ Create debit/credit entries                   │
│           └─ Link to store report for audit               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Return Operation Number                                 │
│     - Return operation number for printing/reference       │
│     - Handle any transaction rollback on errors            │
└─────────────────────────────────────────────────────────────┘
```

### Workflow 2: Report Generation
```
┌─────────────────────────────────────────────────────────────┐
│              START: Destruction Report Request             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Build Query Filters                                     │
│     - Apply store filter based on permissions              │
│     - Add date range filter if specified                   │
│     - Add operation number filter if specified             │
│     - Set grouping options for summary vs detail           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Execute Query and Load Data                             │
│     - Query restaurantrawdestruction with filters          │
│     - Apply grouping or detail sorting                     │
│     - Load related product and store information           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Calculate Financial Impact                              │
│     FOR EACH destruction record:                            │
│       │                                                     │
│       ├─→ Determine pricing strategy from settings         │
│       ├─→ Get appropriate cost price for product           │
│       ├─→ Calculate total destruction cost                 │
│       └─→ Format for display                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Return Formatted Report Data                           │
│     - Include all product and store information            │
│     - Add calculated costs and totals                      │
│     - Format dates and user information                    │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display destruction interface |
| `do=show` | Show reports | Generate destruction reports |
| `do=add` | `add()` | Process destruction operations |
| `do=printoperation` | Print view | Display operation for printing |
| `do=details` | Detail view | Show individual operation details |

### Required Parameters by Action

**Show Reports** (`do=show`):
- `storeId` - Store filter (via POST)
- `from` - Start date filter (YYYY-MM-DD, via POST)
- `to` - End date filter (YYYY-MM-DD, via POST)
- `showopnum` - Show operation numbers flag (via POST)

**Add Destruction** (`do=add`):
- `itr` - Number of products being destroyed (via POST)
- `storeId_hidden` - Target store ID (via POST)
- `product{N}` - Product ID for item N (via POST)
- `newQty{N}` - Destruction quantity for item N (via POST)
- `oldQty{N}` - Previous quantity for item N (via POST)
- `note{N}` - Notes for item N (via POST)
- `realestateid` - Estate ID (via POST)
- `realestateunitid` - Estate unit ID (via POST)

**Print Operation** (`do=printoperation`):
- `num` - Operation number to print (via GET)

**Operation Details** (`do=details`):
- `id` - Store report ID for details (via GET)

---

## 🧮 Calculation Methods

### Destruction Cost Calculation

**Multi-Strategy Pricing**:
```php
switch ($Programsetting->Inventoryevaluation) {
    case "first":      $cost = $product->productBuyPrice; break;
    case "last":       $cost = $product->lastbuyprice; break;
    case "mean":       $cost = $product->meanbuyprice; break;
    case "generalPrice": $cost = $product->meanbuyprice; break;
    case "last_discount": $cost = $product->lastbuyprice_withDiscount; break;
    case "mean_discount": $cost = $product->meanbuyprice_withDiscount; break;
    case "tax":        $cost = $product->lastbuyprice_withTax; break;
    case "mean_tax":   $cost = $product->meanbuyprice_withTax; break;
}
```

**Total Destruction Cost**:
```php
$totalCost = $unitCost * $destructionQuantity;
```

### Inventory Quantity Updates

**Main Inventory Update**:
```php
$currentQuantity = $storeDetail->productquantity;
$newQuantity = $currentQuantity - $destructionQuantity;
$storeDetail->productquantity = $newQuantity;
```

**Size/Color Variant Update**:
```php
if ($sizeId > 0 && $colorId > 0) {
    $sizecolorstoredetail = $sizeColorStoreDetailDAO->load($sizeColorStoreDetailId);
    $currentVariantQty = $sizecolorstoredetail->quantity;
    $newVariantQty = $currentVariantQty - $destructionQuantity;
    $sizecolorstoredetail->quantity = $newVariantQty;
}
```

---

## 🔒 Security & Permissions

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

**User Store Access Control**:
```php
// Multi-store access
if ($_SESSION['searchinonestore'] == 0) {
    if ($_SESSION['storeids'] == 0) {
        // Access all stores
    } else {
        // Access specific stores only
        $stores = $myStoreEx->queryByConditions(' and store.storeId in (' . $_SESSION['storeids'] . ')');
    }
}
```

### Input Validation
- Basic parameter type checking (int casting for operation numbers)
- Session-based user ID validation
- Store ID validation against user permissions

**Security Improvements Needed**:
- Add input sanitization for all POST parameters
- Implement CSRF protection for destruction operations
- Add validation for destruction quantities vs available inventory
- Enhance user permission granularity

### Data Integrity
- Transaction support for inventory updates
- Store report creation for audit trails
- Daily entry creation for accounting compliance

---

## 📊 Performance Considerations

### Database Optimization Tips
1. **Critical Indexes Required**:
   - `restaurantrawdestruction(operationNum, sysdate)` - For report filtering
   - `storedetail(productid, storeid)` - For inventory updates  
   - `storereport(storereportid, tablename)` - For audit trail linking
   - `product(productId)` - For product lookups

2. **Query Optimization**:
   - Batch inventory updates when possible
   - Use prepared statements for repeated operations
   - Consider materialized views for complex reporting

3. **Transaction Management**:
   - Ensure atomic operations for inventory updates
   - Implement proper rollback on failures
   - Batch related operations together

### Memory Management
- Process destruction operations in batches for large operations
- Clear unused object references after processing
- Consider pagination for large report datasets

---

## 🐛 Common Issues & Troubleshooting

### 1. **Inventory Quantity Mismatch**
**Issue**: Inventory quantities don't update correctly after destruction  
**Cause**: Transaction rollback or size/color variant update failures

**Debug**:
```sql
-- Check inventory before/after destruction
SELECT productid, storeid, productquantity, userid, storedetaildate
FROM storedetail 
WHERE productid = [PRODUCT_ID] AND storeid = [STORE_ID];

-- Verify size/color quantities if applicable
SELECT productid, storeid, sizeid, colorid, quantity
FROM sizecolorstoredetail
WHERE productid = [PRODUCT_ID] AND storeid = [STORE_ID];
```

### 2. **Accounting Entries Missing**
**Issue**: Daily entries not created for destruction operations  
**Cause**: Account tree missing or dailyentry function failures

**Debug**:
```sql
-- Check store account tree setup
SELECT storeId, storeName, treeId FROM store WHERE storeId = [STORE_ID];

-- Verify account tree exists  
SELECT id, name FROM accountstree WHERE id = [TREE_ID];

-- Check daily entry creation
SELECT * FROM dailyentry WHERE entryComment LIKE '%تالف مواد تشغيل%';
```

### 3. **Operation Number Duplication**
**Issue**: Multiple operations get same operation number  
**Cause**: Concurrency issues in operation number generation

**Fix**:
```sql
-- Add unique constraint to prevent duplicates
ALTER TABLE restaurantrawdestruction 
ADD CONSTRAINT uk_operation_num UNIQUE (operationNum);
```

### 4. **Size/Color Variant Issues**
**Issue**: Complex product IDs not parsing correctly  
**Cause**: Incorrect format or missing size/color data

**Debug**:
```php
// Verify complex ID format
$productId = "123hasSizeColor-5-7";
if (strpos($productId, "hasSizeColor") !== false) {
    $productIdComplex = explode('-', str_replace("hasSizeColor", "", $productId));
    // Should result in: [0]=123, [1]=5, [2]=7
}
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Destruction Operation
```
1. Select product with known inventory quantity
2. Enter destruction quantity less than available
3. Process destruction operation
4. Verify inventory quantity decreased correctly
5. Check store report entry created
6. Confirm daily accounting entry generated
```

### Test Case 2: Size/Color Variant Destruction
```
1. Use complex product ID with size/color
2. Verify parsing extracts correct IDs
3. Check both main and variant quantities update
4. Validate size/color info in destruction record
```

### Test Case 3: Multi-Product Operation
```
1. Create operation with multiple products
2. Verify unique operation number assigned
3. Check all products processed correctly
4. Confirm all accounting entries created
5. Validate operation can be printed/viewed
```

### Test Case 4: Permission Testing
```
1. Test with user having single store access
2. Verify only allowed stores appear in interface
3. Test with multi-store user permissions
4. Check store filtering works correctly
```

### Test Case 5: Report Generation
```
1. Create destruction operations across date range
2. Generate reports with various filters
3. Verify totals calculate correctly
4. Check operation number grouping
5. Validate pricing strategy calculations
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [inventoryController.php](#) - General inventory management
- [storedetailController.php](#) - Store inventory operations
- [dailyentryController.php](#) - Accounting integration
- [Database Schema Documentation](#) - Table relationships

---

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