fetch( "SELECT COUNT(*) as total_orders, COALESCE(SUM(total), 0) as total_revenue, COALESCE(AVG(total), 0) as avg_order_value, COUNT(DISTINCT customer_id) as unique_customers FROM orders WHERE DATE(created_at) BETWEEN :start AND :end AND payment_status = 'paid'", ['start' => $startDate, 'end' => $endDate] ); // Ensure defaults if (!$salesOverview) { $salesOverview = ['total_orders' => 0, 'total_revenue' => 0, 'avg_order_value' => 0, 'unique_customers' => 0]; } else { $salesOverview['total_orders'] = (int)($salesOverview['total_orders'] ?? 0); $salesOverview['total_revenue'] = (float)($salesOverview['total_revenue'] ?? 0); $salesOverview['avg_order_value'] = (float)($salesOverview['avg_order_value'] ?? 0); $salesOverview['unique_customers'] = (int)($salesOverview['unique_customers'] ?? 0); } } catch (Exception $e) { $salesOverview = ['total_orders' => 0, 'total_revenue' => 0, 'avg_order_value' => 0, 'unique_customers' => 0]; } // Previous period for comparison $daysDiff = (strtotime($endDate) - strtotime($startDate)) / 86400; $prevEndDate = date('Y-m-d', strtotime($startDate . ' -1 day')); $prevStartDate = date('Y-m-d', strtotime($prevEndDate . " -{$daysDiff} days")); try { $prevSalesOverview = db()->fetch( "SELECT COUNT(*) as total_orders, COALESCE(SUM(total), 0) as total_revenue FROM orders WHERE DATE(created_at) BETWEEN :start AND :end AND payment_status = 'paid'", ['start' => $prevStartDate, 'end' => $prevEndDate] ); if (!$prevSalesOverview) { $prevSalesOverview = ['total_orders' => 0, 'total_revenue' => 0]; } else { $prevSalesOverview['total_orders'] = (int)($prevSalesOverview['total_orders'] ?? 0); $prevSalesOverview['total_revenue'] = (float)($prevSalesOverview['total_revenue'] ?? 0); } } catch (Exception $e) { $prevSalesOverview = ['total_orders' => 0, 'total_revenue' => 0]; } try { // Daily Sales Data for chart $dailySales = db()->fetchAll( "SELECT DATE(created_at) as date, COUNT(*) as orders, COALESCE(SUM(total), 0) as revenue FROM orders WHERE DATE(created_at) BETWEEN :start AND :end AND payment_status = 'paid' GROUP BY DATE(created_at) ORDER BY date ASC", ['start' => $startDate, 'end' => $endDate] ); } catch (Exception $e) { $dailySales = []; } // Top Selling Products (from orders JSON items field) $topProducts = []; try { $orders = db()->fetchAll( "SELECT items, total FROM orders WHERE DATE(created_at) BETWEEN :start AND :end AND payment_status = 'paid'", ['start' => $startDate, 'end' => $endDate] ); $productCounts = []; foreach ($orders as $order) { $items = json_decode($order['items'], true) ?? []; foreach ($items as $item) { $name = $item['name'] ?? 'Unknown'; if (!isset($productCounts[$name])) { $productCounts[$name] = ['name' => $name, 'total_sold' => 0, 'total_revenue' => 0]; } $productCounts[$name]['total_sold'] += $item['quantity'] ?? 1; $productCounts[$name]['total_revenue'] += $item['total'] ?? 0; } } usort($productCounts, fn($a, $b) => $b['total_sold'] - $a['total_sold']); $topProducts = array_slice(array_values($productCounts), 0, 10); } catch (Exception $e) { $topProducts = []; } // Sales by Category (from orders JSON - more reliable) $categoryStats = []; try { foreach ($orders ?? [] as $order) { $items = json_decode($order['items'], true) ?? []; foreach ($items as $item) { $cat = 'General'; if (!isset($categoryStats[$cat])) { $categoryStats[$cat] = ['category' => $cat, 'orders' => 0, 'items_sold' => 0, 'revenue' => 0]; } $categoryStats[$cat]['items_sold'] += $item['quantity'] ?? 1; $categoryStats[$cat]['revenue'] += $item['total'] ?? 0; } } $categoryStats = array_values($categoryStats); } catch (Exception $e) { $categoryStats = []; } try { // Customer Acquisition $newCustomers = db()->fetch( "SELECT COUNT(*) as count FROM customers WHERE DATE(created_at) BETWEEN :start AND :end", ['start' => $startDate, 'end' => $endDate] )['count'] ?? 0; } catch (Exception $e) { $newCustomers = 0; } try { $returningCustomers = db()->fetch( "SELECT COUNT(DISTINCT customer_id) as count FROM orders o WHERE DATE(o.created_at) BETWEEN :start AND :end AND payment_status = 'paid' AND customer_id IN ( SELECT customer_id FROM orders WHERE DATE(created_at) < :start2 AND payment_status = 'paid' )", ['start' => $startDate, 'end' => $endDate, 'start2' => $startDate] )['count'] ?? 0; } catch (Exception $e) { $returningCustomers = 0; } try { // Payment Methods Distribution $paymentMethods = db()->fetchAll( "SELECT COALESCE(payment_method, 'Unknown') as method, COUNT(*) as count, SUM(total) as revenue FROM orders WHERE DATE(created_at) BETWEEN :start AND :end AND payment_status = 'paid' GROUP BY payment_method ORDER BY count DESC", ['start' => $startDate, 'end' => $endDate] ); } catch (Exception $e) { $paymentMethods = []; } try { // Abandoned Carts $abandonedCarts = db()->fetch( "SELECT COUNT(*) as count, COALESCE(SUM(subtotal), 0) as value FROM abandoned_carts WHERE DATE(created_at) BETWEEN :start AND :end AND recovered = 0", ['start' => $startDate, 'end' => $endDate] ); if (!$abandonedCarts) { $abandonedCarts = ['count' => 0, 'value' => 0]; } else { $abandonedCarts['count'] = (int)($abandonedCarts['count'] ?? 0); $abandonedCarts['value'] = (float)($abandonedCarts['value'] ?? 0); } } catch (Exception $e) { $abandonedCarts = ['count' => 0, 'value' => 0]; } try { // Order Status Distribution $orderStatuses = db()->fetchAll( "SELECT order_status, COUNT(*) as count FROM orders WHERE DATE(created_at) BETWEEN :start AND :end GROUP BY order_status", ['start' => $startDate, 'end' => $endDate] ); } catch (Exception $e) { $orderStatuses = []; } try { // Hourly Sales Pattern $hourlySales = db()->fetchAll( "SELECT HOUR(created_at) as hour, COUNT(*) as orders, COALESCE(SUM(total), 0) as revenue FROM orders WHERE DATE(created_at) BETWEEN :start AND :end AND payment_status = 'paid' GROUP BY HOUR(created_at) ORDER BY hour", ['start' => $startDate, 'end' => $endDate] ); } catch (Exception $e) { $hourlySales = []; } // Top Customers try { $topCustomers = db()->fetchAll( "SELECT c.customer_id, c.name, c.email, COUNT(o.order_id) as order_count, COALESCE(SUM(o.total), 0) as total_spent FROM customers c JOIN orders o ON c.customer_id = o.customer_id WHERE DATE(o.created_at) BETWEEN :start AND :end AND o.payment_status = 'paid' GROUP BY c.customer_id ORDER BY total_spent DESC LIMIT 10", ['start' => $startDate, 'end' => $endDate] ); } catch (Exception $e) { $topCustomers = []; } // Inventory Stats try { $lowStockCount = db()->count('products', 'stock <= low_stock_threshold AND stock > 0'); $outOfStockCount = db()->count('products', 'stock = 0 AND is_active = 1'); } catch (Exception $e) { $lowStockCount = 0; $outOfStockCount = 0; } // Calculate percentage changes $revenueChange = $prevSalesOverview['total_revenue'] > 0 ? (($salesOverview['total_revenue'] - $prevSalesOverview['total_revenue']) / $prevSalesOverview['total_revenue']) * 100 : 0; $ordersChange = $prevSalesOverview['total_orders'] > 0 ? (($salesOverview['total_orders'] - $prevSalesOverview['total_orders']) / $prevSalesOverview['total_orders']) * 100 : 0; ?>

Advanced Analytics

-

7 Days 30 Days 90 Days 1 Year

Total Revenue

% vs previous period

Total Orders

% vs previous period

Average Order Value

unique customers

Abandoned Carts

potential revenue

Revenue Trend

0 ? ($day['revenue'] / $maxRevenue) * 100 : 0; ?>
No sales data for this period

Top Selling Products

No product data available

$product): ?>
.
sold

Sales by Category

No category data available

$cat): $percentage = ($cat['revenue'] / $totalCatRevenue) * 100; ?>
%

Customer Insights

New Customers
Returning Customers

Top Customers

orders

Payment Methods

No payment data available

%

Inventory Alerts

Low Stock
Out of Stock

Sales by Hour of Day

12am 6am 12pm 6pm 12am