Profitproductcatnew Documentation

Profit Product Category Controller New Documentation

File: /controllers/profitproductcatControllernew.php

Purpose: Enhanced version of category profit analysis with simplified structure and improved calculations

Last Updated: December 20, 2024

Total Functions: 15

Lines of Code: ~932

---

๐Ÿ“‹ Overview

The Profit Product Category Controller New is an enhanced version of the original category controller, providing streamlined category-level profit analysis with simplified code structure. It maintains core functionality while improving:

Primary Functions

Key Improvements Over Original

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Core Category Tables

Table NamePurposeKey Columns
**productcat**Product categoriesproductcatid, productcatname, productcatparent
**product**Product master dataproductid, productname, productcatid
### Sales Transaction Tables

Table NamePurposeKey Columns
**sellbilldetail**Sales line itemssellbilldetailproductid, sellbilldetailquantity, sellbilldetailprice, buyprice
**returnsellbilldetail**Return line itemsreturnsellbilldetailproductid, returnsellbilldetailquantity, returnsellbilldetailprice
**sellandruternbilldetail**Combined bill detailssellbilldetailproductid, sellbilldetailquantity, selltype, buyprice
### Product & Inventory Tables

Table NamePurposeKey Columns
**productunit**Units of measureproductunitid, productnumber
---

๐Ÿ”‘ Key Functions

1. show() / Default Action - Simplified Category Report

Location: Line 203

Purpose: Generate category profit report with simplified interface

Function Signature:

// Triggered when: do=show or empty $do
$productCatData = loadProductCat();
$productCatId = $_REQUEST['productCatId']; 
$startDate = $_REQUEST['from'];
$endDate = $_REQUEST['to'];

Process Flow:

1. Load category dropdown data

2. Validate input parameters

3. Load category information

4. Call getProductInBillByDateAndCatId() for calculations

5. Display results via profitproductcatview/show.html

Simplified Structure:

if (isset($startDate) && isset($endDate) && $startDate != "" && $endDate != "" && 
    isset($productCatId) && $productCatId != "-1") {
    
    $productCatSearchData = loadProductCatById($productCatId);
    $smarty->assign('productCatSearchData', $productCatSearchData);
    
    getProductInBillByDateAndCatId($startDate, $endDate, $productCatId);
    
    $message = "ุชู‚ุฑูŠุฑ ุงุฑุจุงุญ ุตู†ู <h4>" . $productCatSearchData->productCatName . 
               "</h4> ุงู„ุชุงุฑูŠุฎ : ู…ู† " . $startDate . " ุฅู„ู‰ " . $endDate;
    $smarty->assign("message", $message);
}

---

2. getProductInBillByDateAndCatId() - Simplified Category Analysis

Location: Line 243

Purpose: Calculate profit metrics for all products in a single category (no recursive subcategories)

Function Signature:

function getProductInBillByDateAndCatId($startDate, $endDate, $productcatId)

Streamlined Process:

1. Query products in specified category only

2. For each product:

- Calculate sales data

- Calculate return data

- Calculate cost data

- Compute individual profit

3. Aggregate category totals

4. Assign results to template

Simplified Profit Calculation:

$h = 1;
foreach ($productIdData as $productIdDa) {
    $productId = $productIdDa->productid;
    
    // Sales calculations
    $sellPriceData = getTotalSellPriceByDateAndProductId($startDate, $endDate, $productId);
    $sellPricePulsData = getTotalAditionalSellPriceByDateAndProductId($startDate, $endDate, $productId);
    
    $sellPrice = $sellPriceData[0] + $sellPricePulsData[0];
    $quantityUnit = $sellPriceData[1] + $sellPricePulsData[1];
    
    // Return calculations  
    $returnSellPriceData = getTotalReturnSellPriceByDateAndProductId($startDate, $endDate, $productId);
    $returnSellPricePulsData = getTotalAditionalReturnSellPriceByDateAndProductId($startDate, $endDate, $productId);
    
    $returnSellPrice = $returnSellPriceData[0] + $returnSellPricePulsData[0];
    $returnQuantityUnit = $returnSellPriceData[1] + $returnSellPricePulsData[1];
    
    // Cost calculations
    $buybillPriceData = getTotalBuyPriceByDateAndProductId($startDate, $endDate, $productId);
    $buybillPricePulsData = getTotalAditionalBuyPriceByDateAndProductId($startDate, $endDate, $productId);
    
    $buybillPrice = $buybillPriceData[0] + $buybillPricePulsData[0];
    
    // Simple profit calculation
    $yy = $sellPrice - $returnSellPrice;
    $quantityForOneProduct = $quantityUnit - $returnQuantityUnit;
    $xx = ($buybillPrice) / $quantityUnit;
    $profitForOneProduct = ($yy) - ($quantityForOneProduct * $xx);
    
    $finalProductcatProfit += $profitForOneProduct;
    
    $smarty->assign("profitForOneProduct" . $h . '', $profitForOneProduct);
    $smarty->assign("quantityForOneProduct" . $h . '', $quantityForOneProduct);
    
    $h++;
}

---

3. getTotalSellPriceByDateAndProductId() - Simplified Sales Analysis

Location: Line 466

Purpose: Calculate sales revenue with basic discount handling

Function Signature:

function getTotalSellPriceByDateAndProductId($startDate, $endDate, $ProductIdselected)

Simplified Discount Logic:

foreach ($sellbilldetailData as $sellbilldetail) {
    $quantity = $sellbilldetail->sellbilldetailquantity;
    $price = $sellbilldetail->sellbilldetailprice;
    $discountValue = $sellbilldetail->discountvalue;
    $sellbillDiscount = $sellbilldetail->sellbilldiscount;
    $sellbillDiscountType = $sellbilldetail->sellbilldiscounttype;
    $buyprice = $sellbilldetail->buyprice;
    
    // Simple percentage discount handling
    if ($sellbillDiscountType == 2) {
        $sellbillDiscount = ($sellbillDiscount / 100) * $sellbillTotalBill;
    }
    
    $totalPriceBeforeDiscount = $price * $quantity;
    
    // Unit conversion
    $productnumber = $myProductunitEx->getProductNumber($productunitId);
    $quantityUnit += ($quantity * $productnumber);
    
    // Simple discount calculation
    $thirdStep = ($totalPrice / $sellbillTotalBill) * $sellbillDiscount;
    $sellPriceForOneProduct = $totalPriceBeforeDiscount - ($discountValue + $thirdStep);
    $sellPrice += $sellPriceForOneProduct;
}

---

4. getTotalAditionalSellPriceByDateAndProductId() - Combined Bill Processing

Location: Line 525

Purpose: Handle combined sell/return bills with simplified logic

Streamlined Processing:

$sellandreturndetailData = $mySellandruternbilldetailEx->queryWithDateAndConditionsTypeAndProductIdExt($startDate, $endDate, 0, $ProductIdselected);

foreach ($sellandreturndetailData as $sellandreturndetail) {
    // Basic field extraction
    $quantity = $sellandreturndetail->sellbilldetailquantity;
    $price = $sellandreturndetail->sellbilldetailprice;
    $discountValue = $sellandreturndetail->discountvalue;
    $buyprice = $sellandreturndetail->buyprice;
    
    // Simplified discount handling
    $totalPriceBeforeDiscount = $price * $quantity;
    $productnumber = $myProductunitEx->getProductNumber($productunitId);
    $quantityUnit += ($quantity * $productnumber);
    
    $thirdStep = ($totalPrice / $sellbillTotalBill) * $sellbillDiscount;
    $sellPriceForOneProduct = $totalPriceBeforeDiscount - ($discountValue + $thirdStep);
    $sellPrice += $sellPriceForOneProduct;
}

---

5. loadProductCat() - Category Dropdown Data

Location: Line 890

Purpose: Load category data for dropdown selection

Function Signature:

function loadProductCat()

Hierarchical Name Building:

$productcatData = $myProductcatEx->queryProductcatInProduct();
foreach ($productcatData as $productcat) {
    $productcat->productCatName = loadProductCatNameById($productcat->productCatId, $productcatName, 1);
}
return $productcatData;

---

6. loadProductCatNameById() - Category Path Builder

Location: Line 903

Purpose: Build hierarchical category paths for display

Recursive Path Building:

function loadProductCatNameById($productCatId, $productcatName, $itr) {
    global $myProductcatRecord;
    
    $productcatData = $myProductcatRecord->load($productCatId);
    
    if (count($productcatData) > 0) {
        if ($itr == 1) {
            $productcatNamex = $productcatData->productCatName;
        } elseif ($itr == 2) {
            $productcatNamex = $productcatData->productCatName . "/" . $productcatNamex;
        }
        
        if ($productcatData->productCatParent != 0) {
            return loadProductCatNameById($productcatData->productCatParent, $productcatNamex, 2);
        }
    }
    return $productcatNamex;
}

---

๐Ÿ”„ Workflows

Workflow 1: Simplified Category Profit Analysis

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Select Category & Date Range
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Load Category Data
- Load all categories for dropdown
- Build hierarchical names
- Prepare selection interface
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Validate Input Parameters
- Check category ID selection
- Validate date range
- Load selected category data
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Query Products in Selected Category
- Get products for single category (no subcategories)
- Load product master data
- Prepare for individual analysis
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Process Each Product Simply
FOR EACH product:
โ”‚
โ†’ Calculate sales (regular + combined)
โ†’ Calculate returns (regular + combined)
โ†’ Calculate costs (regular + combined)
โ†’ Compute simple profit
โ”‚ โ””โ”€โ†’ Add to category totals โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
5Aggregate & Display Results
- Sum all individual profits
- Calculate total quantities
- Assign to template variables
- Display single view
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
`do=` (empty) or `do=show`Default actionSimplified category profit analysis
`do=success`Success pageDisplay success message
`do=error`Error pageDisplay error message
### Required Parameters

Category Analysis (do=show):

---

๐Ÿงฎ Calculation Methods

Simplified Profit Formula

$yy = $sellPrice - $returnSellPrice;  // Net sales
$quantityForOneProduct = $quantityUnit - $returnQuantityUnit;  // Net quantity
$xx = ($buybillPrice) / $quantityUnit;  // Average unit cost
$profitForOneProduct = ($yy) - ($quantityForOneProduct * $xx);  // Simple profit

Basic Discount Handling

// Percentage discount
if ($sellbillDiscountType == 2) {
    $sellbillDiscount = ($sellbillDiscount / 100) * $sellbillTotalBill;
}

// Apply product and bill discounts
$sellPriceForOneProduct = $totalPriceBeforeDiscount - ($discountValue + $thirdStep);

Category Aggregation

$finalProductcatProfit = 0;
foreach ($productIdData as $productIdDa) {
    // Calculate individual product profit...
    $profitForOneProduct = ($yy) - ($quantityForOneProduct * $xx);
    $finalProductcatProfit += $profitForOneProduct;
}

---

๐Ÿ”’ Security & Permissions

Authentication

Input Validation

Security Improvements Over Original

---

๐Ÿ“Š Performance Considerations

Performance Benefits

1. Reduced Complexity:

- No recursive category tree processing

- Single category processing only

- Fewer database queries per request

2. Improved Response Time:

- Simplified calculations

- Reduced memory usage

- Fewer template variable assignments

3. Better Scalability:

- No stack overflow risks from recursion

- Predictable query patterns

- Consistent performance regardless of category depth

Database Optimization

1. Required Indexes:

- product(productcatid) for category filtering

- sellbilldetail(sellbilldetailproductid, sysdate)

- productcat(productcatparent) for name building

2. Query Efficiency:

- Single category query (no tree traversal)

- Predictable result set sizes

- Better query caching opportunities

---

๐Ÿ› Common Issues & Troubleshooting

1. Missing Subcategory Data

Issue: Report only shows direct category products, not subcategories

Expected Behavior: This is by design - simplified version processes single category only

Solution: Use original profitproductcatController.php for subcategory inclusion

2. Simpler Profit Calculations

Issue: Profit values differ from original controller

Cause: Simplified calculation method vs complex discount handling

Verification: Check if business rules require complex discount calculations

3. Category Name Display

Issue: Hierarchical category names not displaying properly

Cause: loadProductCatNameById() recursion issues

Debug: Check parent-child relationships in productcat table

---

๐Ÿงช Testing Scenarios

Test Case 1: Basic Category Report

1. Select single category with products
2. Set date range with transactions  
3. Run simplified report
4. Verify calculations are correct but simpler than original

Test Case 2: Compare with Original Controller

1. Run same parameters on both controllers
2. Compare results and identify differences
3. Document calculation methodology differences
4. Verify business rule compliance

Test Case 3: Performance Comparison

1. Test with large categories
2. Measure response times vs original
3. Check memory usage
4. Verify scalability improvements

---

๐Ÿ“š Key Differences from Original

FeatureOriginal ControllerNew Controller
**Category Selection**Multi-level dropdown (5 levels)Single dropdown
**Subcategory Inclusion**Recursive tree processingSingle category only
**Discount Calculations**Complex multi-levelSimplified basic
**Optical Products**Full integrationNot implemented
**Template Variables**Dynamic per productStandard pattern
**Performance**Complex, slowerSimple, faster
**Code Maintainability**Complex, harderSimple, easier
**Recursion Risks**Stack overflow possibleNone
---

๐Ÿ“š Related Documentation

---

Documented By: AI Assistant

Review Status: โœ… Complete

Next Review: When major changes occur