MechandiseReturnRequest Documentation
Merchandise Return Request Controller Documentation
File: /controllers/mechandiseReturnRequest.php
Purpose: Manages customer merchandise return requests with approval workflow
Last Updated: December 20, 2024
Total Functions: 8
Lines of Code: ~325
---
๐ Overview
The Merchandise Return Request Controller handles the complete lifecycle of customer return requests for damaged or intact products. It manages:
- โข Customer return request creation and tracking
- โข Product condition assessment (damaged vs. intact)
- โข Multi-product return requests with individual comments
- โข Approval workflow with status tracking
- โข Dynamic product selection and management
- โข Client lookup and association
- โข Soft delete functionality for data integrity
Primary Functions
- โ Create and manage return requests
- โ Track product conditions (damaged/intact)
- โ Multi-product return handling
- โ Approval workflow management
- โ Dynamic product/client selection via AJAX
- โ Soft delete with audit trail
- โ Advanced filtering and search
- โ Status tracking and reporting
Related Controllers
- โข sellbillController.php - Original sales tracking
- โข clientController.php - Customer management
- โข productController.php - Product catalog
- โข returnSellBillController.php - Return processing
---
๐๏ธ Database Tables
Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **mechandisereturnrequest** | Return request headers | id, clientid, damagedintact, agrees, addtoday, adduserid, updatetoday, updateuserid, deltoday, deluserid, conditions | |
| **mechandisereturnproduct** | Return request product details | id, mechandisereturnrequestid, productid, comment, addtoday, adduserid, updatetoday, updateuserid, deltoday, deluserid, conditions |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **client** | Customer information | clientid, clientname, clientphone | |
| **product** | Product catalog | productId, productName, conditions | |
| **user** | System users | userid, employeename |
๐ Key Functions
1. Default Action - Add New Return Request
Location: Lines 6-9
Purpose: Display form for creating new return requests
Process Flow:
1. Display header and add form template
2. Initialize empty form for new request
---
2. appendproduct - Dynamic Product Addition
Location: Lines 10-13
Purpose: AJAX endpoint for adding product entries to return request
Function Signature:
$itr = filter_input(INPUT_POST, 'itr');
Process Flow:
1. Accept iteration number for unique field naming
2. Display product addition template with unique identifiers
3. Enable dynamic form expansion
---
3. show() - Display Return Requests
Location: Lines 14-18
Purpose: Show listing of all return requests with filtering
Features:
- โข DataTables integration for advanced filtering
- โข Real-time search and pagination
- โข Status-based filtering
---
4. edit() - Edit Return Request
Location: Lines 19-33
Purpose: Edit existing return request with products
Function Signature:
$id = filter_input(INPUT_GET, 'id');
Process Flow:
1. Load return request data by ID
2. Get associated client information
3. Load all products in the return request
4. Fetch product names for display
5. Assign data to edit template
Data Loading:
$editdata = R::load('mechandisereturnrequest', $id);
$client = R::getRow('SELECT * FROM `client` WHERE clientid = ?',[$editdata->clientid]);
$editdata->clientname = $client['clientname'];
$mechandisereturnproducts = R::findAll('mechandisereturnproduct',
'mechandisereturnrequestid = ? and conditions = 0',[$id]);
foreach($mechandisereturnproducts as $mechandisereturnproduct){
$product = R::getRow('SELECT * FROM `product` WHERE productId = ?',
[$mechandisereturnproduct->productid]);
$mechandisereturnproduct->productname = $product['productName'];
}
---
5. savedata() - Save/Update Return Request
Location: Lines 102-161
Purpose: Main function for saving return requests with products
Function Signature:
function savedata()
Input Parameters:
- โข
damagedintact- Condition flag (1=damaged, 0=intact) - โข
clientid- Customer ID making the return request - โข
productsitr- Number of products in request - โข
productid_X- Product IDs for each item - โข
comment_X- Comments for each product - โข
mechandiseReturnProductid_X- Existing product record IDs (for updates)
Process Flow:
1. Validate input parameters and get user information
2. Create new request or load existing for updates
3. Set appropriate timestamps and user tracking
4. Loop through all products and save/update each item
5. Redirect to show page on success
Request Record Handling:
if (!$id) {
$realestates = R::dispense('mechandisereturnrequest');
$realestates->conditions = 0;
$realestates->addtoday = $today;
$realestates->adduserid = $userid;
$realestates->agrees = 0; // Pending approval
} else {
$realestates = R::load('mechandisereturnrequest',$id);
$realestates->updatetoday = $today;
$realestates->updateuserid = $userid;
}
Product Processing Loop:
for ($i = 1; $i <= $productsitr; $i++) {
$productid = filter_input(INPUT_POST, 'productid_' . $i);
$comment = filter_input(INPUT_POST, 'comment_' . $i);
$mechandiseReturnProductid = filter_input(INPUT_POST, 'mechandiseReturnProductid_' . $i);
if (!$productid) {continue;} // Skip empty products
if (!$mechandiseReturnProductid) {
// Create new product record
$realestatesunits = R::dispense('mechandisereturnproduct');
$realestatesunits->addtoday = $today;
$realestatesunits->adduserid = $userid;
} else {
// Update existing product record
$realestatesunits = R::load('mechandisereturnproduct',$mechandiseReturnProductid);
$realestatesunits->updatetoday = $today;
$realestatesunits->updateuserid = $userid;
}
$realestatesunits->mechandisereturnrequestid = $mechandisereturnrequestid;
$realestatesunits->productid = $productid;
$realestatesunits->comment = $comment;
$realestatesunits->conditions = 0;
R::store($realestatesunits);
}
---
6. select2client() - Client Search AJAX
Location: Lines 85-97
Purpose: AJAX endpoint for client autocomplete search
Function Signature:
function select2client()
Process Flow:
1. Accept search term from POST
2. Query clients with name/phone matching
3. Return formatted JSON for Select2 dropdown
Search Query:
SELECT clientid, CONCAT(clientname,'/',clientphone) as texts
FROM client
WHERE conditions = 0
AND CONCAT(clientname,'/',clientphone) LIKE '%[searchTerm]%'
LIMIT 50
---
7. select2product() - Product Search AJAX
Location: Lines 68-80
Purpose: AJAX endpoint for product autocomplete search
Function Signature:
function select2product()
Process Flow:
1. Accept product search term
2. Query active products by name
3. Return formatted JSON for dropdown selection
Search Query:
SELECT productId, CONCAT(productName) as texts
FROM product
WHERE conditions = 0
AND CONCAT(productName) LIKE '%[searchTerm]%'
LIMIT 50
---
8. showajax() - DataTables AJAX Handler
Location: Lines 166-284
Purpose: Provide server-side processing for return request listing
Function Signature:
function showajax()
Filter Parameters:
- โข
start_date/end_date- Date range filtering - โข
conditions- Record status filter - โข
clientid- Client filter - โข
productid- Product filter - โข
damagedintact- Condition filter (damaged/intact)
Process Flow:
1. Build dynamic WHERE clause based on filters
2. Add optional product JOIN if filtering by product
3. Apply search functionality across multiple columns
4. Generate approval status dropdown for each record
5. Return formatted data with action buttons
Approval Status Handling:
$agrees = '<select name="agrees" class="selectnew agrees" data-id="'.$row["id"].'">
<option value="0" ';if($row["agrees"] == 0){$agrees .= 'selected';}$agrees .= '>ููุฏ ุงูุงูุชุธุงุฑ</option>
<option value="1" ';if($row["agrees"] == 1){$agrees .= 'selected';}$agrees .='>ูุจูู</option>
<option value="2" ';if($row["agrees"] == 2){$agrees .= 'selected';}$agrees .='>ุฑูุถ</option>
</select>';
Complex Product Loading:
$mechandisereturnproduct = R::getAll('SELECT * FROM `mechandisereturnproduct`
LEFT JOIN product ON mechandisereturnproduct.productid = product.productId
WHERE mechandisereturnproduct.conditions = 0');
$allproductName = '';
foreach($mechandisereturnproduct as $product){
$allproductName .= $product['productName'] . ' / ';
}
---
9. agrees() - Approval Status Management
Location: Lines 51-67
Purpose: AJAX endpoint for updating approval status
Function Signature:
function agrees()
Process Flow:
1. Get return request ID and approval status
2. Update agreement status with timestamp and user
3. Return success/failure response
Approval Logic:
$tables = R::load('mechandisereturnrequest',$id);
$tables->agrees = $agrees;
$tables->agreetoday = $today;
$tables->agreeuserid = $userid;
---
10. removeappend() - Remove Product from Request
Location: Lines 288-303
Purpose: Soft delete individual products from return request
Function Signature:
function removeappend()
Process Flow:
1. Get product record ID
2. Set conditions to 1 (soft delete)
3. Record deletion timestamp and user
4. Return success status
---
11. remove() - Delete Return Request
Location: Lines 305-322
Purpose: Soft delete entire return request
Function Signature:
function remove()
Process Flow:
1. Load return request by ID
2. Set soft delete flags and audit information
3. Redirect to listing page
---
๐ Workflows
Workflow 1: Return Request Creation
---
Workflow 2: Approval Process
---
๐ URL Routes & Actions
| URL Parameter | Function Called | Description | |
|---|---|---|---|
| `do=` (empty) | Default action | Display add return request form | |
| `do=appendproduct` | appendproduct | AJAX add product form | |
| `do=show` | show() | Display return request listing | |
| `do=edit` | edit() | Edit return request | |
| `do=savedata` | savedata() | Save/update return request | |
| `do=showajax` | showajax() | DataTables AJAX data | |
| `do=select2client` | select2client() | Client search AJAX | |
| `do=select2product` | select2product() | Product search AJAX | |
| `do=removeappend` | removeappend() | Remove product from request | |
| `do=agrees` | agrees() | Update approval status | |
| `do=remove` | remove() | Delete return request |
๐งฎ Calculation Methods
Condition Assessment
// Product condition flag
if($row["damagedintact"] == 1){
$condition = 'ุชุงูู'; // Damaged
} else {
$condition = 'ุณููู
'; // Intact
}
Approval Status Logic
- โข
agrees = 0- Pending approval (ููุฏ ุงูุงูุชุธุงุฑ) - โข
agrees = 1- Approved (ูุจูู) - โข
agrees = 2- Rejected (ุฑูุถ)
Audit Trail Tracking
// Creation tracking
$addtoday = date("Y-m-d H:i:s");
$adduserid = $_SESSION['userid'];
// Update tracking
$updatetoday = date("Y-m-d H:i:s");
$updateuserid = $_SESSION['userid'];
// Deletion tracking
$deltoday = date("Y-m-d H:i:s");
$deluserid = $_SESSION['userid'];
---
๐ Security & Permissions
Input Sanitization
// Proper input filtering throughout
$damagedintact = filter_input(INPUT_POST, 'damagedintact');
$clientid = filter_input(INPUT_POST, 'clientid');
$productid = filter_input(INPUT_POST, 'productid_' . $i);
Soft Delete Implementation
- โข Uses
conditionsflag instead of hard delete - โข Preserves audit trail and data integrity
- โข Allows for data recovery if needed
Session-Based User Tracking
- โข All operations tracked with user ID from session
- โข Timestamps recorded for all modifications
- โข Complete audit trail for compliance
---
๐ Performance Considerations
Database Optimization
1. Indexes Needed:
- mechandisereturnrequest(clientid, addtoday)
- mechandisereturnrequest(agrees, conditions)
- mechandisereturnproduct(mechandisereturnrequestid, conditions)
- mechandisereturnproduct(productid, conditions)
2. Query Performance:
- AJAX searches limited to 50 results
- Efficient filtering with proper WHERE clauses
- Soft delete queries may benefit from conditions index
AJAX Optimization
- โข Autocomplete searches with result limits
- โข Dynamic form expansion without full page reload
- โข Efficient JSON responses for Select2 dropdowns
---
๐ Common Issues & Troubleshooting
1. Incorrect Product Loading in showajax()
Issue: Product query may return all products instead of products for specific request
Location: Line 239-240
Problem: Query missing WHERE clause for specific request
Fix: Filter products by request ID:
$mechandisereturnproduct = R::getAll('SELECT * FROM `mechandisereturnproduct`
LEFT JOIN product ON mechandisereturnproduct.productid = product.productId
WHERE mechandisereturnproduct.conditions = 0
AND mechandisereturnproduct.mechandisereturnrequestid = ?', [$row['id']]);
2. Approval Status Not Updating
Issue: AJAX approval updates failing
Cause: Missing proper response handling
Debug:
// Check AJAX response
$('.agrees').change(function(){
var id = $(this).data('id');
var agrees = $(this).val();
// Add error handling
});
3. Dynamic Product Addition Issues
Issue: Product fields not appearing correctly
Cause: JavaScript iteration conflicts
Fix: Ensure unique field naming and proper template rendering
4. Search Performance
Issue: Client/product searches slow with large datasets
Cause: No indexes on search fields
Fix: Add indexes on commonly searched columns:
CREATE INDEX idx_client_search ON client(clientname, clientphone, conditions);
CREATE INDEX idx_product_search ON product(productName, conditions);
---
๐งช Testing Scenarios
Test Case 1: Basic Return Request Creation
1. Select client via autocomplete search
2. Set product condition (damaged/intact)
3. Add multiple products with comments
4. Save request and verify in listing
Test Case 2: Approval Workflow
1. Create return request with pending status
2. Update approval status via dropdown
3. Verify status change and audit trail
4. Test rejection with proper display
Test Case 3: Dynamic Product Management
1. Add products dynamically to request
2. Remove products from request
3. Edit existing request products
4. Verify product association integrity
Test Case 4: Search and Filtering
1. Filter by date range
2. Filter by client and product
3. Filter by condition and approval status
4. Test search functionality across fields
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข Return Policy Documentation - Business rules for returns
- โข AJAX Integration Guide - Frontend integration patterns
- โข Database Schema Documentation - Table relationships
---
Documented By: AI Assistant
Review Status: โ ๏ธ Needs Product Query Fix in showajax()
Next Review: After product loading issue resolved