RestaurantRawDestruction Documentation
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
- โ Record inventory destruction/wastage operations
- โ Update product quantities across stores
- โ Calculate financial impact using multiple pricing strategies
- โ Generate accounting entries for destroyed inventory
- โ Track destruction operations with unique operation numbers
- โ Support size/color product variants
- โ Multi-store destruction management
- โ 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 |
| 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 |
| 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 |
| 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:
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:
// 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:
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:
$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:
$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:
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:
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:
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:
$parentId = $pro->productCatId;
$pathArr = fetch_recursive($parentId, $categories);
$pro->productName = $pro->productName . '/' . $pathArr;
Size/Color Enhancement:
$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:
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:
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:
$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
Workflow 2: Report Generation
---
๐ 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 |
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:
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:
$totalCost = $unitCost * $destructionQuantity;
Inventory Quantity Updates
Main Inventory Update:
$currentQuantity = $storeDetail->productquantity;
$newQuantity = $currentQuantity - $destructionQuantity;
$storeDetail->productquantity = $newQuantity;
Size/Color Variant Update:
if ($sizeId > 0 && $colorId > 0) {
$sizecolorstoredetail = $sizeColorStoreDetailDAO->load($sizeColorStoreDetailId);
$currentVariantQty = $sizecolorstoredetail->quantity;
$newVariantQty = $currentVariantQty - $destructionQuantity;
$sizecolorstoredetail->quantity = $newVariantQty;
}
---
๐ Security & Permissions
Authentication & Authorization
include_once("../public/authentication.php");
User Store Access Control:
// 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:
-- 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:
-- 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:
-- 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:
// 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 - 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