Real Estate Units Reports Controller Documentation
File: /controllers/realestateunitsreports.php
Purpose: Generates comprehensive financial reports for real estate operations including income, expenses, and inventory consumption
Last Updated: December 20, 2024
Total Functions: 2
Lines of Code: ~120
---
๐ Overview
The Real Estate Units Reports Controller is a specialized reporting module that provides comprehensive financial analysis for real estate operations. It consolidates data from multiple sources including rental income (from tenants), ownership expenses (to suppliers), and inventory consumption related to property operations.
Primary Functions
- โ Combined real estate financial reporting
- โ Supplier payment expense tracking
- โ Client rental income tracking
- โ Property-specific financial analysis
- โ Unit-specific financial breakdown
- โ Inventory consumption tracking
- โ Date range filtering and analysis
- โ Multi-month period calculations
Related Controllers
- โข realestateunitsowners.php - Supplier payment data source
- โข realestateunitsrenters.php - Client income data source
- โข expensesController.php - General expense data
- โข restaurantrawdestruction.php - Inventory consumption
---
๐๏ธ Database Tables
Primary Data Sources
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **realestateunitspaids** | Main payment records (both income & expense) | id, supplierid, clientid, realestateid, realestateunitid, totalpaid, payed, addtoday | |
| **realestateunitpaidinstallments** | Individual installment records | id, realestateunitpaidid, totalpaid, payed, del | |
| **expenses** | General property-related expenses | expensesid, realestateid, realestateunitid, expensesdate, expensevalue | |
| **restaurantrawdestruction** | Inventory consumption by property | id, realestateid, realestateunitid, quantity, sysdate |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **realestates** | Property master data | id, realestatename | |
| **realestatesunits** | Property unit details | id, unitname | |
| **supplier** | Property owners/suppliers | supplierid, suppliername | |
| **client** | Tenants/clients | clientid, clientname | |
| **product** | Inventory items | productId, productName | |
| **programsettings** | System configuration | programsettingsid, Inventoryevaluation |
๐ Key Functions
1. Default Action - Report Display
Location: Line 6
Purpose: Displays the main report interface template
Function Signature:
// Triggered when: do parameter is empty
if (empty($do))
Process Flow:
1. Display header template
2. Display main report template (realestateunitsreportsview/show.html)
3. Display footer template
Features:
- โข Basic report interface
- โข Filter selection forms
- โข Date range pickers
- โข Property/unit selection dropdowns
---
2. getdata() - Comprehensive Report Generation
Location: Line 10
Purpose: Generates detailed financial report with supplier expenses, client income, general expenses, and inventory consumption
Function Signature:
// Triggered when: do=getdata
$start_date = filter_input(INPUT_POST, 'start_date');
$end_date = filter_input(INPUT_POST, 'end_date');
$supplierid = filter_input(INPUT_POST, 'supplierid');
$clientid = filter_input(INPUT_POST, 'clientid');
$realestateid = filter_input(INPUT_POST, 'realestateid');
$realestateunitid = filter_input(INPUT_POST, 'realestateunitid');
Process Flow:
1. Parse Input Parameters - Extract date range and filter criteria
2. Build Search Queries - Create dynamic WHERE clauses for each data source
3. Query Supplier Payments - Get paid amounts to property owners
4. Query Client Payments - Get received amounts from tenants
5. Query General Expenses - Get other property-related expenses
6. Query Inventory Consumption - Get consumed inventory items
7. Apply Inventory Valuation - Calculate costs based on system settings
8. Calculate Period Duration - Determine months for analysis
9. Assign Data to Template - Pass all data to display template
Data Sources Queried:
Supplier Payments (Property Purchases/Expenses):
$srealestateunitspaids = R::findAll('realestateunitspaids',
"where del < 2 and clientid = 0 and payed > 0 $searchQuery $ssearchQuery");
Client Payments (Rental Income):
$crealestateunitspaids = R::findAll('realestateunitspaids',
"where del < 2 and supplierid = 0 and payed > 0 $searchQuery $csearchQuery");
General Expenses:
$expenses = R::getAll("SELECT * FROM expenses
left join realestates on expenses.realestateid = realestates.id
left join realestatesunits on expenses.realestateunitid = realestatesunits.id
where expenses.conditions = 0 $esearchQuery");
Inventory Consumption:
$restaurantrawdestruction = R::getAll("SELECT *, $buyprice as buypricenew, quantity as quantitynew
FROM restaurantrawdestruction
left join product on restaurantrawdestruction.productid = product.productId
left join realestates on restaurantrawdestruction.realestateid = realestates.id
left join realestatesunits on restaurantrawdestruction.realestateunitid = realestatesunits.id
where restaurantrawdestruction.conditions = 0 $rsearchQuery");
---
๐ Workflows
Workflow 1: Comprehensive Financial Report Generation
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default display | Show report interface | |
| `do=getdata` | Data generation | Generate comprehensive report |
Date Range (Optional - defaults to current date):
- โข
start_date- Report start date (YYYY-MM-DD) - โข
end_date- Report end date (YYYY-MM-DD)
Filters (All Optional):
- โข
supplierid- Filter by specific supplier - โข
clientid- Filter by specific client - โข
realestateid- Filter by specific property - โข
realestateunitid- Filter by specific unit
---
๐งฎ Calculation Methods
Date Range Handling
if($start_date != '' && $end_date != '') {
$searchQuery .= ' and realestateunitspaids.addtoday >= "' . $start_date . ' 00-00-00"
and realestateunitspaids.addtoday <= "' . $end_date . ' 23-59-55" ';
} else {
// Default to current date
$searchQuery .= ' and realestateunitspaids.addtoday >= "' . $date . ' 00-00-00"
and realestateunitspaids.addtoday <= "' . $date . ' 23-59-55" ';
}
Inventory Valuation Method Selection
$programsettings = R::getRow('select * from programsettings WHERE programsettingsid = 1');
switch ($programsettings['Inventoryevaluation']) {
case "first":
$buyprice = 'restaurantrawdestruction.productBuyPrice';
break;
case "last":
$buyprice = 'restaurantrawdestruction.lastbuyprice';
break;
case "mean":
case "generalPrice":
$buyprice = 'restaurantrawdestruction.meanbuyprice';
break;
case "last_discount":
$buyprice = 'restaurantrawdestruction.lastbuyprice_withDiscount';
break;
case "mean_discount":
$buyprice = 'restaurantrawdestruction.meanbuyprice_withDiscount';
break;
}
Period Duration Calculation
$months = (int)abs((strtotime($end_date) - strtotime($start_date))/(60*60*24*30));
Data Enhancement for Display
// Enhance supplier payment data
foreach($srealestateunitspaids as $srealestateunitspaid) {
$realestate = R::load('realestates', $srealestateunitspaid->realestateid);
$supplier = R::getRow('select * from supplier WHERE supplierid = ? ', [$srealestateunitspaid->supplierid]);
$realestateunitpaidinstallments = R::findAll('realestateunitpaidinstallments',
'realestateunitpaidid = ? and del < 2 and payed > 0', [$srealestateunitspaid->id]);
$srealestateunitspaid->realestate = $realestate;
$srealestateunitspaid->supplier = $supplier;
$srealestateunitspaid->realestateunitpaidinstallments = $realestateunitpaidinstallments;
}
---
๐ Security & Permissions
Input Sanitization
$start_date = filter_input(INPUT_POST, 'start_date');
$end_date = filter_input(INPUT_POST, 'end_date');
$supplierid = filter_input(INPUT_POST, 'supplierid');
$clientid = filter_input(INPUT_POST, 'clientid');
$realestateid = filter_input(INPUT_POST, 'realestateid');
$realestateunitid = filter_input(INPUT_POST, 'realestateunitid');
Data Access Control
- โข No explicit permission checks in this controller
- โข Relies on authentication in
impOpreation.php - โข All data filtering based on business logic (del < 2, conditions = 0)
SQL Injection Prevention
- โข Uses RedBeanPHP ORM for most queries
- โข Direct SQL uses proper WHERE clause building
- โข Numeric filters properly validated
---
๐ Performance Considerations
Database Optimization Tips
1. Critical Indexes Needed:
-- For date range queries
CREATE INDEX idx_realestateunitspaids_date ON realestateunitspaids(addtoday, del);
CREATE INDEX idx_expenses_date ON expenses(expensesdate, conditions);
CREATE INDEX idx_restaurantraw_date ON restaurantrawdestruction(sysdate, conditions);
-- For property filtering
CREATE INDEX idx_realestateunitspaids_property ON realestateunitspaids(realestateid, realestateunitid);
CREATE INDEX idx_expenses_property ON expenses(realestateid, realestateunitid);
-- For entity filtering
CREATE INDEX idx_realestateunitspaids_entities ON realestateunitspaids(supplierid, clientid, del);
```
2. **Query Optimization**:
- Date range queries with proper timestamp formatting
- Efficient joins with LEFT JOIN strategy
- Proper use of WHERE conditions to filter early
- Separate queries for different data sources
3. **Memory Considerations**:
- Large date ranges may return significant data
- Consider pagination for very large result sets
- Multiple data arrays loaded simultaneously
### Performance Issues to Watch
**Potential Bottlenecks**:
sql
-- This pattern may be slow for large datasets
SELECT * FROM realestateunitspaids WHERE del < 2 AND payed > 0 AND addtoday BETWEEN ... ;
-- Solution: Ensure composite indexes
CREATE INDEX idx_performance ON realestateunitspaids(del, payed, addtoday);
---
## ๐ Common Issues & Troubleshooting
### 1. **Missing Data in Reports**
**Issue**: Some transactions don't appear in report despite being in database
**Cause**: Filtering conditions too restrictive
**Debug**:
sql
-- Check filtering conditions
SELECT COUNT(*) FROM realestateunitspaids WHERE del < 2; -- All active records
SELECT COUNT(*) FROM realestateunitspaids WHERE del < 2 AND payed > 0; -- Paid only
SELECT COUNT(*) FROM realestateunitspaids WHERE del < 2 AND clientid = 0; -- Supplier payments
SELECT COUNT(*) FROM realestateunitspaids WHERE del < 2 AND supplierid = 0; -- Client payments
### 2. **Incorrect Inventory Valuation**
**Issue**: Inventory costs showing incorrect amounts
**Cause**: Wrong valuation method selected or missing price data
**Debug**:
sql
-- Check available price fields
SELECT productid, productBuyPrice, lastbuyprice, meanbuyprice,
lastbuyprice_withDiscount, meanbuyprice_withDiscount
FROM restaurantrawdestruction
WHERE realestateid = [ID] LIMIT 10;
-- Check system setting
SELECT Inventoryevaluation FROM programsettings WHERE programsettingsid = 1;
### 3. **Date Range Issues**
**Issue**: Reports showing no data for valid date ranges
**Cause**: Date format mismatch or timezone issues
**Debug**:
sql
-- Check actual date formats in database
SELECT MIN(addtoday), MAX(addtoday) FROM realestateunitspaids WHERE del < 2;
SELECT MIN(expensesdate), MAX(expensesdate) FROM expenses WHERE conditions = 0;
SELECT MIN(sysdate), MAX(sysdate) FROM restaurantrawdestruction WHERE conditions = 0;
### 4. **Missing Related Data**
**Issue**: Reports show main records but missing supplier/client names
**Cause**: Broken foreign key relationships
**Fix**:
sql
-- Find orphaned records
SELECT p.id, p.supplierid, s.supplierid as supplier_exists
FROM realestateunitspaids p
LEFT JOIN supplier s ON p.supplierid = s.supplierid
WHERE p.supplierid > 0 AND s.supplierid IS NULL;
-- Find missing client relationships
SELECT p.id, p.clientid, c.clientid as client_exists
FROM realestateunitspaids p
LEFT JOIN client c ON p.clientid = c.clientid
WHERE p.clientid > 0 AND c.clientid IS NULL;
---
## ๐งช Testing Scenarios
### Test Case 1: Basic Report Generation
1. Set date range covering known transactions
2. Run report without filters
3. Verify all 4 data sections populate
4. Check totals match individual records
5. Validate period calculation is correct
### Test Case 2: Property-Specific Filtering
1. Select specific property from dropdown
2. Run report for date range
3. Verify only that property's transactions appear
4. Check both supplier and client data filtered correctly
5. Validate expenses and inventory filtered to property
### Test Case 3: Unit-Level Analysis
1. Select specific property and unit
2. Run detailed report
3. Verify unit-level filtering works across all data sources
4. Check that property-level expenses still appear
5. Validate inventory consumption specific to unit
### Test Case 4: Edge Cases
1. Test with empty date ranges (current date default)
2. Test with future date ranges (should return empty)
3. Test with very large date ranges (performance)
4. Test with filters returning no results
5. Test inventory valuation method changes
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข realestateunitsowners.md - Supplier payment data source
- โข realestateunitsrenters.md - Client income data source
- โข expensesController.md - General expense data source
- โข Database Schema Documentation - Table relationships
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When reporting requirements change