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:

Primary Functions

Related Controllers

---

๐Ÿ—„๏ธ Database Tables

Primary Tables (Direct Operations)

Table NamePurposeKey Columns
**mechandisereturnrequest**Return request headersid, clientid, damagedintact, agrees, addtoday, adduserid, updatetoday, updateuserid, deltoday, deluserid, conditions
**mechandisereturnproduct**Return request product detailsid, mechandisereturnrequestid, productid, comment, addtoday, adduserid, updatetoday, updateuserid, deltoday, deluserid, conditions
### Reference Tables

Table NamePurposeKey Columns
**client**Customer informationclientid, clientname, clientphone
**product**Product catalogproductId, productName, conditions
**user**System usersuserid, 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:

---

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:

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:

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

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
START: Create Return Request
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
1Select Customer
- Search clients via AJAX autocomplete
- Select customer making return request
- Load customer information for display
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
2Set Return Condition
- Choose condition: Damaged (1) or Intact (0)
- Affects processing and approval workflow
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
3Add Products to Return
FOR EACH product to return:
โ”‚
โ†’ Search and select product via AJAX
โ†’ Add specific comments/reasons
โ†’ Option to add more products dynamically
โ”‚ โ””โ”€โ†’ Remove products if needed โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
4Save and Track
- Create return request with pending status
- Link all products to request
- Set agrees = 0 (pending approval)
- Ready for management review
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

Workflow 2: Approval Process

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
Return Request Lifecycle
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
Status 0: Pending Approval
- Request submitted by customer/staff
- Awaiting management review
- All products listed with conditions
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
Management Review
- Review customer details and reason
- Assess product conditions and comments
- Check return policy compliance
- Make approval decision
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ–ผ
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
Final Status
Status 1: Approved
โ”‚ โ””โ”€โ†’ Process return and refund โ”‚
Status 2: Rejected
โ”‚ โ””โ”€โ†’ Mark as "ู…ุฑุชุฌุน ู„ู„ุชุณู„ูŠู…" (returned to delivery) โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

---

๐ŸŒ URL Routes & Actions

URL ParameterFunction CalledDescription
`do=` (empty)Default actionDisplay add return request form
`do=appendproduct`appendproductAJAX 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

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

Session-Based User Tracking

---

๐Ÿ“Š 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

---

๐Ÿ› 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

---

Documented By: AI Assistant

Review Status: โš ๏ธ Needs Product Query Fix in showajax()

Next Review: After product loading issue resolved