๐Ÿ“š ERP Documentation Viewer

Beautiful, colorful documentation for your ERP system

Buy Bill Reports Controller Documentation

File: /controllers/buyBillreportController.php

Purpose: Generates comprehensive reports for purchase bills, supplier transactions, and inventory serial tracking

Last Updated: December 20, 2024

Total Functions: 10

Lines of Code: ~629

---

๐Ÿ“‹ Overview

The Buy Bill Reports Controller is a specialized reporting module that provides detailed purchase bill analysis and inventory tracking capabilities. It handles:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables (Direct Operations)

Table NamePurposeKey Columns
**buybill**Purchase bills masterbuybillid, buybillsupplierid, buybillserial, buybilldate, buybilltotalbill, buybillaftertotalbill, buybilldiscount, tax, conditions
**buybilldetail**Purchase bill line itemsbuybilldetailid, buybillid, buybilldetailproductid, buybilldetailquantity, buybilldetailtotalprice, productnumber
**returnbuybill**Purchase return billsreturnbuybillid, returnbuybillsupplierid, returnbuybilldate, returnbuybilltotalbill, returnbuybillaftertotalbill
**returnbuybilldetail**Return bill detailsreturnbuybilldetailid, returnbuybillid, returnbuybilldetailproductid, returnbuybilldetailquantity
**buyandruternbill**Combined buy & returnbuybillid, buybillsupplierid, buybillprice, returnbuybillprice, buybilldate
**buyandruternbilldetail**Combined bill detailsbuyandruternbilldetailid, buybillid, buybilldetailproductid, buybilldetailquantity, billtype
### Serial Tracking Tables

Table NamePurposeKey Columns
**productserial**Product serial numbersproductserialid, productid, serialnumber, storeid, sizeid, colorid
**soldserialproduct**Sold serial trackingsoldserialproductid, productserialid, clientid, sellbilltype, sellbillid
### Reference Tables

Table NamePurposeKey Columns
**supplier**Supplier master datasupplierid, suppliername, supplierdebt
**product**Product informationproductid, productname, productcatid
**productcat**Product categoriesproductcatid, productcatname, productcatparent
**store**Store/warehouse datastoreid, storename
**unit**Measurement unitsunitid, unitname
### System Tables

Table NamePurposeKey Columns
**programsettings**System configurationprogramsettingsid, reportsplusshours
**billname**Bill type templatesbillnameid, billname, type
**billsettings**Bill configurationbillsettingsid, billnameid, settingkey, settingvalue
**youtubelink**Tutorial linksyoutubelinkid, title, url
**storedetail**Store inventory detailsstoredetailid, storeid, productid, storedetailquantity
**storereport**Store reportsstorereportid, storeid, productid
**save**Cash registers/safessaveid, savename, savevalue
**savedaily**Daily cash movementssavedailyid, saveid, savedailyvalue, savedailydate
---

๐Ÿ”‘ Key Functions

1. show() / Default Action - Purchase Bill Reports

Location: Line 340

Purpose: Generate comprehensive purchase bill reports with filtering and calculations

Function Signature:

// Triggered when: do=show or empty $do
$supplierId = $_REQUEST['supplierId'];
$serial = $_REQUEST['serial'];
$buybillid = $_REQUEST['buybillid'];
$from = $_REQUEST['from']; 
$to = $_REQUEST['to'];

Process Flow:

1. Build dynamic query string with supplier, serial, bill ID, and date filters

2. Handle time zone adjustments via reportsPlusHours setting

3. Query regular purchase bills (buybill table)

4. Query combined buy/return bills (buyandruternbill table)

5. Calculate totals for each bill:

- Total bill amounts

- Product quantities

- Discount processing (fixed vs percentage)

- Tax calculations

6. Merge datasets and assign to template

7. Display via buyBillreportview/show.html

Key Calculations:

// Discount processing
if ($buybilldiscountrype == 0) { // Fixed amount
    $totaldiscount = $totaldiscount + $buybilldiscount + $detaildiscount;
} else { // Percentage
    $discountvalue = ($buybilltotalbill / 100) * $buybilldiscount;
    $totaldiscount = $totaldiscount + $discountvalue + $detaildiscount;
}

// Tax calculation
$taxvalue = $buybillaftertotalbill - ($buybilltotalbill - $discountvalue);

Template Variables:

---

2. notSoldSerials Action - Serial Number Tracking

Location: Line 277

Purpose: Track product serial numbers between inventory and sales

Process Flow:

1. Receive search parameters:

- storeid - Store/warehouse filter

- product - Product ID (supports size/color variants)

- client - Customer filter for sold serials

- productserial - Specific serial number search

2. Build product query with size/color support:

   if (strpos($product, "hasSizeColor") !== false) {
       $productIdComplex = explode('-', str_replace("hasSizeColor", "", $product));
       $product = $productIdComplex[0];
       $sizeId = $productIdComplex[1];
       $colorId = $productIdComplex[2];
       $productQuery = " and productserial.productid = $product and productserial.sizeid =$sizeId and productserial.colorid=$colorId ";
   }
   ```
3. Query inventory serials via `ProductserialMySqlExtDAO`
4. Query sold serials via `SoldserialproductMySqlExtDAO`
5. Filter for sales only: `sellbilltype in(0,1)`
6. Display via `buyBillreportview/notSoldSerials.html`

**Search Modes**:
- **By Serial Number**: Find specific serial across inventory and sales
- **By Store**: List all serials in a warehouse/store
- **By Customer**: Show serials sold to specific customer
- **By Product**: All serials for a product (with size/color variants)

**Template Variables**:
- `$inStoresSerial` - Available inventory serials
- `$soldSerials` - Sold/transferred serials
- `$allStores` - Store dropdown data

---

### 3. **getBuyBillNames()** - Bill Template Loader
**Location**: Line 540  
**Purpose**: Load purchase bill templates and configurations

**Function Signature**:
php

function getBuyBillNames()

**Process Flow**:
1. Query `billname` table for type = 1 (purchase bills)
2. Return available bill templates for dropdowns

**Returns**: Array of bill name objects for template selection

---

### 4. **loadBillProperties()** - Bill Configuration Loader
**Location**: Line 549  
**Purpose**: Load specific bill template settings and properties

**Function Signature**:
php

function loadBillProperties($billnameid)

**Process Flow**:
1. Query `billsettings` table by bill name ID
2. Return configuration settings for the selected bill template

**Usage**: Used by bill creation forms to load template-specific settings

---

### 5. **getProducts()** - Product Catalog with Categories
**Location**: Line 558  
**Purpose**: Load complete product list with category hierarchy

**Function Signature**:
php

function getProducts()

**Process Flow**:
1. Query all products via `ProductMySqlExtDAO->queryAllExt()`
2. For each product, build category path:
   - Call `fetch_recursive()` to traverse category tree
   - Build hierarchical category string
   - Assign to template variables `$names{N}`
3. Return enriched product array

**Category Processing**:
- Builds full category paths (e.g., "Electronics/Computers/Laptops/")
- Handles multi-level category hierarchies
- Provides dropdown-friendly category names

---

### 6. **fetch_recursive()** - Category Tree Traversal
**Location**: Line 577  
**Purpose**: Recursively build category hierarchy paths

**Function Signature**:
php

function fetch_recursive($parentid, $categories)

**Process Flow**:
1. Load category data by parent ID
2. Append current category name to path
3. Check for parent category (`productCatParent != 0`)
4. Recursively call for parent categories
5. Return complete category path string

**Usage**: Called by `getProducts()` to build category breadcrumbs

---

### 7. **getSuppliers()** - Supplier Dropdown Data
**Location**: Line 596  
**Purpose**: Load active suppliers for report filtering

**Function Signature**:
php

function getSuppliers()

**Process Flow**:
1. Query suppliers with condition = 0 (active/undeleted)
2. Return array for dropdown population

**Returns**: Array of supplier objects for filter dropdowns

---

### 8. **getProductCatParents()** - Category Hierarchy
**Location**: Line 602  
**Purpose**: Load product category structure for filtering

**Function Signature**:
php

function getProductCatParents()

**Process Flow**:
1. Query all product categories via `queryAllCategories()`
2. Return hierarchical category structure

**Returns**: Category tree for product filtering dropdowns

---

### 9. **checkRoundNumbers()** - Number Formatting Settings
**Location**: Line 610  
**Purpose**: Check system setting for number rounding preferences

**Function Signature**:
php

function checkRoundNumbers()

**Process Flow**:
1. Query program settings for rounding configuration
2. Return rounding status for display formatting

**Returns**: Boolean/setting for number display formatting

---

### 10. **showBuyBills()** - Purchase Bill Serials
**Location**: Line 623  
**Purpose**: Load purchase bill serial numbers for dropdown filtering

**Function Signature**:
php

function showBuyBills()

**Process Flow**:
1. Query all non-deleted purchase bills
2. Extract serial numbers for filter dropdown

**Returns**: Array of bill serials for report filtering

---

## ๐Ÿ”„ Workflows

### Workflow 1: Purchase Bill Report Generation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ START: Select Filters (Supplier/Date/Serial) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 1. Build Query Parameters โ”‚

โ”‚ - Parse supplier filter โ”‚

โ”‚ - Parse date range with timezone โ”‚

โ”‚ - Parse bill serial/ID filters โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 2. Query Purchase Bills โ”‚

โ”‚ - Query buybill table (regular purchases) โ”‚

โ”‚ - Query buyandruternbill table (combined bills) โ”‚

โ”‚ - Apply WHERE clause filters โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 3. Process Each Bill Record โ”‚

โ”‚ FOR EACH purchase bill: โ”‚

โ”‚ โ”‚ โ”‚

โ”‚ โ”œโ”€โ†’ Load bill detail items โ”‚

โ”‚ โ”‚ โ”œโ”€ Product quantities โ”‚

โ”‚ โ”‚ โ”œโ”€ Unit prices โ”‚

โ”‚ โ”‚ โ””โ”€ Line totals โ”‚

โ”‚ โ”‚ โ”‚

โ”‚ โ”œโ”€โ†’ Calculate discount amount โ”‚

โ”‚ โ”‚ โ”œโ”€ Fixed amount vs percentage โ”‚

โ”‚ โ”‚ โ””โ”€ Add detail-level discounts โ”‚

โ”‚ โ”‚ โ”‚

โ”‚ โ”œโ”€โ†’ Calculate tax amount โ”‚

โ”‚ โ”‚ โ””โ”€ (After-discount total - pre-discount) = tax โ”‚

โ”‚ โ”‚ โ”‚

โ”‚ โ””โ”€โ†’ Sum quantities and amounts โ”‚

โ”‚ โ”œโ”€ Total bill amount โ”‚

โ”‚ โ”œโ”€ Total product quantities โ”‚

โ”‚ โ””โ”€ Running discount/tax totals โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 4. Generate Report Output โ”‚

โ”‚ - Merge regular and combined bill data โ”‚

โ”‚ - Assign totals to template variables โ”‚

โ”‚ - Display via buyBillreportview/show.html โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

### Workflow 2: Serial Number Tracking Report

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ START: Search by Serial/Store/Product/Client โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 1. Parse Search Parameters โ”‚

โ”‚ - Detect product size/color variants โ”‚

โ”‚ - Build product query filters โ”‚

โ”‚ - Set search mode (serial/store/product/client) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 2. Query Inventory Serials โ”‚

โ”‚ IF searching by: โ”‚

โ”‚ โ”œโ”€ Serial Number โ†’ Find exact match โ”‚

โ”‚ โ”œโ”€ Store ID โ†’ All serials in store โ”‚

โ”‚ โ”œโ”€ Product โ†’ All serials for product+variants โ”‚

โ”‚ โ””โ”€ Client โ†’ No inventory query (sales only) โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 3. Query Sold Serials โ”‚

โ”‚ IF searching by: โ”‚

โ”‚ โ”œโ”€ Serial Number โ†’ Find if sold โ”‚

โ”‚ โ”œโ”€ Store ID โ†’ No sold query (inventory only) โ”‚

โ”‚ โ”œโ”€ Product โ†’ All sold serials for product โ”‚

โ”‚ โ””โ”€ Client โ†’ All serials sold to client โ”‚

โ”‚ Apply filter: sellbilltype in(0,1) [sales only] โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”‚

โ–ผ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”

โ”‚ 4. Cross-Reference and Display โ”‚

โ”‚ - Match serial numbers between inventory and sales โ”‚

โ”‚ - Identify available vs sold status โ”‚

โ”‚ - Show customer who bought (if sold) โ”‚

โ”‚ - Display via notSoldSerials.html template โ”‚

โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

## ๐ŸŒ URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) or `do=show` | `show()` | Purchase bill reports with filtering |
| `do=notSoldSerials` | Serial tracking | Product serial number tracking report |

### Required Parameters by Action

**Purchase Bill Reports** (`do=show`):
- `supplier` - Supplier ID (-1 for all suppliers)
- `serial` - Bill serial number (-1 for all serials)
- `buybillid` - Specific bill ID (-1 for all bills)
- `from` - Start date (YYYY-MM-DD)  
- `to` - End date (YYYY-MM-DD)

**Serial Tracking** (`do=notSoldSerials`):
- `storeid` - Store/warehouse ID (optional)
- `product` - Product ID or "hasSizeColor" variant (optional)
- `client` - Customer ID for sold serials (optional)
- `productserial` - Specific serial number (optional)

---

## ๐Ÿงฎ Calculation Methods

### Purchase Bill Totals
php

foreach ($buyBillData1 as $myBillData) {

$buybillid = $myBillData->buybillid;

$totalBills = $totalBills + $myBillData->buybillaftertotalbill;

// Sum product quantities

foreach ($buybilldetailes as $mybuybilldetailes) {

$productnumber = $mybuybilldetailes->productnumber;

$buybilldetailquantity = $mybuybilldetailes->buybilldetailquantity;

$totalqty = $totalqty + ($productnumber * $buybilldetailquantity);

}

}

### Discount Processing
php

// Fixed amount discount

if ($buybilldiscountrype == 0) {

$totaldiscount = $totaldiscount + $buybilldiscount + $detaildiscount;

$myBillData->buybilldiscount = ($buybilldiscount + $detaildiscount);

}

// Percentage discount

else {

$discountvalue = ($buybilltotalbill / 100) * $buybilldiscount;

$totaldiscount = $totaldiscount + $discountvalue + $detaildiscount;

$myBillData->buybilldiscount = ($discountvalue + $detaildiscount);

}

### Tax Calculation
php

// Tax = After-total - (Pre-total - Discount)

$taxvalue = $buybillaftertotalbill - ($buybilltotalbill - $discountvalue);

$taxvalue = round($taxvalue, 2);

$taxvalue = ($taxvalue == -0) ? 0 : $taxvalue; // Handle negative zero

### Size/Color Product Parsing
php

if (strpos($product, "hasSizeColor") !== false) {

$productIdComplex = explode('-', str_replace("hasSizeColor", "", $product));

$product = $productIdComplex[0]; // Base product ID

$sizeId = $productIdComplex[1]; // Size variant ID

$colorId = $productIdComplex[2]; // Color variant ID

}

---

## ๐Ÿ”’ Security & Permissions

### Access Control
php

// Authentication required for all actions

include_once("../public/authentication.php");

### Input Sanitization
php

// Filter and cast input parameters

$storeid = (int) filter_input(INPUT_POST, 'storeid');

$product = (int) filter_input(INPUT_POST, 'product');

$client = (int) filter_input(INPUT_POST, 'client');

$productserial = filter_input(INPUT_POST, 'productserial');

### SQL Injection Prevention
- All database queries use DAO layer with parameterized queries
- String inputs filtered through `filter_input()` functions
- Integer casts applied to numeric parameters

---

## ๐Ÿ“Š Performance Considerations

### Database Optimization Tips
1. **Required Indexes**:
   - `buybill(buybillsupplierid, buybilldate)`
   - `buybilldetail(buybillid)`
   - `productserial(serialnumber, productid, storeid)`
   - `soldserialproduct(clientid, sellbilltype)`

2. **Query Optimization**:
   - Date filtering with proper timestamp format
   - Use of specific WHERE clauses in serial searches
   - Efficient JOIN operations in DAO extended methods

3. **Memory Management**:
   - Large date ranges may return many purchase bills
   - Serial number searches can be expensive without proper indexing
   - Category tree traversal is recursive (watch stack depth)

### Known Performance Issues
sql

-- Serial searches without indexes can be slow

SELECT * FROM productserial ps

JOIN soldserialproduct ssp ON ps.productserialid = ssp.productserialid

WHERE ps.productid = ? AND ssp.clientid = ?;

-- Solution: Add composite indexes

CREATE INDEX idx_productserial_product_store ON productserial(productid, storeid);

CREATE INDEX idx_soldserial_client_type ON soldserialproduct(clientid, sellbilltype);

---

## ๐Ÿ› Common Issues & Troubleshooting

### 1. **Missing Serial Numbers in Results**
**Issue**: Serial tracking shows empty results despite known inventory  
**Cause**: Serial numbers not properly linked between `productserial` and `soldserialproduct`

**Debug**:
sql

SELECT COUNT(*) FROM productserial WHERE serialnumber = '[SERIAL]';

SELECT COUNT(*) FROM soldserialproduct ssp

JOIN productserial ps ON ps.productserialid = ssp.productserialid

WHERE ps.serialnumber = '[SERIAL]';

### 2. **Incorrect Purchase Totals**
**Issue**: Report totals don't match individual bill sums  
**Cause**: Mixed discount types or missing detail records

**Debug**:
sql

SELECT bb.buybillid, bb.buybilltotalbill, bb.buybillaftertotalbill,

bb.buybilldiscount, bb.buybilldiscountrype,

SUM(bbd.buybilldetailtotalprice) as detail_total

FROM buybill bb

LEFT JOIN buybilldetail bbd ON bb.buybillid = bbd.buybillid

WHERE bb.buybillid = [ID]

GROUP BY bb.buybillid;

### 3. **Size/Color Product Parsing Errors**
**Issue**: Size/color variants not found in searches  
**Cause**: Incorrect "hasSizeColor" format or missing variant data

**Fix**:
php

// Verify format: "123hasSizeColor-456-789"

// Where: 123=productid, 456=sizeid, 789=colorid

if (strpos($product, "hasSizeColor") !== false && strpos($product, "-") !== false) {

// Process variant

} else {

// Handle as regular product

}

### 4. **Time Zone Issues in Date Filtering**
**Issue**: Reports miss transactions due to time zone differences  
**Cause**: `reportsPlusHours` setting not applied correctly

**Fix**:
php

// Ensure proper time zone adjustment

$Programsetting = $ProgramsettingDAO->load(1);

if (isset($Programsetting->reportsPlusHours)) {

$reportsPlusHours = $Programsetting->reportsPlusHours + 24; // +24 for end of day

$to = date('Y-m-d H:i:s', strtotime('+' . $reportsPlusHours . ' hour', strtotime($to)));

}

---

## ๐Ÿงช Testing Scenarios

### Test Case 1: Basic Purchase Report

1. Select supplier with recent purchases

2. Set date range covering known transactions

3. Verify bill count matches database

4. Check total calculations (amounts, quantities, discounts, tax)

5. Confirm all bill types included (regular + combined)

### Test Case 2: Serial Number Tracking

1. Create test products with serial numbers

2. Record purchase with specific serials

3. Create sale bill using some serials

4. Search by serial number and verify status

5. Search by store and verify inventory

6. Search by customer and verify sold items

### Test Case 3: Size/Color Variant Handling

1. Create product with size and color variants

2. Add serials for different size/color combinations

3. Search using "hasSizeColor" format

4. Verify correct variant filtering

5. Test edge cases (missing variants, invalid format)

### Test Case 4: Discount and Tax Calculations

1. Create bills with fixed amount discounts

2. Create bills with percentage discounts

3. Add detail-level discounts

4. Verify total calculations match manual computation

5. Test edge cases (zero tax, 100% discount)

### Debug Mode Enable
php

// Add at top of controller for debugging

error_reporting(E_ALL);

ini_set('display_errors', 1);

// Debug query building in show()

echo "Query String: " . $queryString . "
";

// Debug serial search logic

echo "Product Query: " . $productQuery . "
";

echo "In Store Serials: " . count($inStoresSerial) . "
";

echo "Sold Serials: " . count($soldSerials) . "
";

```

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur

โ†‘