๐Ÿ“š ERP Documentation Viewer

Beautiful, colorful documentation for your ERP system

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

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables (Direct Operations)

Table NamePurposeKey Columns
**billtemplate**Template master dataid, name, userid, sysdate, del
**billtemplatedetail**Template product detailsid, billTemplateId, type, parcode, productid, sizeid, colorid, unitid, quantity
### Product Reference Tables

Table NamePurposeKey Columns
**product**Product master dataproductid, productname, productnumber, productprice, productCatId
**productcat**Product categoriesid, productCatName, productCatParent
**productunit**Product unitsproductunitid, productunitname, productid
**size**Product sizessizeid, sizename
**color**Product colorscolorid, colorname
### System Tables

Table NamePurposeKey Columns
**programsettings**System configurationprogramsettingsid, 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

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When template usage analytics are added

โ†‘