Onlinestoresync Documentation
Online Store Sync Controller Documentation
File: /controllers/onlinestoresync.php
Purpose: Real-time data synchronization between ERP and online store with automatic inventory management
Last Updated: December 20, 2024
Total Functions: 25+
Lines of Code: ~1,136
---
๐ Overview
The Online Store Sync Controller provides real-time, bidirectional data synchronization between the ERP system and external online stores. It handles:
- โข Real-time category and product synchronization with change tracking
- โข Automatic inventory quantity updates
- โข Store movement and reporting synchronization
- โข Customer debt synchronization
- โข Online order processing and inventory allocation
- โข Product creation from online orders
- โข Category hierarchy management
- โข Barcode generation and management
- โข Store-to-store inventory transfers
- โข Error logging and backup systems
- โข Bulk synchronization with performance optimization
Primary Functions
- โ Real-time sync with change detection
- โ Automatic inventory quantity updates
- โ Customer debt change synchronization
- โ Online order processing and fulfillment
- โ Dynamic product and category creation
- โ Multi-store inventory management
- โ Store movement tracking
- โ Error handling and backup logging
- โ Barcode generation and validation
- โ Image encoding and transfer
- โ Performance-optimized batch processing
Related Controllers
- โข onlinestoresetting.php - Sync configuration
- โข onlinestoremainsetting.php - Basic store settings
- โข productController.php - Product management
- โข storedetailController.php - Inventory management
- โข storemovementController.php - Store transfers
---
๐๏ธ Database Tables
Primary Synchronization Tables
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **onlinetempcategory** | Modified categories queue | id, productCatId, changes pending sync | |
| **onlinetempproduct** | Modified products queue | id, productId, changes pending sync | |
| **onlinetempstoredetail** | Inventory change queue | id, productid, storeid, quantity changes | |
| **onlinetempstorereport** | Store report queue | id, storereportid, operation details |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **onlinetemporder** | Order staging | id, onlineorderid, customerid, ordertotal, orderstatus | |
| **onlinetemporderclient** | Customer staging | id, erpid, customer_id, clientname, clientmobile, clientareaid | |
| **onlinetemporderproduct** | Order items staging | id, orderid, productid, quantity, price, total |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **productcat** | Categories master | productCatId, productCatName, productCatParent, conditions | |
| **product** | Products master | productId, productName, productCatId, conditions, pricing | |
| **storedetail** | Inventory quantities | storedetailid, productid, storeid, productquantity | |
| **storereport** | Inventory movements | storereportid, productid, storeid, operation details | |
| **storemovement** | Store transfers | id, productid, storeidfrom, storeidto, transferproductamount | |
| **client** | Customer master | clientid, clientname, clientdebt, clientareaid | |
| **clientdebtchange** | Debt change log | clientdebtchangeid, clientid, amount, type, date |
| Table Name | Purpose | Key Columns | |
|---|---|---|---|
| **onlinestoresetting** | Sync configuration | url, availableStores, timing settings | |
| **programsettings** | System settings | usedParcode, parcodeDigits, inventory settings | |
| **availableparcode** | Barcode pool | value, available barcodes |
๐ Key Functions
1. syncCatAndProducts - Real-time Change Sync
Location: Line 232
Purpose: Synchronize only categories and products that have changed
Process Flow:
1. Process Modified Categories:
$onlineTempCategory = $productCatExt->queryAllForCURLSyncAndLock();
if (count($onlineTempCategory) > 0) {
// Encode category images
foreach ($onlineTempCategory as $value) {
$path = str_replace('\\', '/', getcwd()) . '/../views/default/images/cat_image/' . $value->logo;
$value->logo_base64 = base64_encode(file_get_contents($path));
}
// Send to online store
$response = CURL_IT2($onlineTempCategory, $onlineStoreSetting->url . '/api_erp/syncEditedCatsFromERPCURL');
// Clear queue if successful
if ((int) $response == 1) {
$onlineTempCategoryEX->TRUNCATE();
} else {
// Log error for retry
$myfile = fopen("backup/" . date("Y-m-d") . ".txt", "a+");
$txt = "syncEditedCatsFromERPCURL ERROR " . date("Y-m-d H:i:s") . " ;\r\n";
fwrite($myfile, $txt);
}
}
```
2. **Process Modified Products**:
```php
$onlineTempProduct = $productExt->queryAllSimpleForCurlNormalSyncAndLock('', $joinConditionWithStore);
if (count($onlineTempProduct) > 0) {
// Process product images (up to 8 per product)
foreach ($onlineTempProduct as $value) {
$path = str_replace('\\', '/', getcwd()) . '/../views/default/images/product_image/';
$value->logo_base64 = base64_encode(file_get_contents($path . $value->logo));
$value->logo1_base64 = base64_encode(file_get_contents($path . $value->logo1));
// ... through logo7_base64
}
$response = CURL_IT2($onlineTempProduct, $onlineStoreSetting->url . '/api_erp/syncEditedProductsFromERPCURL');
if ((int) $response == 1) {
$onlineTempProductEX->TRUNCATE();
}
}
```
---
### 2. **syncProductQuantityAndStoreReport - Inventory Sync**
**Location**: Line 283
**Purpose**: Sync inventory quantities and store movement reports
**Process Flow**:
1. **Quantity Synchronization**:
```php
$onlineTempStoreDetail = $productExt->queryAllOrderedLimitedSimpleForCurlNormal2('', $joinConditionWithStore);
foreach ($onlineTempStoreDetail as $value) {
// Calculate quantity based on store selection
if (empty($onlineStoreSetting->availableStores)) {
$value->quantity = 0;
} else {
$value->quantity = $value->sumProductQuantity;
}
// Encode images for quantity update
$path = str_replace('\\', '/', getcwd()) . '/../views/default/images/product_image/';
$value->logo_base64 = base64_encode(file_get_contents($path . $value->logo));
// ... additional image encoding
}
$response = CURL_IT2($onlineTempStoreDetail, $onlineStoreSetting->url . '/api_erp/syncProductQuantityFromERPCURL');
```
2. **Store Report Synchronization**:
```php
$onlineTempStoreReport = $onlineTempStoreReportEX->queryAllSimpleAndLockForCurl();
if (count($onlineTempStoreReport) > 0) {
$response = CURL_IT2($onlineTempStoreReport, $onlineStoreSetting->url . '/api_erp/insertNewStoreReportFromERPCURL');
if ((int) $response == 1) {
$onlineTempStoreReportEX->TRUNCATE();
}
}
```
---
### 3. **syncClientsDeptOnline - Customer Debt Sync**
**Location**: Line 335
**Purpose**: Synchronize customer debt changes to online store
**Process Flow**:
1. Get last synchronized debt change ID
2. Query all debt changes after that ID
3. Send in batches to online store
4. Update synchronization pointer
**Implementation**:
php
if ($onlineStoreSetting->clientdebtchangeStartId >= 0) {
$last = $onlineStoreSetting->clientdebtchangeStartId;
} else {
// Get last ID from online store
$last = CURL_IT2($clientsDebtHistory, $onlineStoreSetting->url . '/api_erp/getLastClientDebtChangeIdInOnlineShop');
}
$clientsDebtHistory = $clientDeptChangeEX->getAllClientDeptChangeAfterId($id, ' and client.clientid != 1 ');
foreach ($clientsDebtHistory as $value) {
array_push($partOfClientsDebtHistory, $value);
CURL_IT($partOfClientsDebtHistory, $onlineStoreSetting->url . '/api_erp/updateClientsDebtFromERPCURL');
$partOfClientsDebtHistory = array();
}
---
### 4. **saveOnlineOrders - Order Processing**
**Location**: Line 365
**Purpose**: Retrieve and process orders from online store
**Process Flow**:
1. **Retrieve Orders from Online Store**:
```php
$allOrders = CURL_IT2(array(), $onlineStoreSetting->url . '/api_erp/ERPSendOrders');
$allOrders = json_decode($allOrders);
```
2. **Process Each Order**:
```php
foreach ($allOrders as $data_arr) {
$the_order = $data_arr->order;
$order_products = $data_arr->order_products;
// Save/update order header
$onlineTempOrder = $onlineTempOrderDAO->queryByOnlineorderid($the_order->id);
$onlineTempOrder->customerid = getclientId($the_order->client, $onlineStoreSetting, $the_order->id, $the_order->customer_id);
$onlineTempOrder->ordertotal = $the_order->order_total;
$onlineTempOrder->shippingcost = $the_order->shipping_cost;
// ... additional order fields
if (isset($onlineTempOrder->id) && $onlineTempOrder->id > 0) {
$onlineTempOrderDAO->update($onlineTempOrder);
} else {
$onlineTempOrderDAO->insert($onlineTempOrder);
}
}
```
3. **Process Order Products with Inventory Movement**:
```php
$operationnum = getNextIdStoreMovement();
foreach ($order_products as $value) {
$onlineTempOrderProduct->productid = getProductId($value->product_data, $onlineStoreSetting);
$onlineTempOrderProduct->quantity = $value->quantity;
// ... save order product
// Move inventory: main store โ online store
moveProductFromStoreToAnother($onlineTempOrderProduct->productid,
$onlineTempOrderProduct->quantity,
$mainStoreId, $onlineStoreId, $operationnum);
}
```
---
### 5. **getclientId() - Customer Management**
**Location**: Line 579
**Purpose**: Get or create customer from online order data
**Function Signature**:
php
function getclientId($client_data, $onlineStoreSetting, $orderid, $customer_id)
**Process Flow**:
1. Check if customer has ERP ID (existing customer)
2. If not, create temporary customer record
3. Use default client area for new customers
4. Store customer data for later processing
---
### 6. **getProductId() - Product Management**
**Location**: Line 615
**Purpose**: Get or create product from online order data
**Function Signature**:
php
function getProductId($product_data, $onlineStoreSetting)
**Process Flow**:
1. **Check Existing Product**:
```php
$productId = (int) $product_data->erpid;
if ($productId < 1) {
// Product doesn't exist in ERP, create new
}
```
2. **Create New Product**:
```php
$product = $productDAO->queryByProductName($product_data->name);
$parcode = generateParcode();
removeParcodeFromTable($parcode);
// Set product properties
$product->productName = $product_data->name;
$product->productCatId = getCatId($product_data->cat, $onlineStoreSetting);
$product->productBuyPrice = $product_data->productBuyPrice;
$product->parcode = $parcode;
// ... additional properties
$productId = $productDAO->insert($product);
```
3. **Handle Product Images**:
```php
$success = file_put_contents('../views/default/images/product_image/' . $product_data->logo,
base64_decode($product_data->logo_base64));
// ... save additional images
```
4. **Create Supporting Records**:
```php
// Product unit
$productUnit->productid = $productId;
$productUnit->unitid = 1;
$productUnitDAO->insert($productUnit);
// Store detail
$storeDetail->productid = $productId;
$storeDetail->productquantity = 0;
$storeDetailDAO->insert($storeDetail);
// Store report
$storeReport->processname = "ุฅุถุงูุฉ ู
ูุชุฌ";
$storeReportDAO->insert($storeReport);
```
---
### 7. **getCatId() - Category Management**
**Location**: Line 744
**Purpose**: Get or create category from online data
**Function Signature**:
php
function getCatId($cat_data, $onlineStoreSetting)
**Similar to getProductId() but for categories**:
- Check existing category by ERP ID
- Create new category if needed
- Handle category images
- Set up category relationships
- Sync back to online store
---
### 8. **Inventory Management Functions**
#### **moveProductFromStoreToAnother()**
**Location**: Line 1002
**Purpose**: Transfer inventory between stores with full tracking
php
function moveProductFromStoreToAnother($productId, $transferproductAmount, $storeidfrom, $storeidto, $operationnum)
{
// Record the movement
$myStoremovement->productid = $productId;
$myStoremovement->transferproductamount = $transferproductAmount;
$myStoremovement->storeidfrom = $storeidfrom;
$myStoremovement->storeidto = $storeidto;
$myStoremovement->operationnum = $operationnum;
$transferproductId = $myStoremovementRecord->insert($myStoremovement);
// Decrease quantity in source store
$storedetailFromData = getStoredetailData($storeidfrom, $productId);
$productquantityFromAfter = decreaseProductQuantity($storedetailFromId,
$productquantityFromBefore,
$transferproductAmount);
// Increase quantity in destination store
$storedetailToData = getStoredetailData($storeidto, $productId);
$productquantityToAfter = increaseProductQuantity($storedetailToId,
$productquantityToBefore,
$transferproductAmount);
// Record both movements in store report
insertStorereport($productId, $storeidfrom, $transferproductAmount,
$productquantityFromBefore, $productquantityFromAfter,
1, $transferproductId, "ุชุญููู ู ูุชุฌุงุช ู ู ุงูู ุฎุฒู", "storemovementController.php");
insertStorereport($productId, $storeidto, $transferproductAmount,
$productquantityToBefore, $productquantityToAfter,
0, $transferproductId, "ุชุญููู ู ูุชุฌุงุช ุฅูู ุงูู ุฎุฒู", "storemovementController.php");
}
#### **increaseProductQuantity() / decreaseProductQuantity()**
**Location**: Lines 919, 942
**Purpose**: Modify store quantities with sync notification
php
function increaseProductQuantity($storedetailId, $productquantityBefore, $productChangeAmount)
{
$productquantityAfter = $productquantityBefore + $productChangeAmount;
// Update database
$myStoredetail = $myStoredetailRecord->load($storedetailId);
$myStoredetail->productquantity = $productquantityAfter;
$myStoredetailEx->updateProductquantity($myStoredetail);
// Trigger sync notification
onlineTempStoreDetailFunc($myStoredetail->storeid, $myStoredetail->productid,
0, 0, abs($productChangeAmount), 1);
return $productquantityAfter;
}
---
### 9. **Barcode Generation System**
#### **generateParcode()**
**Location**: Line 865
**Purpose**: Generate unique product barcode
php
function generateParcode()
{
global $availableParcodeEX;
$parcode = $availableParcodeEX->getAvailableParcodeValue();
// Recursively check uniqueness
$data = checkbarcode($parcode);
if ($data != 2) {
$parcode = generateParcode(); // Recursive call
}
return $parcode;
}
#### **checkbarcode()**
**Location**: Line 814
**Purpose**: Validate barcode uniqueness and format
php
function checkbarcode($parcode, $productId = 0)
{
if ($Programsettingdata->usedParcode == 0) {
// Check available barcode pool
$parcodeResult = $availableParcodeDAO->queryByValue($parcode);
if (isset($parcodeResult) && count($parcodeResult) > 0) {
return 2; // Available
}
}
// Check for duplicates in products
$data = $productExt->isParcodeRepated($parcode, $query);
return count($data) > 0 ? 1 : 2; // 1=duplicate, 2=unique
}
#### **removeParcodeFromTable()**
**Location**: Line 877
**Purpose**: Remove used barcode from available pool
---
### 10. **Sync Helper Functions**
#### **CURL_IT() / CURL_IT2()**
**Location**: Lines 1081, 1109
**Purpose**: Send data to online store with response handling
php
function CURL_IT2($data_arr, $url)
{
$post = ['data_arr' => json_encode($data_arr)];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$response = curl_exec($ch);
curl_close($ch);
return $response; // CURL_IT2 returns response, CURL_IT doesn't
}
---
## ๐ Workflows
### Workflow 1: Real-time Change Synchronization
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Real-time Sync Process โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Check Change Queues โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Category Changes: โ โ
โ โ - Query onlinetempcategory table โ โ
โ โ - Lock records for processing โ โ
โ โ โ โ
โ โ Product Changes: โ โ
โ โ - Query onlinetempproduct table โ โ
โ โ - Include store filter conditions โ โ
โ โ - Lock records for processing โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Process Category Changes โ
โ IF categories have changes: โ
โ โ โ
โ โโโ Load category data with images โ
โ โ โ
โ โโโ Encode images to Base64 โ
โ โ โ
โ โโโ Send via CURL to online store โ
โ โ โโ POST to /api_erp/syncEditedCatsFromERPCURL โ
โ โ โ
โ โโโ Check response status โ
โ โ โโ Success: Clear change queue โ
โ โ โโ Failure: Log error for retry โ
โ โ โ
โ โโโ Continue to product processing โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Process Product Changes โ
โ IF products have changes: โ
โ โ โ
โ โโโ Load product data with store quantities โ
โ โ โ
โ โโโ Calculate quantities from selected stores โ
โ โ โ
โ โโโ Process multiple product images โ
โ โ โโ Main product image (logo) โ
โ โ โโ Additional images (logo1-7) โ
โ โ โ
โ โโโ Encode all images to Base64 โ
โ โ โ
โ โโโ Send via CURL to online store โ
โ โ โโ POST to /api_erp/syncEditedProductsFromERPCURLโ
โ โ โ
โ โโโ Clear change queue if successful โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Error Handling and Logging โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Success Path: โ โ
โ โ - Clear processed change queues โ โ
โ โ - Return "Done" status โ โ
โ โ - Update last sync timestamp โ โ
โ โ โ โ
โ โ Error Path: โ โ
โ โ - Write to backup/[date].txt file โ โ
โ โ - Preserve changes for retry โ โ
โ โ - Log specific error details โ โ
โ โ - Return error status โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
### Workflow 2: Online Order Processing and Fulfillment
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START: Process Online Orders โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 1. Retrieve Orders from Online Store โ
โ - Call online store API: /api_erp/ERPSendOrders โ
โ - Parse JSON response โ
โ - Extract order headers and line items โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 2. Process Each Order โ
โ FOR EACH order in response: โ
โ โ โ
โ โโโ Extract order header data โ
โ โ โโ Order ID, customer info โ
โ โ โโ Totals, shipping, status โ
โ โ โโ Payment information โ
โ โ โ
โ โโโ Process customer information โ
โ โ โโ Check if customer exists in ERP โ
โ โ โโ Create/update customer record โ
โ โ โโ Handle customer area assignment โ
โ โ โ
โ โโโ Save/update order header โ
โ โโ Insert new orders โ
โ โโ Update existing orders โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 3. Process Order Line Items โ
โ FOR EACH product in order: โ
โ โ โ
โ โโโ Validate/Create Product โ
โ โ โโ Check if product exists in ERP โ
โ โ โโ Create new product if needed โ
โ โ โ โโ Generate barcode โ
โ โ โ โโ Create category if needed โ
โ โ โ โโ Save product images โ
โ โ โ โโ Create store records โ
โ โ โ โโ Initialize inventory โ
โ โ โโ Get/assign ERP product ID โ
โ โ โ
โ โโโ Save order line item โ
โ โ โโ Product ID, quantity, price โ
โ โ โโ Shipping cost allocation โ
โ โ โโ Discount information โ
โ โ โ
โ โโโ Handle Inventory Movement โ
โ โโ Get next operation number โ
โ โโ Move inventory: main store โ online store โ
โ โโ Update store quantities โ
โ โโ Record store movements โ
โ โโ Generate store reports โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 4. Inventory Allocation Process โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ For Each Order Product: โ โ
โ โ โ โ
โ โ Step 1: Get Inventory Data โ โ
โ โ - Load current quantities from main store โ โ
โ โ - Validate sufficient inventory โ โ
โ โ โ โ
โ โ Step 2: Record Movement โ โ
โ โ - Insert storemovement record โ โ
โ โ - Set operation number for grouping โ โ
โ โ - Link to order for tracking โ โ
โ โ โ โ
โ โ Step 3: Update Source Store (Main) โ โ
โ โ - Decrease quantity in main store โ โ
โ โ - Record "outbound" store report โ โ
โ โ - Update last process date โ โ
โ โ โ โ
โ โ Step 4: Update Destination Store (Online) โ โ โ
โ โ - Increase quantity in online store โ โ
โ โ - Record "inbound" store report โ โ
โ โ - Trigger sync notification โ โ
โ โ โ โ
โ โ Step 5: Handle Store Creation โ โ
โ โ - Create store record if doesn't exist โ โ
โ โ - Initialize with transferred quantity โ โ
โ โ - Record creation in store report โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ 5. Completion and Status Update โ
โ - Update order processing status โ
โ - Clear temporary order data โ
โ - Return success confirmation โ
โ - Trigger inventory sync if needed โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
---
## ๐ URL Routes & Actions
| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=syncCatAndProducts` | Real-time sync | Sync changed categories and products |
| `do=syncProductQuantityAndStoreReport` | Inventory sync | Sync quantities and store reports |
| `do=syncClientsDeptOnline` | Debt sync | Sync customer debt changes |
| `do=saveOnlineOrders` | Order processing | Process orders from online store |
| `do=autoSyncWithOnline` | Auto sync UI | Display auto-sync interface |
| `do=autoSyncWithOnlinCatAndProduct` | Category/Product UI | Auto-sync for categories/products |
| `do=autoSyncWithOnlinProductQuantity` | Quantity UI | Auto-sync for quantities |
| `do=updateonlineproductsFromTo` | Range sync | Sync products by ID range |
| `do=updateonlineclientsFromTo` | Range sync | Sync clients by ID range |
| `do=syncClientsDeptOnlineFromTo` | Range sync | Sync debt changes by ID range |
### Range Synchronization Parameters
**Product Range Sync** (`do=updateonlineproductsFromTo`):
- `from` - Starting product ID
- `afterFromId` - Whether to start after the from ID (0/1)
- `to` - Ending product ID
- `tillEnd` - Sync to end of table (0/1)
**Client Range Sync** (`do=updateonlineclientsFromTo`):
- `from` - Starting client ID
- `afterFromId` - Whether to start after the from ID (0/1)
- `to` - Ending client ID
- `tillEnd` - Sync to end of table (0/1)
**Debt Range Sync** (`do=syncClientsDeptOnlineFromTo`):
- `from` - Starting debt change ID
- `afterFromId` - Whether to start after the from ID (0/1)
- `to` - Ending debt change ID
- `tillEnd` - Sync to end of table (0/1)
---
## ๐งฎ Synchronization Logic
### Change Detection System
The system uses temporary tables to track changes:
php
// Categories: onlinetempcategory
// Products: onlinetempproduct
// Store quantities: onlinetempstoredetail
// Store reports: onlinetempstorereport
// Changes are queued when:
// 1. Category is modified
// 2. Product is modified
// 3. Inventory quantity changes
// 4. Store movements occur
### Store Inventory Calculation
php
if (empty($onlineStoreSetting->availableStores)) {
$value->quantity = 0; // No stores selected
} else {
$value->quantity = $value->sumProductQuantity; // Sum from selected stores
}
### Inventory Movement Logic
php
// Order fulfillment flow:
// 1. Customer places order online
// 2. System reserves inventory in main store
// 3. Transfers inventory to online store
// 4. Updates both store quantities
// 5. Records movements for audit
$mainStoreId = explode(',', $onlineStoreSetting->availableStores)[0];
$onlineStoreId = $onlineStoreSetting->onlinestoreid;
moveProductFromStoreToAnother($productId, $quantity, $mainStoreId, $onlineStoreId, $operationnum);
---
## ๐ Security & Permissions
### Change Queue Security
- Queue tables prevent concurrent access issues
- Locking mechanisms during processing
- Transaction rollback on errors
### Data Validation
php
// Product creation validation
if (isset($product->productName) && $product->productName != "") {
// Only process if valid product name
}
// Barcode uniqueness validation
$data = checkbarcode($parcode);
if ($data != 2) {
$parcode = generateParcode(); // Generate new if not unique
}
### Access Control
- Session-based authentication required
- Admin permissions for sync operations
- Store access restrictions apply
---
## ๐ Performance Considerations
### Batch Processing Optimization
1. **Real-time Processing**: Only process changed records
2. **Queue Management**: Clear queues after successful sync
3. **Error Recovery**: Preserve failed records for retry
4. **Image Processing**: Batch encode multiple images efficiently
### Memory Management
php
// Process images in batches to prevent memory exhaustion
foreach ($onlineTempProduct as $value) {
// Process 8 images per product
// Clear variables after each batch
}
### Database Performance
1. **Indexes Required**:
- `onlinetempcategory(productCatId)`
- `onlinetempproduct(productId)`
- `onlinetempstoredetail(productid, storeid)`
2. **Queue Optimization**:
- Regular queue cleanup
- Efficient TRUNCATE operations
- Proper locking mechanisms
---
## ๐ Common Issues & Troubleshooting
### 1. **Sync Queue Buildup**
**Issue**: Change queues grow but don't process
**Cause**: Network issues or online store downtime
**Solutions**:
php
// Check queue sizes
SELECT COUNT(*) FROM onlinetempcategory;
SELECT COUNT(*) FROM onlinetempproduct;
// Manual queue cleanup (if needed)
TRUNCATE onlinetempcategory;
TRUNCATE onlinetempproduct;
### 2. **Image Processing Failures**
**Issue**: Products sync but images missing
**Cause**: File path issues or corrupted images
**Debug**:
php
// Check image path resolution
$path = str_replace('\\', '/', getcwd()) . '/../views/default/images/product_image/';
echo "Image path: " . $path . "\n";
// Check file existence
if (!file_exists($path . $value->logo)) {
echo "Missing image: " . $value->logo . "\n";
}
### 3. **Inventory Discrepancies**
**Issue**: Online store quantities don't match ERP
**Cause**: Failed inventory movements or store filter issues
**Debug Queries**:
sql
-- Check store detail quantities
SELECT sd.productid, sd.storeid, sd.productquantity
FROM storedetail sd
WHERE sd.productid = [PRODUCT_ID];
-- Check store movements
SELECT * FROM storemovement
WHERE productid = [PRODUCT_ID]
ORDER BY transferproductdate DESC;
-- Check online store settings
SELECT availableStores FROM onlinestoresetting WHERE id = 1;
### 4. **Order Processing Failures**
**Issue**: Orders not creating products/customers
**Cause**: Missing category data or barcode generation issues
**Debug**:
php
// Check barcode generation
$parcode = generateParcode();
echo "Generated barcode: " . $parcode . "\n";
// Check category creation
echo "Category ID: " . getCatId($cat_data, $onlineStoreSetting) . "\n";
---
## ๐งช Testing Scenarios
### Test Case 1: Real-time Sync
1. Modify a category in ERP
2. Verify entry in onlinetempcategory table
3. Run syncCatAndProducts
4. Verify queue cleared and category updated online
5. Repeat for products
### Test Case 2: Order Processing
1. Create test order in online store
2. Run saveOnlineOrders
3. Verify order appears in onlinetemporder
4. Check customer creation/mapping
5. Verify inventory movements
6. Check store quantities updated
### Test Case 3: Inventory Sync
1. Change product quantity in ERP store
2. Verify entry in onlinetempstoredetail
3. Run syncProductQuantityAndStoreReport
4. Verify online store quantity updated
5. Check store reports generated
### Test Case 4: Range Synchronization
1. Use updateonlineproductsFromTo with specific range
2. Verify only products in range synchronized
3. Test afterFromId and tillEnd flags
4. Check performance with large ranges
```
---
๐ Related Documentation
- โข CLAUDE.md - PHP 8.2 migration guide
- โข onlinestoresetting.md - Sync configuration
- โข storemovementController.md - Store transfers
- โข storedetailController.md - Inventory management
---
Documented By: AI Assistant
Review Status: โ Complete
Next Review: When major changes occur