# STORE PRICING SYSTEM - COMPREHENSIVE ANALYSIS

## Overview
This document provides a detailed analysis of how store owners set their price lists and how the pricing system is managed and used throughout the application.

---

## 1. PRICING SYSTEM ARCHITECTURE

### 1.1 Database Structure
The pricing system uses the `store_pricing` table with the following structure:
- `id` - Primary key
- `store_id` - Foreign key to stores table
- `network_type` - Network (currently 'mtn' only)
- `min_size_gb` - Minimum package size in GB for this pricing tier
- `max_size_gb` - Maximum package size in GB for this pricing tier
- `price_per_gb` - Store owner's price per GB for this range
- `is_active` - Whether this pricing rule is active (1) or inactive (0)

### 1.2 Key Components
- **StorePricingManager Class** (`app/classes/StorePricingManager.php`) - Core pricing logic
- **Store Pricing Page** (`pages/store_pricing.php`) - UI for store owners to manage prices
- **API Endpoints**:
  - `pages/add_store_pricing.php` - Add new pricing rules
  - `pages/update_store_pricing.php` - Update existing pricing rules

---

## 2. HOW STORE OWNERS SET PRICES

### 2.1 Initial Setup (Default Pricing)
When a new store is created, default pricing is automatically set up:
- **Location**: `app/classes/StoreManager.php` → `setupDefaultPricing()` method (line 869-880)
- **Process**: Copies all active pricing rules from `agent_pricing_rules` table (where `role = 'agent'`)
- **Result**: Store starts with admin's base pricing, which store owners can then customize

```php
private function setupDefaultPricing($storeId) {
    // Copy default pricing from agent_pricing_rules
    $stmt = $this->conn->prepare("
        INSERT INTO store_pricing (store_id, network_type, min_size_gb, max_size_gb, price_per_gb, is_active)
        SELECT ?, network_type, min_size_gb, max_size_gb, price_per_gb, is_active
        FROM agent_pricing_rules
        WHERE role = 'agent' AND is_active = 1
    ");
    $stmt->bind_param("i", $storeId);
    $stmt->execute();
    $stmt->close();
}
```

### 2.2 Price Management Interface
**Location**: `pages/store_pricing.php`

#### Features:
1. **View Admin-Defined Ranges**
   - Store owners see all admin-defined package size ranges
   - Each range shows:
     - Size range (min GB - max GB)
     - Admin base price per GB
     - Store owner's current price per GB (if set)
     - Status (Active/Inactive/Not Set)
     - Example pricing for the range

2. **Set New Prices**
   - For ranges without prices, store owners can click "Set Price"
   - Modal form allows entering price per GB
   - **CRITICAL CONSTRAINT**: Store owners can ONLY set prices for ranges that exactly match admin-defined ranges
   - Validation ensures range boundaries match admin rules (within 0.001 tolerance)

3. **Edit Existing Prices**
   - Store owners can edit prices for ranges they've already configured
   - Only the `price_per_gb` value can be changed
   - Range boundaries (`min_size_gb`, `max_size_gb`) are locked to admin definitions

4. **Visual Warnings**
   - Prices below admin base price are highlighted in red
   - Warning message: "Setting prices below admin base pricing will result in losses"

### 2.3 Price Setting Process Flow

#### Step 1: Access Pricing Page
- Store owner navigates to `pages/store_pricing.php`
- System loads:
  - Store's current pricing from `store_pricing` table
  - Admin pricing rules from `agent_pricing_rules` table
  - Creates a map matching store prices to admin ranges

#### Step 2: Set/Edit Price
- Store owner clicks "Set Price" or "Edit" button
- Modal form opens with:
  - Pre-filled range information (from admin rules)
  - Admin base price display
  - Input field for price per GB
  - Live preview of pricing

#### Step 3: Validation
**Location**: `pages/add_store_pricing.php` (lines 51-73)

**Critical Validations**:
1. **Range Matching**: Must exactly match an admin-defined range
   ```php
   // Verify that this range matches an admin-defined range exactly
   $adminCheckStmt = $conn->prepare("
       SELECT id, min_size_gb, max_size_gb, price_per_gb 
       FROM agent_pricing_rules 
       WHERE network_type = ? 
       AND role = 'agent' 
       AND is_active = 1
       AND ABS(min_size_gb - ?) < 0.001 
       AND ABS(max_size_gb - ?) < 0.001
       LIMIT 1
   ");
   ```

2. **Value Validation**:
   - `min_size_gb > 0`
   - `max_size_gb > 0`
   - `price_per_gb > 0`
   - `min_size_gb < max_size_gb`

3. **Authorization**: Verifies store ownership
   ```php
   if (!$store || $store['owner_id'] != $userId) {
       echo json_encode(['success' => false, 'message' => 'Unauthorized']);
       exit();
   }
   ```

#### Step 4: Save Price
- Uses `StorePricingManager::setStorePricing()` method
- If pricing exists for that range: **UPDATE**
- If pricing doesn't exist: **INSERT**
- Returns success/error response

---

## 3. HOW PRICING IS USED IN THE SYSTEM

### 3.1 Price Calculation
**Location**: `app/classes/StorePricingManager.php` → `calculatePrice()` method (lines 126-161)

**Process**:
1. Parse package size to GB (handles MB, GB, or plain numbers)
2. Query `store_pricing` table for matching range:
   ```php
   SELECT price_per_gb FROM store_pricing
   WHERE store_id = ? AND network_type = ? 
   AND min_size_gb <= ? AND max_size_gb >= ?
   AND is_active = 1
   ORDER BY min_size_gb DESC
   LIMIT 1
   ```
3. Calculate: `price = price_per_gb × package_size_gb`
4. Return price information with source

**Returns**:
```php
[
    'price' => 3.50,              // Final calculated price
    'source' => 'tiered',         // Pricing source
    'package_size_gb' => 1.0,     // Parsed package size
    'price_per_gb' => 3.50        // Price per GB used
]
```

### 3.2 Usage Points in System

#### A. Public Store Page (`store.php`)
- Customers view packages with store-specific prices
- Uses `StorePricingManager::calculatePrice()` to display prices

#### B. Store Order Processing (`process_store_order.php`)
- **Line 66**: Calculates price for customer orders
```php
$pricingManager = new StorePricingManager($conn);
$priceInfo = $pricingManager->calculatePrice($storeId, $package, $network);
$amount = $priceInfo['price'];
```
- Price is stored in `orders.amount` field
- Used for payment processing (Paystack or Mobile Money)

#### C. User Dashboard (`pages/user_dashboard.php`)
- **Lines 358-368**: Calculates prices when adding items to cart
- For store owners/agents: Uses store pricing
- For regular agents: Falls back to role-based pricing
```php
if ($userStoreId) {
    // USE STORE PRICING
    $storePricingManager = new StorePricingManager($conn);
    $pricingResult = $storePricingManager->calculatePrice($userStoreId, $bundleLabel, $networkType);
    $cost = $pricingResult['price'];
} else {
    // Fallback to role-based pricing
    $pricingManager = new CustomPricingManager($conn);
    $pricingResult = $pricingManager->calculatePrice($bundleLabel, $networkType, $role);
    $cost = $pricingResult['price'];
}
```

#### D. API Order Creation (`api/create_order.php`)
- **Line 228**: Uses store pricing for bulk order processing
- Calculates prices for each order item

#### E. Package Availability Checks
- `check_agent_package_availability.php` - Checks if package has pricing
- `get_available_packages.php` - Returns packages with store prices
- `get_store_packages.php` - Lists packages with pricing

### 3.3 Price Display to Customers/Agents

#### Store Public Page
- Shows packages with store-specific prices
- Prices are calculated in real-time using store's pricing rules

#### Agent Dashboard
- Agents see prices based on their store's pricing
- If agent belongs to a store: Uses store pricing
- If agent doesn't belong to a store: Uses role-based pricing

#### Order History
- Shows the price that was charged (from `orders.amount`)
- Calculates profit: `store_price - admin_price`

---

## 4. PRICING CONSTRAINTS AND RULES

### 4.1 Admin-Controlled Constraints
1. **Range Boundaries**: Store owners CANNOT create custom ranges
   - Must use exact ranges defined in `agent_pricing_rules`
   - Range matching uses 0.001 tolerance for floating-point precision

2. **Network Types**: Currently limited to 'mtn' only
   - System is designed to support multiple networks
   - Only MTN is actively used

3. **Active Status**: Store owners can activate/deactivate pricing rules
   - Inactive rules won't be used in price calculations
   - Store owners can toggle `is_active` flag

### 4.2 Store Owner Flexibility
1. **Price per GB**: Store owners can set any positive price
   - No maximum limit enforced
   - Warning shown if below admin base price
   - System allows prices that result in losses (store owner's choice)

2. **Multiple Ranges**: Store owners can set different prices for different size ranges
   - Example: 1-5GB at GH₵3.50/GB, 6-10GB at GH₵3.00/GB
   - Enables tiered pricing strategies

### 4.3 Precision Handling
- Uses 4 decimal places for range matching
- Format: `sprintf('%.4f-%.4f', min, max)` for consistent key generation
- Prevents floating-point precision issues

---

## 5. PRICING FLOW DIAGRAM

```
┌─────────────────────────────────────────────────────────────┐
│                    STORE CREATION                            │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ setupDefaultPricing() copies from agent_pricing_rules │  │
│  │ → Creates store_pricing entries with admin base      │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────┐
│              STORE OWNER PRICING MANAGEMENT                 │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ 1. View admin-defined ranges                          │  │
│  │ 2. Set/Edit price_per_gb for each range               │  │
│  │ 3. Validation: Range must match admin rules           │  │
│  │ 4. Save to store_pricing table                        │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                  PRICE CALCULATION                           │
│  ┌──────────────────────────────────────────────────────┐  │
│  │ calculatePrice(storeId, packageSize, networkType)    │  │
│  │ 1. Parse package size to GB                          │  │
│  │ 2. Find matching range in store_pricing              │  │
│  │ 3. Calculate: price_per_gb × package_size_gb        │  │
│  │ 4. Return price with metadata                        │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                          │
                          ▼
┌─────────────────────────────────────────────────────────────┐
│                    PRICE USAGE                               │
│  ┌──────────────┬──────────────┬──────────────┐            │
│  │ Store Page   │ Order Proc.  │ User Dash    │            │
│  │ (Display)    │ (Payment)    │ (Cart)       │            │
│  └──────────────┴──────────────┴──────────────┘            │
└─────────────────────────────────────────────────────────────┘
```

---

## 6. KEY FEATURES AND BENEFITS

### 6.1 For Store Owners
1. **Custom Pricing**: Set their own prices per GB for each range
2. **Profit Control**: Can adjust margins by setting prices above admin base
3. **Tiered Pricing**: Different prices for different package sizes
4. **Visual Feedback**: See admin base prices to make informed decisions
5. **Easy Management**: Simple UI to set/edit prices

### 6.2 For System
1. **Consistency**: All stores use same range structure (admin-controlled)
2. **Flexibility**: Each store can have different prices
3. **Validation**: Prevents invalid ranges or unauthorized changes
4. **Performance**: Efficient queries with indexed lookups
5. **Scalability**: Supports multiple networks (currently MTN)

### 6.3 For Customers/Agents
1. **Transparent Pricing**: See store-specific prices before ordering
2. **Consistent Experience**: Prices calculated the same way everywhere
3. **Real-time Updates**: Prices reflect store owner's current settings

---

## 7. TECHNICAL IMPLEMENTATION DETAILS

### 7.1 Price Lookup Algorithm
```php
// Find matching pricing rule
SELECT price_per_gb FROM store_pricing
WHERE store_id = ? 
  AND network_type = ? 
  AND min_size_gb <= package_size_gb 
  AND max_size_gb >= package_size_gb
  AND is_active = 1
ORDER BY min_size_gb DESC  // Prefer larger ranges if overlap
LIMIT 1
```

### 7.2 Range Matching Logic
- Uses floating-point comparison with tolerance (0.001)
- Formats keys to 4 decimal places for consistency
- Prevents duplicate ranges for same store

### 7.3 Package Size Parsing
Handles multiple formats:
- "1GB" → 1.0 GB
- "500MB" → 0.4883 GB (500/1024)
- "5" → 5.0 GB (assumed)

### 7.4 Transaction Safety
- Price calculations happen before order creation
- Prices are stored in orders table (immutable after order creation)
- Balance checks use calculated prices

---

## 8. SECURITY AND VALIDATION

### 8.1 Authorization Checks
- Store owners can only modify their own store's pricing
- Ownership verified on every update/add operation
- Session-based authentication required

### 8.2 Input Validation
- All numeric inputs validated (positive numbers)
- Range boundaries validated (min < max)
- SQL injection prevention (prepared statements)
- XSS prevention (htmlspecialchars in display)

### 8.3 Data Integrity
- Foreign key constraints (store_id references stores)
- Range matching prevents invalid configurations
- Active flag allows soft deletion

---

## 9. FUTURE ENHANCEMENTS (Potential)

1. **Multiple Networks**: Extend beyond MTN to other networks
2. **Bulk Price Import**: CSV import for bulk price updates
3. **Price History**: Track price changes over time
4. **Price Templates**: Save and apply pricing templates
5. **Automated Pricing**: Rules-based automatic price adjustments
6. **Price Comparison**: Compare prices across stores
7. **Discount Rules**: Percentage or fixed discounts per range

---

## 10. SUMMARY

The store pricing system provides a flexible, controlled way for store owners to set their own prices while maintaining system consistency through admin-defined ranges. The system:

- ✅ Allows store owners to customize prices per GB for each admin-defined range
- ✅ Enforces range boundaries to match admin rules exactly
- ✅ Calculates prices dynamically based on package size and store pricing
- ✅ Uses prices throughout the system (orders, cart, display, etc.)
- ✅ Provides visual feedback and warnings for pricing decisions
- ✅ Maintains data integrity and security through validation and authorization

The pricing system is central to the application's functionality, enabling each store to operate independently with its own pricing strategy while maintaining overall system consistency.

