Realestateunitsrenters Documentation
Real Estate Units Renters Controller Documentation
File: /controllers/realestateunitsrenters.php
Purpose: Manages property rental agreements, tenant payments, and installment tracking for real estate tenants/clients
Last Updated: December 20, 2024
Total Functions: 8
Lines of Code: ~516
---
๐ Overview
The Real Estate Units Renters Controller handles the management of property rental transactions between clients (tenants) and the company. It manages rental agreements, advance payments, installment schedules, and payment tracking for both properties and individual units. This controller is specifically designed for tracking income from property rentals.
Primary Functions
- โ Property and unit rental agreement management
- โ Advance payment processing for rentals
- โ Rental installment payment scheduling
- โ Payment tracking and status updates
- โ Property and unit availability status management
- โ Income record integration
- โ Payment history tracking
- โ Installment consolidation and editing
Related Controllers
- โข incomeController.php - Income processing via CURL
- โข realestateunitsowners.php - Property ownership management
- โข realestateunitsreports.php - Property reporting
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **realestateunitspaids** | Main rental payment records | id, clientid, realestateid, realestateunitid, valuerents, advancepayment, totalpaid, payed, numberinstallments, del | |
| **realestateunitpaidinstallments** | Individual rental installment records | id, realestateunitpaidid, clientid, valuerent, totalpaid, installmentdate, payed, del | |
| **realestateunitpaidhistorys** | Payment history tracking | id, realestateunitpaidid, realestateunitpaidinstallmentid, clientid, advancepayment, incomeid |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **realestates** | Property master data | id, realestatename, cavaible, incometypeid | |
| **realestatesunits** | Property unit details | id, unitname, cavaible | |
| **client** | Tenants/clients | clientid, clientname | |
| **income** | Generated income records | incomeid, incomedate | |
| **user** | System users | userid, employeename |
๐ Key Functions
1. savedata() - Main Save Function
Location: Line 48
Purpose: Creates or updates property rental records with installment schedules
Function Signature:
function savedata()
Process Flow:
1. Extract form data (client, property, unit, amounts, installments)
2. Create/update main rental record (realestateunitspaids)
3. Update property and unit availability status
4. Process advance payment if provided
5. Loop through installment schedule
6. Create/update installment records
7. Process payments via income system
Key Differences from Owners Controller:
- โข Uses
clientidinstead ofsupplierid - โข Updates both property and unit availability (
cavaible) - โข Creates income records instead of expense records
- โข Sets
supplierid = 0and usesclientid
Payment Status Logic:
if ($totalpaid == 0) {
$payed = 0; // No payment
} else if ($valuerents > $totalpaid) {
$payed = 1; // Partial payment
} else {
$payed = 2; // Fully paid
// Set property and unit as unavailable
}
---
2. paieds() - Payment Processing
Location: Line 202
Purpose: Creates income records and payment history for rental payments
Function Signature:
function paieds($clientid, $realestateid, $advancepayment, $realestateunitpaidid, $realestateunitpaidinstallmentid)
Process Flow:
1. Load client and property information
2. Build income description in Arabic
3. Prepare income data array
4. Call income controller via CURL
5. Create payment history record
6. Link income ID back to payment record
Income Description Format:
$incomesname = ' ุงูุฑุงุฏ ููุนูุงุฑ ' . $realestates->realestatename;
$incomecomment = ' ุงูุฑุงุฏ ููุนูุงุฑ ' . $realestates->realestatename . ' ููู
ุณุชุฃุฌุฑ ' . $client['clientname'] . ' ุจุชุงุฑูุฎ ' . $today;
Income Data Structure:
$send_data = array(
'Costcenterid' => '-1',
'clientid' => $clientid,
'parent' => $realestates->incometypeid,
'name' => $incomesname,
'Value' => $advancepayment,
'saveid' => $_SESSION['saveid'],
'comment' => $incomecomment,
'curlpost' => 1
);
---
3. savepayed() - Additional Payment Processing
Location: Line 164
Purpose: Processes additional payments for existing rental installments
Function Signature:
function savepayed()
Process Flow:
1. Get payment details from POST data
2. Update main payment record total
3. Update installment payment amount
4. Recalculate payment status
5. Update property and unit availability if fully paid
6. Process income via paieds() function
Dual Availability Update:
if ($payed == 2) { // Fully paid
R::exec("UPDATE `realestates` SET `cavaible`= 1 WHERE id = '".$realestateid."'");
R::exec("UPDATE `realestatesunits` SET `cavaible`= 1 WHERE id = '".$realestateunitid."'");
}
---
4. showajax() - Data Table Display
Location: Line 241
Purpose: Provides AJAX data for DataTables display with filtering and pagination
Function Signature:
function showajax()
Process Flow:
1. Define table columns for DataTables (includes unit name)
2. Build search query with filters
3. Add permission-based restrictions
4. Execute paginated query with joins
5. Format data for JSON response
6. Include action buttons for each row
Enhanced Search Filters:
- โข Client filter (
clientid) - โข Property filter (
realestateid) - โข Unit filter (
realestateunitid) - โข Date range and deletion status
SQL Query with Unit Join:
SELECT realestateunitspaids.*, employeename, clientname, realestatename, unitname
FROM realestateunitspaids
LEFT JOIN user ON realestateunitspaids.adduserid = user.userid
LEFT JOIN client ON realestateunitspaids.clientid = client.clientid
LEFT JOIN realestates ON realestateunitspaids.realestateid = realestates.id
LEFT JOIN realestatesunits ON realestateunitspaids.realestateunitid = realestatesunits.id
WHERE realestateunitspaids.supplierid = 0 [filters]
---
5. removecontroller() - Soft Delete
Location: Line 381
Purpose: Soft deletes rental records and reverses related transactions
Function Signature:
function removecontroller()
Process Flow:
1. Load rental record by ID
2. Set deletion flags and timestamps
3. Reset property availability (note: inconsistency in implementation)
4. Delete related income via CURL
5. Mark installments as deleted
6. Delete installment income records
7. Update payment history status
Availability Update Issue:
// Note: There's an inconsistency - sets savaible instead of cavaible
R::exec("UPDATE `realestates` SET `savaible`= 0 WHERE id = '" . $tables->realestateid . "'");
// Missing unit availability reset
---
6. removeappend() - Remove Installment
Location: Line 411
Purpose: Removes individual installment records
Function Signature:
function removeappend()
Process Flow:
1. Load installment record by table parameter
2. Set deletion status
3. Reset property availability (inconsistent field name)
4. Delete related income record
5. Update parent payment totals
6. Decrease installment count
---
7. editid() - Consolidate Installments
Location: Line 345
Purpose: Consolidates unpaid installments into the last installment
Function Signature:
function editid()
Process Flow:
1. Find all unpaid installments for the rental record
2. Calculate total unpaid amount
3. Delete unpaid installments (set del = 2)
4. Add total to the last installment
5. Update installment count
Issue in Implementation:
// Line 366: Uses undefined variable $real
R::exec("UPDATE `realestateunitspaids` SET `numberinstallments`= $real WHERE id = '" . $id . "'");
---
8. CURL_IT2() - External API Communication
Location: Line 487
Purpose: Handles CURL requests to other controllers (primarily income)
Function Signature:
function CURL_IT2($data_arr = array(), $url)
Process Flow:
1. Build full URL to target controller
2. Add session data to request
3. Execute CURL POST request
4. Return response from target controller
---
๐ Workflows
Workflow 1: New Property Rental Agreement
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default display | Show add form | |
| `do=show` | Display template | Show data table view | |
| `do=edit&id=X` | Display template | Edit existing rental record | |
| `do=savedata` | `savedata()` | Create/update rental record | |
| `do=showajax` | `showajax()` | AJAX data for DataTables | |
| `do=removeappend` | `removeappend()` | Remove installment record | |
| `do=removecontroller` | `removecontroller()` | Soft delete rental record | |
| `do=savepayed` | `savepayed()` | Process additional payment | |
| `do=editid` | `editid()` | Consolidate installments |
Save Data (do=savedata):
- โข
clientid- Tenant/client ID - โข
realestateid- Property ID - โข
realestateunitid- Unit ID - โข
valuerents- Total rental value - โข
advancepayment- Initial payment amount - โข
numberinstallments- Number of installments - โข
valuerent_N- Amount for each installment N - โข
installmentdate_N- Due date for installment N
Edit View (do=edit):
- โข
id- Rental record ID
Additional Payment (do=savepayed):
- โข
realestateunitpaidid- Main payment record ID - โข
realestateunitpaidinstallmentid- Installment record ID - โข
payed- Additional payment amount
---
๐งฎ Calculation Methods
Payment Status Calculation
if ($totalpaid == 0) {
$payed = 0; // No payment made
} else if ($valuerents > $totalpaid) {
$payed = 1; // Partially paid
} else {
$payed = 2; // Fully paid
// Property and unit become unavailable
}
Dual Availability Management
// When creating new rental record
R::exec("UPDATE `realestates` SET `cavaible`= 1 WHERE id = '" . $realestateid . "'");
R::exec("UPDATE `realestatesunits` SET `cavaible`= 1 WHERE id = '" . $realestateunitid . "'");
// When fully paid
if ($payed == 2) {
R::exec("UPDATE `realestates` SET `cavaible`= 0 WHERE id = '".$realestateid."'");
R::exec("UPDATE `realestatesunits` SET `cavaible`= 0 WHERE id = '".$realestateunitid."'");
}
Income Record Creation
$send_data = array(
'Costcenterid' => '-1',
'clientid' => $clientid,
'parent' => $realestates->incometypeid,
'name' => $incomesname,
'Value' => $advancepayment,
'saveid' => $_SESSION['saveid'],
'comment' => $incomecomment,
'curlpost' => 1
);
---
๐ Security & Permissions
Input Validation
$clientid = filter_input(INPUT_POST, 'clientid');
$realestateid = filter_input(INPUT_POST, 'realestateid');
$realestateunitid = filter_input(INPUT_POST, 'realestateunitid');
$valuerents = filter_input(INPUT_POST, 'valuerents');
Session Management
- โข All functions use
$_SESSION['userid']for audit trails - โข Session data passed via CURL to income controller
- โข User ID recorded in add/update/delete operations
Data Integrity
- โข Soft delete pattern (del = 0,1,2)
- โข Audit trail with timestamps and user IDs
- โข Property and unit availability consistency
- โข Income reversal on deletion
---
๐ Performance Considerations
Database Optimization
1. Indexes Recommended:
- realestateunitspaids(clientid, realestateid, realestateunitid)
- realestateunitpaidinstallments(realestateunitpaidid)
- realestateunitspaids(del, addtoday)
- realestatesunits(id, cavaible)
2. Query Patterns:
- Date range filtering for reports
- Client-based filtering
- Property and unit availability lookups
- Multi-table joins for display
CURL Performance
- โข Income controller calls may add latency
- โข Consider batching multiple income operations
- โข Error handling for failed CURL requests
---
๐ Common Issues & Troubleshooting
1. Field Name Inconsistency
Issue: Mixed use of savaible vs cavaible for availability fields
Cause: Inconsistent field naming between owners and renters
Debug:
-- Check field names in realestates table
SHOW COLUMNS FROM realestates LIKE '%avaible%';
-- Check for inconsistent updates
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%avaible%';
2. Undefined Variable in editid()
Issue: PHP error - undefined variable $real on line 369
Cause: Variable used in SQL update without definition
Fix:
// Replace line 369
$remainingCount = R::count('realestateunitpaidinstallments', 'realestateunitpaidid = ? AND del < 2', [$id]);
R::exec("UPDATE `realestateunitspaids` SET `numberinstallments`= $remainingCount WHERE id = '" . $id . "'");
3. Unit Availability Not Reset on Deletion
Issue: Unit remains marked as occupied after rental deletion
Cause: Missing unit availability reset in removecontroller()
Fix:
// Add after line 392
R::exec("UPDATE `realestatesunits` SET `cavaible`= 0 WHERE id = '" . $tables->realestateunitid . "'");
4. Income Record Validation
Issue: Rental payments recorded but no income entries created
Cause: CURL failure to income controller
Debug:
SELECT p.*, h.incomeid, i.incomeid as actual_income
FROM realestateunitspaids p
LEFT JOIN realestateunitpaidhistorys h ON p.realestateunitpaidhistoryid = h.id
LEFT JOIN income i ON h.incomeid = i.incomeid
WHERE p.advancepayment > 0 AND p.clientid > 0 AND i.incomeid IS NULL;
---
๐งช Testing Scenarios
Test Case 1: Complete Rental Process
1. Create new rental agreement with advance payment
2. Verify property and unit status change to occupied
3. Check income record creation
4. Add installment payments
5. Verify payment status calculations
6. Confirm full payment updates availability
Test Case 2: Unit-Specific Rental
1. Create rental for specific unit within property
2. Verify both property and unit marked as occupied
3. Test that other units remain available
4. Check deletion properly resets unit availability
Test Case 3: Data Integrity
1. Create rental record with installments
2. Delete using removecontroller()
3. Verify all related records marked as deleted
4. Check income records are cancelled
5. Confirm property and unit availability reset
Test Case 4: Bug Verification
1. Test editid() function for undefined variable error
2. Verify field name consistency across operations
3. Check unit availability reset on deletion
4. Validate income record creation
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข realestateunitsowners.md - Ownership management
- โข realestateunitsreports.md - Reporting system
- โข incomeController.md - Income processing
---
Documented By: AI Assistant
Review Status: โ ๏ธ Needs Bug Fixes (undefined variable, field name inconsistency)
Next Review: After bug fixes are implemented