๐Ÿ“š ERP Documentation Viewer

Beautiful, colorful documentation for your ERP system

Product Reports Controller Documentation

File: /controllers/productReportsController.php

Purpose: Generates comprehensive inventory reports with price analysis, category-based filtering, and inventory valuation

Last Updated: December 20, 2024

Total Functions: 12+

Lines of Code: ~890

---

๐Ÿ“‹ Overview

The Product Reports Controller is a specialized reporting module that provides detailed product and inventory analysis capabilities. It handles:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables (Direct Operations)

Table NamePurposeKey Columns
**product**Product master dataproductid, productname, productcatid, productbuysprice, productsellallprice, productquantity, productdate
**productcat**Product categoriesproductcatid, productcatname, productcatparent, buydiscount, selldiscount, discounttype
**store**Store/warehouse datastoreid, storename, storeaddress
### Inventory Tables (Referenced)

Table NamePurposeKey Columns
**storedetail**Product inventory by storestoredetailid, storedetailproductid, storedetailstoreid, storedetailproductquantity
**buypriceshistorybook**Purchase price historybuypriceshistorybookid, productid, buyprice, buypricewithindiscount, buypricetax
### System Tables

Table NamePurposeKey Columns
**programsettings**System configurationprogramsettingsid, inventoryevaluation, settingkey, settingvalue
**youtubelink**Tutorial linksyoutubelinkid, title, url
**usergroup**User permissionsusergroupid, usergroupname, permissions
### Reference Tables

Table NamePurposeKey Columns
**user**System usersuserid, username, usergroupid
---

๐Ÿ”‘ Key Functions

1. reportWithAllPrices - Complete Product Price Report

Location: Line 108

Purpose: Generate comprehensive report showing all product prices and inventory valuation

Function Signature:

// Triggered when: do=reportWithAllPrices
$sellAllDiscount = (float) $_REQUEST['sellAllDiscount'];
$productCatId = $_REQUEST['productCatId'];
$startDate = $_REQUEST['from'];
$endDate = $_REQUEST['to'];

Process Flow:

1. Load program settings for inventory evaluation method

2. Load YouTube tutorial links

3. Get product categories for dropdown

4. Process category selection:

- Single category: Call searchProductsWithBuyPrice()

- All categories: Call searchProductsWithBuyPriceforallSimple()

5. Apply weighted discount calculations

6. Display report or print version

Features:

---

2. reportWithBuyPrice - Buy Price Analysis Report

Location: Line 172

Purpose: Focus on purchase prices and category-based cost analysis

Function Signature:

// Triggered when: do=reportWithBuyPrice
$productCatId = $_REQUEST['productCatId'];

Process Flow:

1. Load all categories with parent relationships

2. Load YouTube tutorial links

3. Process category selection:

- Single category: Call searchProductsWithBuyPrice()

- All categories: Loop through all categories calling searchProductsWithBuyPriceforall()

4. Calculate totals across all categories

5. Display comprehensive buy price report

Features:

---

3. searchProductsWithBuyPrice() - Core Price Analysis Logic

Location: Line 321

Purpose: Main function for product price analysis with inventory valuation

Function Signature:

function searchProductsWithBuyPrice($sellAllDiscount = 0)

Process Flow:

1. Build date filter query if date range provided

2. Load program settings for inventory evaluation method

3. Query products by category with quantity summation

4. For each product:

- Apply inventory evaluation method (first/last/mean/tax)

- Calculate weighted discount pricing

- Apply category discounts (fixed or percentage)

- Process all 12 price levels

- Calculate running totals

5. Assign processed data to template

Inventory Evaluation Methods:

Discount Processing:

if ($discounttype == 0) { // Fixed amount discount
    $productBuyPrice = $productBuyPrice - $buydiscount;
    $productSellAllPrice = $productSellAllPrice - $selldiscount;
} else { // Percentage discount
    $productBuyPrice = $productBuyPrice - (($buydiscount / 100) * $productBuyPrice);
    $productSellAllPrice = $productSellAllPrice - (($selldiscount / 100) * $productSellAllPrice);
}

---

4. searchProductsWithBuyPriceforallSimple() - All Products Analysis

Location: Line 509

Purpose: Simplified version for processing all products across categories

Function Signature:

function searchProductsWithBuyPriceforallSimple($sellAllDiscount = 0)

Process Flow:

1. Load program settings for evaluation method

2. Build date filter if provided

3. Query all products with quantity summation

4. Process each product with same logic as single category

5. Apply category discounts from loaded category data

6. Calculate grand totals across all products

Key Differences from Single Category:

---

5. searchProductsWithBuyPriceforall() - Category Loop Processor

Location: Line 686

Purpose: Process products for a specific category when looping through all categories

Function Signature:

function searchProductsWithBuyPriceforall($productCatId, $i)

Process Flow:

1. Load program settings

2. Query products for specific category

3. Process each product with inventory evaluation

4. Apply category-specific discounts

5. Calculate category totals

6. Assign to indexed template variables (totalPrice{$i}, totalQuantity{$i})

7. Add to global running totals

Template Variable Pattern:

$smarty->assign('totalPrice' . $i, $totalPrice);
$smarty->assign('totalQuantity' . $i, $totalQuantity);

---

6. getProductCats() - Category Navigation Builder

Location: Line 240

Purpose: Build category hierarchy for navigation and display

Function Signature:

function getProductCats()

Process Flow:

1. Query all products with category information

2. For each product:

- Get category parent hierarchy

- Build recursive category path

- Assign navigation variables to template

3. Create indexed category data for template loops

Recursive Category Building:

function fetch_recursive($parentid, $categories) {
    $catData = $productCatExt->getCategoryAndParentByCatId($parentid);
    $categories .= $catData->productCatName . '/';
    if ($newParentId != 0) {
        fetch_recursive($newParentId, $categories);
    }
}

---

7. getAllProducts() - Product Dropdown Data

Location: Line 306

Purpose: Load product list with category names for selection dropdowns

Function Signature:

function getAllProducts()

Process Flow:

1. Query all products with extended category information

2. Build full product name with category path

3. Return array for dropdown population

Product Name Construction:

$productFullName = $pro->productCatName . '/' . $pro->productName;

---

8. showProductsWithBuyPrice() - Basic Display Function

Location: Line 827

Purpose: Simple product display with buy price analysis (appears unused)

Note: This function appears to be legacy code and is not actively used in the current workflow.

---

๐Ÿ”„ Workflows

Workflow 1: Complete Product Price Report Generation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Select Category & Options
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load System Configuration
- Get inventory evaluation method
- Load program settings
- Check user permissions
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Process Category Selection
IF single category:
โ†’ Call searchProductsWithBuyPrice()
โ”‚ โ””โ”€โ†’ Get category hierarchy path โ”‚
IF all categories:
โ†’ Call searchProductsWithBuyPriceforallSimple()
โ”‚ โ””โ”€โ†’ Process entire product catalog โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Apply Inventory Evaluation Method
SWITCH evaluation method:
โ†’ "first": Use original purchase price
โ†’ "last": Use most recent purchase price
โ†’ "mean": Calculate average purchase price
โ†’ "last_discount": Last price with discount
โ†’ "mean_discount": Average price with discount
โ†’ "tax": Last price including tax
โ”‚ โ””โ”€โ†’ "mean_tax": Average price including tax โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Process Each Product
FOR EACH product in results:
โ”‚
โ†’ Apply weighted discount calculation
โ”‚ โ”œโ”€ Calculate discount percentage
โ”‚ โ”‚ โ””โ”€ Apply to buy price โ”‚
โ”‚
โ†’ Process all 12 price levels
โ”‚ โ”œโ”€ productSellAllPrice
โ”‚ โ”œโ”€ productSellUnitPrice
โ”‚ โ”œโ”€ productSellHalfPrice
โ”‚ โ”‚ โ””โ”€ price4 through price13 โ”‚
โ”‚
โ†’ Apply category discounts
โ”‚ โ”œโ”€ Check discount type (fixed vs percentage)
โ”‚ โ”‚ โ””โ”€ Apply to all price levels โ”‚
โ”‚
โ”‚ โ””โ”€โ†’ Calculate inventory value โ”‚
โ”‚ โ””โ”€ Quantity ร— Evaluated Price โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
5Generate Report Output
IF print mode:
โ”‚ โ””โ”€โ†’ Display weightedDiscountReportPrint.html โ”‚
ELSE:
โ”‚ โ””โ”€โ†’ Display reportWithAllPrices.html โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

Workflow 2: Buy Price Category Analysis

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Category Buy Price Analysis
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Category Structure
- Get all categories with parent relationships
- Build category hierarchy
- Load YouTube tutorial links
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Process Category Selection
IF single category:
โ†’ Get products for specific category
โ†’ Build category path display
โ”‚ โ””โ”€โ†’ Display single category report โ”‚
IF all categories:
โ†’ Loop through each category
โ†’ Process products per category
โ”‚ โ””โ”€โ†’ Calculate grand totals โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Category Loop Processing
FOR EACH category:
โ”‚
โ†’ Call searchProductsWithBuyPriceforall()
โ”‚
โ†’ Process products in category
โ”‚ โ”œโ”€ Apply inventory evaluation
โ”‚ โ”œโ”€ Calculate category totals
โ”‚ โ”‚ โ””โ”€ Store in indexed variables โ”‚
โ”‚
โ”‚ โ””โ”€โ†’ Add to grand totals โ”‚
โ”œโ”€ totalcount += category quantity
โ”‚ โ””โ”€ totalpricecount += category value โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Generate Category Summary Report
- Display all categories with individual totals
- Show grand total across all categories
- Present via allreportWithBuyPrice.html
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
`do=` (empty)Default (disabled)Product movement report (not implemented)
`do=reportWithAllPrices``searchProductsWithBuyPrice()`Complete product pricing report
`do=reportWithBuyPrice``searchProductsWithBuyPrice()` / Category loopBuy price analysis report
### Required Parameters by Action

Complete Price Report (do=reportWithAllPrices):

Buy Price Report (do=reportWithBuyPrice):

Output Formats

Print Mode (when sellAllDiscount > 0):

Standard Mode:

---

๐Ÿงฎ Calculation Methods

Inventory Evaluation Calculation

switch ($pro_price) {
    case "first":
        $productBuyPrice = (float) $pro->productBuyPrice;
        break;
    case "last":
        $productBuyPrice = (float) $pro->lastbuyprice;
        break;
    case "mean":
        $productBuyPrice = (float) $pro->meanbuyprice;
        break;
    case "last_discount":
        $productBuyPrice = (float) $pro->lastbuyprice_withDiscount;
        break;
    case "mean_discount":
        $productBuyPrice = (float) $pro->meanbuyprice_withDiscount;
        break;
    case "tax":
        $productBuyPrice = (float) $pro->lastbuyprice_withTax;
        break;
    case "mean_tax":
        $productBuyPrice = (float) $pro->meanbuyprice_withTax;
        break;
    default:
        $productBuyPrice = (float) $pro->overAllAveragePrice;
        break;
}

Weighted Discount Processing

$pro->weightedDiscount = (float) ($pro->weightedDiscount - $sellAllDiscount);
$pro->weightedDiscountBuyPrice = (float) $pro->lastbuyprice;
$pro->weightedDiscountPer = 1 - ($pro->weightedDiscount / 100);
$pro->weightedDiscountBuyPriceAfterDisc = round(($pro->weightedDiscountBuyPrice * $pro->weightedDiscountPer), 2);

Category Discount Application

// Fixed amount discount
if ($discounttype == 0) {
    $productBuyPrice = $productBuyPrice - $buydiscount;
    $productSellAllPrice = $productSellAllPrice - $selldiscount;
    // Apply to all 12 price levels
}
// Percentage discount
else {
    $productBuyPrice = $productBuyPrice - (($buydiscount / 100) * $productBuyPrice);
    $productSellAllPrice = $productSellAllPrice - (($selldiscount / 100) * $productSellAllPrice);
    // Apply to all 12 price levels
}

Total Value Calculation

$totalPrice += $pro->sumProductQuantity * $productBuyPrice;
$totalQuantity += $pro->sumProductQuantity;

---

๐Ÿ”’ Security & Permissions

User Permission Levels

$userGroup = $userGroupDAO->load($_SESSION['usergroupid']);
$smarty->assign("userGroup", $userGroup);

Permission Checks:

Input Sanitization

$sellAllDiscount = (float) $_REQUEST['sellAllDiscount'];
$productCatId = $_REQUEST['productCatId'];
$startDate = $_REQUEST['from'];
$endDate = $_REQUEST['to'];

Security Measures:

---

๐Ÿ“Š Performance Considerations

Database Optimization Tips

1. Indexes Required:

- product(productcatid, productdate)

- productcat(productcatparent)

- storedetail(storedetailproductid)

- buypriceshistorybook(productid)

2. Query Optimization:

- Date filtering for product additions: product.productDate >= ? AND product.productDate <= ?

- Category filtering with parent relationships

- Quantity summation queries with proper GROUP BY

3. Memory Management:

- Large product catalogs may require pagination

- Category loop processing can be memory intensive

- Template variable cleanup for multiple categories

Known Performance Issues

-- This query can be slow for large product catalogs
SELECT product.*, SUM(storedetail.storedetailproductquantity) as sumProductQuantity
FROM product 
LEFT JOIN storedetail ON product.productid = storedetail.storedetailproductid
WHERE product.productcatid = ?
GROUP BY product.productid;

-- Solution: Add covering index
CREATE INDEX idx_product_cat_date ON product(productcatid, productdate, productid);

---

๐Ÿ› Common Issues & Troubleshooting

1. Missing Price Data

Issue: Products show zero or null prices

Cause: Missing buypriceshistorybook entries or incorrect evaluation method

Debug:

SELECT p.productname, p.productbuysprice, 
       bph.buyprice, bph.buypricewithindiscount
FROM product p
LEFT JOIN buypriceshistorybook bph ON p.productid = bph.productid
WHERE p.productcatid = [CATEGORY_ID];

2. Incorrect Quantity Totals

Issue: Quantity summation doesn't match actual inventory

Cause: Missing or duplicate storedetail records

Debug:

SELECT productid, SUM(storedetailproductquantity) as total_qty
FROM storedetail 
WHERE storedetailproductid = [PRODUCT_ID]
GROUP BY storedetailproductid;

3. Category Hierarchy Issues

Issue: Category paths not displaying correctly

Cause: Circular references or missing parent categories

Fix:

-- Check for circular references
WITH RECURSIVE cat_tree AS (
  SELECT productcatid, productcatname, productcatparent, 1 as level
  FROM productcat WHERE productcatparent = 0
  UNION ALL
  SELECT c.productcatid, c.productcatname, c.productcatparent, ct.level + 1
  FROM productcat c
  INNER JOIN cat_tree ct ON c.productcatparent = ct.productcatid
  WHERE ct.level < 10
)
SELECT * FROM cat_tree WHERE level > 5;

4. Discount Calculation Errors

Issue: Discount calculations producing negative prices

Cause: Discount values higher than base prices

Fix:

// Add validation before discount application
if ($discounttype == 0) { // Fixed discount
    $productBuyPrice = max(0, $productBuyPrice - $buydiscount);
} else { // Percentage discount
    if ($buydiscount <= 100) {
        $productBuyPrice = $productBuyPrice - (($buydiscount / 100) * $productBuyPrice);
    }
}

---

๐Ÿงช Testing Scenarios

Test Case 1: Basic Product Report

1. Select category with products
2. Verify all price levels display correctly
3. Check quantity summation accuracy
4. Confirm discount calculations
5. Validate total calculations

Test Case 2: Inventory Evaluation Methods

1. Set up product with multiple purchase prices
2. Test each evaluation method (first/last/mean/tax)
3. Verify calculations match expected values
4. Check discount applications

Test Case 3: Category Hierarchy

1. Create nested category structure
2. Add products to various levels
3. Test "all categories" report
4. Verify category totals accuracy
5. Check parent path generation

Test Case 4: Date Range Filtering

1. Add products on different dates
2. Set date range filters
3. Verify only products in range appear
4. Test edge cases (same date, empty range)

Debug Mode Enable

// Add at top of controller for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Debug evaluation method
echo "Evaluation Method: " . $pro_price . "<br>";

// Debug price calculations
echo "Buy Price: " . $productBuyPrice . "<br>";
echo "Quantity: " . $pro->sumProductQuantity . "<br>";
echo "Total Value: " . ($pro->sumProductQuantity * $productBuyPrice) . "<br>";

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur

โ†‘