# 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
- [x] Real-time sync with change detection
- [x] Automatic inventory quantity updates
- [x] Customer debt change synchronization
- [x] Online order processing and fulfillment
- [x] Dynamic product and category creation
- [x] Multi-store inventory management
- [x] Store movement tracking
- [x] Error handling and backup logging
- [x] Barcode generation and validation
- [x] Image encoding and transfer
- [x] Performance-optimized batch processing

### Related Controllers
- [onlinestoresetting.php](onlinestoresetting.md) - Sync configuration
- [onlinestoremainsetting.php](onlinestoremainsetting.md) - Basic store settings
- [productController.php](productController.md) - Product management
- [storedetailController.php](storedetailController.md) - Inventory management
- [storemovementController.php](storemovementController.md) - 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 |

### Order Processing Tables
| 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 |

### Core Data Tables
| 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 |

### Configuration Tables
| 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**:
   ```php
   $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](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [onlinestoresetting.md](onlinestoresetting.md) - Sync configuration
- [storemovementController.md](storemovementController.md) - Store transfers
- [storedetailController.md](storedetailController.md) - Inventory management

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When major changes occur