= :date_from AND DATE(sale_date) <= :date_to'; $params[':date_from'] = $dateFrom; $params[':date_to'] = $dateTo; $sql = 'SELECT * FROM sales_orders' . $where . ' ORDER BY sale_date DESC'; try { $stmt = db()->prepare($sql); foreach ($params as $k => $v) { $stmt->bindValue($k, $v); } $stmt->execute(); $salesReport = $stmt->fetchAll(); } catch(Throwable $e) { $dbError = $e->getMessage(); $salesReport = []; } } elseif ($tab === 'orders') { $branchFilter = $_GET['branch'] ?? ''; $params = []; $where = base_sales_query_filters($params, null, $branchFilter ?: null); $where .= " AND status = 'order'"; $sql = 'SELECT * FROM sales_orders' . $where . ' ORDER BY sale_date ASC'; try { $stmt = db()->prepare($sql); foreach ($params as $k => $v) { $stmt->bindValue($k, $v); } $stmt->execute(); $followUpOrders = $stmt->fetchAll(); $onlineStmt = db()->query("SELECT * FROM online_orders WHERE status IN ('pending', 'accepted') ORDER BY created_at ASC"); $onlineOrders = $onlineStmt->fetchAll(); } catch(Throwable $e) { $dbError = $e->getMessage(); $followUpOrders = []; $onlineOrders = []; } } elseif ($tab === 'daily') { $reportDate = $_GET['date'] ?? date('Y-m-d'); $branchFilter = $_GET['branch'] ?? ''; $params = []; $where = base_sales_query_filters($params, null, $branchFilter ?: null); $where .= " AND DATE(sale_date) = :rdate AND status != 'order'"; $params[':rdate'] = $reportDate; $dailyTotals = [ 'seller' => [], 'outlet' => [], 'payment' => [], 'total' => 0 ]; try { // By Seller $sql = "SELECT cashier_name, SUM(total_amount) as total FROM sales_orders" . $where . " GROUP BY cashier_name"; $stmt = db()->prepare($sql); $stmt->execute($params); $dailyTotals['seller'] = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // By Outlet $sql = "SELECT branch_code, SUM(total_amount) as total FROM sales_orders" . $where . " GROUP BY branch_code"; $stmt = db()->prepare($sql); $stmt->execute($params); $dailyTotals['outlet'] = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // By Payment $sql = "SELECT payment_method, SUM(total_amount) as total FROM sales_orders" . $where . " GROUP BY payment_method"; $stmt = db()->prepare($sql); $stmt->execute($params); $dailyTotals['payment'] = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // Grand total $sql = "SELECT SUM(total_amount) as total FROM sales_orders" . $where; $stmt = db()->prepare($sql); $stmt->execute($params); $dailyTotals['total'] = (float) $stmt->fetchColumn(); } catch(Throwable $e) { $dbError = $e->getMessage(); } } elseif ($tab === 'expenses') { $dateFrom = $_GET['date_from'] ?? date('Y-m-01'); $dateTo = $_GET['date_to'] ?? date('Y-m-t'); $branchFilter = $_GET['branch'] ?? ''; $categoryFilter = $_GET['category_id'] ?? ''; $params = []; $whereConditions = ["DATE(e.expense_date) >= :date_from", "DATE(e.expense_date) <= :date_to"]; $params[':date_from'] = $dateFrom; $params[':date_to'] = $dateTo; if ($user['role'] !== 'owner') { $ubranches = get_user_branches($user); if ($branchFilter && $branchFilter === 'general') { $whereConditions[] = "e.branch_code IS NULL"; } elseif ($branchFilter && in_array($branchFilter, $ubranches, true)) { $whereConditions[] = "e.branch_code = :branch"; $params[':branch'] = $branchFilter; } else { if (empty($ubranches)) { $whereConditions[] = "e.branch_code IS NULL"; } else { $inQuery = implode(',', array_fill(0, count($ubranches), '?')); // We must use numbered placeholders if mixing with named placeholders? // PDO might not like mixing ? and :name. // Let's create named placeholders for in query. $namedParams = []; foreach($ubranches as $i => $ub) { $key = ':ubranch_' . $i; $namedParams[] = $key; $params[$key] = $ub; } $inQuery = implode(', ', $namedParams); $whereConditions[] = "(e.branch_code IN ($inQuery) OR e.branch_code IS NULL)"; } } } else { if ($branchFilter) { if ($branchFilter === 'general') { $whereConditions[] = "e.branch_code IS NULL"; } else { $whereConditions[] = "e.branch_code = :branch"; $params[':branch'] = $branchFilter; } } } if ($categoryFilter) { $whereConditions[] = "e.category_id = :category_id"; $params[':category_id'] = $categoryFilter; } $where = " WHERE " . implode(" AND ", $whereConditions); $sql = "SELECT e.*, c.name_ar as category_name_ar, c.name_en as category_name_en, u.username as created_by_name FROM expenses e LEFT JOIN expense_categories c ON e.category_id = c.id LEFT JOIN users u ON e.created_by = u.id " . $where . " ORDER BY e.expense_date DESC"; try { $stmt = db()->prepare($sql); foreach ($params as $k => $v) { $stmt->bindValue($k, $v); } $stmt->execute(); $expensesReport = $stmt->fetchAll(); $catStmt = db()->query("SELECT id, name_ar, name_en FROM expense_categories ORDER BY name_ar"); $expenseCategories = $catStmt->fetchAll(); } catch(Throwable $e) { $dbError = $e->getMessage(); $expensesReport = []; $expenseCategories = []; } } else { $report = ['gross' => 0.0, 'branch_totals' => [], 'payment_totals' => [], 'product_totals' => [], 'sales_count' => 0]; try { $report = report_metrics(); } catch (Throwable $e) { $dbError = $e->getMessage(); } } require __DIR__ . '/includes/header.php'; ?>
= h(tr('الفترة من', 'Period from')) ?> = h($dateFrom) ?> = h(tr('إلى', 'to')) ?> = h($dateTo) ?>
= h(tr('الفرع:', 'Branch:')) ?> = h(branch_label($branchFilter)) ?>
= h(tr('لا توجد مبيعات في هذه الفترة.', 'No sales found in this period.')) ?>
| = h(tr('التاريخ', 'Date')) ?> | = h(tr('رقم الإيصال', 'Receipt No')) ?> | = h(tr('الكاشير', 'Cashier')) ?> | = h(tr('الفرع', 'Branch')) ?> | = h(tr('طريقة الدفع', 'Payment Method')) ?> | = h(tr('الحالة', 'Status')) ?> | = h(tr('المجموع', 'Subtotal')) ?> | = h(tr('الضريبة', 'VAT')) ?> | = h(tr('الإجمالي', 'Total')) ?> |
|---|---|---|---|---|---|---|---|---|
| = h(date('Y-m-d H:i', strtotime((string)$sale['sale_date']))) ?> | = h((string)$sale['receipt_no']) ?> | = h((string)$sale['cashier_name']) ?> | = h(branch_label((string)$sale['branch_code'])) ?> | = h(ucfirst((string)$sale['payment_method'])) ?> | = h(tr('طلب حجز', 'Order')) ?> = h(tr('مدفوع', 'Paid')) ?> | = h(currency($calcSubtotal)) ?> | = h(currency($vat)) ?> | = h(currency($total)) ?> |
| = h(tr('الإجمالي الكلي', 'Grand Total')) ?> | = h(currency($subtotalSum)) ?> | = h(currency($vatSum)) ?> | = h(currency($totalSum)) ?> | |||||
= h(tr('تاريخ الإصدار:', 'Generated on:')) ?> = date('Y-m-d H:i') ?>
= h(tr('لا توجد مصروفات في هذه الفترة.', 'No expenses found in this period.')) ?>
| = h(tr('التاريخ', 'Date')) ?> | = h(tr('الفرع', 'Branch')) ?> | = h(tr('التصنيف', 'Category')) ?> | = h(tr('الوصف', 'Description')) ?> | = h(tr('المسجل', 'Logged By')) ?> | = h(tr('المبلغ', 'Amount')) ?> |
|---|---|---|---|---|---|
| = h(date('Y-m-d', strtotime((string)$exp['expense_date']))) ?> | = h(tr('عام', 'General')) ?> | = h($exp['category_name_ar'] . ' / ' . $exp['category_name_en']) ?> | = h((string)$exp['description']) ?> | = h((string)$exp['created_by_name']) ?> | = h(currency((float)$exp['amount'])) ?> |
| = h(tr('الإجمالي الكلي', 'Grand Total')) ?> | = h(currency($totalSum)) ?> | ||||
= h(tr('المحاسب / المُعد', 'Prepared by / Accountant')) ?>
= h(tr('المراجع', 'Checked by')) ?>
= h(tr('المدير العام', 'General Manager')) ?>
= h(date('Y-m-d H:i')) ?>
= h(tr('الفرع:', 'Branch:')) ?> = h(branch_label($branchFilter)) ?>
= h(tr('لا توجد طلبات للمتابعة.', 'No follow-up orders.')) ?>
| = h(tr('التاريخ', 'Date')) ?> | = h(tr('رقم الإيصال', 'Receipt No')) ?> | = h(tr('العميل', 'Customer')) ?> | = h(tr('هاتف العميل', 'Customer Phone')) ?> | = h(tr('الفرع', 'Branch')) ?> | = h(tr('المبلغ المستحق', 'Due Amount')) ?> | = h(tr('إجراءات', 'Actions')) ?> |
|---|---|---|---|---|---|---|
| = h(date('Y-m-d H:i', strtotime((string)$sale['sale_date']))) ?> | = h((string)$sale['receipt_no']) ?> | = h((string)($sale['customer_name'] ?: '-')) ?> | = h((string)($sale['customer_phone'] ? phone_display($sale['customer_phone']) : '-')) ?> | = h(branch_label((string)$sale['branch_code'])) ?> | = h(currency((float)$sale['total_amount'])) ?> | = h(tr('عرض', 'View')) ?> |
= h(tr('لا توجد طلبات متجر نشطة حالياً.', 'No active online orders currently.')) ?>
| = h(tr('التاريخ', 'Date')) ?> | = h(tr('رقم الطلب', 'Order ID')) ?> | = h(tr('العميل', 'Customer')) ?> | = h(tr('هاتف العميل', 'Customer Phone')) ?> | = h(tr('العنوان', 'Address')) ?> | = h(tr('الحالة', 'Status')) ?> | = h(tr('الإجمالي', 'Total')) ?> |
|---|---|---|---|---|---|---|
| = h(date('Y-m-d H:i', strtotime((string)$order['created_at']))) ?> | #= h((string)$order['id']) ?> | = h((string)($order['customer_name'] ?: '-')) ?> | = h((string)($order['customer_phone'] ? phone_display($order['customer_phone']) : '-')) ?> | = h((string)($order['customer_address'] ?: '-')) ?> | = h(tr('قيد الانتظار', 'Pending')) ?> = h(tr('مقبول', 'Accepted')) ?> | = h(currency((float)$order['total_amount'])) ?> |
= h(tr('التاريخ:', 'Date:')) ?> = h($reportDate) ?>
= h(tr('الفرع:', 'Branch:')) ?> = h(branch_label($branchFilter)) ?>
= h(tr('أضف عملية بيع أولاً لبدء التقارير.', 'Add a first sale to activate reports.')) ?>
= h(tr('عند تسجيل عمليات بيع ستظهر هنا طرق الدفع.', 'Payment mix will appear here once sales are logged.')) ?>