# Supplier Reports Controller Documentation

**File**: `/controllers/supplierReportsController.php`  
**Purpose**: Comprehensive supplier reporting module with advanced features for debt tracking, transaction management, and financial operations  
**Last Updated**: December 20, 2024  
**Total Functions**: 17+  
**Lines of Code**: ~2,100+

---

## 📋 Overview

The Supplier Reports Controller is a comprehensive reporting module that provides advanced supplier account analysis and debt tracking capabilities. It handles:
- Individual supplier debt reports with advanced filtering
- Supplier transaction history with detailed analysis
- Purchase bill tracking (buy, return, combined) with product details
- Ajax-powered data tables for large datasets
- Check withdrawal tracking and management
- Advanced currency support and conversion
- Cash register/safe integration
- Multi-user permission levels
- Transaction deletion and reversal capabilities
- Real-time data processing with AJAX
- Export capabilities and print views

### Primary Functions
- [x] Generate comprehensive supplier debt reports
- [x] Track supplier payment history with detailed analysis
- [x] Purchase transaction analysis with product breakdowns
- [x] Advanced date range filtering with timezone support
- [x] Debt balance calculations with currency conversion
- [x] Transaction linking to source documents
- [x] Purchase bill detail analysis with discount calculations
- [x] Net view calculations for cleaner reports
- [x] Ajax-powered data tables for performance
- [x] Check withdrawal management
- [x] Transaction deletion and reversal
- [x] Multi-currency support
- [x] User permission management
- [x] Cash register/safe integration

### Related Controllers
- [buyBillController.php](buyBillController.md) - Purchase operations
- [supplierController.php](#) - Supplier management
- [returnBuyBillController.php](#) - Purchase returns
- [supplierPayedDeptController.php](#) - Payment processing
- [checkwithdrawalController.php](#) - Check withdrawals
- [kempialaController.php](#) - Promissory notes
- [dailyentry.php](#) - Journal entries
- [saveController.php](#) - Cash register management
- [currencyController.php](#) - Currency management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **supplierdebtchange** | Supplier debt transaction log | supplierdebtchangeid, supplierid, supplierdebtchangeamount, supplierdebtchangetype, supplierdebtchangedate, tablename, currencyId, conversionFactor |
| **supplier** | Supplier master data | supplierid, suppliername, suppliercurrentDebt, suppliercurrentDebtInCurrency, inUse |

### Purchase Tables (Referenced)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **buybill** | Purchase bills | buybillid, buybillsupplierid, buybilltotalbill, buybillaftertotalbill, buybilltotalpayed, buybilldiscounttype, buybilldiscount |
| **buybilldetail** | Purchase bill line items | buybilldetailid, buybillid, buybilldetailproductid, buybilldetailquantity, buybilldetailtotalprice |
| **returnbuybill** | Purchase return bills | returnbuybillid, returnbuybillsupplierid, returnbuybilltotalbill, returnbuybillaftertotalbill |
| **returnbuybilldetail** | Return bill details | returnbuybilldetailid, returnbuybillid, returnbuybilldetailproductid, returnbuybilldetailquantity |
| **buyandruternbill** | Combined buy & return | buybillid, buybillsupplierid, buybillprice, returnbuybillprice, buybilldate |
| **buyandruternbilldetail** | Combined bill details | buyandruternbilldetailid, buybillid, buybilldetailproductid, buybilldetailquantity, buytype |

### Financial Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **checkwithdrawal** | Check withdrawals | checkwithdrawalid, bankaccountid, supplierid, checkwithdrawalamount, checkwithdrawaldate |
| **save** | Cash registers/safes | saveid, savename, savecurrentvalue, conversionFactor |
| **savedaily** | Daily cash movements | savedailyid, saveid, savedailychangeamount, savedailychangetype, savedailymodelid, tablename |
| **currency** | Currency definitions | currencyid, currencyname, conversionfactor |

### Reference Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **user** | System users | userid, username, viewbills, searchinonesave, usergroupid |
| **youtubelink** | Tutorial links | youtubelinkid, title, url |
| **programsettings** | System configuration | programsettingsid, reportsPlusHours |
| **associatedtags** | Tag system | id, tagname |
| **product** | Product information | productid, productName |
| **productcat** | Product categories | productCatId, productCatName |
| **unit** | Measurement units | unitid, unitName |

---

## 🔑 Key Functions

### 1. **show() / Default Action** - Main Report Interface
**Location**: Line 172  
**Purpose**: Display main supplier reporting interface with filtering options

**Function Signature**:
```php
// Triggered when: do is empty or do=show
$startDate = $_REQUEST['from'];
$endDate = $_REQUEST['to'];
$supplierId = $_POST['supplierId'];
$saveId = filter_input(INPUT_POST, 'saveId');
```

**Process Flow**:
1. Load supplier and save dropdown data
2. Handle project and cost center filtering
3. Display main report interface
4. Integrate with Ajax data tables

---

### 2. **showallajax()** - Ajax Data Table Handler
**Location**: Line 652  
**Purpose**: Handle Ajax requests for supplier payment data tables

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

**Process Flow**:
1. Parse DataTables Ajax parameters (pagination, sorting, searching)
2. Build complex SQL query with multiple filters
3. Apply user permission restrictions
4. Handle date range filtering with timezone support
5. Execute query and format results for DataTables
6. Return JSON response with pagination metadata

**Key Features**:
- Server-side pagination for large datasets
- Advanced filtering (supplier, save, date, serial number)
- User permission enforcement
- Real-time totals calculation
- Search functionality across multiple columns

**SQL Query Structure**:
```sql
SELECT supplierdebtchange.*, supplier.suppliername, user.employeename, save.savename
FROM supplierdebtchange
JOIN supplier ON supplier.supplierid = supplierdebtchange.supplierid
JOIN user ON user.userid = supplierdebtchange.userid
JOIN savedaily ON savedaily.savedailymodelid = supplierdebtchange.supplierdebtchangeid
JOIN save ON savedaily.saveid = save.saveid
WHERE supplierdebtchange.tablename = 'supplierPayedDeptController.php'
```

---

### 3. **showallajaxCheques()** - Check Withdrawal Ajax Handler
**Location**: Line 952  
**Purpose**: Handle Ajax requests for check withdrawal data tables

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

**Process Flow**:
1. Query check withdrawal data with bank and supplier information
2. Apply filtering by supplier and date range
3. Format data for DataTables display
4. Handle check status (active/deleted)
5. Return formatted JSON response

**SQL Query**:
```sql
SELECT checkwithdrawalnumber, bankname, accountname, suppliername, 
       checkwithdrawaldate, checkwithdrawalamount, conditions, dailyentryid
FROM checkwithdrawal c
JOIN bankaccount a ON a.accountid = c.bankaccountid
JOIN bank b ON b.bankid = a.bankid
LEFT JOIN supplier s ON s.supplierid = c.supplierid
```

---

### 4. **supplierShow()** - Detailed Supplier Report
**Location**: Line 1351  
**Purpose**: Generate comprehensive supplier account statement

**Function Signature**:
```php
function supplierShow($supplierid, $startDate, $endDate, $order)
```

**Process Flow**:
1. Build dynamic SQL query with supplier and date filters
2. Apply user permission restrictions
3. Query supplier debt change history
4. Link each transaction to source documents
5. Handle net view processing for cleaner display
6. Calculate running balances
7. Load additional data (bank info, bill details)

**Order Options**:
- `order = 1` - Date descending
- `order = 2` - ID ascending (default)

**Transaction Processing Logic**:
```php
foreach ($shownData as $data) {
    if ($data->tablename == "buyBillController.php") {
        $buybillid = $buyBillDAO->load($data->supplierdebtchangemodelid);
        $data->totalbillvalue = $buybillid->buybillaftertotalbill;
        $data->buybillpaid = $buybillid->buybilltotalpayed;
        $data->link = "buyBillController.php?do=details&id=" . $data->supplierdebtchangemodelid;
    }
    // ... handle other transaction types
}
```

---

### 5. **showAllOperations()** - Comprehensive Operations Report
**Location**: Line 1249  
**Purpose**: Display all supplier operations (bills, returns, payments) in unified view

**Function Signature**:
```php
function showAllOperations($supplierid, $startDate, $endDate)
```

**Process Flow**:
1. Call `showBuyBillsBySupplierAndDate()` for purchase data
2. Call `showReturnBuyBillsBySupplierAndDate()` for return data
3. Query `supplierdebtchange` for other operations
4. Cross-reference and eliminate double-counting
5. Calculate net payment totals
6. Load additional metadata (bank info for checks)

**Data Integration**:
```php
// Purchase bills from multiple sources
$buybillData = showBuyBillsBySupplierAndDate($supplierid, $startDate, $endDate);
$returnbuybillData = showReturnBuyBillsBySupplierAndDate($supplierid, $startDate, $endDate);

// Payment operations
$SupplierShowData = $supplierDeptChangeExt->queryBySupplierIdAndDateNew_f($queryString);

// Eliminate double-counting
foreach ($buybillData as $data) {
    if ($data->buybilltotalpayed != 0) {
        $totalPrice += $data->buybilltotalpayed;
    }
}
```

---

### 6. **supplierShowforbuyonly()** - Purchase-Only Analysis
**Location**: Line 1893  
**Purpose**: Focus on purchase transactions with detailed product analysis

**Function Signature**:
```php
function supplierShowforbuyonly($supplierid, $startDate, $endDate)
```

**Process Flow**:
1. Apply user permission filtering based on `viewbills` setting
2. Query supplier debt changes for purchase-related transactions
3. Load detailed product information for each bill
4. Calculate totals with tax and discount processing
5. Generate product-level analysis

**User Permission Logic**:
```php
$userData = $myUserRecord->load($_SESSION['userid']);
if ($userData->viewbills == 0) {
    $queryString .= ' user.userid =' . $_SESSION['userid'] . ' AND';
} else if ($userData->viewbills == 2) {
    $queryString .= ' user.usergroupid =' . $_SESSION['usergroupid'] . ' AND';
}
```

**Product Detail Loading**:
```php
$myselldata = R::getAll('select buybilldetail.*, product.productName, productcat.productCatName, unit.unitName
    from buybilldetail
    JOIN product ON buybilldetail.buybilldetailproductid = product.productId
    JOIN productunit ON buybilldetail.productunitid = productunit.productunitid
    JOIN unit ON unit.unitId = productunit.unitid
    JOIN productcat ON productcat.productCatId = product.productCatId
    where buybillid=' . $data->supplierdebtchangemodelid);
```

---

### 7. **delete()** - Transaction Deletion and Reversal
**Location**: Line 393  
**Purpose**: Delete supplier debt transactions with full reversal logic

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

**Process Flow**:
1. Load transaction details and supplier information
2. Use supplier locking mechanism to prevent conflicts
3. Calculate reversal amounts and update supplier debt
4. Create offsetting entries in `supplierdebtchange`
5. Update cash register/save balances
6. Reverse journal entries in daily entry system
7. Commit transaction or rollback on error

**Supplier Locking**:
```php
$supplierdata = getSupplierDataFromSupplierInUseSP($supplierId);
// Uses stored procedure to lock supplier during transaction processing
```

**Reversal Logic**:
```php
if ($oldchangeType == 0) { // It was get money
    $supplierDebtAfterTotal = $supplierDebtAfter - $payedDebt;
    $newChangeType = 1;
    $processname = "الغاء تحصيل من مورد";
} else { // It was payed debt
    $supplierDebtAfterTotal = $supplierDebtAfter + $payedDebt;
    $processname = "الغاء سداد ديون مورد";
}
```

---

### 8. **showBuyBillsBySupplierAndDate()** - Purchase Bills Analysis
**Location**: Line 1601  
**Purpose**: Comprehensive purchase bill analysis with discount processing

**Function Signature**:
```php
function showBuyBillsBySupplierAndDate($supplierid, $startDate, $endDate)
```

**Process Flow**:
1. Build dynamic queries for both `buybill` and `buyandruternbill` tables
2. Apply supplier and date filters
3. Process discount calculations for each bill
4. Count product quantities via detail tables
5. Merge datasets from multiple sources
6. Calculate totals for template display

**Dynamic Query Building**:
```php
$queryString = '';
if (!empty($supplierid)) {
    $queryString .= ' AND buybill.buybillsupplierid = ' . $supplierid;
}
if (!empty($startDate)) {
    $queryString .= ' AND buybill.buybilldate >= "' . $startDate . '"';
}
if (!empty($endDate)) {
    $queryString .= ' AND buybill.buybilldate <= "' . $endDate . '"';
}
```

---

### 9. **Currency and Save Management Functions**

**getSaveValueAndMinus()** / **getSaveValueAndPlus()** - Lines 519/539  
Handle cash register/save balance calculations with currency conversion:

```php
function getSaveValueAndPlus($savevaluechanged, $saveid, $saveConversionFactor = 0) {
    $saveData = $SaveExt->loadForUpdateEx($saveid);
    $saveValuebefore = $saveData->savecurrentvalue;
    
    if ($saveConversionFactor == 0) {
        $saveConversionFactor = $saveData->conversionFactor;
    }
    
    $savevaluechanged = round(($savevaluechanged * $saveConversionFactor), 4);
    $saveValueafter = $saveValuebefore + $savevaluechanged;
    
    return array($saveId, $saveValuebefore, $saveValueafter, $savevaluechanged, $saveConversionFactor);
}
```

---

### 10. **Supplier Locking Management**

**getSupplierDataFromSupplierInUseSP()** - Line 1854  
**markSupplierAsNOTInUse()** - Line 1876

Handle supplier locking to prevent concurrent modifications:

```php
function getSupplierDataFromSupplierInUseSP($supplier) {
    $supplier_data = $supplierExt->callSupplierInUseSP($supplier);
    while ($supplier_data->suppliercurrentDebt == 'in_use') {
        sleep(1);
        $noOfTries++;
        if ($noOfTries > 15) { // 15 second timeout
            R::exec('UPDATE supplier SET inUse = 0 where supplierid = ' . $supplier);
        }
        $supplier_data = $supplierExt->callSupplierInUseSP($supplier);
    }
    return $supplier_data;
}
```

---

## 🔄 Workflows

### Workflow 1: Ajax Data Loading Process
```
┌─────────────────────────────────────────────────────────────┐
│              START: Ajax Request from DataTable            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Parse DataTables Parameters                             │
│     - Pagination (start, length)                           │
│     - Ordering (column, direction)                         │
│     - Search filters                                        │
│     - Custom filters (supplier, save, date)                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Apply User Permissions                                  │
│     - Check viewbills setting                              │
│     - Apply user/group restrictions                        │
│     - Check save restrictions                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Build Dynamic SQL Query                                 │
│     - Base JOIN structure                                   │
│     - Add WHERE clauses for filters                        │
│     - Add date range with timezone handling                │
│     - Add ORDER BY and LIMIT clauses                       │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Execute Queries                                         │
│     - Main data query                                       │
│     - Count query for pagination                            │
│     - Totals query for summary                              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Format Data for DataTables                              │
│     - Process each row                                      │
│     - Add action buttons (edit, delete, print)             │
│     - Calculate running totals                              │
│     - Apply row styling based on status                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Return JSON Response                                    │
│     - Data array                                            │
│     - Pagination metadata                                   │
│     - Totals summary                                        │
│     - Draw counter for DataTables                           │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Transaction Deletion Process
```
┌─────────────────────────────────────────────────────────────┐
│              START: Delete Transaction Request             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Transaction Details                                │
│     - Get supplier debt change record                      │
│     - Load supplier information                             │
│     - Identify related records (save, daily entry)         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Lock Supplier Record                                    │
│     - Use stored procedure to lock supplier                │
│     - Wait for lock or timeout after 15 seconds           │
│     - Force unlock if needed                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Calculate Reversal Amounts                              │
│     - Determine new supplier debt balance                  │
│     - Calculate currency conversions                        │
│     - Determine save balance changes                        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Create Reversal Entries                                 │
│     - Update supplier debt                                  │
│     - Insert offsetting debt change entry                  │
│     - Update save balance                                   │
│     - Insert save daily entry                               │
│     - Reverse journal entry                                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Commit or Rollback                                      │
│     - Commit transaction if successful                      │
│     - Rollback and release lock on error                   │
│     - Log any issues                                        │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) or `do=show` | Default action | Main report interface |
| `do=showallajax` | `showallajax()` | Ajax payment data |
| `do=showallajaxCheques` | `showallajaxCheques()` | Ajax check data |
| `do=oneSupplier` | `supplierShow()` | Individual supplier report |
| `do=supplierShowforbuyonly` | `supplierShowforbuyonly()` | Purchase-only analysis |
| `do=all` | `showAllOperations()` | Comprehensive operations |
| `do=remove` | `delete()` | Delete transaction |
| `do=edit` | Default + edit form | Edit transaction |
| `do=update` | Database update | Update transaction |
| `do=editprint` | Print view | Print transaction |

### Required Parameters by Action

**Main Report Interface** (`do=show`):
- `from` - Start date (optional)
- `to` - End date (optional)
- `supplierId` - Supplier filter (optional)
- `saveId` - Save filter (optional)

**Individual Supplier Report** (`do=oneSupplier`):
- `supplierid` - Supplier ID (required)
- `from` - Start date
- `to` - End date
- `order` - Sort order (1=date desc, 2=ID desc)

**Ajax Requests**:
- Standard DataTables parameters (start, length, order, search)
- Custom filters (supplierId, saveId, from, to)

---

## 🧮 Calculation Methods

### Currency Conversion
```php
// Convert to save currency
$savevaluechanged = round(($savevaluechanged * $saveConversionFactor), 4);

// Track both main currency and supplier currency
$supplierDeptChange->debtchangbeforeInSupplierCurrency = $supplierDebtBeforeInSuppCurr;
$supplierDeptChange->debtchangamountInSupplierCurrency = $payedDebtInSuppCurr;
$supplierDeptChange->debtchangafterInSupplierCurrency = $supplierDebtAfterTotalInSuppCurr;
```

### Discount Processing in Combined Bills
```php
// Fixed amount discount
if ($buybilldiscountrype == 0) {
    $myfialtotal = $mytotal - $buybilldiscount;
} 
// Percentage discount
else {
    $myfialtotal = $mytotal - (($mytotal * $buybilldiscount) / 100);
}
```

### Tax Calculation
```php
$data->tax = ($sellBillData->buybilltotalbill - $discount) * $sellBillData->payedtax / 100;
```

### Net View Balance Calculation
```php
foreach ($shownData as $mov) {
    if ($mov->supplierdebtchangetype == "1") { // Payment
        $mov->supplierdebtchangebefore = $startbefore + $startvalue;
        $startbefore = $startbefore + $startvalue;
    } else { // Purchase/Debt increase
        $mov->supplierdebtchangebefore = $startbefore - $startvalue;
        $startbefore = $startbefore - $startvalue;
    }
}
```

---

## 🔒 Security & Permissions

### User Permission Levels
```php
// Individual user restriction
if ($userData->viewbills == 0) {
    $queryString .= ' user.userid =' . $_SESSION['userid'] . ' AND';
}
// User group restriction  
else if ($userData->viewbills == 2) {
    $queryString .= ' user.usergroupid =' . $_SESSION['usergroupid'] . ' AND';
}
// Full access (viewbills == 1) - no restrictions

// Save restriction
if ($userdata->searchinonesave == 1) {
    $queryString .= ' supplierdebtchange.saveid = ' . $userdata->saveid . ' AND';
}
```

### Input Sanitization
- All POST/GET parameters filtered and validated
- Numeric IDs cast to integers: `(int) $_REQUEST['supplierId']`
- Date validation and proper formatting
- SQL injection prevented by DAO layer parameterized queries
- CSRF protection via session validation

### Access Control
- Requires authentication via `../public/authentication.php`
- Permission checks for data visibility
- Transaction modification restrictions
- Audit trail for all changes

---

## 📊 Performance Considerations

### Database Optimization

**Critical Indexes Required**:
```sql
-- Core performance indexes
CREATE INDEX idx_supplier_debt_date ON supplierdebtchange(supplierid, supplierdebtchangedate);
CREATE INDEX idx_supplier_debt_table ON supplierdebtchange(tablename, del, supplierdebtchangedate);
CREATE INDEX idx_savedaily_link ON savedaily(savedailymodelid, tablename);
CREATE INDEX idx_buybill_supplier_date ON buybill(buybillsupplierid, buybilldate);
CREATE INDEX idx_checkwithdrawal_supplier ON checkwithdrawal(supplierid, checkwithdrawaldate);
```

**Query Optimization**:
- Server-side pagination prevents memory issues
- Efficient JOIN structures in Ajax queries
- Date range filtering with proper time zone handling
- Query result caching where appropriate

**Memory Management**:
- Ajax loading prevents large dataset memory issues
- Pagination limits result sets
- Efficient data structures in processing loops

### Performance Features
1. **Ajax DataTables**: Handle large datasets efficiently
2. **Server-side Processing**: Pagination, sorting, filtering on database side
3. **Selective Loading**: Only load needed data based on user permissions
4. **Query Optimization**: Efficient JOINs and WHERE clauses
5. **Result Caching**: Cache dropdown data and static content

---

## 🐛 Common Issues & Troubleshooting

### 1. **Ajax Timeout Issues**
**Issue**: DataTables requests timing out with large datasets
**Cause**: Complex queries or missing indexes
**Solutions**:
- Add required database indexes
- Optimize JOIN queries
- Reduce date range for large suppliers
- Check `reportsPlusHours` setting for timezone issues

### 2. **Supplier Lock Conflicts**
**Issue**: "Supplier in use" errors during transaction processing
**Cause**: Concurrent access or stale locks
**Debug**:
```sql
SELECT supplierid, inUse FROM supplier WHERE inUse = 1;
-- Check for locked suppliers

UPDATE supplier SET inUse = 0 WHERE supplierid = [ID];
-- Force unlock if needed
```

### 3. **Currency Conversion Errors**
**Issue**: Incorrect balance calculations with multi-currency
**Cause**: Missing conversion factors or rounding issues
**Solutions**:
- Verify currency conversion factors are set
- Check save conversion factors
- Ensure proper rounding (4 decimal places)

### 4. **Permission Access Issues**
**Issue**: Users seeing unauthorized data
**Cause**: Permission logic not properly applied
**Debug**: Check user settings and permission application in queries

### 5. **Transaction Reversal Failures**
**Issue**: Delete operation fails or creates incorrect balances
**Cause**: Missing related records or calculation errors
**Solutions**:
- Check all related table dependencies
- Verify journal entry reversal
- Ensure save balance updates are correct

---

## 🧪 Testing Scenarios

### Test Case 1: Ajax Data Loading
```
1. Load main report page with large dataset
2. Test pagination, sorting, and filtering
3. Verify search functionality across columns
4. Check totals calculation accuracy
5. Test different user permission levels
```

### Test Case 2: Transaction Deletion
```
1. Create test supplier transaction
2. Verify balance updates correctly
3. Delete the transaction
4. Verify reversal calculations are correct
5. Check all related records are updated
```

### Test Case 3: Multi-Currency Operations
```
1. Set up supplier with non-default currency
2. Create transactions in supplier currency
3. Verify conversion calculations
4. Test save balance updates with conversion
5. Check reporting accuracy in both currencies
```

### Test Case 4: User Permissions
```
1. Test with viewbills = 0 (own data only)
2. Test with viewbills = 2 (group data)
3. Test with searchinonesave = 1
4. Verify data visibility restrictions
5. Test transaction modification permissions
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [buyBillController.md](buyBillController.md) - Purchase operations
- [supplierController.php](#) - Supplier management
- [saveController.php](#) - Cash register management
- [currencyController.php](#) - Currency management
- [Database Schema Documentation](#) - Table relationships

---

## 📝 Summary

**Controller Purpose**: Comprehensive supplier debt tracking with advanced features  
**Function Count**: 17+  
**Table Count**: 15+ (direct and referenced)  
**Notable Findings**: 
- Advanced Ajax data table implementation for performance
- Complex multi-currency support with conversion tracking
- Sophisticated user permission system
- Transaction reversal with full audit trail
- Real-time supplier locking mechanism
- Comprehensive financial integration (saves, checks, journal entries)

---

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