Bill Template Controller Documentation
File: /controllers/billTemplateController.php
Purpose: Manages predefined bill templates for quick product selection and standardized billing
Last Updated: December 20, 2024
Total Functions: 5
Lines of Code: ~324
---
๐ Overview
The Bill Template Controller provides functionality for creating, managing, and using predefined bill templates. These templates allow users to create standardized product combinations for both sales and returns, streamlining the billing process by pre-defining commonly sold product groups with quantities and specifications.
Primary Functions
- โ Create bill templates with product combinations
- โ Support both sale and return product templates
- โ Handle products with size and color variations
- โ Display template listings with edit/delete capabilities
- โ Edit existing templates with full product details
- โ Delete templates and associated details
- โ Support product unit variations
- โ Transaction-based operations for data consistency
Related Controllers
- โข sellbillController.php - Uses templates for quick bill creation
- โข buyBillController.php - Purchase operations
- โข productController.php - Product management
- โข returnsellbillController.php - Return operations
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **billtemplate** | Template master data | id, name, userid, sysdate, del | |
| **billtemplatedetail** | Template product details | id, billTemplateId, type, parcode, productid, sizeid, colorid, unitid, quantity |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **product** | Product master data | productid, productname, productnumber, productprice, productCatId | |
| **productcat** | Product categories | id, productCatName, productCatParent | |
| **productunit** | Product units | productunitid, productunitname, productid | |
| **size** | Product sizes | sizeid, sizename | |
| **color** | Product colors | colorid, colorname |
| Table Name | Purpose | Key Columns |
|---|---|---|
| **programsettings** | System configuration | programsettingsid, settingkey, settingvalue |
๐ Key Functions
1. Default Action - Display Template Form
Location: Line 63-66
Purpose: Show bill template creation form
Process Flow:
1. Display header template
2. Show billTemplateview/bill.html form
3. Load product selection interface
4. Enable custom validation
---
2. add() - Create/Update Template
Location: Line 123-226
Purpose: Create new template or update existing template with product details
Function Signature:
function add()
// Returns: template ID
Transaction Handling:
$mytransactions = new Transaction();
try {
// Template operations
$mytransactions->commit();
} catch (Exception $ex) {
$mytransactions->rollback();
}
Process Flow:
1. Create/Update Template Master:
$billTemplate->name = $name ?: "ูู
ูุฐุฌ " . $id;
$billTemplate->userid = $_SESSION['userid'];
$billTemplate->sysdate = date('Y-m-d H:i:s');
$billTemplate->del = 0;
if ($id > 0) {
$billTemplateEX->insertWithId($billTemplate, $id);
} else {
$id = $billTemplateDAO->insert($billTemplate);
}
```
2. **Process Sale Products** (type = 0):
```php
for ($i = 1; $i <= $itr; $i++) {
$product = filter_input(INPUT_POST, "product$i");
$pronum = (float) filter_input(INPUT_POST, "pronum$i");
// Handle size/color combinations
if (strpos($product, "hasSizeColor") !== false) {
$productIdComplex = explode('-', str_replace("hasSizeColor", "", $product));
$product = $productIdComplex[0];
$sizeId = $productIdComplex[1];
$colorId = $productIdComplex[2];
}
$billTemplateDetail->type = 0; // Sale
$billTemplateDetail->productid = $product;
$billTemplateDetail->quantity = $pronum;
}
```
3. **Process Return Products** (type = 1):
```php
for ($i = 1; $i <= $itr; $i++) {
$product = filter_input(INPUT_POST, "returnproduct$i");
$billTemplateDetail->type = 1; // Return
$billTemplateDetail->productid = $product;
}
```
**Size/Color Processing**:
php
if (strpos($product, "hasSizeColor") !== false) {
// Format: "productid-hasSizeColor-sizeid-colorid"
$productIdComplex = explode('-', str_replace("hasSizeColor", "", $product));
$product = $productIdComplex[0];
$sizeId = $productIdComplex[1];
$colorId = $productIdComplex[2];
}
---
### 3. **show()** - Display Templates
**Location**: Line 73-77
**Purpose**: List all available bill templates
**Process Flow**:
1. Query all templates: `$billTemplateDAO->queryAll()`
2. Assign to Smarty: `$smarty->assign("allTemplates", $allTemplates)`
3. Display: `billTemplateview/show.html`
---
### 4. **edit()** - Load Template for Editing
**Location**: Line 248-307
**Purpose**: Load template data with full product details for editing
**Function Signature**:
php
function edit($id)
**Process Flow**:
1. **Load Template Master**:
```php
$billTemplate = $billTemplateDAO->load($id);
$smarty->assign("billTemplate", $billTemplate);
```
2. **Load Sale Products** (type = 0):
```php
$billTemplateDetails = $billTemplateDetailEX->queryByBillTemplateIdEXAndType($id, 0);
foreach ($billTemplateDetails as $mydetales) {
// Build product path from categories
$parentId = $mydetales->productCatId;
$pathArr = getProductPath_recursive($parentId, $categories);
$mydetales->productName = $mydetales->productName . '/' . $pathArr;
// Add size/color information
if ($mydetales->sizeName != '')
$mydetales->productName .= "/ " . $mydetales->sizeName;
if ($mydetales->colorName != '')
$mydetales->productName .= "/ " . $mydetales->colorName;
// Load available units for product
$myunitdata = $myProductunitEx->queryWithProductIdAndCondition($mydetales->productid);
$smarty->assign("myunitdata" . $i, $myunitdata);
}
```
3. **Load Return Products** (type = 1):
```php
$billTemplateDetails = $billTemplateDetailEX->queryByBillTemplateIdEXAndType($id, 1);
// Similar processing for return products
```
**Product Path Building**:
php
function getProductPath_recursive($parentid, $categories) {
$catData = $productCatExt->getCategoryAndParentByCatId($parentid);
if (count($catData) > 0) {
$categories .= $catData->productCatName . '/';
return getProductPath_recursive($catData->productCatParent, $categories);
}
return substr($categories, 0, strlen($categories) - 1);
}
---
### 5. **delete()** - Delete Template
**Location**: Line 228-246
**Purpose**: Remove template and all associated details
**Function Signature**:
php
function delete($id)
**Transaction Process**:
php
$mytransactions = new Transaction();
try {
$billTemplateDAO->delete($id);
$billTemplateDetailDAO->deleteByBillTemplateId($id);
$mytransactions->commit();
} catch (Exception $ex) {
$mytransactions->rollback();
}
**Cleanup Operations**:
1. Delete template master record
2. Delete all template detail records
3. Maintain referential integrity
---
## ๐ Workflows
### Workflow 1: Create Bill Template
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Create Template โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Access Template Form โ
โ - Load product categories and units โ
โ - Initialize template form interface โ
โ - Display sale and return sections โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Configure Template Details โ
โ - Enter template name โ
โ - Add sale products with quantities โ
โ - Add return products (if needed) โ
โ - Specify units, sizes, colors โ
โ - Set product codes (parcode) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Process Sale Products โ
โ FOR EACH sale product: โ
โ โ โ
โ โโโ Validate product selection โ
โ โโโ Parse size/color combinations โ
โ โโโ Set quantity and unit โ
โ โโโ Create template detail record โ
โ โ โโ type = 0 (sale) โ
โ โ โโ productid, sizeid, colorid โ
โ โ โโ quantity, unitid, parcode โ
โ โ โ
โ โโโ Insert detail record โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Process Return Products โ
โ FOR EACH return product: โ
โ โ โ
โ โโโ Validate product selection โ
โ โโโ Parse size/color combinations โ
โ โโโ Set quantity and unit โ
โ โโโ Create template detail record โ
โ โ โโ type = 1 (return) โ
โ โ โโ productid, sizeid, colorid โ
โ โ โโ quantity, unitid, parcode โ
โ โ โ
โ โโโ Insert detail record โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. Finalize Template โ
โ - Commit transaction โ
โ - Return template ID โ
โ - Redirect to success page โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
### Workflow 2: Edit Template
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Edit Template โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Load Template Data โ
โ - Get template master information โ
โ - Load sale products (type = 0) โ
โ - Load return products (type = 1) โ
โ - Build product category paths โ
โ - Load available units for each product โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Display Edit Form โ
โ - Pre-populate template name โ
โ - Show existing sale products with: โ
โ โโ Full product path (category/product/size/color) โ
โ โโ Current quantity โ
โ โโ Selected unit โ
โ โโ Product code โ
โ - Show existing return products โ
โ - Allow additions and modifications โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Process Update (do=update) โ
โ - Delete existing template and details โ
โ - Recreate template with new data โ
โ - Use same add() function logic โ
โ - Maintain template ID if specified โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Success Response โ
โ - Redirect to success page โ
โ - Template ready for use โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
## ๐ URL Routes & Actions
| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default | Display template creation form |
| `do=add` | `add()` | Create new template |
| `do=show` | Display | Show all templates list |
| `do=edit` | `edit($id)` | Load template for editing |
| `do=showdetail` | `edit($id)` | Show template details (view-only) |
| `do=update` | `delete($id)` + `add()` | Update existing template |
| `do=delete` | `delete($id)` | Remove template |
| `do=sucess` | Template | Success page |
| `do=error` | Template | Error page |
### Required Parameters by Action
**Create Template** (`do=add`):
- `name` - Template name (optional, auto-generated if empty)
- `hidden_itr` - Number of sale products
- `returnhidden_itr` - Number of return products
- Dynamic arrays: `product{N}`, `pronum{N}`, `productunit{N}`, `parcode{N}`
- Return arrays: `returnproduct{N}`, `returnpronum{N}`, etc.
**Edit Template** (`do=edit`):
- `id` - Template ID to edit
**Update Template** (`do=update`):
- `id` - Template ID to update
- Same product arrays as create
**Delete Template** (`do=delete`):
- `id` - Template ID to delete
---
## ๐งฎ Business Logic
### Product Type Classification
- **type = 0**: Sale products (normal sales items)
- **type = 1**: Return products (items to be returned)
### Size/Color Handling
php
// Input format: "productid-hasSizeColor-sizeid-colorid"
if (strpos($product, "hasSizeColor") !== false) {
$productIdComplex = explode('-', str_replace("hasSizeColor", "", $product));
$product = $productIdComplex[0]; // Main product ID
$sizeId = $productIdComplex[1]; // Size variant
$colorId = $productIdComplex[2]; // Color variant
}
### Template Naming
php
// Auto-generate name if not provided
if (empty($name)) {
$billTemplate->name = "ูู ูุฐุฌ " . $id; // "Template " + ID
}
### Product Path Display
php
// Build full product hierarchy: Category/Subcategory/Product/Size/Color
$mydetales->productName = $mydetales->productName . '/' . $pathArr;
if ($mydetales->sizeName != '') $mydetales->productName .= "/ " . $mydetales->sizeName;
if ($mydetales->colorName != '') $mydetales->productName .= "/ " . $mydetales->colorName;
---
## ๐ Security & Permissions
### Input Filtering
php
$id = (int) filter_input(INPUT_POST, "id");
$name = filter_input(INPUT_POST, "name");
$parcode = filter_input(INPUT_POST, "parcode$i");
$product = filter_input(INPUT_POST, "product$i");
$pronum = (float) filter_input(INPUT_POST, "pronum$i");
### Authentication
- โ
User session tracking: `$_SESSION['userid']`
- โ
Database user association
- โ No explicit permission checks
- โ No role-based access control
### Input Validation
- โ
Type casting for numeric values
- โ
Basic input filtering
- โ
Empty value checks
- โ No SQL injection protection beyond filtering
- โ No CSRF token validation
---
## ๐ Performance Considerations
### Transaction Management
php
$mytransactions = new Transaction();
try {
// Multiple database operations
$mytransactions->commit();
} catch (Exception $ex) {
$mytransactions->rollback();
}
### Optimization Opportunities
1. **Batch Insert Operations**:
- Multiple detail inserts could be batched
- Reduce database round trips
2. **Caching**:
- Product category paths could be cached
- Unit data caching for frequently used products
3. **Query Optimization**:
- Index on `billTemplateId` and `type`
- Composite index for product searches
### Database Load
- **Light Operations**: Template management is relatively low-volume
- **Complex Queries**: Product path building uses recursive queries
- **Transaction Safety**: Proper rollback on failures
---
## ๐ Common Issues & Troubleshooting
### 1. **Size/Color Parsing Errors**
**Issue**: Complex product format parsing fails
**Debug**: Check product input format: `productid-hasSizeColor-sizeid-colorid`
### 2. **Missing Product Units**
**Issue**: Product units not loading in edit form
**Debug**:
sql
SELECT * FROM productunit WHERE productid = ?;
### 3. **Template Update Issues**
**Issue**: Update operation fails
**Cause**: Delete-then-add approach may leave orphaned records
**Solution**: Ensure transaction rollback on failure
### 4. **Product Path Building Infinite Loop**
**Issue**: Circular category references cause recursion
**Debug**: Check category parent relationships
---
## ๐งช Testing Scenarios
### Test Case 1: Basic Template Creation
1. Create template with simple products
2. Verify template master record
3. Check detail records for sale products
4. Validate return products if added
5. Confirm template appears in listing
### Test Case 2: Size/Color Combinations
1. Add products with size/color variants
2. Verify correct parsing of complex IDs
3. Check detail records have proper size/color IDs
4. Validate display in edit form
### Test Case 3: Template Update
1. Create initial template
2. Edit and add/remove products
3. Verify old records are properly deleted
4. Check new records are inserted correctly
5. Confirm no orphaned detail records
### Test Case 4: Error Handling
1. Submit invalid product combinations
2. Test transaction rollback scenarios
3. Verify error page display
4. Check database consistency after errors
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข sellbillController.md - Sales operations using templates
- โข productController.php - Product management
- โข Database Schema Documentation - Table relationships
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When template usage analytics are added