Production Out Controller Documentation
File: /controllers/productionOutController.php
Purpose: Manages simple production/manufacturing processes for converting raw materials into finished products
Last Updated: December 20, 2024
Total Functions: 15
Lines of Code: ~903
---
๐ Overview
The Production Out Controller handles simple manufacturing operations where multiple raw materials are consumed to produce a single finished product. It manages:
- โข Raw material consumption from inventory
- โข Finished product creation and inventory updates
- โข Cost calculation and price updates
- โข Supplier debt management
- โข Inventory movement tracking
- โข Daily accounting entries
- โข Manufacturing transaction logging
Primary Functions
- โ Create simple production orders (1 output, multiple inputs)
- โ Raw material inventory deduction
- โ Finished product inventory addition
- โ Production cost calculation and allocation
- โ Supplier debt management for manufacturing costs
- โ Inventory movement reporting
- โ Daily accounting entry generation
- โ Size/color variant support
- โ Unit of measure conversions
Related Controllers
- โข productionOutManyController.php - Multiple output production
- โข productionEquationController.php - Production formulas
- โข productionRateController.php - Production rates
- โข buyBillController.php - Raw material purchasing
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **productionout** | Production header records | id, outStore, inStore, supplier, productid, sizeid, colorid, outQuantity, outUnitCost, outAllCost, outAllCostTot, comment, userid, del, sysDate, dailyentryid | |
| **productionoutdetails** | Raw material consumption | id, productionOutId, productid, sizeid, colorid, unitid, price, quantity, inTotalCost |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **storedetail** | Main inventory quantities | storedetailid, storeid, productid, productquantity, userid, storedetaildate | |
| **sizecolorstoredetail** | Size/color variant inventory | id, storeid, productid, sizeid, colorid, quantity, userid, sysdate | |
| **storereport** | Inventory movement log | storereportid, productid, sizeid, colorid, storeid, productquantity, productbefore, productafter, storereporttype, storereportmodelid, processname, tablename, storereportdate, userid |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **buypriceshistorybook** | Purchase price history | id, theDate, storeId, productid, sizeid, colorid, buyprice, buyQuantity, sellQuantity, del, userid, sysDate | |
| **supplier** | Supplier master data | supplierid, suppliername, suppliercurrentDebt, supplierdate, userid | |
| **supplierdebtchange** | Supplier debt change log | supplierdebtchangeid, supplierid, supplierdebtchangebefore, supplierdebtchangeamount, supplierdebtchangeafter, supplierdebtchangetype, processname, supplierdebtchangemodelid, tablename, comment, supplierdebtchangedate, userid, dailyentryid |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **product** | Product master data | productId, productName, productCatId, productBuyPrice, lastbuyprice, meanbuyprice | |
| **productcat** | Product categories | productCatId, productCatName | |
| **productunit** | Unit conversions | productunitid, productid, unitname, productnumber, proUnitBuyPrice | |
| **store** | Store/warehouse definitions | storeId, storeName, conditions, treeId | |
| **programsettings** | System configuration | programsettingsid, settingkey, settingvalue |
๐ Key Functions
1. Default Action - Add Production Form
Location: Line 200
Purpose: Display form for creating new simple production orders
Function Signature:
// Triggered when: do= (empty)
Process Flow:
1. Load all active stores for dropdowns
2. Set production number counter
3. Load manufacturing settings
4. Display add form template
Features:
- โข Store selection for input/output
- โข Production number assignment
- โข Settings integration
- โข Custom template flags
---
2. add() - Create Production Order
Location: Line 345
Purpose: Process simple manufacturing operation with raw material consumption
Function Signature:
function add()
Process Flow:
1. Extract and validate production header data
2. Handle size/color variants for output product
3. Create production header record
4. Process input raw materials
5. Update inventory quantities (increase output, decrease inputs)
6. Update product pricing information
7. Update supplier debt
8. Generate daily accounting entry
Transaction Control:
$mytransactions = new Transaction();
try {
// All production operations
$mytransactions->commit();
doInventoryDailyEntry($productionOut);
} catch (Exception $e) {
$mytransactions->rollback();
}
Size/Color Handling:
if (strpos($productId, "hasSizeColor") !== false) {
$productIdComplex = explode('-', str_replace("hasSizeColor", "", $productId));
$productId = $outProductId = $productIdComplex[0];
$sizeId = $productIdComplex[1];
$colorId = $productIdComplex[2];
}
Raw Material Processing:
for ($i = 1; $i <= $productItr; $i++) {
if (filter_input(INPUT_POST, 'product' . $i)) {
// Extract product and unit information
$productunitData = $myProductunitEx->queryWithProductIdAndUnitId($productId, $unitId);
$finalquantity = $quantity * $productunitData->productnumber;
// Decrease inventory
decrease($productId, $sizeId, $colorId, $finalquantity, $id, $inStore);
$totalInProductsCost += $inTotalCost;
}
}
---
3. edit() - Edit Production Order
Location: Line 220
Purpose: Load existing production order for modification
Process Flow:
1. Load production header by ID
2. Load all raw material details
3. Build display names with product/category/variant info
4. Assign data to edit template
Product Name Building:
$productionOut->productName = $productionOut->productName . '/ ' . $productionOut->productCatName;
if (!empty($productionOut->sizeid) && !empty($productionOut->colorid)) {
$productionOut->productid = "hasSizeColor" . $productionOut->productid . "-" . $productionOut->sizeid . "-" . $productionOut->colorid;
$productionOut->productName .= '/ ' . $productionOut->sizeName . '/ ' . $productionOut->colorName;
}
---
4. update() - Update Production Order
Location: Line 256
Purpose: Modify existing production orders using delete-and-recreate pattern
Function Signature:
function update()
Process Flow:
1. Delete existing production order (reverses all effects)
2. Create new production order with updated data
3. Maintains data integrity through transaction control
Note: This approach ensures all inventory movements, costs, and supplier debts are properly reversed and re-applied.
---
5. show() - List Production Orders
Location: Line 265
Purpose: Display filtered list of production orders with search capabilities
Process Flow:
1. Extract filter parameters
2. Build dynamic query string
3. Apply default date filter if no filters specified
4. Load and display production orders
5. Include YouTube tutorials
Filter Options:
- โข Output store selection
- โข Input store selection
- โข Supplier selection
- โข Specific product selection
- โข Date range filtering
- โข Production order ID
Default Filter Logic:
if ($query == " and productionout.del=0 ") {
$from = $to = date('Y-m-d');
$query .= " and date(productionout.sysDate) >= '$from' and date(productionout.sysDate) <= '$to' ";
}
---
6. delete() - Delete Production Order
Location: Line 473
Purpose: Reverse all effects of a production order and remove from system
Function Signature:
function delete()
Process Flow:
1. Load production order data
2. Reverse finished product inventory increase
3. Reverse raw material inventory decreases
4. Reverse supplier debt changes
5. Delete production detail records
6. Delete production header record
7. Reverse daily accounting entry
Reversal Logic:
// Reverse output product increase
decrease($productionOut->productid, $productionOut->sizeid, $productionOut->colorid, $productionOut->outQuantity, $id, $productionOut->outStore);
// Reverse raw material decreases
foreach ($allProductionOutDetail as $p) {
$productunitData = $myProductunitEx->queryWithProductIdAndUnitId($p->productid, $p->unitid);
$finalquantity = $p->quantity * $productunitData->productnumber;
increase($p->productid, $p->sizeid, $p->colorid, $finalquantity, $id, $productionOut->inStore);
}
---
7. decrease() - Reduce Inventory
Location: Line 519
Purpose: Decrease product quantities in inventory (for raw material consumption)
Function Signature:
function decrease($productId, $sizeId, $colorId, $finalquantity, $sellbillId, $sellbillstoreId = 0, $type = "")
Process Flow:
1. Get current inventory levels
2. Decrease main inventory quantity
3. Update size/color specific inventory if applicable
4. Create inventory movement report
5. Handle negative inventory scenarios
Inventory Update Logic:
if (count($allStoredetailData) > 0) {
// Update existing inventory record
$productquantityAfter = decreaseProductQuantity($storedetailId, $productquantityBefore, $finalquantity);
insertStorereportupdate($productId, $sizeId, $colorId, $sellbillstoreId, $finalquantity, $productquantityBefore, $productquantityAfter, 1, $sellbillId, "ุชุตููุน ู
ุจุณุท ููู
ูุชุฌ" . $type, "productionExecutionController.php", date("Y-m-d H:i:s"));
} else {
// Create new inventory record with negative quantity
$specialQuantityAfter = $finalquantity * -1;
insertStoredetailupdate($sellbillstoreId, $productId, $specialQuantityAfter, date("Y-m-d H:i:s"));
}
---
8. increase() - Add to Inventory
Location: Line 570
Purpose: Increase product quantities in inventory (for finished goods)
Function Signature:
function increase($productId, $sizeId, $colorId, $finalquantity, $sellbillId, $sellbillstoreId = 0, $type = "")
Process Flow:
1. Get current inventory levels
2. Increase main inventory quantity
3. Update size/color specific inventory if applicable
4. Create inventory movement report
Key Difference: Creates new positive inventory records if product doesn't exist in store.
---
9. getBuyPriceFromAndHandleBuyPricesHistoryBook() - FIFO Cost Calculation
Location: Line 727
Purpose: Calculate raw material costs using FIFO methodology
Function Signature:
function getBuyPriceFromAndHandleBuyPricesHistoryBook($storeId, $productid, $sizeid, $colorid, $productBuyPrice, $soldQuantity, $type = 0)
Process Flow:
1. Find earliest available inventory batches
2. Consume quantities in FIFO order
3. Calculate weighted average cost
4. Update sell quantities in price history
5. Return actual cost per unit
FIFO Logic:
do {
$buyPriceFromHistoryBook = $buyPricesHistoryBookEX->getBuyPriceOfFirstAvailableSellQuantity($storeId, $productid, $sizeid, $colorid);
if (isset($buyPriceFromHistoryBook->id) && $buyPriceFromHistoryBook->id > 0 && $remainQuantity > 0) {
$availableBuyQuantity = $buyPriceFromHistoryBook->buyQuantity - $buyPriceFromHistoryBook->sellQuantity;
// Process available quantity
}
} while (isset($buyPriceFromHistoryBook->id) && $buyPriceFromHistoryBook->id > 0 && $remainQuantity > 0);
---
10. increaseBuyPricesHistoryBookBuyQuantity() - Price History Update
Location: Line 792
Purpose: Record new inventory purchases in price history
Function Signature:
function increaseBuyPricesHistoryBookBuyQuantity($theDate, $storeId, $productid, $sizeid, $colorid, $buyprice, $buyQuantity)
Features:
- โข Records purchase date and price
- โข Supports size/color variants
- โข Enables FIFO cost calculation
- โข Tracks available quantities for sale
---
11. updateSupplierDebt() - Supplier Debt Management
Location: Line 830
Purpose: Update supplier debt balances
Function Signature:
function updateSupplierDebt($supplierId, $supplierDebtAfter)
Updates: Current debt balance and last update date.
---
12. insertSupplierDebtChange() - Debt Change Logging
Location: Line 846
Purpose: Log all supplier debt changes for audit trail
Function Signature:
function insertSupplierDebtChange($supplierId, $supplierDebtChangeBefore, $supplierDebtChangeAmount, $supplierDebtChangeType, $processname, $supplierDebtChangeModelId, $supplierDebtChangeAfter, $tablename, $comment)
Tracks: Before/after balances, change amount, change type, and linking information.
---
13. doInventoryDailyEntry() - Accounting Integration
Location: Line 867
Purpose: Generate daily accounting entries for production transactions
Function Signature:
function doInventoryDailyEntry($productionOut)
Process Flow:
1. Calculate raw material cost totals
2. Get store and supplier account tree IDs
3. Create debit entries (finished goods inventory, supplier debt)
4. Create credit entry (raw materials inventory)
5. Link to production order for reference
Accounting Logic:
$dailyEntryDebtorArray = array();
// Debit: Finished goods inventory
$dailyEntryDebtor->accountstreeid = $treeIdOutStore;
$dailyEntryDebtor->value = $rawMaterialCost;
// Debit: Supplier debt
$dailyEntryDebtor->accountstreeid = $suppData['treeId'];
$dailyEntryDebtor->value = $productionOut->outAllCost;
$dailyEntryCreditorArray = array();
// Credit: Raw materials inventory
$dailyEntryCreditor->value = $rawMaterialCost + $productionOut->outAllCost;
$dailyEntryCreditor->accountstreeid = $treeIdInStore;
---
๐ Workflows
Workflow 1: Simple Production Process
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default action | Display add production form | |
| `do=add` | `add()` | Create new production order | |
| `do=edit&id={id}` | Edit display | Load production order for editing | |
| `do=update` | `update()` | Update existing production order | |
| `do=show` | `show()` | List production orders with filters | |
| `do=delete&id={id}` | `delete()` | Delete production order |
Add Production (do=add):
- โข
outStore- Output store ID - โข
inStore- Input store ID - โข
supplier- Supplier ID - โข
productOut- Output product (may include hasSizeColor encoding) - โข
outQuantity- Output quantity - โข
outUnitCost- Unit cost - โข
outAllCostTot_h- Total cost - โข
inProItr- Number of input products - โข
product{i}- Input product IDs - โข
unitId{i}- Unit IDs for inputs - โข
price{i}- Unit prices for inputs - โข
quantity{i}- Quantities for inputs
Show/Filter (do=show):
- โข
outStore- Output store filter (optional) - โข
inStore- Input store filter (optional) - โข
supplier- Supplier filter (optional) - โข
productOut- Product filter (optional) - โข
from- Date from filter (optional) - โข
to- Date to filter (optional) - โข
outId- Production ID filter (optional)
---
๐งฎ Calculation Methods
Production Cost Calculation
// Raw material total cost
$totalInProductsCost = 0;
for ($i = 1; $i <= $productItr; $i++) {
$price = (float) filter_input(INPUT_POST, 'price' . $i);
$quantity = (float) filter_input(INPUT_POST, 'quantity' . $i);
$inTotalCost = $price * $quantity;
$totalInProductsCost += $inTotalCost;
}
// Output product cost allocation
$outProductPrice = $outAllCostTot; // Total allocated cost
$outQuantity = (float) filter_input(INPUT_POST, 'outQuantity');
$unitCost = $outAllCostTot / $outQuantity;
Unit Conversion Calculation
$productunitData = $myProductunitEx->queryWithProductIdAndUnitId($productId, $unitId);
$finalquantity = $quantity * $productunitData->productnumber;
FIFO Cost Calculation
$totalPrice = 0;
$remainQuantity = $soldQuantity;
do {
$buyPriceFromHistoryBook = $buyPricesHistoryBookEX->getBuyPriceOfFirstAvailableSellQuantity($storeId, $productid, $sizeid, $colorid);
$availableBuyQuantity = $buyPriceFromHistoryBook->buyQuantity - $buyPriceFromHistoryBook->sellQuantity;
if ($availableBuyQuantity >= $remainQuantity) {
$totalPrice += $remainQuantity * $buyPriceFromHistoryBook->buyprice;
$remainQuantity = 0;
} else {
$totalPrice += $availableBuyQuantity * $buyPriceFromHistoryBook->buyprice;
$remainQuantity -= $availableBuyQuantity;
}
} while ($remainQuantity > 0 && isset($buyPriceFromHistoryBook->id));
$averageCost = $totalPrice / $soldQuantity;
---
๐ Security & Permissions
Authentication Requirements
include_once("../public/authentication.php");
Input Validation
- โข All numeric inputs cast to appropriate types
- โข Product and unit IDs validated against database
- โข Date parameters validated for proper format
- โข Transaction control prevents partial updates
Data Integrity
- โข Transaction rollback on any failure
- โข Inventory movement logging for audit trail
- โข Supplier debt change tracking
- โข Daily accounting entry generation
- โข Cascading deletion logic
---
๐ Performance Considerations
Database Optimization Tips
1. Critical Indexes:
- productionout(outStore, inStore, sysDate)
- productionoutdetails(productionOutId)
- storedetail(storeid, productid)
- buypriceshistorybook(storeId, productid, sizeid, colorid, theDate)
2. Query Optimization:
- Batch inventory updates within transactions
- Efficient FIFO price calculation
- Minimize N+1 query patterns
3. Memory Management:
- Process raw materials incrementally
- Clean up temporary variables
- Proper transaction scope
---
๐งช Testing Scenarios
Test Case 1: Basic Production Order
1. Create production order: 1 chair from 4 legs + 1 seat
2. Set costs: legs $5 each, seat $20, total chair cost $50
3. Verify inventory changes:
- Chair quantity +1
- Leg quantity -4
- Seat quantity -1
4. Check cost updates:
- Chair buy price updated to $50
- Price history recorded
5. Verify supplier debt increased by $50
6. Check daily accounting entry created
Test Case 2: Size/Color Variant Production
1. Create red large chair from materials
2. Verify hasSizeColor encoding works
3. Check variant-specific inventory updates
4. Confirm size/color inventory tracking
Test Case 3: Edit and Delete Operations
1. Create production order
2. Edit with different materials/quantities
3. Verify old data reversed and new applied
4. Delete order
5. Confirm all effects reversed:
- Inventory restored
- Supplier debt reversed
- Accounting entry reversed
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข productionOutManyController.md - Multiple output production
- โข productionEquationController.md - Production formulas
- โข buyBillController.md - Raw material purchasing
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur