# Claim Debt Controller Documentation

**File**: `/controllers/claimdebtController.php`  
**Purpose**: Manages claim debt collection with complex payment processing, tax calculations, and financial integrations  
**Last Updated**: December 20, 2024  
**Total Functions**: 4  
**Lines of Code**: ~581

---

## 📋 Overview

The Claim Debt Controller is a sophisticated financial module that handles the collection process for financial claims. It manages:
- Debt collection record creation and management
- Complex payment processing with CURL integrations
- Tax and discount calculations across multiple bills
- Bank and cash payment method handling
- Daily entry journal integration
- Payment reversal and audit trail maintenance
- Integration with sellbillAjaxController for payment processing

### Primary Functions
- [x] Create and manage claim debt collection records
- [x] Process complex payment calculations with taxes and discounts
- [x] Handle multiple payment methods (cash/bank)
- [x] Integrate with external payment processing via CURL
- [x] Create accounting journal entries
- [x] Support payment reversal with full audit trail
- [x] Ajax data tables for debt collection tracking

### Related Controllers
- [claimController.php](claimController.md) - Financial claims management
- [sellbillAjaxController.php](#) - Payment processing integration
- [dailyentryajax.php](#) - Journal entry creation
- [saveController.php](#) - Cash management
- [bankController.php](#) - Bank account management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **claimdebts** | Main debt collection records | id, claimid, paymethod, saveid, bankid, saveidorbankid, bankaccountid, claim_value, transaction_number, direct_debit, tax_rate, direct_tax, full_total, claim_debtcomment, addtoday, adduserid |

### Claim Tables (Referenced)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **claims** | Parent claim records | id, claim_value, debttrue |
| **claimsellbills** | Claim sell bill relationships | id, claimid, claimsellbillid, claimsellbillfinalbill, sellbilldiscount, sellbilltax, sellbilltaxdiscount, dailyentryid, del |
| **claimreturnsellbills** | Claim return bill relationships | id, claimid, claimreturnsellbillid, claimreturnsellbillfinalbill, returnsellbilldiscount, returnsellbilltax, returnsellbilltaxdiscount, dailyentryid, del |

### Financial Tables (Referenced)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **save** | Cash registers/safes | saveid, savename, savevalue, conditions |
| **bank** | Bank accounts | bankid, bankname |
| **sellbill** | Sales bills | sellbillid, sellbillclientid |
| **returnsellbill** | Return bills | returnsellbillid, returnsellbillclientid |
| **client** | Customer data | clientid, treeId |
| **clientdebtchange** | Customer debt tracking | clientdebtchangeid, billid, tablename |

### Audit Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **dailyentry** | Accounting journal entries | id, entryComment |

---

## 🔑 Key Functions

### 1. **Default Action** - Add Debt Collection Form
**Location**: Lines 10-39  
**Purpose**: Display debt collection form for a specific claim

**Process Flow**:
1. Load claim data from claim ID parameter
2. Load available cash registers (filtered by user permissions)
3. Load available bank accounts
4. Display debt collection form

**User Permission Handling**:
```php
if ($_SESSION['searchinonesave'] == 0) {
    // Multiple cash registers
    $saveQuery = '';
    if ($_SESSION['saveids'] != 0) {
        $saveQuery .= ' and saveid in (' . $_SESSION['saveids'] . ')';
    }
    $saves = R::getAll('SELECT * FROM `save` WHERE conditions = 0 ' . $saveQuery);
} else {
    // Single cash register
    $smarty->assign('allSave', $_SESSION['saveid']);
}
```

**Template**: `claimdebtview/add.html`

---

### 2. **show()** - List Debt Collections
**Location**: Lines 39-51  
**Purpose**: Display debt collection listing page

**Template**: `claimdebtview/show.html`

---

### 3. **edit()** - Edit Debt Collection
**Location**: Lines 52-86  
**Purpose**: Display debt collection editing form with existing data

**Template**: `claimdebtview/edit.html`

---

### 4. **detail()** - View Debt Collection Details
**Location**: Lines 86-107  
**Purpose**: Read-only view of debt collection details with payment method information

**Payment Method Display**:
```php
if ($claimdebt->paymethod == 0) {
    // Cash payment
    $save = R::getRow('SELECT * FROM `save` WHERE saveid = ?', [$claimdebt->saveid]);
    $smarty->assign("save", $save);
} else {
    // Bank payment
    $bank = R::getRow('SELECT * FROM `bank` WHERE bankid = ?', [$claimdebt->bankid]);
    $smarty->assign("bank", $bank);
}
```

**Template**: `claimdebtview/detail.html`

---

### 5. **savedata()** - Process Debt Collection
**Location**: Lines 117-308  
**Purpose**: Complex debt collection processing with payment integration

**Function Signature**:
```php
function savedata()
```

**Critical Process Flow**:
```
1. Extract Form Data
   ├── Payment method (0=cash, 1=bank)
   ├── Financial amounts (claim_value, direct_debit, direct_tax)
   ├── Payment details (transaction_number, tax_rate)
   └── Account information (saveid, bankid, bankaccountid)

2. Handle Existing Records
   ├── If updating, delete existing record first
   └── Always create new record (no true updates)

3. Calculate Payment Distribution
   ├── Calculate discount percentage: direct_debit / claim_value
   ├── Calculate tax percentage: direct_tax / claim_value
   └── Apply percentages to individual bills

4. Process Sell Bills
   ├── Load all claim sell bills
   ├── Calculate proportional discounts and taxes per bill
   ├── Create payment records via CURL
   ├── Create journal entries for tax/discount
   └── Update bill records with calculation details

5. Process Return Bills
   ├── Load all claim return bills
   ├── Apply same calculation method
   ├── Handle negative amounts properly
   └── Create corresponding entries

6. Finalize Collection
   ├── Mark parent claim as collected (debttrue = 1)
   └── Return success status
```

**Complex Calculation Logic**:
```php
// Calculate proportional rates
$allsellbilldiscount = $direct_debit / $claim_value;
$allsellbilltax = $direct_tax / $claim_value;

// Apply to each bill
foreach ($claimsellbills as $claimsellbill) {
    $sellbilldiscount = $allsellbilldiscount * $claimsellbill->claimsellbillfinalbill;
    $sellbilltax = $allsellbilltax * $claimsellbill->claimsellbillfinalbill;
    $sellbilltaxdiscount = $sellbilldiscount + $sellbilltax;
    
    // Net payment amount
    $netPayment = $claimsellbill->claimsellbillfinalbill - $sellbilldiscount - $sellbilltax;
}
```

**CURL Payment Integration**:
```php
$arrayclaimsellbill = array(
    'bill_id' => $claimsellbill->claimsellbillid,
    'payed' => $netPayment,
    'paytype_txt' => 'دفع المطلبه رقم ' . $claimid . ' للفاتوره رقم ' . $claimsellbill->claimsellbillid,
    'paytype' => $paytype,
    'saveId' => $saveid,
    'bankAccountId' => $bankaccountid
);

$data_arr = array(
    'erpDB' => $_SESSION['dbname'],
    'curlpost' => 1,
    'userId' => $_SESSION['userid'],
    'id_pay' => json_encode([$arrayclaimsellbill]),
);

CURL_Request($data_arr, 'sellbillAjaxController.php?do=makeSellBillPayment', 0, 1, '', 'POST');
```

**Journal Entry Creation**:
```php
$data_arr = array(
    'itr' => 3,
    'branchid_entry' => 0,
    'dDateTime' => date("Y-m-d"),
    'user_id' => $_SESSION['userid'],
    'entryComment' => 'دفع المطلبه رقم ' . $claimid . ' للفاتوره رقم ' . $claimsellbill->claimsellbillid,
    'E_parent1' => 398, // Discount account
    'valueFrom1' => $sellbilldiscount,
    'E_parent2' => 77,  // Tax account
    'valueFrom2' => $sellbilltax,
    'E_parent3' => $client['treeId'], // Client account
    'valueTo3' => $sellbilltaxdiscount,
    'totalValueFrom_hidden' => $sellbilltaxdiscount,
    'totalValueTo_hidden' => $sellbilltaxdiscount,
);

$dailyEntry = CURL_Request($data_arr, 'dailyentryajax.php?do=add', 0, 1, '', 'POST');
```

---

### 6. **showajax()** - Ajax Data Table
**Location**: Lines 309-416  
**Purpose**: Provide data for debt collection listing

**Columns Returned**:
1. Debt collection ID
2. Parent claim ID
3. Payment method (خزنة/بنك)
4. Payment source (safe/bank name)
5. Claim value
6. Transaction number
7. Direct debit amount
8. Direct tax amount
9. Full total (net amount)
10. Add date
11. Employee name
12. Detail button
13. Edit button (if not deleted)
14. Delete button (if not deleted)

**Payment Method Display**:
```php
if ($row["paymethod"] == 0) {
    $sub_array[] = 'خزنة'; // Cash
    $sub_array[] = $row["savename"];
} else {
    $sub_array[] = 'بنك'; // Bank
    $sub_array[] = $row["bankname"];
}
```

---

### 7. **removecontroller()** - Reverse Debt Collection
**Location**: Lines 419-539  
**Purpose**: Complex reversal of debt collection with full audit trail

**Function Signature**:
```php
function removecontroller($fid = 0)
```

**Reversal Process**:
```
1. Mark Debt Record as Deleted
   ├── Set del = 2
   ├── Record deletion timestamp
   └── Record deleting user

2. Update Parent Claim
   ├── Set debttrue = 0 (not collected)
   └── Allow claim to be processed again

3. Reverse Sell Bill Payments
   ├── Find payment records in clientdebtchange
   ├── Call sellbillAjaxController to reverse payments
   └── Reverse corresponding journal entries

4. Reverse Return Bill Payments
   ├── Same process as sell bills
   └── Handle negative amounts properly

5. Clean Up Accounting
   ├── Reverse all daily entries
   └── Maintain audit trail
```

**Payment Reversal Logic**:
```php
foreach($claimsellbills as $claimsellbill) {
    // Find the original payment record
    $clientdebtchange = R::getCell('SELECT clientdebtchangeid FROM clientdebtchange 
        WHERE `billid` = ? and tablename = ?', 
        [$claimsellbill->claimsellbillid, 'clientPayedDeptSellBillsController.php']);
    
    // Reverse the payment via CURL
    $data_arr = array(
        'clientdebtchangeId' => $clientdebtchange,
        'curlpost' => 1,
        'paytype' => $paytype,
        'userId' => $_SESSION['userid'],
    );
    
    CURL_Request($data_arr, 'sellbillAjaxController.php?do=delMakeSellBillPayment', 0, 1, '', 'POST');
    
    // Reverse the journal entry
    reverseEntryWithItsID($claimsellbill->dailyentryid);
}
```

---

## 🔄 Workflows

### Workflow 1: Debt Collection Processing
```
┌─────────────────────────────────────────────────────────────┐
│                START: Collect Claim Debt                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Setup Collection Parameters                             │
│     - Select payment method (cash/bank)                     │
│     - Enter total claim value                               │
│     - Specify direct debit amount                           │
│     - Specify direct tax amount                             │
│     - Enter transaction reference                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Calculate Payment Distribution                          │
│     - Calculate discount rate = direct_debit / claim_value  │
│     - Calculate tax rate = direct_tax / claim_value        │
│     - Apply rates to each bill proportionally              │
│     - Calculate net payment per bill                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Process Individual Bills                               │
│     FOR EACH claim sell bill:                              │
│       ├─→ Calculate proportional discount                  │
│       ├─→ Calculate proportional tax                       │
│       ├─→ Calculate net payment                            │
│       ├─→ Create payment via CURL                          │
│       ├─→ Create journal entry for tax/discount            │
│       └─→ Update bill with calculation details             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Process Return Bills                                    │
│     FOR EACH claim return bill:                            │
│       ├─→ Apply same calculation method                    │
│       ├─→ Handle negative amounts properly                 │
│       ├─→ Create return payment via CURL                  │
│       └─→ Create corresponding journal entries             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Finalize Collection                                     │
│     - Mark parent claim as collected                        │
│     - Create debt collection audit record                  │
│     - Update all related bill records                      │
│     - Generate success response                             │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Payment Reversal Process
```
┌─────────────────────────────────────────────────────────────┐
│                START: Reverse Debt Collection               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Validate Reversal Request                               │
│     - Check debt collection exists                          │
│     - Verify user permissions                               │
│     - Confirm parent claim status                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Mark Records as Deleted                                 │
│     - Soft delete debt collection record                    │
│     - Reset parent claim collection status                  │
│     - Record deletion audit trail                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Reverse Individual Payments                             │
│     FOR EACH processed bill:                               │
│       ├─→ Find original payment record                     │
│       ├─→ Call payment reversal via CURL                  │
│       ├─→ Reverse corresponding journal entry              │
│       └─→ Update customer debt accordingly                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Complete Reversal                                       │
│     - Verify all payments reversed                          │
│     - Confirm journal entries reversed                      │
│     - Return claim to collectable status                   │
│     - Generate reversal confirmation                        │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) with `id` | Default action | Display debt collection form for claim |
| `do=show` | Show view | Display debt collection listing |
| `do=edit&id={id}` | Edit view | Display debt collection edit form |
| `do=detail&id={id}` | Detail view | Display debt collection details |
| `do=savedata` | `savedata()` | Process debt collection |
| `do=showajax` | `showajax()` | Ajax data for debt collection table |
| `do=removecontroller` | `removecontroller()` | Reverse debt collection |

---

## 🧮 Calculation Methods

### Proportional Tax and Discount Distribution
```php
// Calculate rates based on total claim
$allsellbilldiscount = $direct_debit / $claim_value;    // Discount rate
$allsellbilltax = $direct_tax / $claim_value;          // Tax rate

// Apply to individual bills
$sellbilldiscount = $allsellbilldiscount * $claimsellbill->claimsellbillfinalbill;
$sellbilltax = $allsellbilltax * $claimsellbill->claimsellbillfinalbill;
$sellbilltaxdiscount = $sellbilldiscount + $sellbilltax;

// Net payment calculation
$netPayment = $claimsellbill->claimsellbillfinalbill - $sellbilldiscount - $sellbilltax;
```

### Full Total Calculation
```php
$claimdebts->full_total = $claim_value - $direct_debit - $direct_tax;
```

### Return Bill Amount Handling
```php
// Handle negative amounts for return bills
$returnsellbilldiscount = $allsellbilldiscount * abs($claimreturnsellbill->claimreturnsellbillfinalbill);
$returnsellbilltax = $allsellbilltax * abs($claimreturnsellbill->claimreturnsellbillfinalbill);
$netPayment = abs($claimreturnsellbill->claimreturnsellbillfinalbill) - $returnsellbilldiscount - $returnsellbilltax;
```

---

## 🔒 Security & Permissions

### User Permission Integration
```php
// Cash register access control
if ($_SESSION['searchinonesave'] == 0) {
    // Multiple registers allowed
    if ($_SESSION['saveids'] != 0) {
        $saveQuery .= ' and saveid in (' . $_SESSION['saveids'] . ')';
    }
} else {
    // Single register restriction
    $smarty->assign('allSave', $_SESSION['saveid']);
}

// Bank account filtering
if ($_SESSION['bankids'] != 0) {
    $bankQuery .= ' and bankid in (' . $_SESSION['bankids'] . ')';
}
```

### Input Sanitization
- All form inputs filtered with `filter_input()`
- Financial amounts validated as numeric
- CURL data properly encoded and transmitted
- SQL injection prevented by RedBean ORM

### Audit Trail Maintenance
- Full deletion audit with timestamps and user IDs
- Journal entry references stored for reversal
- Payment record linkage maintained for tracking

---

## 📊 Performance Considerations

### Database Optimization
1. **Critical Indexes**:
   - `claimdebts(claimid, del, addtoday)`
   - `claimsellbills(claimid, del)`
   - `claimreturnsellbills(claimid, del)`
   - `clientdebtchange(billid, tablename)`

2. **CURL Performance**:
   - Multiple CURL requests for each bill in claim
   - Consider batch processing for large claims
   - Network latency can impact processing time

### Memory Management
- Large claims with many bills may consume significant memory
- CURL response handling should include timeout settings
- Consider processing claims in batches for very large collections

---

## 🐛 Common Issues & Troubleshooting

### 1. **CURL Payment Processing Failures**
**Issue**: Payments not processing through CURL integration  
**Cause**: Network issues, session problems, or target controller errors

**Debug**:
```php
// Add CURL error handling
$response = CURL_Request($data_arr, 'sellbillAjaxController.php?do=makeSellBillPayment', 0, 1, '', 'POST');
if ($response === false) {
    error_log('CURL Error: ' . curl_error($ch));
}
```

### 2. **Journal Entry Creation Failures**
**Issue**: Daily entries not created properly  
**Cause**: Account tree issues or missing client tree IDs

**Debug**:
```sql
-- Check client tree ID exists
SELECT treeId FROM client WHERE clientid = {client_id};

-- Verify account tree structure
SELECT * FROM accountstree WHERE id IN (398, 77, {client_tree_id});
```

### 3. **Payment Reversal Issues**
**Issue**: Cannot find original payment records for reversal  
**Cause**: Payment record not created or wrong table name reference

**Debug**:
```sql
-- Find payment records
SELECT * FROM clientdebtchange 
WHERE billid = {bill_id} 
AND tablename = 'clientPayedDeptSellBillsController.php';

-- Check if payment was actually created
SELECT * FROM clientdebtchange 
WHERE billid = {bill_id} 
ORDER BY clientdebtchangedate DESC;
```

### 4. **Calculation Precision Issues**
**Issue**: Rounding errors in tax/discount distribution  
**Cause**: Floating point precision in PHP calculations

**Fix**:
```php
// Use number_format for consistent rounding
$sellbilldiscount = round($allsellbilldiscount * $claimsellbill->claimsellbillfinalbill, 2);
$sellbilltax = round($allsellbilltax * $claimsellbill->claimsellbillfinalbill, 2);
```

---

## 🧪 Testing Scenarios

### Test Case 1: Complex Collection Processing
```
1. Create claim with multiple bills (sell and return)
2. Set up collection with mixed payment method
3. Apply significant tax and discount amounts
4. Process collection and verify calculations
5. Check all CURL integrations successful
6. Verify journal entries created correctly
7. Confirm parent claim marked as collected
```

### Test Case 2: Payment Reversal Integrity
```
1. Process a debt collection completely
2. Verify all payments and journal entries exist
3. Reverse the debt collection
4. Check all payments properly reversed
5. Verify journal entries reversed
6. Confirm parent claim returns to collectable status
7. Verify customer balances correct
```

### Test Case 3: Edge Case Handling
```
1. Test with very small claim amounts (rounding)
2. Test with claims containing only return bills
3. Test with zero tax or zero discount
4. Test CURL timeout scenarios
5. Test concurrent collection attempts
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [claimController.md](claimController.md) - Financial claims management
- [sellbillAjaxController.php](#) - Payment processing integration
- [dailyentryajax.php](#) - Journal entry creation
- [CURL Integration Guide](#) - External controller communication

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur