IncomeStatmentForPeriod Documentation
Income Statement For Period Controller Documentation
File: /controllers/incomeStatmentForPeriod.php
Purpose: Generates comprehensive income statements with profit/loss calculations for specified periods using multiple pricing methods
Last Updated: December 20, 2024
Total Functions: 25+
Lines of Code: ~991
---
๐ Overview
The Income Statement For Period Controller is a sophisticated financial reporting module that generates detailed profit and loss statements. It provides comprehensive financial analysis with:
- โข Multi-period income statement generation
- โข Multiple pricing method support (first, last, mean, with/without discounts and taxes)
- โข Cost of goods sold calculations with various pricing strategies
- โข Revenue recognition from sales, services, and returns
- โข Expense tracking including salaries and operational costs
- โข Restaurant-specific raw material destruction tracking
- โข VAT calculations and tax-inclusive reporting
- โข Automatic time zone adjustment for global operations
Primary Functions
- โ Generate comprehensive income statements
- โ Multiple buy price calculation methods
- โ Revenue analysis from multiple sources
- โ Cost of goods sold calculations
- โ Expense and salary tracking
- โ Profit margin analysis
- โ Restaurant cost tracking
- โ Tax and VAT calculations
Related Controllers
- โข sellbillController.php - Sales transaction data
- โข buyBillController.php - Purchase data for COGS
- โข expensesController.php - Operating expenses
- โข salaryReportController.php - Payroll costs
---
๐๏ธ Database Tables
Sales Revenue Tables
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **sellbill** | Sales transactions | sellbillid, sellbillaftertotalbill, sellbilltotalpayed, sellbilldate, conditions | |
| **sellbilldetail** | Sales line items | sellbilldetailid, sellbillid, sellbilldetailquantity, sellbilldetailtotalprice, productunitid | |
| **returnsellbill** | Sales returns | returnsellbillid, returnsellbillaftertotalbill, returnsellbillsysdate | |
| **returnsellbilldetail** | Return line items | returnsellbilldetailid, returnsellbillid, returnsellbilldetailquantity | |
| **sellbillandrutern** | Combined sell/return bills | sellbillid, sellbillprice, returnsellbillprice, sellbilldate | |
| **sellandruternbilldetail** | Combined bill details | sellandruternbilldetailid, sellbillid, selltype |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **product** | Product master data | productid, lastbuyprice, meanbuyprice, lastbuyprice_withDiscount, meanbuyprice_withDiscount | |
| **productunit** | Product units | productunitid, productnumber | |
| **buybilldetail** | Purchase details for cost | buybilldetailid, buyprice, buydiscount, buydiscounttype | |
| **restaurantrawdestruction** | Raw material waste | id, productid, quantity, productBuyPrice, lastbuyprice, meanbuyprice |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **expenses** | Operating expenses | expensesid, expensesValue, expensesdate, expensestypeid | |
| **expensestype** | Expense categories | expensestypeid, expensestypename | |
| **salaryreport** | Payroll costs | salaryreportid, salaryreportnet, salaryreportdate | |
| **employeepersonnel** | Employee transactions | employeepersonnelid, employeepersonneltype, employeepersonnelvalue |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **bills** | Service bills | billid, finalnetbillvalue, billdate | |
| **billsproducts** | Service line items | billsproductsid, productno, productBuyPrice | |
| **billsreturn** | Service returns | billsreturnid, finalnetbillvalue |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **programsettings** | System settings | programsettingsid, reportsPlusHours, vatValue | |
| **lastbillidspricesupdated** | Price tracking | id, buybill, sell, retsell, buyquantity |
๐ Key Functions
1. show() / Default Action - Generate Income Statement
Location: Line 284
Purpose: Main function that orchestrates income statement generation
Process Flow:
1. Date Range Processing:
$startDate = $_REQUEST['from'];
$endDate = $_REQUEST['to'];
$buyPriceType = $_POST["buyPriceType"];
if (empty($startDate) && empty($endDate)) {
$startDate = $endDate = date('Y-m-d');
}
```
2. **Time Zone Adjustment**:
```php
if (isset($Programsetting->reportsPlusHours) && !empty($Programsetting->reportsPlusHours)) {
$reportsPlusHours = $Programsetting->reportsPlusHours + 24;
$endDate = date('Y-m-d H:i:s', strtotime('+' . $reportsPlusHours . ' hour', strtotime($endDate)));
$startDate = date('Y-m-d H:i:s', strtotime('+' . $Programsetting->reportsPlusHours . ' hour', strtotime($startDate)));
}
```
3. **Revenue Calculation**:
```php
$totalSellPrice = getTotalSellbillByDate($startDate, $endDate) + getTotalAditionalSellbillByDate($startDate, $endDate);
$totalReturnSellPrice = getTotalReturnSellbillByDate($startDate, $endDate) + getTotalAditionalReturnSellbillByDate($startDate, $endDate);
$totalSellCost = $totalSellPrice - $totalReturnSellPrice;
```
4. **Cost of Goods Sold**:
```php
$bills_sellcost = get_total_sellcost($startDate, $endDate);
$total_sellcost = 0;
foreach ($bills_sellcost as $value) {
switch ($buyPriceType) {
case "first": $pro_price = (float) $value->buyprice; break;
case "last": $pro_price = (float) $value->lastbuyprice; break;
case "mean": $pro_price = (float) $value->meanbuyprice; break;
case "last_discount": $pro_price = (float) $value->lastbuyprice_withDiscount; break;
case "mean_discount": $pro_price = (float) $value->meanbuyprice_withDiscount; break;
}
$total_sellcost += ($value->productno * $pro_price);
}
```
5. **Expense and Salary Tracking**:
```php
$totalExpenses = getTotalExpensesByDate($startDate, $endDate);
$totalsalary = gettotalsalary($startDate, $endDate);
```
6. **Final Profit Calculation**:
```php
$total_profit = $totalSellCost - $totalBuyCost - $restaurantRawDestruction;
$profitFinal = $total_profit - ($totalExpenses + $totalsalary);
```
---
### 2. **getTotalSellbillByDate()** - Sales Revenue Calculation
**Location**: Line 500
**Purpose**: Calculate total sales revenue for specified period
**Implementation**:
php
function getTotalSellbillByDate($startDate, $endDate) {
global $mySellbillEx;
$totalSellbill = $mySellbillEx->queryWithDateAndConditionsExt($startDate, $endDate);
return $totalSellbill;
}
---
### 3. **getTotalQuantityBuyPriceByDate()** - COGS Calculation
**Location**: Line 561
**Purpose**: Calculate cost of goods sold using selected pricing method
**Process Flow**:
1. **Query Sales Data**:
```php
$sellbilldetailData = $mySellbilldetailEx->queryWithDateAndConditionsExt($startDate, $endDate);
```
2. **Price Method Selection**:
```php
switch ($buyPriceType) {
case "first": $buyPrice = (float) $sellbilldetail->buyprice; break;
case "last": $buyPrice = (float) $sellbilldetail->lastbuyprice; break;
case "mean": $buyPrice = (float) $sellbilldetail->meanbuyprice; break;
case "last_discount": $buyPrice = (float) $sellbilldetail->lastbuyprice_withDiscount; break;
case "mean_discount": $buyPrice = (float) $sellbilldetail->meanbuyprice_withDiscount; break;
case "tax": $buyPrice = (float) $sellbilldetail->lastbuyprice_withTax; break;
case "mean_tax": $buyPrice = (float) $sellbilldetail->meanbuyprice_withTax; break;
}
```
3. **Unit Conversion and Calculation**:
```php
$quantity = $sellbilldetail->sellbilldetailquantity;
$productnumber = $myProductunitEx->getProductNumber($productunitId);
if ($productnumber == 0) $productnumber = 1;
$productBuyPrice = $buyPrice * $productnumber;
$totalQuantityBuyPrice += ($quantity * $productBuyPrice);
```
---
### 4. **gettotalsalary()** - Payroll Cost Calculation
**Location**: Line 870
**Purpose**: Calculate total salary and employee-related costs
**Process Flow**:
1. **Base Salary Calculation**:
```php
$allsalary = $SalaryreportEX->queryAllbydata($startDate, $endDate);
$sumsalary = 0;
foreach ($allsalary as $myallsalary) {
$sumsalary += $myallsalary->salaryreportnet;
}
```
2. **Employee Personnel Transactions**:
```php
$allpersonaldata = $EmployeepersonnelEX->queryAllbydateforreport($startDate, $endDate);
foreach ($allpersonaldata as $myallpersonaldata) {
if ($myallpersonaldata->employeepersonneltype == 4) {
$Borrow += $myallpersonaldata->employeepersonnelvalue;
} elseif ($myallpersonaldata->employeepersonneltype == 3) {
$Withdrawal += $myallpersonaldata->employeepersonnelvalue;
} elseif ($myallpersonaldata->employeepersonneltype == 6) {
$Repayment += $myallpersonaldata->employeepersonnelvalue;
}
}
```
3. **Final Calculation**:
```php
$allfinal = ($sumsalary + $Withdrawal + $Borrow) - $Repayment;
return $allfinal;
```
---
### 5. **getRestaurantRawDestruction()** - Material Waste Tracking
**Location**: Line 960
**Purpose**: Calculate cost of destroyed/wasted raw materials
**Implementation**:
php
function getRestaurantRawDestruction($startDate, $endDate, $buyPriceType) {
global $restaurantRawDestructionEX;
$restaurantRawDestruction = $restaurantRawDestructionEX->queryBySysdateBetween($startDate, $endDate);
$rawDestructionCost = 0;
foreach ($restaurantRawDestruction as $value) {
switch ($buyPriceType) {
case 'first': $rawDestructionCost += $value->productBuyPrice * $value->quantity; break;
case 'last': $rawDestructionCost += $value->lastbuyprice * $value->quantity; break;
case "last_discount": $rawDestructionCost += $value->lastbuyprice_withDiscount * $value->quantity; break;
case "mean_discount": $rawDestructionCost += $value->meanbuyprice_withDiscount * $value->quantity; break;
default: $rawDestructionCost += $value->meanbuyprice * $value->quantity; break;
}
}
return $rawDestructionCost;
}
---
## ๐ Workflows
### Workflow 1: Complete Income Statement Generation
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Income Statement Request โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Date Range Processing โ
โ - Parse from/to dates โ
โ - Apply timezone adjustments โ
โ - Set default to current date if empty โ
โ - Add time bounds (00:00:00 to 23:59:59) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Revenue Calculation โ
โ A. Sales Revenue: โ
โ โโ Regular sales (sellbill) โ
โ โโ Combined sell/return transactions โ
โ โโ Service bills (optical/restaurant) โ
โ B. Sales Returns: โ
โ โโ Return bills (returnsellbill) โ
โ โโ Return portions of combined bills โ
โ โโ Service return bills โ
โ C. Net Sales = Sales Revenue - Sales Returns โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Cost of Goods Sold Calculation โ
โ A. Choose Pricing Method: โ
โ โโ First purchase price โ
โ โโ Last purchase price โ
โ โโ Mean (average) purchase price โ
โ โโ Prices with discount applied โ
โ โโ Prices with tax included โ
โ B. Calculate for Each Item Sold: โ
โ โโ Get quantity sold โ
โ โโ Get product unit conversion โ
โ โโ Apply selected pricing method โ
โ โโ Sum: quantity ร unit conversion ร price โ
โ C. Include Service Item Costs โ
โ D. Subtract Return Item Costs โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Operating Expenses โ
โ A. Direct Expenses: โ
โ โโ Query expenses table by date range โ
โ โโ Filter by expense type โ
โ โโ Sum all expense values โ
โ B. Payroll Costs: โ
โ โโ Base salaries from salary reports โ
โ โโ Employee withdrawals โ
โ โโ Employee loans/advances โ
โ โโ Loan repayments (subtract) โ
โ C. Restaurant-Specific: โ
โ โโ Raw material destruction/waste costs โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. Profit Calculations โ
โ A. Gross Profit: โ
โ โโ Net Sales - Cost of Goods Sold - Material Waste โ
โ B. Net Profit: โ
โ โโ Gross Profit - Operating Expenses - Payroll โ
โ C. Assign All Values to Template โ
โ D. Generate Report Display โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
## ๐ URL Routes & Actions
| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=show` or `do=` (empty) | Default action | Generate income statement report |
| `do=sucess` | Success page | Display success message |
| `do=error` | Error page | Display error message |
### Required Parameters
**Generate Report** (`do=show`):
- `from` - Start date (YYYY-MM-DD)
- `to` - End date (YYYY-MM-DD)
- `buyPriceType` - Pricing method (first/last/mean/last_discount/mean_discount/tax/mean_tax)
### URL Examples
Basic report for current month
incomeStatmentForPeriod.php?from=2024-01-01&to=2024-01-31
With specific pricing method
incomeStatmentForPeriod.php?from=2024-01-01&to=2024-01-31&buyPriceType=mean_discount
---
## ๐งฎ Calculation Methods
### Buy Price Method Selection
php
switch ($buyPriceType) {
case "first":
$message .= " ู ุงูุญุณุงุจ ุจู ุณุนุฑ ุดุฑุงุก";
$buyPrice = (float) $sellbilldetail->buyprice;
break;
case "last":
$message .= " ู ุงูุญุณุงุจ ุจู ุงุฎุฑ ุณุนุฑ ุดุฑุงุก";
$buyPrice = (float) $sellbilldetail->lastbuyprice;
break;
case "mean":
$message .= " ู ุงูุญุณุงุจ ุจู ู ุชูุณุท ุณุนุฑ ุงูุดุฑุงุก";
$buyPrice = (float) $sellbilldetail->meanbuyprice;
break;
case "last_discount":
$message .= " ู ุงูุญุณุงุจ ุจู ุงุฎุฑ ุณุนุฑ ุดุฑุงุก ุจุนุฏ ุงูุฎุตู ";
$buyPrice = (float) $sellbilldetail->lastbuyprice_withDiscount;
break;
case "mean_discount":
$message .= " ู ุงูุญุณุงุจ ุจู ู ุชูุณุท ุณุนุฑ ุงูุดุฑุงุก ุจุนุฏ ุงูุฎุตู ";
$buyPrice = (float) $sellbilldetail->meanbuyprice_withDiscount;
break;
case "tax":
$message .= " ู ุงูุญุณุงุจ ุจู ุงุฎุฑ ุณุนุฑ ุดุฑุงุก ุดุงู ู ุงูููู ุฉ ุงูู ุถุงูุฉ";
$buyPrice = (float) $sellbilldetail->lastbuyprice_withTax;
break;
case "mean_tax":
$message .= " ู ุงูุญุณุงุจ ุจู ู ุชูุณุท ุณุนุฑ ุงูุดุฑุงุก ุดุงู ู ุงูููู ุฉ ุงูู ุถุงูุฉ";
$buyPrice = (float) $sellbilldetail->meanbuyprice_withTax;
break;
}
### Unit Conversion Handling
php
$quantity = $sellbilldetail->sellbilldetailquantity;
$productunitId = $sellbilldetail->productunitid;
$productnumber = $myProductunitEx->getProductNumber($productunitId);
if ($productnumber == 0) {
$productnumber = 1; // Prevent division by zero
}
$productBuyPrice = $buyPrice * $productnumber;
$totalQuantityBuyPrice += ($quantity * $productBuyPrice);
### Salary Cost Calculation
php
// Base salaries
$sumsalary = 0;
foreach ($allsalary as $myallsalary) {
$sumsalary += $myallsalary->salaryreportnet;
}
// Employee transactions
$Withdrawal = 0; $Borrow = 0; $Repayment = 0;
foreach ($allpersonaldata as $myallpersonaldata) {
switch ($myallpersonaldata->employeepersonneltype) {
case 4: $Borrow += $myallpersonaldata->employeepersonnelvalue; break;
case 3: $Withdrawal += $myallpersonaldata->employeepersonnelvalue; break;
case 6: $Repayment += $myallpersonaldata->employeepersonnelvalue; break;
}
}
$totalSalaryCost = ($sumsalary + $Withdrawal + $Borrow) - $Repayment;
---
## ๐ Security & Permissions
### Authentication Check
php
include_once("../public/authentication.php");
### Input Validation
- Date format validation for start/end dates
- Pricing method validation against allowed values
- SQL injection prevention via DAO layer
- Numeric validation for calculations
### Data Access Control
- All queries filtered by date range
- Condition-based filtering (conditions = 0) for active records
- User session validation for access rights
---
## ๐ Performance Considerations
### Database Optimization Tips
1. **Critical Indexes Required**:
```sql
CREATE INDEX idx_sellbill_date_conditions ON sellbill(sellbilldate, conditions);
CREATE INDEX idx_sellbilldetail_date ON sellbilldetail(sellbilldate);
CREATE INDEX idx_returnsellbill_date ON returnsellbill(returnsellbillsysdate, conditions);
CREATE INDEX idx_expenses_date ON expenses(expensesdate, conditions);
CREATE INDEX idx_salaryreport_date ON salaryreport(salaryreportdate);
```
2. **Query Optimization**:
- Use of proper date range queries
- Efficient JOIN operations in extended DAOs
- Minimal data retrieval with specific column selection
3. **Memory Management**:
- Large datasets may consume significant memory
- Consider pagination for very long date ranges
- Efficient array processing for calculations
### Known Performance Bottlenecks
php
// This section can be slow for large datasets
foreach ($sellbilldetailData as $sellbilldetail) {
$productnumber = $myProductunitEx->getProductNumber($productunitId);
// Consider caching product unit numbers
}
**Solution**:
php
// Cache product unit numbers
static $unitCache = array();
if (!isset($unitCache[$productunitId])) {
$unitCache[$productunitId] = $myProductunitEx->getProductNumber($productunitId);
}
$productnumber = $unitCache[$productunitId];
---
## ๐ Common Issues & Troubleshooting
### 1. **Incorrect Profit Calculations**
**Issue**: Profit figures don't match expected values
**Cause**: Wrong pricing method or missing data
**Debug**:
php
// Add debugging output
echo "Sales Total: " . $totalSellPrice . "
";
echo "Returns Total: " . $totalReturnSellPrice . "
";
echo "COGS Total: " . $totalQuantityBuyPrice . "
";
echo "Expenses Total: " . $totalExpenses . "
";
echo "Salary Total: " . $totalsalary . "
";
### 2. **Date Range Issues**
**Issue**: No data returned for valid date range
**Cause**: Timezone conversion or date format problems
**Debug**:
php
echo "Start Date: " . $startDate . "
";
echo "End Date: " . $endDate . "
";
echo "Reports Plus Hours: " . $Programsetting->reportsPlusHours . "
";
### 3. **Missing Revenue Data**
**Issue**: Sales data not appearing in report
**Cause**: Condition filtering or date field mismatches
**Debug**:
sql
-- Check data availability
SELECT COUNT(*) FROM sellbill
WHERE sellbilldate BETWEEN '2024-01-01' AND '2024-01-31'
AND conditions = 0;
### 4. **Memory Exhaustion**
**Issue**: Script timeout or memory errors for large date ranges
**Cause**: Processing too much data at once
**Solution**:
php
// Add memory monitoring
echo "Memory usage: " . memory_get_usage(true) / 1024 / 1024 . " MB
";
ini_set('memory_limit', '512M');
---
## ๐งช Testing Scenarios
### Test Case 1: Basic Income Statement
1. Set date range to known transaction period
2. Select "mean" pricing method
3. Verify all revenue sections populate
4. Check COGS calculations against manual calculation
5. Confirm final profit matches expected result
### Test Case 2: Different Pricing Methods
1. Run same date range with different pricing methods
2. Verify COGS changes appropriately
3. Compare first vs last vs mean price impacts
4. Test discount and tax inclusive methods
### Test Case 3: Edge Cases
1. Test empty date range (no transactions)
2. Test single day with mixed transaction types
3. Test period spanning year boundary
4. Verify timezone adjustment accuracy
### Debug Mode Enable
php
// Add at top of controller for debugging
error_reporting(E_ALL);
ini_set('display_errors', 1);
// Add calculation debugging
function debug_calculation($label, $value) {
echo "$label: " . number_format($value, 2) . "
";
}
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข sellbillController.md - Sales transaction management
- โข buyBillController.md - Purchase transaction management
- โข expensesController.md - Expense management
- โข Database Schema Documentation - Table relationships and indexes
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur