# Car Review Controller Documentation

**File**: `/controllers/carReviewController.php`  
**Purpose**: Manages dual-reviewer approval system for automotive and financial transactions across multiple business processes  
**Last Updated**: December 20, 2024  
**Total Functions**: 2  
**Lines of Code**: ~543

---

## 📋 Overview

The Car Review Controller implements a sophisticated dual-reviewer approval system that ensures financial and operational integrity across multiple business processes. This controller manages:
- Two-tier approval workflow for critical business transactions
- Multi-module review tracking (sales, purchases, contracts, files, etc.)
- Reviewer role assignment and permission management
- Review status tracking and completion monitoring
- Bulk approval operations across different transaction types

### Primary Functions
- [x] Dual-reviewer approval system implementation
- [x] Multi-module transaction review tracking
- [x] Reviewer permission and role management
- [x] Review completion status monitoring
- [x] Bulk approval operations
- [x] Cross-module review analytics
- [x] Review audit trail maintenance

### Related Controllers
- [sellbillController.php](#) - Sales bill transactions
- [buyBillController.php](#) - Purchase bill transactions
- [savedailyController.php](#) - Daily cash operations
- [importContractController.php](#) - Import contracts
- [fileController.php](#) - File management
- [shippingFilesController.php](#) - Shipping documentation
- [carTrackingController.php](#) - Car tracking operations
- [dollarEarningsController.php](#) - Dollar earnings tracking

---

## 🗄️ Database Tables

### Primary Review Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **carreview** | Review tracking records | carreviewid, tablename, modelid, reviewuserid1, reviewuserid2, sysdate1, sysdate2 |
| **carreviewer** | Reviewer configuration | carreviewerid, reviewer1, reviewer2 |

### Monitored Transaction Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **savedaily** | Daily cash operations | savedailyid, savedailychangeamount, savedailychangetype |
| **sellbill** | Sales bills | sellbillid, sellbillclientid, conditions |
| **buybill** | Purchase bills | buybillid, supplierid, conditions |
| **importcontract** | Import contracts | id, del |
| **carfile** | Car documentation | id, del |
| **shippingfile** | Shipping files | id |
| **cartracking** | Car tracking records | id |
| **dollarearnings** | Dollar earnings | id, conditions |

---

## 🔑 Key Functions

### 1. **Default Action** - Review Dashboard
**Location**: Lines 8-327  
**Purpose**: Display comprehensive review dashboard showing pending approvals across all modules

**Process Flow**:
1. **Load Reviewer Configuration**:
   ```php
   $reviewersData = R::load('carreviewer',1);
   $reviewersData['reviewer1'] = explode(',', $reviewersData['reviewer1']);
   $reviewersData['reviewer2'] = explode(',', $reviewersData['reviewer2']);
   ```

2. **Verify User Permissions**:
   ```php
   if($_SESSION['userid'] != -1 && 
      !in_array($_SESSION['userid'], $reviewersData['reviewer1']) && 
      !in_array($_SESSION['userid'], $reviewersData['reviewer2'])){
       header("location:index.php");
   }
   ```

3. **Process Each Module for Review Status**:

**Module Processing Pattern** (repeated for each transaction type):
```php
// Example: Save Daily Operations
$todaySaveDaily = R::getAll("SELECT DISTINCT savedaily.savedailyid, savedaily.* FROM `savedaily` 
    LEFT JOIN carreview ON carreview.tablename = 'savedailyController.php' 
        and modelid = savedailyid 
    WHERE reviewuserid1 IS NULL OR reviewuserid2 IS NULL 
        OR reviewuserid1 = 0 OR reviewuserid2 = 0 
    order by savedailyid");

foreach ($todaySaveDaily as $value) {
   $isExist = R::getAll("SELECT * from carreview where tablename = 'savedailyController.php' 
       and modelid = ?", [$value['savedailyid']]);
   
   if(count($isExist) == 0){
        $saveNotReviewed1++;
        $saveNotReviewed2++;
   }
   else{
       if(count($isExist) == 2){
           // Both reviewers completed
           array_push($saveReviewed1, $value['savedailyid']);
           array_push($saveReviewed2, $value['savedailyid']);
       }
       else{
           // One reviewer completed
           if($isExist[0]['reviewuserid1'] > 0){
               array_push($saveReviewed1, $value['savedailyid']);
               $saveNotReviewed2++;
           } else {
               array_push($saveReviewed2, $value['savedailyid']);
               $saveNotReviewed1++;
           }
       }
   }
}
```

### Modules Monitored for Review:

#### 1. **Save Daily Operations**
- **Table**: `savedaily`
- **Controller**: `savedailyController.php`
- **Purpose**: Daily cash register operations
- **Review Criteria**: All transactions require dual approval

#### 2. **Sales Bills**
- **Table**: `sellbill`
- **Controller**: `sellbillController.php`
- **Purpose**: Customer sales transactions
- **Review Criteria**: Non-cancelled bills (`conditions = 0`)

#### 3. **Purchase Bills**
- **Table**: `buybill`
- **Controller**: `buyBillController.php`
- **Purpose**: Supplier purchase transactions
- **Review Criteria**: Active bills (`conditions = 0`)

#### 4. **Import Contracts**
- **Table**: `importcontract`
- **Controller**: `importContractController.php`
- **Purpose**: Import contract documentation
- **Review Criteria**: Non-deleted contracts (`del < 2`)

#### 5. **Car Files**
- **Table**: `carfile`
- **Controller**: `fileController.php`
- **Purpose**: Car documentation files
- **Review Criteria**: Active files (`del < 2`)

#### 6. **Shipping Files**
- **Table**: `shippingfile`
- **Controller**: `shippingFilesController.php`
- **Purpose**: Shipping documentation
- **Review Criteria**: All shipping files

#### 7. **Car Tracking**
- **Table**: `cartracking`
- **Controller**: `carTrackingController.php`
- **Purpose**: Vehicle movement tracking
- **Review Criteria**: All tracking records

#### 8. **Dollar Earnings**
- **Table**: `dollarearnings`
- **Controller**: `dollarEarningsController.php`
- **Purpose**: Foreign currency earnings
- **Review Criteria**: Active records (`conditions = 0`)

---

### 2. **savedata** - Bulk Review Approval
**Location**: Lines 328-539  
**Purpose**: Process bulk approval submissions from reviewers

**Function Signature**:
```php
// Triggered when: do=savedata
// POST data contains comma-separated IDs for each module
```

**Input Parameters**:
```php
$saveDailyIds1 = filter_input(INPUT_POST, 'saveDailyIds1');     // Reviewer 1 approvals
$saveDailyIds2 = filter_input(INPUT_POST, 'saveDailyIds2');     // Reviewer 2 approvals
$billIds1 = filter_input(INPUT_POST, 'billIds1');               // Sales bills reviewer 1
$billIds2 = filter_input(INPUT_POST, 'billIds2');               // Sales bills reviewer 2
$buyBillIds1 = filter_input(INPUT_POST, 'buyBillIds1');         // Purchase bills reviewer 1
$buyBillIds2 = filter_input(INPUT_POST, 'buyBillIds2');         // Purchase bills reviewer 2
// ... similar for other modules
```

**Process Flow**:
1. **Verify Reviewer Authorization**:
   ```php
   $reviewersData = R::load('carreviewer',1);
   if(in_array($_SESSION['userid'], explode(',', $reviewersData['reviewer1']))) {
       // Process reviewer 1 approvals
   }
   if(in_array($_SESSION['userid'], explode(',', $reviewersData['reviewer2']))) {
       // Process reviewer 2 approvals
   }
   ```

2. **Process Approvals by Module** (pattern for each module):
   ```php
   if (isset($saveDailyIds1)) {
       foreach (explode(",", $saveDailyIds1) as $value) {
           if (!$value) continue;
           $review = R::dispense('carreview');
           $review->tablename = 'savedailyController.php';
           $review->modelid = $value;
           $review->reviewuserid1 = $_SESSION['userid'];
           $review->sysdate1 = date("Y-m-d H:i:s");
           R::store($review);
       }
   }
   ```

3. **Handle Multiple Reviews**:
   - Creates new review record if none exists
   - Updates existing record if partial review exists
   - Maintains separate timestamps for each reviewer

**Approval Logic**:
- Each transaction can have 0, 1, or 2 approvals
- Reviewer 1 sets `reviewuserid1` and `sysdate1`
- Reviewer 2 sets `reviewuserid2` and `sysdate2`
- Both fields populated = fully approved
- Missing fields = pending review

---

## 🔄 Workflows

### Workflow 1: Dual-Review Approval Process
```
┌─────────────────────────────────────────────────────────────┐
│            START: Transaction Created in System            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Transaction Requires Review                             │
│     - Transaction created in source system                  │
│     - No review record exists in carreview table           │
│     - Appears on both reviewers' dashboards                 │
│     - Status: Pending both reviews                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. First Reviewer Approval                                 │
│     - Reviewer 1 or 2 accesses review dashboard             │
│     - Selects transactions for approval                     │
│     - Submits bulk approval                                 │
│     - Creates carreview record with reviewer ID and date    │
│     - Status: Pending second review                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Second Reviewer Approval                                │
│     - Remaining reviewer sees transaction                   │
│     - Provides second approval                              │
│     - Updates carreview record with second reviewer info    │
│     - Status: Fully approved                                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Transaction Complete                                    │
│     - Both reviewuserid1 and reviewuserid2 populated        │
│     - Transaction no longer appears on review dashboards    │
│     - Audit trail preserved with reviewer IDs and dates     │
│     - Transaction considered approved for processing         │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Review Dashboard Loading
```
┌─────────────────────────────────────────────────────────────┐
│               START: User Accesses Review Dashboard        │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Verify User Authorization                               │
│     - Check user ID against reviewer1 and reviewer2 lists   │
│     - Redirect unauthorized users                           │
│     - Load reviewer configuration                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Query Each Module for Pending Reviews                   │
│     FOR EACH business module:                               │
│       │                                                     │
│       ├─→ Query transactions requiring review               │
│       │   (LEFT JOIN with carreview table)                 │
│       │                                                     │
│       ├─→ Categorize by review status:                     │
│       │   ├─ No reviews: Count for both reviewers          │
│       │   ├─ One review: Count for remaining reviewer      │
│       │   └─ Two reviews: Mark as completed                │
│       │                                                     │
│       └─→ Track completed reviews by reviewer              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Display Review Dashboard                                │
│     - Show pending review counts by module                  │
│     - Display transactions awaiting user's review           │
│     - Highlight completed reviews                           │
│     - Provide bulk selection interface                      │
│     - Enable bulk approval submission                       │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default dashboard | Display review dashboard with pending approvals |
| `do=savedata` | Bulk approval | Process selected approvals from reviewers |

### Required Parameters by Action

**Review Dashboard** (`do=` empty):
- No parameters required
- User authentication verified via session
- Reviewer authorization checked against configuration

**Bulk Approval** (`do=savedata`):
- Module-specific ID lists (comma-separated):
  - `saveDailyIds1`, `saveDailyIds2` - Daily operations
  - `billIds1`, `billIds2` - Sales bills
  - `buyBillIds1`, `buyBillIds2` - Purchase bills
  - `contractIds1`, `contractIds2` - Import contracts
  - `fileIds1`, `fileIds2` - Car files
  - `shippingIds1`, `shippingIds2` - Shipping files
  - `trackingIds1`, `trackingIds2` - Car tracking
  - `dollarIds1`, `dollarIds2` - Dollar earnings

---

## 🔒 Security & Access Control

### Reviewer Authorization
```php
// Load reviewer configuration
$reviewersData = R::load('carreviewer',1);
$reviewersData['reviewer1'] = explode(',', $reviewersData['reviewer1']);
$reviewersData['reviewer2'] = explode(',', $reviewersData['reviewer2']);

// Verify user authorization
if($_SESSION['userid'] != -1 && 
   !in_array($_SESSION['userid'], $reviewersData['reviewer1']) && 
   !in_array($_SESSION['userid'], $reviewersData['reviewer2'])){
    header("location:index.php");
}
```

### Role-Based Processing
```php
// Separate processing for each reviewer role
if(in_array($_SESSION['userid'], explode(',', $reviewersData['reviewer1']))) {
    // Process reviewer 1 approvals
}
if(in_array($_SESSION['userid'], explode(',', $reviewersData['reviewer2']))) {
    // Process reviewer 2 approvals
}
```

### Audit Trail
- Each approval records reviewer ID and timestamp
- Maintains complete review history
- Prevents approval tampering through database constraints
- Supports review reversal tracking

---

## 📊 Review Analytics

### Dashboard Metrics
For each module, the dashboard tracks:
- **Not Reviewed Count**: Transactions requiring both approvals
- **Reviewer 1 Pending**: Transactions needing first approval
- **Reviewer 2 Pending**: Transactions needing second approval
- **Completed Reviews**: Transactions with both approvals

### Template Variables (per module):
```php
// Example for Save Daily
$smarty->assign("saveNotReviewed1", $saveNotReviewed1);    // Count pending review 1
$smarty->assign("saveNotReviewed2", $saveNotReviewed2);    // Count pending review 2
$smarty->assign("saveReviewed1", $saveReviewed1);          // Array of completed by reviewer 1
$smarty->assign("saveReviewed2", $saveReviewed2);          // Array of completed by reviewer 2
```

---

## 🧮 Business Logic

### Review State Logic
```php
if(count($isExist) == 0){
    // No reviews yet - needs both reviewers
    $moduleNotReviewed1++;
    $moduleNotReviewed2++;
}
else{
    if(count($isExist) == 2){
        // Both reviews complete
        array_push($moduleReviewed1, $value['id']);
        array_push($moduleReviewed2, $value['id']);
    }
    else{
        // One review complete, determine which reviewer remains
        if($isExist[0]['reviewuserid1'] > 0){
            array_push($moduleReviewed1, $value['id']);
            $moduleNotReviewed2++;
        } else {
            array_push($moduleReviewed2, $value['id']);
            $moduleNotReviewed1++;
        }
    }
}
```

### Approval Recording
```php
// Create new review record
$review = R::dispense('carreview');
$review->tablename = 'savedailyController.php';
$review->modelid = $value;
$review->reviewuserid1 = $_SESSION['userid'];  // or reviewuserid2
$review->sysdate1 = date("Y-m-d H:i:s");     // or sysdate2
R::store($review);
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **Incomplete Review Records**
**Issue**: Transactions show as partially reviewed but missing reviewer information  
**Cause**: Database inconsistency or failed approval save

**Debug Query**:
```sql
-- Find orphaned review records
SELECT cr.*, 
       CASE WHEN reviewuserid1 = 0 THEN 'Missing Reviewer 1'
            WHEN reviewuserid2 = 0 THEN 'Missing Reviewer 2'
            ELSE 'Complete' END as status
FROM carreview cr
WHERE (reviewuserid1 = 0 AND reviewuserid2 > 0) 
   OR (reviewuserid1 > 0 AND reviewuserid2 = 0);
```

### 2. **Reviewer Configuration Issues**
**Issue**: Users cannot access review dashboard  
**Cause**: Incorrect reviewer1/reviewer2 configuration

**Fix**:
```sql
-- Check reviewer configuration
SELECT * FROM carreviewer WHERE carreviewerid = 1;

-- Update reviewer lists (comma-separated user IDs)
UPDATE carreviewer SET 
    reviewer1 = '1,2,3', 
    reviewer2 = '4,5,6' 
WHERE carreviewerid = 1;
```

### 3. **Performance Issues with Large Datasets**
**Issue**: Dashboard loads slowly with many pending reviews  
**Solution**: Add database indexes

```sql
CREATE INDEX idx_carreview_table_model ON carreview(tablename, modelid);
CREATE INDEX idx_carreview_reviewers ON carreview(reviewuserid1, reviewuserid2);
```

---

## 🧪 Testing Scenarios

### Test Case 1: Dual Approval Workflow
```
1. Create transaction in any monitored module
2. Verify appears on both reviewers' dashboards
3. Login as reviewer 1, approve transaction
4. Verify shows as pending for reviewer 2 only
5. Login as reviewer 2, provide second approval
6. Verify transaction no longer appears on dashboards
7. Confirm both reviewer IDs and dates recorded
```

### Test Case 2: Bulk Approval Operations
```
1. Generate multiple transactions across different modules
2. Login as authorized reviewer
3. Select multiple transactions for approval
4. Submit bulk approval
5. Verify all selected transactions processed
6. Confirm review records created correctly
7. Test with second reviewer for completion
```

### Test Case 3: Unauthorized Access Prevention
```
1. Login as user not in reviewer1 or reviewer2 lists
2. Attempt to access review dashboard
3. Verify redirected to index.php
4. Test with expired session
5. Verify proper access control enforcement
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [sellbillController.php](#) - Sales operations requiring review
- [buyBillController.php](#) - Purchase operations requiring review
- [savedailyController.php](#) - Daily operations requiring review

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When reviewer configuration or approval workflow changes