# 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
- [x] Property and unit rental agreement management
- [x] Advance payment processing for rentals
- [x] Rental installment payment scheduling
- [x] Payment tracking and status updates
- [x] Property and unit availability status management
- [x] Income record integration
- [x] Payment history tracking
- [x] Installment consolidation and editing

### Related Controllers
- [incomeController.php](incomeController.md) - Income processing via CURL
- [realestateunitsowners.php](realestateunitsowners.md) - Property ownership management
- [realestateunitsreports.php](realestateunitsreports.md) - 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 |

### Reference Tables
| 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**:
```php
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 `clientid` instead of `supplierid`
- Updates both property and unit availability (`cavaible`)
- Creates income records instead of expense records
- Sets `supplierid = 0` and uses `clientid`

**Payment Status Logic**:
```php
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**:
```php
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**:
```php
$incomesname = ' ايراد للعقار  ' . $realestates->realestatename;
$incomecomment = ' ايراد للعقار  ' . $realestates->realestatename . ' للمستأجر  ' . $client['clientname'] . ' بتاريخ  ' . $today;
```

**Income Data Structure**:
```php
$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**:
```php
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**:
```php
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**:
```php
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**:
```sql
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**:
```php
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**:
```php
// 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**:
```php
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**:
```php
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**:
```php
// 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**:
```php
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
```
┌─────────────────────────────────────────────────────────────┐
│            START: Create Property Rental Agreement         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Enter Rental Details                                    │
│     - Select property                                       │
│     - Select specific unit (optional)                       │
│     - Select tenant/client                                  │
│     - Enter total rental value                              │
│     - Set advance payment                                   │
│     - Define installment schedule                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Create Rental Record                                    │
│     - Insert into realestateunitspaids                     │
│     - Set property as occupied (cavaible = 1)              │
│     - Set unit as occupied (cavaible = 1)                  │
│     - Calculate payment status                              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Advance Payment (if any)                       │
│     - Call paieds() function                               │
│     - Create income record via CURL                        │
│     - Update payment history                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Create Installment Schedule                             │
│     FOR EACH installment:                                   │
│       ├─→ Insert installment record                        │
│       ├─→ Set due date                                     │
│       ├─→ Process payment if amount > 0                    │
│       └─→ Create income record if paid                     │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Update Final Status                                     │
│     - Check if fully paid                                  │
│     - Update property/unit availability if needed          │
│     - Return success confirmation                          │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 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 |

### Required Parameters by Action

**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
```php
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
```php
// 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
```php
$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
```php
$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**:
```sql
-- 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**:
```php
// 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**:
```php
// 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**:
```sql
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](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [realestateunitsowners.md](realestateunitsowners.md) - Ownership management
- [realestateunitsreports.md](realestateunitsreports.md) - Reporting system
- [incomeController.md](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