Car Documentation
Car Controller Documentation
File: /controllers/carController.php
Purpose: Manages car inventory records, vehicle specifications, and automotive product tracking
Last Updated: December 20, 2024
Total Functions: 4
Lines of Code: ~210
---
๐ Overview
The Car Controller manages automotive inventory within the ERP system, handling vehicle records and their associated product data. This controller manages:
- โข Car master record creation and modification
- โข Vehicle specification tracking (brand, model, color, chassis, etc.)
- โข Integration with product inventory system
- โข Car listing and search functionality
- โข Soft delete operations for car records
Primary Functions
- โ Car record creation and editing
- โ Vehicle specification management
- โ Product-car relationship tracking
- โ AJAX-powered car listing with filters
- โ Soft delete functionality
- โ Store quantity updates when cars are registered
Related Controllers
- โข carChasisController.php - Chassis number management
- โข productController.php - Product management
- โข carReviewController.php - Car review system
- โข carTrackingController.php - Car movement tracking
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|---|---|---|
| **cars** | Car master records | id, productid, brand, carcolor, carmodel, chasisno, cartype, carvalue, carnumber, carmotor, notes, sysdate, userid, del |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **product** | Product master data | productid, productName, conditions | |
| **storedetail** | Store inventory | storedetailid, productid, productquantity |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **programsettings** | System configuration | programsettingsid, settingkey, settingvalue | |
| **usergroup** | User group permissions | usergroupid, usergroupname |
๐ Key Functions
1. Default Action - Add New Car Form
Location: Lines 24-32
Purpose: Display form for adding new car records
Process Flow:
1. Load all active products for dropdown selection
2. Display car addition form
3. Set template variables for form population
SQL Query:
SELECT productId, productName
FROM product
WHERE conditions = 0
Template Variables:
- โข
$allProducts- Array of active products - โข
$importcontract- Flag for import contract integration
---
2. show - Car Listing with AJAX
Location: Lines 33-47
Purpose: Display car listing interface with filtering capabilities
Process Flow:
1. Load authentication and permission checks
2. Set display mode (show=2 for alternative view)
3. Load product data for filters
4. Display car listing template with AJAX integration
Features:
- โข Date range filtering
- โข Product-based filtering
- โข Deleted records toggle
- โข AJAX-powered data loading
---
3. edit - Edit Existing Car
Location: Lines 48-65
Purpose: Load and display car data for editing
Function Signature:
// URL: ?do=edit&id={car_id}
$id = filter_input(INPUT_GET, 'id');
Process Flow:
1. Load car record by ID
2. Load associated product information
3. Load all products for dropdown
4. Display edit form with pre-populated data
Template Variables:
- โข
$cardata- Car record data - โข
$productdata- Associated product details - โข
$allProducts- All available products
---
4. savedata() - Save Car Record
Location: Lines 75-118
Purpose: Create or update car records with complete validation
Function Signature:
function savedata()
Input Parameters:
$productid = filter_input(INPUT_POST, 'productid');
$brand = filter_input(INPUT_POST, 'brand');
$carcolor = filter_input(INPUT_POST, 'carcolor');
$carmodel = filter_input(INPUT_POST, 'carmodel');
$chasisno = filter_input(INPUT_POST, 'chasisno');
$cartype = filter_input(INPUT_POST, 'cartype');
$carvalue = filter_input(INPUT_POST, 'carvalue');
$carnumber = filter_input(INPUT_POST, 'carnumber');
$carmotor = filter_input(INPUT_POST, 'carmotor');
$notes = filter_input(INPUT_POST, 'notes');
$carid = filter_input(INPUT_POST, 'carid');
Process Flow:
1. Create or Load Record:
if (!$carid) {
$cars = R::dispense('cars');
$cars->del = 0; // Not deleted
} else {
$cars = R::load('cars', $carid);
}
```
2. **Set Record Properties**:
```php
$cars->sysdate = $today;
$cars->userid = $_SESSION['userid'];
$cars->productid = $productid;
$cars->brand = $brand;
$cars->carcolor = $carcolor;
// ... etc for all fields
```
3. **Store Record and Update Inventory**:
```php
$carid = R::store($cars);
R::exec('UPDATE storedetail SET productquantity = 0 WHERE productid = ?', [$productid]);
```
**Special Behavior**:
- When car is registered, product quantity in store is set to 0
- This indicates the product is now a specific car unit
- Maintains link between product and car for tracking
---
### 5. **showajax()** - AJAX Data Provider
**Location**: Lines 119-191
**Purpose**: Provide paginated, filtered car data for DataTables
**Function Signature**:
php
function showajax()
**Input Parameters**:
php
$start_date = $_POST['start_date']; // Filter start date
$end_date = $_POST['end_date']; // Filter end date
$del = $_POST['del']; // Include deleted records
$data1 = $_POST['data1']; // Product filter
$_POST['search']['value'] // Search term
$_POST['order'] // Sort specification
$_POST['start'], $_POST['length'] // Pagination
**Process Flow**:
1. **Build Dynamic Query**:
```php
$searchQuery = " ";
if ($del == '') {
$searchQuery .= " and cars.del = 0 ";
}
if ($data1 != '') {
$searchQuery .= " and cars.productid = " . $data1 . " ";
}
```
2. **Apply Date Filters**:
```php
if ($start_date != '') {
$searchQuery .= 'and DATE(cars.sysdate) >= "' . $start_date . '"';
}
```
3. **Apply Search and Sorting**:
```php
if (isset($_POST['search']['value']) && $_POST['search']['value'] != "") {
$searchQuery .= 'and (cars.id LIKE "%' . $_POST["search"]["value"] . '%"
OR product.productName like "%' . $_POST["search"]["value"] . '%")';
}
```
4. **Return DataTables JSON**:
```php
$output = array(
"draw" => intval($_POST["draw"]),
"recordsTotal" => intval($apps),
"recordsFiltered" => $totals ? $totals : 0,
"data" => array()
);
```
**Return Format**:
json
{
"draw": 1,
"recordsTotal": 150,
"recordsFiltered": 25,
"data": [
[id, productName, sysdate, editButton, deleteButton],
// ... more rows
]
}
---
### 6. **removecontroller()** - Soft Delete
**Location**: Lines 194-209
**Purpose**: Soft delete car records (set del=1 instead of physical deletion)
**Function Signature**:
php
function removecontroller()
**Process Flow**:
1. Get car ID from POST data
2. Load car record
3. Set del=1 (soft delete flag)
4. Update system date and user
5. Store changes
php
$tables = R::load('cars', $id);
$tables->del = 1;
$tables->sysdate = $today;
$tables->userid = $userid;
R::store($tables);
---
## ๐ Workflows
### Workflow 1: Car Registration Process
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Register New Car โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Load Product Selection โ
โ - Query all active products โ
โ - Display product dropdown โ
โ - Show car registration form โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Capture Car Specifications โ
โ - Product association โ
โ - Brand and model information โ
โ - Color and type specification โ
โ - Chassis number (unique identifier) โ
โ - Motor details and car number โ
โ - Value estimation and notes โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Save Car Record โ
โ - Create new cars table record โ
โ - Link to product via productid โ
โ - Set creation timestamp and user โ
โ - Set del=0 (active record) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Update Store Inventory โ
โ - Set product quantity to 0 in storedetail โ
โ - Indicates product now exists as specific car โ
โ - Maintains product-car tracking relationship โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
### Workflow 2: Car Search and Management
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Search Cars โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Apply Search Filters โ
โ - Date range filter (creation date) โ
โ - Product type filter โ
โ - Include/exclude deleted records โ
โ - Free text search (ID, product name) โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Execute Dynamic Query โ
โ - Build WHERE clause based on filters โ
โ - Join cars table with product table โ
โ - Apply sorting and pagination โ
โ - Count total matching records โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Display Results โ
โ - DataTables AJAX format โ
โ - Car ID and product name โ
โ - Creation date โ
โ - Edit and delete action buttons โ
โ - Pagination and sorting controls โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
## ๐ URL Routes & Actions
| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default display | Show add car form |
| `do=show` | Car listing | Display car list with AJAX |
| `do=edit` | Edit form | Show edit form for specific car |
| `do=savedata` | `savedata()` | Save new or updated car record |
| `do=showajax` | `showajax()` | AJAX data provider for listing |
| `do=removecontroller` | `removecontroller()` | Soft delete car record |
### Required Parameters by Action
**Add New Car** (`do=` empty):
- No parameters required
**Show Car List** (`do=show`):
- `show` - Optional display mode (2 for alternative view)
**Edit Car** (`do=edit`):
- `id` - Car ID to edit (required)
**Save Car** (`do=savedata`):
- `productid` - Associated product ID
- `brand` - Car brand name
- `carcolor` - Car color
- `carmodel` - Car model
- `chasisno` - Chassis number (unique)
- `cartype` - Vehicle type
- `carvalue` - Car value/price
- `carnumber` - Car registration/plate number
- `carmotor` - Motor specifications
- `notes` - Additional notes
- `carid` - Car ID (for updates, empty for new)
---
## ๐งฎ Business Logic
### Product-Car Relationship
php
// When car is registered, product becomes unavailable in general inventory
R::exec('UPDATE storedetail SET productquantity = 0 WHERE productid = ?', [$productid]);
This design pattern indicates:
- Each car is associated with a product type
- Once registered as specific car, product is no longer available as general inventory
- Maintains traceability from product to specific vehicle
### Soft Delete Pattern
php
// Instead of DELETE, set flag
$tables->del = 1;
$tables->sysdate = $today;
$tables->userid = $userid;
Benefits:
- Data preservation for historical reporting
- Audit trail maintenance
- Ability to restore records
- Referential integrity preservation
---
## ๐ Security & Permissions
### Authentication
php
include_once("../public/authentication.php");
- Required for show and edit operations
- Missing for add operation (potential security gap)
### Input Sanitization
php
$id = filter_input(INPUT_GET, 'id');
$productid = filter_input(INPUT_POST, 'productid');
// Proper input filtering implemented
### Permission Management
- Uses `programsettings` and `usergroup` tables
- Assigns user group data to templates
- Individual function permissions not explicitly checked
---
## ๐ Performance Considerations
### Database Optimization
1. **Indexes Recommended**:
```sql
CREATE INDEX idx_cars_del_sysdate ON cars(del, sysdate);
CREATE INDEX idx_cars_productid ON cars(productid);
CREATE INDEX idx_cars_chasisno ON cars(chasisno);
```
2. **Query Optimization**:
- AJAX queries use proper LIMIT for pagination
- JOINs with product table for display
- Dynamic WHERE clause building
### AJAX Performance
- Pagination implemented (`LIMIT` with `start` and `length`)
- Server-side processing for large datasets
- Efficient search across relevant fields
---
## ๐ Common Issues & Troubleshooting
### 1. **Product Quantity Reset**
**Issue**: Product quantity always set to 0 when car registered
**Behavior**: By design - indicates product now exists as specific car
**Verification**:
sql
SELECT c.id, c.chasisno, p.productName, s.productquantity
FROM cars c
JOIN product p ON p.productid = c.productid
JOIN storedetail s ON s.productid = c.productid
WHERE c.del = 0;
### 2. **Duplicate Chassis Numbers**
**Issue**: No validation prevents duplicate chassis numbers
**Risk**: Data integrity issues with car identification
**Fix**: Add validation in `savedata()`:
php
// Check for existing chassis number
$existingCar = R::findOne('cars', 'chasisno = ? AND del = 0 AND id != ?', [$chasisno, $carid ?: 0]);
if ($existingCar) {
throw new Exception('Chassis number already exists');
}
### 3. **Search Performance**
**Issue**: LIKE queries without proper indexes can be slow
**Solution**: Add full-text indexes or optimize search patterns
---
## ๐งช Testing Scenarios
### Test Case 1: Car Registration
1. Access car addition form
2. Select product from dropdown
3. Fill all car specifications
4. Submit form
5. Verify car record created
6. Confirm product quantity set to 0
7. Check car appears in listing
### Test Case 2: Car Search and Filter
1. Access car listing page
2. Apply date range filter
3. Apply product type filter
4. Use text search
5. Verify results match filters
6. Test pagination
7. Test sorting by different columns
### Test Case 3: Car Edit and Delete
1. Select car from listing
2. Click edit button
3. Modify specifications
4. Save changes
5. Verify updates in database
6. Test soft delete functionality
7. Verify deleted cars excluded from default view
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข carChasisController.md - Chassis management
- โข productController.php - Product management
- โข Database Schema Documentation - Table relationships
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur