Quickprofitreports Documentation

Quick Profit Reports Controller Documentation

File: /controllers/quickprofitreports.php

Purpose: Generates comprehensive quick profit analysis reports for sales performance tracking

Last Updated: December 20, 2024

Total Functions: 2+

Lines of Code: ~406

---

๐Ÿ“‹ Overview

The Quick Profit Reports Controller is a specialized reporting module that provides detailed profit analysis capabilities across multiple dimensions. It handles:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Profit Tables (Direct Operations)

Table NamePurposeKey Columns
**quickprofitgeneral**System-wide profit totalsid, netSellVal, netSellCostBuyPrice, netSellCostLastBuyPrice, netSellCostMeanBuyPrice, netSellCostLastBuyPricewithDiscount, netSellCostMeanBuyPricewithDiscount, netSellCostOverAllAveragePrice
**quickprofitday**Daily profit breakdownid, theDate, sellVal, sellCostBuyPrice, sellCostLastBuyPrice, sellCostMeanBuyPrice, returnSellVal, returnSellCostBuyPrice, returnSellCostLastBuyPrice, returnSellCostMeanBuyPrice
**quickprofitclient**Client-specific profitsid, clientId, theDate, sellVal, sellCostBuyPrice, sellCostLastBuyPrice, sellCostMeanBuyPrice, returnSellVal, clientname, areaName
**quickprofitproduct**Product-level profitsid, productId, theDate, sellVal, sellCostBuyPrice, sellCostLastBuyPrice, sellCostMeanBuyPrice, returnSellVal, returnSellCostBuyPrice, returnSellCostLastBuyPrice
**quickprofitstore**Store-specific profitsid, storeId, theDate, sellVal, sellCostBuyPrice, sellCostLastBuyPrice, sellCostMeanBuyPrice, returnSellVal, returnSellCostBuyPrice, returnSellCostLastBuyPrice
### Reference Tables

Table NamePurposeKey Columns
**store**Store master datastoreid, storename, storedesc
**client**Customer informationclientid, clientname, clientarea
**product**Product master dataproductid, productname, productCatId
**productcat**Product categoriesproductCatId, productCatName, productCatParent
**youtubelink**Tutorial/help linksyoutubelinkid, title, url
**programsettings**System configurationprogramsettingsid, settingkey, settingvalue
### Calculation Reference Tables

Table NamePurposeKey Columns
**sellbill**Sales transactionssellbillid, sellbillclientid, sellbilltotalbill, sellbilldate
**buypriceshistorybook**Purchase price historyproductId, buyPrice, lastBuyPrice, meanBuyPrice
**storedetail**Inventory costsproductid, storeid, buyprice, lastbuyprice, meanbuyprice
---

๐Ÿ”‘ Key Functions

1. Default Action - General Profit Overview

Location: Line 109

Purpose: Display system-wide profit summary and overview dashboard

Function Signature:

// Triggered when: empty $do
// No parameters required

Process Flow:

1. Include authentication check

2. Load general profit data from quickprofitgeneral table

3. Load YouTube tutorial links

4. Set empty dates flag for template

5. Display via general.html template

Features:

---

2. day - Daily Profit Report

Location: Line 122

Purpose: Generate daily profit breakdown with date range filtering

Function Signature:

// Triggered when: do=day
$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Process Flow:

1. Parse and validate date parameters

2. Set default buy price type to "first" if not specified

3. Build dynamic query string for date filtering

4. Query quickprofitday table with date constraints

5. Handle empty date scenario (show general profits)

6. Display via day.html template

Query Building:

if (isset($from) && !empty($from)) {
    $queryString .= 'and quickprofitday.theDate >= "' . $from . '" ';
}
if (isset($to) && !empty($to)) {
    $queryString .= 'and quickprofitday.theDate <= "' . $to . '" ';
}

Features:

---

3. storeday - Store-Specific Daily Profits

Location: Line 159

Purpose: Generate daily profit reports filtered by store and date range

Function Signature:

// Triggered when: do=storeday
$storeId = filter_input(INPUT_POST, "storeId");
$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Process Flow:

1. Load all store master data for dropdown

2. Parse store and date filter parameters

3. Build query with store and date constraints

4. Query quickprofitstore table

5. Display via storeDay.html template

Query Building:

if (isset($storeId) && !empty($storeId)) {
    $queryString .= 'and quickprofitstore.storeId = "' . $storeId . '" ';
}

Features:

---

4. productday - Product-Level Profit Analysis

Location: Line 197

Purpose: Track profit performance for specific products over time

Function Signature:

// Triggered when: do=productday
$productId = filter_input(INPUT_POST, "productId");
$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Process Flow:

1. Load program settings for display configuration

2. Parse product and date parameters

3. Build query for product-specific filtering

4. Query quickprofitproduct table

5. Display via productDay.html template

Features:

---

5. catday - Category Profit Report

Location: Line 234

Purpose: Analyze profit performance by product category

Function Signature:

// Triggered when: do=catday
$lastCatId = filter_input(INPUT_POST, "lastCatId");
$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Process Flow:

1. Load program settings

2. Parse category and date parameters

3. Build query with category filtering via JOIN to productcat

4. Query quickprofitproduct with category constraints

5. Display via catDay.html template

Query Building:

if (isset($lastCatId) && !empty($lastCatId)) {
    $queryString .= 'and productcat.productCatId = "' . $lastCatId . '" ';
}

Features:

---

6. allcatday - Hierarchical Category Profit Summary

Location: Line 272

Purpose: Comprehensive category analysis with sub-category rollup

Function Signature:

// Triggered when: do=allcatday
$level = filter_input(INPUT_POST, 'level');
$productCatId = filter_input(INPUT_POST, 'productCatId' . $level);
$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Process Flow:

1. Load program settings and category hierarchy via getCategoryChilds()

2. Parse hierarchical category selection (supports multiple levels)

3. Handle category level fallback logic

4. Build category ID string including all subcategories via getAllSubCat()

5. Query with category IN clause for hierarchical inclusion

6. Use specialized queryAllEXGroupByCatAndDate() method

7. Display via allCatDay.html template

Category Hierarchy Processing:

$catsIDS = '' . $productCatId;
if ($productCatId != '') {
    getAllSubCat($productCatId, 1); // mode = 1 get all sub cats
}

Advanced Query:

if (isset($catsIDS) && !empty($catsIDS)) {
    $queryString .= 'and productcat.productCatId in (' . $catsIDS . ') ';
}

Features:

---

7. clientday - Client Profit Analysis

Location: Line 323

Purpose: Track profit performance per customer over time

Function Signature:

// Triggered when: do=clientday
$clientId = filter_input(INPUT_POST, "clientId");
$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Process Flow:

1. Parse client and date filter parameters

2. Build query string for client-specific filtering

3. Query quickprofitclient table

4. Display via clientDay.html template

Features:

---

8. getAllSubCat() - Recursive Category Function

Location: Line 367

Purpose: Recursively build category ID list including all subcategories

Function Signature:

function getAllSubCat($catid, $mode)

Process Flow:

1. Query subcategories using queryByParentExt()

2. For each subcategory:

- Add to global $catsIDS string (mode 1)

- Or collect last-level categories (mode 2)

- Recursively call self for deeper levels

3. Build comma-separated ID string for SQL IN clauses

Modes:

Recursive Logic:

foreach ($result as $data) {
    if ($mode == 1) {
        $catsIDS .= "," . $data->productCatId;
        getAllSubCat($data->productCatId, $mode);
    }
}

---

๐Ÿ”„ Workflows

Workflow 1: Daily Profit Report Generation

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Select Date Range & Price Type
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Parse Input Parameters
- from: Start date (YYYY-MM-DD)
- to: End date (YYYY-MM-DD)
- buyPriceType: first/last/mean
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Build Dynamic Query String
IF from date provided:
ADD: and quickprofitday.theDate >= "from"
IF to date provided:
ADD: and quickprofitday.theDate <= "to"
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Handle Empty Date Scenario
IF no dates provided:
โ”‚
โ†’ Load general profit summary
โ†’ Set emptyDates flag = 1
โ”‚ โ””โ”€โ†’ Display general.html template โ”‚
ELSE:
โ”‚
โ”‚ โ””โ”€โ†’ Continue to daily query โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Query Daily Profit Data
- Execute queryAllEX() on quickprofitday
- Apply date range filters
- Set emptyDates flag = 0
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
5Load Supporting Data
- Load YouTube tutorial links
- Assign buy price type for template
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
6Display Report
- Assign data to Smarty template
- Display via day.html template
- Include profit calculations by price type
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

Workflow 2: Hierarchical Category Profit Analysis

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Select Category Level & Date Range
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Category Hierarchy
- Call getCategoryChilds() from reportfunctions.php
- Build category tree structure
- Assign to template for dropdown population
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Process Category Selection
- Parse level parameter
- Get productCatId for selected level
- Handle fallback to previous level if needed
- Initialize category ID string
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Recursive Subcategory Collection
IF productCatId is not empty:
โ”‚
โ†’ Call getAllSubCat(productCatId, 1)
โ”‚
โ†’ Query subcategories via queryByParentExt()
โ”‚
โ”‚ โ”œโ”€โ†’ FOR EACH subcategory:
โ”‚
โ”‚ โ”‚ โ”‚ โ””โ”€ Recursively call getAllSubCat() โ”‚
โ”‚
โ”‚ โ”‚ โ””โ”€โ†’ Build comma-separated ID list โ”‚
โ”‚
โ”‚ โ””โ”€โ†’ Result: "123,124,125,126..." for SQL IN clause โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Build Enhanced Query
- Add date range filters if provided
- Use specialized queryAllEXGroupByCatAndDate()
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
5Execute Aggregated Query
- Query quickprofitproduct with JOIN to productcat
- GROUP BY category and date
- Sum profit values across subcategories
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
6Display Hierarchical Report
- Show category tree structure
- Display aggregated profit values
- Include subcategory breakdown
- Present via allCatDay.html template
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
`do=` (empty)Default actionGeneral system profit overview
`do=day`Daily reportingDaily profit breakdown with date filtering
`do=storeday`Store daily analysisStore-specific daily profits
`do=productday`Product analysisIndividual product profit tracking
`do=catday`Category analysisSingle category profit report
`do=allcatday`Hierarchical categoriesMulti-level category profit with rollup
`do=clientday`Client analysisCustomer-specific profit tracking
### Required Parameters by Action

General Report (do= empty):

Daily Report (do=day):

Store Daily (do=storeday):

Product Daily (do=productday):

Category Daily (do=catday):

All Categories (do=allcatday):

Client Daily (do=clientday):

---

๐Ÿงฎ Calculation Methods

Buy Price Types

The system supports multiple cost calculation methods controlled by $buyPriceType:

"first" - First Purchase Price:

"last" - Last Purchase Price:

"mean" - Average Purchase Price:

"withDiscount" - Discount-Adjusted Prices:

Profit Calculations

// Basic profit calculation
$profit = $sellVal - $sellCost;
$profitMargin = ($profit / $sellVal) * 100;

// Net profit (including returns)
$netProfit = ($sellVal - $returnSellVal) - ($sellCost - $returnSellCost);

Return Impact Analysis

// Returns reduce both revenue and cost
$netSellVal = $sellVal - $returnSellVal;
$netSellCost = $sellCost - $returnSellCost;
$netProfit = $netSellVal - $netSellCost;

---

๐Ÿ”’ Security & Permissions

Authentication

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

Input Sanitization

$from = filter_input(INPUT_POST, "from");
$to = filter_input(INPUT_POST, "to");
$buyPriceType = filter_input(INPUT_POST, "buyPriceType");

Data Access Control

---

๐Ÿ“Š Performance Considerations

Database Optimization Tips

1. Required Indexes:

   -- Daily reports
   CREATE INDEX idx_quickprofitday_date ON quickprofitday(theDate);
   
   -- Store reports  
   CREATE INDEX idx_quickprofitstore_store_date ON quickprofitstore(storeId, theDate);
   
   -- Product reports
   CREATE INDEX idx_quickprofitproduct_product_date ON quickprofitproduct(productId, theDate);
   
   -- Client reports
   CREATE INDEX idx_quickprofitclient_client_date ON quickprofitclient(clientId, theDate);
   
   -- Category hierarchy
   CREATE INDEX idx_productcat_parent ON productcat(productCatParent);
   ```

2. **Query Optimization**:
   - Date range queries benefit from proper date formatting
   - Category hierarchy queries can be expensive with deep nesting
   - Consider materialized views for complex aggregations

3. **Memory Management**:
   - Large date ranges may return significant data
   - Category recursion limited by available memory
   - Template variable cleanup important for category reports

### Known Performance Issues
sql

-- Recursive category queries can be slow with deep hierarchies

-- Consider limiting recursion depth or using iterative approach

-- Date range queries without indexes

SELECT * FROM quickprofitday

WHERE theDate BETWEEN '2024-01-01' AND '2024-12-31';

-- Solution: Add proper date index and limit ranges

CREATE INDEX idx_quickprofitday_thedate ON quickprofitday(theDate);

---

## ๐Ÿ› Common Issues & Troubleshooting

### 1. **Empty Profit Data**
**Issue**: Reports show no data despite having sales  
**Cause**: Profit calculation process (`calcquickprofit.php`) not running

**Debug**:
sql

-- Check if profit tables are populated

SELECT COUNT(*) FROM quickprofitday WHERE theDate >= '2024-01-01';

SELECT COUNT(*) FROM quickprofitproduct WHERE theDate >= '2024-01-01';

**Fix**: Run profit calculation process to populate tables

### 2. **Category Hierarchy Issues**
**Issue**: Subcategories not included in reports  
**Cause**: `getAllSubCat()` recursion failing or category relationships broken

**Debug**:
sql

-- Check category parent relationships

SELECT productCatId, productCatName, productCatParent

FROM productcat WHERE productCatParent IS NOT NULL;

-- Verify category hierarchy integrity

SELECT COUNT(*) as orphaned_categories

FROM productcat c1

LEFT JOIN productcat c2 ON c1.productCatParent = c2.productCatId

WHERE c1.productCatParent IS NOT NULL AND c2.productCatId IS NULL;

### 3. **Date Range Problems**
**Issue**: Date filters not working correctly  
**Cause**: Date format mismatch or timezone issues

**Debug**:
php

// Check date format in queries

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

// Verify date format matches database

echo "From: " . $from . " To: " . $to . "
";

**Fix**:
php

// Ensure proper date format

if (!empty($from)) $from .= " 00:00:00";

if (!empty($to)) $to .= " 23:59:59";

### 4. **Buy Price Type Confusion**
**Issue**: Profit calculations inconsistent between reports  
**Cause**: Different buy price types selected or default not set

**Fix**:
php

// Always set default buy price type

if (!isset($buyPriceType) || empty($buyPriceType)) {

$buyPriceType = "first";

}

---

## ๐Ÿงช Testing Scenarios

### Test Case 1: Daily Profit Accuracy

1. Create test sales with known costs

2. Run profit calculation process

3. Generate daily report for test date

4. Verify profit = revenue - cost matches manually calculated values

5. Test with different buy price types

### Test Case 2: Category Hierarchy Rollup

1. Create category structure: Parent > Child > Grandchild

2. Add products to grandchild category

3. Generate sales for these products

4. Run allcatday report selecting parent category

5. Verify totals include all descendant categories

### Test Case 3: Date Range Filtering

1. Create sales across multiple months

2. Test date range spanning partial months

3. Verify exact date boundary handling

4. Test edge cases (single day, year boundaries)

### Debug Mode Enable
php

// Add at top of controller for debugging

error_reporting(E_ALL);

ini_set('display_errors', 1);

// Debug query building

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

echo "Category IDs: " . $catsIDS . "
";

// Debug data results

echo "

";

print_r($quickProfitDay);

echo "

";

```

---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur