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
- โ Dual-reviewer approval system implementation
- โ Multi-module transaction review tracking
- โ Reviewer permission and role management
- โ Review completion status monitoring
- โ Bulk approval operations
- โ Cross-module review analytics
- โ 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 |
| 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:
$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 - 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