Auto Sales Report Controller Documentation
File: /controllers/autoSalesReport.php
Purpose: Generates automated sales reports comparing purchase and sale data to calculate profit margins
Last Updated: December 20, 2024
Total Functions: 4
Lines of Code: ~240
---
๐ Overview
The Auto Sales Report Controller is a specialized reporting module that provides comprehensive profit analysis by tracking products from purchase to sale. It handles:
- โข Serial number-based product tracking
- โข Purchase vs sale price comparison
- โข Profit margin calculations
- โข Supplier and client filtering
- โข Date range analysis
- โข Real-time data retrieval with AJAX
- โข DataTables integration for dynamic reporting
- โข Return exclusion logic
Primary Functions
- โ Generate profit analysis reports
- โ Track products by serial numbers
- โ Compare buy and sell prices
- โ Filter by supplier, client, product code
- โ Date range filtering
- โ AJAX-based data loading
- โ Return bill exclusion
- โ Real-time profit calculations
Related Controllers
- โข sellbillController.php - Sales operations
- โข buyBillController.php - Purchase operations
- โข clientReportsController.php - Client reporting
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **sellbilldetail** | Sales bill line items | sellbilldetailid, sellbillid, sellbilldetailproductid, parcode, sellbilldetailquantity | |
| **productserial** | Product serial number tracking | serialnumber, billid, del | |
| **sellbill** | Sales bills master | sellbillid, sellbillclientid, sellbillaftertotalbill, sellbilldate, conditions | |
| **buybill** | Purchase bills master | buybillid, buybillsupplierid, buybillaftertotalbill, buybilldate |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **client** | Customer information | clientid, clientname | |
| **supplier** | Supplier information | supplierid, suppliername | |
| **buybilldetail** | Purchase bill line items | buybilldetailid, buybillid | |
| **returnsellbill** | Sales return bills | returnsellbillid, returnsellbillclientid, returnsellbilldate, conditions | |
| **returnsellbilldetail** | Return bill details | returnsellbilldetailid, returnsellbillid, parcode |
๐ Key Functions
1. Default Action - Report Interface
Location: Line 25
Purpose: Display the main report interface
Process Flow:
1. Display header template
2. Load main report interface (autoSalesReportview/index.html)
3. Display footer template
---
2. select2supplier() - Supplier Search
Location: Line 45
Purpose: AJAX endpoint for supplier autocomplete functionality
Function Signature:
function select2supplier()
Process Flow:
1. Get search term from POST data
2. Query suppliers with LIKE match on supplier name
3. Format results for Select2 dropdown
4. Return JSON response
SQL Query:
SELECT supplierid, suppliername as name
FROM supplier
WHERE suppliername LIKE '%{searchTerm}%'
LIMIT 50
---
3. select2client() - Client Search
Location: Line 63
Purpose: AJAX endpoint for client autocomplete functionality
Function Signature:
function select2client()
Process Flow:
1. Get search term from POST data
2. Query clients with LIKE match on client name
3. Format results for Select2 dropdown
4. Return JSON response
SQL Query:
SELECT clientid, clientname as name
FROM client
WHERE clientname LIKE '%{searchTerm}%'
LIMIT 50
---
4. select2code() - Product Code Search
Location: Line 81
Purpose: AJAX endpoint for product code autocomplete
Function Signature:
function select2code()
Process Flow:
1. Get search term from POST data
2. Query unique product codes from sales details
3. Format results for Select2 dropdown
4. Return JSON response
SQL Query:
SELECT parcode
FROM sellbilldetail
WHERE parcode LIKE '%{searchTerm}%'
LIMIT 50
---
5. showajax() - Main Report Data
Location: Line 99
Purpose: Generate profit analysis report with DataTables integration
Function Signature:
function showajax()
Process Flow:
1. Parse filter parameters (dates, supplier, client, product code)
2. Build dynamic WHERE clause based on filters
3. Execute complex JOIN query linking purchases to sales
4. Filter out returned items
5. Calculate profit margins
6. Format data for DataTables
7. Add totals row
8. Return JSON response
Key Features:
- โข Return Exclusion: Checks
returnsellbillto exclude returned items - โข Profit Calculation:
sellbillaftertotalbill - buybillaftertotalbill - โข Date Filtering: Defaults to current day if no dates provided
- โข DataTables Integration: Supports sorting, pagination, search
Complex SQL Query:
SELECT *, sellbilldetail.sellbillid as sellbillidend,
sellbilldetail.parcode as parcodes,
sellbill.sellbilldate as sellbilldates
FROM sellbilldetail
LEFT JOIN sellbill ON sellbilldetail.sellbillid = sellbill.sellbillid
AND sellbill.conditions = 0
LEFT JOIN client ON sellbill.sellbillclientid = client.clientid
LEFT JOIN productserial ON sellbilldetail.parcode = productserial.serialnumber
LEFT JOIN buybill ON productserial.billid = buybill.buybillid
LEFT JOIN buybilldetail ON buybill.buybillid = buybilldetail.buybillid
LEFT JOIN supplier ON buybill.buybillsupplierid = supplier.supplierid
WHERE productserial.del = 0 {searchQuery}
Return Check Logic:
$countreturnsellbill = R::count("returnsellbill",
" LEFT JOIN returnsellbilldetail ON returnsellbill.returnsellbillid = returnsellbilldetail.returnsellbillid
WHERE returnsellbilldetail.parcode = ?
AND returnsellbill.returnsellbilldate >= ?
AND returnsellbill.conditions = 0 ",
[$row["parcodes"], $row["sellbilldates"]]);
---
๐ Workflows
Workflow 1: Profit Analysis Report Generation
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default action | Main report interface | |
| `do=select2client` | `select2client()` | Client autocomplete | |
| `do=select2supplier` | `select2supplier()` | Supplier autocomplete | |
| `do=showajax` | `showajax()` | Report data via AJAX | |
| `do=select2code` | `select2code()` | Product code autocomplete |
Client Search (do=select2client):
- โข Method: POST
- โข Parameter:
searchTerm - โข Returns: JSON array for Select2
Supplier Search (do=select2supplier):
- โข Method: POST
- โข Parameter:
searchTerm - โข Returns: JSON array for Select2
Report Data (do=showajax):
- โข Method: POST
- โข Parameters:
fromdate,todate,data1(supplier),data2(client),data3(code) - โข Returns: DataTables-formatted JSON
---
๐งฎ Calculation Methods
Profit Calculation
$finaltotals += round($row["sellbillaftertotalbill"] - $row["buybillaftertotalbill"]);
Return Detection Logic
$countreturnsellbill = R::count("returnsellbill",
" LEFT JOIN returnsellbilldetail ON returnsellbill.returnsellbillid = returnsellbilldetail.returnsellbillid
WHERE returnsellbilldetail.parcode = ?
AND returnsellbill.returnsellbilldate >= ?
AND returnsellbill.conditions = 0 ",
[$row["parcodes"], $row["sellbilldates"]]);
if ($countreturnsellbill == 0) {
// Include in profit calculation
}
Date Range Handling
if ($fromdate != '' && $todate != '') {
$searchQuery .= " and sellbilldate >= '$fromdate' and sellbilldate <= '$todate' ";
} else {
$today = date("Y-m-d");
$searchQuery .= 'and sellbilldate >= "' . $today . ' 00-00-00" and sellbilldate <= "' . $today . ' 23-59-55" ';
}
---
๐ Security & Permissions
Input Sanitization
- โข POST parameters are used directly in SQL queries
- โข Security Risk: SQL injection vulnerability in search filters
- โข Recommendation: Use parameterized queries
Current Security Issues
// VULNERABLE CODE
$searchQuery .= " and client.clientid = " . $clientid . " ";
$searchQuery .= " and supplier.supplierid = " . $supplierid . " ";
// SHOULD BE
$searchQuery .= " and client.clientid = ? ";
// With parameter binding
---
๐ Performance Considerations
Database Optimization Tips
1. Required Indexes:
- productserial(serialnumber, billid)
- sellbilldetail(parcode, sellbillid)
- sellbill(sellbilldate, conditions)
- buybill(buybillid, buybillsupplierid)
2. Query Performance:
- Complex JOIN across 6+ tables
- No LIMIT on main query (potential memory issues)
- Subquery for each row to check returns
Known Performance Issues
- โข N+1 Query Problem: Return check executed for each result row
- โข Large Joins: Multiple LEFT JOINs can be slow with large datasets
- โข Missing Pagination: No LIMIT clause for large result sets
---
๐ Common Issues & Troubleshooting
1. Missing Products in Report
Issue: Products don't appear in profit analysis
Cause: Product missing from productserial table or del = 1
Debug:
SELECT * FROM productserial WHERE serialnumber = '{code}';
2. Incorrect Profit Calculations
Issue: Profit margins don't match expected values
Cause: Return exclusion or wrong price fields
Check:
SELECT sellbillaftertotalbill, buybillaftertotalbill
FROM sellbill s, buybill b
WHERE s.sellbillid = {sellbillid} AND b.buybillid = {buybillid};
3. Performance Issues
Issue: Report loads slowly or times out
Cause: Large date ranges or missing indexes
Solutions:
- โข Add date range limits
- โข Create composite indexes
- โข Implement pagination
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข sellbillController.md - Sales operations
- โข buyBillController.php - Purchase operations
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur