# Online Store Settings Controller Documentation

**File**: `/controllers/onlinestoresetting.php`  
**Purpose**: Advanced online store synchronization configuration and data transfer management  
**Last Updated**: December 20, 2024  
**Total Functions**: 10+  
**Lines of Code**: ~584

---

## 📋 Overview

The Online Store Settings Controller manages advanced configuration for synchronizing data between the ERP system and external online stores. It handles:
- Online store URL and connection configuration
- Bulk data synchronization (categories, products, clients)
- Store selection for inventory synchronization
- Synchronization scheduling and timing
- Customer debt synchronization
- Order retrieval and processing
- Image encoding and transfer for products/categories
- Data chunking for large transfers
- Error handling and backup logging

### Primary Functions
- [x] Configure online store connection settings
- [x] Bulk synchronize categories with image transfer
- [x] Bulk synchronize products with multiple images
- [x] Synchronize customer/client data
- [x] Transfer customer debt history
- [x] Retrieve and process online orders
- [x] Manage store inventory selection
- [x] Handle data chunking for performance
- [x] Image encoding and transfer (Base64)
- [x] Error logging and backup creation

### Related Controllers
- [onlinestoremainsetting.php](onlinestoremainsetting.md) - Basic store settings
- [onlinestoresync.php](onlinestoresync.md) - Real-time synchronization
- [onlineCatController.php](onlineCatController.md) - Category management
- [productController.php](productController.md) - Product management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **onlinestoresetting** | Sync configuration | onlinesettingid, url, availableStores, onlinestoreid, updatetype, timing settings |
| **onlinetemporder** | Temporary order storage | id, onlineorderid, customerid, ordertotal, createdatetime, orderstatus |
| **onlinetemporderproduct** | Order line items | id, orderid, productid, quantity, price, total |

### Source Tables (Read for Sync)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **productcat** | Categories to sync | productCatId, productCatName, productCatParent, logo, conditions |
| **product** | Products to sync | productId, productName, productCatId, logo, logo1-7, conditions |
| **client** | Customers to sync | clientid, clientname, clientcode, clientmobile, clientdebt, conditions |
| **storedetail** | Inventory quantities | storedetailid, productid, storeid, productquantity |

### Configuration Tables
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **store** | Available stores | storeId, storeName, conditions |
| **clientarea** | Customer areas | id, name, description |
| **government** | Geographic data | governmentid, name |
| **goverarea** | Area-government mapping | id, governmentid, clientareaid |
| **youtubelink** | Help videos | youtubelinkid, title, url |

---

## 🔑 Key Functions

### 1. **Default Action / Settings Display**
**Location**: Line 145  
**Purpose**: Display online store synchronization configuration form

**Process Flow**:
1. Load current online store settings
2. Parse available stores from comma-separated string
3. Load client area and government data
4. Display configuration form with current values

**Template Variables**:
```php
$onlineStoreSetting = getOrHandleOnlineStoreSetting();
$onlineStoreSetting->availableStores = explode(',', $onlineStoreSetting->availableStores);
$allStores = $storeDAO->queryAll();
$clientareaData = $ClientareaDAO->load($onlineStoreSetting->onlineclientareaid);
```

---

### 2. **update() - Save Configuration**
**Location**: Line 502  
**Purpose**: Update synchronization settings and store selections

**Function Signature**:
```php
function update()
```

**Process Flow**:
1. Extract configuration parameters
2. Process store selection array
3. Update timing and synchronization settings
4. Save to database
5. Handle store quantity updates if stores changed

**Key Settings**:
```php
$onlineStoreSetting->url = $url;
$onlineStoreSetting->availableStores = $choosenStores_str;
$onlineStoreSetting->onlinestoreid = $onlinestoreid;
$onlineStoreSetting->updatetype = $updatetype;
$onlineStoreSetting->catprohour = $catprohour;
$onlineStoreSetting->catprominute = $catprominute;
$onlineStoreSetting->proquantityhour = $proquantityhour;
$onlineStoreSetting->proquantityminute = $proquantityminute;
$onlineStoreSetting->clientshour = $clientshour;
$onlineStoreSetting->clientsminute = $clientsminute;
$onlineStoreSetting->ordershour = $ordershour;
$onlineStoreSetting->ordersminute = $ordersminute;
$onlineStoreSetting->clientdebtchangeStartId = $clientdebtchangeStartId;
```

---

### 3. **updateonlinecatsandproducts - Full Data Sync**
**Location**: Line 174  
**Purpose**: Complete synchronization of categories and products with images

**Process Flow**:

#### Phase 1: Category Synchronization
```php
// Process categories in batches of 100
$limit = 100;
$all_items_count = $productCatExt->getCategoriesCount();

for ($i = $start; $i <= $all_items_count->productCatId; $i+=$limit) {
    $all_items = $productCatExt->queryAllOrderedLimitedForCURL($start, $limit);
    
    // Encode category images
    foreach ($all_items as $value) {
        $path = getcwd() . '/../views/default/images/cat_image/' . $value->logo;
        $value->logo_base64 = base64_encode(file_get_contents($path));
    }
    
    // Send to online store
    CURL_IT($all_items, $onlineStoreSetting->url . '/api_erp/copyCatsFromERPCURL');
}
```

#### Phase 2: Parent Relationship Update
```php
// Update category parent relationships
for ($i = $start; $i <= $all_items_count->productCatId; $i+=$limit) {
    $all_items = $productCatExt->queryAllOrderedLimitedForCURL($start, $limit);
    CURL_IT($all_items, $onlineStoreSetting->url . '/api_erp/updateCatParentOnlyCurl');
}
```

#### Phase 3: Product Synchronization  
```php
// Process products in batches of 50
$limit = 50;
$all_products_count = $productExt->getProductsCountForCURLNormal('', $joinConditionWithStore);

for ($i = $start; $i <= $all_products_count->productId; $i+=$limit) {
    $allproduct = $productExt->queryAllOrderedLimitedSimpleForCurlNormal($start, $limit, '', $joinConditionWithStore);
    
    // Process each product
    foreach ($allproduct as $value) {
        // Set quantity based on store selection
        if (empty($onlineStoreSetting->availableStores)) {
            $value->quantity = 0;
        } else {
            $value->quantity = $value->sumProductQuantity;
        }
        
        // Encode multiple product images
        $path = 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));
        $value->logo2_base64 = base64_encode(file_get_contents($path . $value->logo2));
        $value->logo3_base64 = base64_encode(file_get_contents($path . $value->logo3));
        $value->logo4_base64 = base64_encode(file_get_contents($path . $value->logo4));
        $value->logo5_base64 = base64_encode(file_get_contents($path . $value->logo5));
        $value->logo6_base64 = base64_encode(file_get_contents($path . $value->logo6));
        $value->logo7_base64 = base64_encode(file_get_contents($path . $value->logo7));
    }
    
    // Send to online store
    CURL_IT($allproduct, $onlineStoreSetting->url . '/api_erp/copyProductsFromERPCURL');
}
```

---

### 4. **updateonlinecats - Category Only Sync**
**Location**: Line 285  
**Purpose**: Synchronize only categories (faster operation)

**Features**:
- Same batching logic as full sync
- Only processes category data
- Updates parent relationships
- Includes image encoding

---

### 5. **updateonlineproducts - Product Only Sync**
**Location**: Line 340  
**Purpose**: Synchronize only products (most common operation)

**Features**:
- Product batching with image processing
- Store-based quantity calculation
- Multiple image encoding (up to 8 images per product)
- Store filter application

---

### 6. **updateonlineclients - Client Sync**
**Location**: Line 416  
**Purpose**: Synchronize customer/client data to online store

**Process Flow**:
```php
$limit = 100;
$all_clients_count = $clientEX->getClientsCountForCURLNormal(' and clientid != 1 ');

for ($i = $start; $i <= $all_clients_count->clientid; $i+=$limit) {
    $allclients = $clientEX->queryAllOrderedLimitedSimpleForCurlNormal($start, $limit, ' and clientid != 1 ');
    CURL_IT($allclients, $onlineStoreSetting->url . '/api_erp/copyClientsFromERPCURL');
    
    // Update start position
    $lastitem = end($allclients);
    $start = $lastitem->clientid;
}
```

**Features**:
- Excludes default client (clientid != 1)
- Batched processing
- Proper iteration handling

---

### 7. **onlineOrders - Order Management**
**Location**: Line 442  
**Purpose**: Display and filter online store orders

**Function Signature**:
```php
// POST parameters
$clientId = (int) $_POST["clientid"];
$orderid = (int) $_POST["orderid"];  
$from = $_POST["from"];
$to = $_POST["to"];
```

**Query Building**:
```php
$sqlQuery = '';
if ($orderid > 0) {
    $sqlQuery .= " and onlinetemporder.onlineorderid = " . $orderid;
} else {
    if ($clientId > 0) {
        $sqlQuery .= " and onlinetemporder.customerid = " . $clientId;
    }
    if (!empty($from)) {
        $sqlQuery .= " and onlinetemporder.createdatetime >= '" . $from . "'";
    }
    if (!empty($to)) {
        $sqlQuery .= " and onlinetemporder.createdatetime <= '" . $to . "'";
    }
}

// Default to today if no filters
if ($sqlQuery == "") {
    $sqlQuery .= " and onlinetemporder.createdatetime >= '" . date('Y-m-d 00:00:00') . "'";
    $sqlQuery .= " and onlinetemporder.createdatetime <= '" . date('Y-m-d 59:59:59') . "'";
}
```

---

### 8. **onlineOrderDetails - Order Detail View**
**Location**: Line 477  
**Purpose**: Display detailed view of specific order

**Process Flow**:
1. Load order header information
2. Load order line items with product details
3. Display comprehensive order view

```php
$onlineTempOrders = $onlineTempOrderEX->queryAllEX(' and onlinetemporder.id = ' . $id);
$onlineTempOrderProducts = $onlineTempOrderProductEX->queryByOrderidEX($onlineTempOrders->onlineorderid);
```

---

### 9. **CURL_IT() - Data Transfer Function**
**Location**: Line 558  
**Purpose**: Send data to online store via CURL POST

**Function Signature**:
```php
function CURL_IT($data_arr, $url)
```

**Process**:
```php
$post = [
    'data_arr' => json_encode($data_arr), // Encode array as JSON
];

$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

// Disable SSL verification for internal transfers
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

$response = curl_exec($ch);
curl_close($ch);
```

**Features**:
- JSON data encoding
- SSL verification bypass for internal networks
- Error handling
- Response capture

---

## 🔄 Workflows

### Workflow 1: Complete Data Synchronization
```
┌─────────────────────────────────────────────────────────────┐
│            START: Full Data Sync to Online Store           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Verify Online Store Configuration                       │
│     - Check online store URL is set                         │
│     - Verify connection to online store                     │
│     - Load synchronization settings                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Phase 1: Category Synchronization                       │
│     FOR EACH batch of 100 categories:                       │
│       │                                                     │
│       ├─→ Load category data from productcat table         │
│       │                                                     │
│       ├─→ Process category images                          │
│       │   ├─ Read image files from disk                    │
│       │   ├─ Convert to Base64 encoding                    │
│       │   └─ Attach to category data                       │
│       │                                                     │
│       ├─→ Send batch via CURL to online store              │
│       │   └─ POST to /api_erp/copyCatsFromERPCURL          │
│       │                                                     │
│       └─→ Continue until all categories processed          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Phase 2: Update Category Relationships                  │
│     FOR EACH batch of 100 categories:                       │
│       │                                                     │
│       ├─→ Load parent-child relationships                  │
│       │                                                     │
│       └─→ Send relationship updates                        │
│           └─ POST to /api_erp/updateCatParentOnlyCurl      │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Phase 3: Product Synchronization                        │
│     FOR EACH batch of 50 products:                          │
│       │                                                     │
│       ├─→ Load product data with store quantities          │
│       │   └─ Filter by selected stores if configured       │
│       │                                                     │
│       ├─→ Calculate quantities                             │
│       │   ├─ If no stores selected: quantity = 0           │
│       │   └─ Else: sum quantities from selected stores     │
│       │                                                     │
│       ├─→ Process multiple product images                  │
│       │   ├─ logo (main image)                             │
│       │   ├─ logo1 through logo7 (additional images)       │
│       │   ├─ Convert each to Base64                        │
│       │   └─ Attach to product data                        │
│       │                                                     │
│       ├─→ Send batch via CURL to online store              │
│       │   └─ POST to /api_erp/copyProductsFromERPCURL      │
│       │                                                     │
│       └─→ Continue until all products processed            │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Completion and Response                                 │
│     - Log completion time                                   │
│     - Return success response                               │
│     - Update last sync timestamp                            │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Online Order Processing
```
┌─────────────────────────────────────────────────────────────┐
│                START: View Online Orders                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Apply Order Filters                                     │
│     ┌─────────────────────────────────────────────────────┐ │
│     │ Filter Options:                                     │ │
│     │ - Specific order ID                                 │ │
│     │ - Customer/client ID                                │ │
│     │ - Date range (from/to)                              │ │
│     │ - Default: today's orders only                      │ │
│     └─────────────────────────────────────────────────────┘ │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Build Dynamic SQL Query                                 │
│     - Start with base onlinetemporder query                 │
│     - Add client filter if specified                        │
│     - Add date range filters if specified                   │
│     - Add specific order filter if specified                │
│     - Apply default date filter if no filters               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Load Order Data                                         │
│     - Execute query against onlinetemporder table           │
│     - Load associated customer information                   │
│     - Load online store configuration                       │
│     - Prepare data for display                              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Display Orders List                                     │
│     - Show order summary information                        │
│     - Include customer details                              │
│     - Show order totals and status                          │
│     - Provide drill-down links for details                  │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display synchronization settings |
| `do=update` | `update()` | Save synchronization configuration |
| `do=updateonlinecatsandproducts` | Bulk sync | Full category and product sync |
| `do=updateonlinecats` | Category sync | Categories only synchronization |
| `do=updateonlineproducts` | Product sync | Products only synchronization |
| `do=updateonlineclients` | Client sync | Customer data synchronization |
| `do=onlineOrders` | Order listing | Display/filter online orders |
| `do=onlineOrderDetails` | Order details | Show specific order details |

### Required Parameters by Action

**Configuration Update** (`do=update`):
- `url` - Online store URL
- `onlinestoreid` - Online store ID
- `onlineclientareaid` - Default client area
- `updatetype` - Synchronization type
- `stores[]` - Array of store IDs to sync
- `catprohour/catprominute` - Category sync timing
- `proquantityhour/proquantityminute` - Product quantity sync timing
- `clientshour/clientsminute` - Client sync timing
- `ordershour/ordersminute` - Order sync timing
- `clientdebtchangeStartId` - Starting ID for debt sync

**Order Filtering** (`do=onlineOrders`):
- `clientid` - Filter by customer ID
- `orderid` - Filter by specific order
- `from` - Start date filter
- `to` - End date filter

**Order Details** (`do=onlineOrderDetails`):
- `id` - Order ID to display

---

## 🧮 Synchronization Logic

### Store Selection Processing
```php
$choosenStores = filter_input(INPUT_POST, 'stores', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
$choosenStores_str = '';
foreach ($choosenStores as $value) {
    $choosenStores_str .= $value . ",";
}
$choosenStores_str = rtrim($choosenStores_str, ','); // Remove trailing comma
```

### Image Encoding Process
```php
// Category images
$path = str_replace('\\', '/', getcwd()) . '/../views/default/images/cat_image/' . $value->logo;
$value->logo_base64 = base64_encode(file_get_contents($path));

// Product images (up to 8 per product)
$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
```

### Quantity Calculation
```php
if (empty($onlineStoreSetting->availableStores)) {
    $value->quantity = 0; // No stores selected = no inventory
} else {
    $value->quantity = $value->sumProductQuantity; // Sum from selected stores
}
```

---

## 🔒 Security & Permissions

### Data Transfer Security
- CURL SSL verification disabled for internal networks
- JSON encoding prevents injection attacks
- URL validation for online store endpoints

### Access Control
- Requires admin-level permissions
- Session-based authentication
- Operation logging for audit trails

### Input Validation
- Store ID validation against available stores
- URL format validation
- Date range validation for order filters
- Numeric validation for timing parameters

---

## 📊 Performance Considerations

### Batch Processing
1. **Category Batches**: 100 records per batch
2. **Product Batches**: 50 records per batch  
3. **Client Batches**: 100 records per batch

**Reasoning**:
- Products require more processing (multiple images)
- Categories are simpler data structures
- Clients have minimal data transfer

### Image Processing Optimization
```php
// Potential optimization: Check if image exists before encoding
if (file_exists($path . $value->logo)) {
    $value->logo_base64 = base64_encode(file_get_contents($path . $value->logo));
} else {
    $value->logo_base64 = ''; // Empty for missing images
}
```

### Memory Management
- Large datasets chunked to prevent memory exhaustion
- Image encoding done per batch, not all at once
- CURL responses released after each batch

---

## 🐛 Common Issues & Troubleshooting

### 1. **Synchronization Timeouts**
**Issue**: Large data sets cause timeout errors  
**Cause**: Too many records processed at once

**Solutions**:
```php
// Reduce batch sizes
$limit = 25; // Instead of 50 for products

// Add timeout handling
curl_setopt($ch, CURLOPT_TIMEOUT, 120); // 2 minutes
```

### 2. **Image Upload Failures**
**Issue**: Products sync but images missing  
**Cause**: File path issues or missing images

**Debug**:
```php
// Check image paths
$path = str_replace('\\', '/', getcwd()) . '/../views/default/images/product_image/';
echo "Image path: " . $path . $value->logo . "\n";

// Verify file exists
if (!file_exists($path . $value->logo)) {
    echo "Missing image: " . $value->logo . "\n";
}
```

### 3. **Store Selection Issues**
**Issue**: Wrong inventory quantities in online store  
**Cause**: Store filter not applied correctly

**Debug Query**:
```sql
SELECT sd.productid, sd.storeid, sd.productquantity
FROM storedetail sd
WHERE sd.storeid IN (1,2,3) -- Selected stores
AND sd.productid = [PRODUCT_ID];
```

### 4. **Connection Failures**
**Issue**: CURL requests failing  
**Cause**: Network issues or incorrect URLs

**Debug**:
```php
$response = curl_exec($ch);
if ($response === false) {
    echo 'CURL Error: ' . curl_error($ch);
}
echo 'HTTP Code: ' . curl_getinfo($ch, CURLINFO_HTTP_CODE);
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Configuration
```
1. Set online store URL
2. Select stores for synchronization
3. Configure timing parameters
4. Save settings and verify persistence
5. Test connection to online store
```

### Test Case 2: Category Synchronization
```
1. Create test categories with images
2. Run category-only sync
3. Verify categories appear in online store
4. Check parent-child relationships
5. Verify image display
```

### Test Case 3: Product Synchronization
```
1. Create products with multiple images
2. Set quantities in selected stores
3. Run product sync
4. Verify quantities match store selection
5. Check all images transferred correctly
```

### Test Case 4: Order Processing
```
1. Create test orders in online store
2. Use order filtering interface
3. Test date range filtering
4. Test customer filtering
5. Verify order detail display
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [onlinestoremainsetting.md](onlinestoremainsetting.md) - Basic store configuration
- [onlinestoresync.md](onlinestoresync.md) - Real-time synchronization
- [onlineCatController.md](onlineCatController.md) - Category management

---

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