+
+

+
+
+ + +
+
+
diff --git a/includes/lang.php b/includes/lang.php new file mode 100644 index 0000000..5bb9816 --- /dev/null +++ b/includes/lang.php @@ -0,0 +1,200 @@ + [ + 'dashboard' => 'Dashboard', + 'pos' => 'POS', + 'orders' => 'Orders', + 'customers' => 'Customers', + 'items' => 'Items', + 'services' => 'Services', + 'branches' => 'Branches', + 'users' => 'Users', + 'settings' => 'Settings', + 'logout' => 'Logout', + 'login' => 'Login', + 'username' => 'Username', + 'password' => 'Password', + 'submit' => 'Submit', + 'save' => 'Save', + 'save_changes' => 'Save Changes', + 'cancel' => 'Cancel', + 'add_new' => 'Add New', + 'edit' => 'Edit', + 'delete' => 'Delete', + 'actions' => 'Actions', + 'search' => 'Search', + 'total' => 'Total', + 'status' => 'Status', + 'date' => 'Date', + 'phone' => 'Phone', + 'name' => 'Name', + 'name_en' => 'Name (EN)', + 'name_ar' => 'Name (AR)', + 'price' => 'Price', + 'quantity' => 'Quantity', + 'subtotal' => 'Subtotal', + 'vat' => 'VAT', + 'vat_total' => 'VAT Total', + 'payment_status' => 'Payment Status', + 'received' => 'Received', + 'processing' => 'Processing', + 'ready' => 'Ready', + 'delivered' => 'Delivered', + 'cancelled' => 'Cancelled', + 'unpaid' => 'Unpaid', + 'partially_paid' => 'Partially Paid', + 'paid' => 'Paid', + 'cash' => 'Cash', + 'card' => 'Card', + 'transfer' => 'Transfer', + 'new_order' => 'New Order', + 'order_details' => 'Order Details', + 'customer_name' => 'Customer Name', + 'select_customer' => 'Select Customer', + 'add_item' => 'Add Item', + 'edit_item' => 'Edit Item', + 'delete_item' => 'Delete Item', + 'select_item' => 'Select Item', + 'select_service' => 'Select Service', + 'checkout' => 'Checkout', + 'back_to_pos' => 'Back to POS', + 'language' => 'Language', + 'arabic' => 'Arabic', + 'english' => 'English', + 'branch' => 'Branch', + 'all_branches' => 'All Branches', + 'category' => 'Category', + 'categories' => 'Categories', + 'add_category' => 'Add Category', + 'edit_category' => 'Edit Category', + 'delete_category' => 'Delete Category', + 'categories_management' => 'Categories Management', + 'add_new_category' => 'Add New Category', + 'select_category' => 'Select Category', + 'all' => 'All', + 'variant' => 'Variant', + 'variants' => 'Variants', + 'add_variant' => 'Add Variant', + 'select_variant' => 'Select Variant', + 'variant_name_en' => 'Variant Name (EN)', + 'variant_name_ar' => 'Variant Name (AR)', + 'default' => 'Default', + 'vat_percent' => 'VAT %', + 'image_url' => 'Image URL', + 'items_management' => 'Items Management', + 'variants_prices' => 'Variants & Prices', + 'no_items_found' => 'No items found', + 'pricing_management' => 'Pricing Management', + 'are_you_sure' => 'Are you sure?', + ], + 'ar' => [ + 'dashboard' => 'لوحة القيادة', + 'pos' => 'نقطة البيع', + 'orders' => 'الطلبات', + 'customers' => 'العملاء', + 'items' => 'الأصناف', + 'services' => 'الخدمات', + 'branches' => 'الفروع', + 'users' => 'المستخدمين', + 'settings' => 'الإعدادات', + 'logout' => 'تسجيل الخروج', + 'login' => 'تسجيل الدخول', + 'username' => 'اسم المستخدم', + 'password' => 'كلمة المرور', + 'submit' => 'إرسال', + 'save' => 'حفظ', + 'save_changes' => 'حفظ التغييرات', + 'cancel' => 'إلغاء', + 'add_new' => 'إضافة جديد', + 'edit' => 'تعديل', + 'delete' => 'حذف', + 'actions' => 'إجراءات', + 'search' => 'بحث', + 'total' => 'الإجمالي', + 'status' => 'الحالة', + 'date' => 'التاريخ', + 'phone' => 'الهاتف', + 'name' => 'الاسم', + 'name_en' => 'الاسم (EN)', + 'name_ar' => 'الاسم (AR)', + 'price' => 'السعر', + 'quantity' => 'الكمية', + 'subtotal' => 'المجموع الفرعي', + 'vat' => 'ضريبة القيمة المضافة', + 'vat_total' => 'إجمالي الضريبة', + 'payment_status' => 'حالة الدفع', + 'received' => 'تم الاستلام', + 'processing' => 'قيد المعالجة', + 'ready' => 'جاهز', + 'delivered' => 'تم التسليم', + 'cancelled' => 'ملغي', + 'unpaid' => 'غير مدفوع', + 'partially_paid' => 'مدفوع جزئياً', + 'paid' => 'مدفوع', + 'cash' => 'نقد', + 'card' => 'بطاقة', + 'transfer' => 'تحويل', + 'new_order' => 'طلب جديد', + 'order_details' => 'تفاصيل الطلب', + 'customer_name' => 'اسم العميل', + 'select_customer' => 'اختر العميل', + 'add_item' => 'إضافة صنف', + 'edit_item' => 'تعديل صنف', + 'delete_item' => 'حذف صنف', + 'select_item' => 'اختر الصنف', + 'select_service' => 'اختر الخدمة', + 'checkout' => 'إتمام الطلب', + 'back_to_pos' => 'العودة لنقطة البيع', + 'language' => 'اللغة', + 'arabic' => 'العربية', + 'english' => 'الإنجليزية', + 'branch' => 'الفرع', + 'all_branches' => 'جميع الفروع', + 'category' => 'الفئة', + 'categories' => 'الفئات', + 'add_category' => 'إضافة فئة', + 'edit_category' => 'تعديل فئة', + 'delete_category' => 'حذف فئة', + 'categories_management' => 'إدارة الفئات', + 'add_new_category' => 'إضافة فئة جديدة', + 'select_category' => 'اختر الفئة', + 'all' => 'الكل', + 'variant' => 'النوع', + 'variants' => 'الأنواع', + 'add_variant' => 'إضافة نوع', + 'select_variant' => 'اختر النوع', + 'variant_name_en' => 'اسم النوع (EN)', + 'variant_name_ar' => 'اسم النوع (AR)', + 'default' => 'افتراضي', + 'vat_percent' => 'نسبة الضريبة %', + 'image_url' => 'رابط الصورة', + 'items_management' => 'إدارة الأصناف', + 'variants_prices' => 'الأنواع والأسعار', + 'no_items_found' => 'لا يوجد أصناف', + 'pricing_management' => 'إدارة الأسعار', + 'are_you_sure' => 'هل أنت متأكد؟', + ] +]; + +function __($key) { + global $translations, $lang; + return $translations[$lang][$key] ?? $key; +} + +function is_rtl() { + global $lang; + return $lang === 'ar'; +} + +function is_arabic() { + global $lang; + return $lang === 'ar'; +} \ No newline at end of file diff --git a/index.php b/index.php index 9416a71..017f431 100644 --- a/index.php +++ b/index.php @@ -1,52 +1,8 @@ - - - - - - Chat Assistant - - - - - - - - - - - - - -
-
-
-
-
-
-
-
- Chat Assistant - Admin -
-
-
- Hello! I'm your assistant. How can I help you today? -
-
-
-
- - -
-
-
-
- - - - \ No newline at end of file +session_start(); +if (isset($_SESSION['user_id'])) { + header('Location: admin.php'); +} else { + header('Location: login.php'); +} +exit; diff --git a/items.php b/items.php new file mode 100644 index 0000000..ec036ed --- /dev/null +++ b/items.php @@ -0,0 +1,860 @@ + false, 'error' => 'Unauthorized']); + exit; + } + header('Location: login.php'); + exit; +} + +$current_role = $_SESSION['role'] ?? 'cashier'; +if ($current_role === 'cashier') { + if (isset($_POST['ajax'])) { + header('Content-Type: application/json'); + echo json_encode(['success' => false, 'error' => 'Forbidden']); + exit; + } + header('Location: admin.php'); + exit; +} + +$branch_id = $_SESSION['branch_id']; + +function handleImageUpload($file) { + if (!$file || $file['error'] !== UPLOAD_ERR_OK) { + return null; + } + + $targetDir = "assets/images/items/"; + if (!is_dir($targetDir)) { + mkdir($targetDir, 0775, true); + } + + $fileExtension = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); + $newFileName = uniqid('item_', true) . '.' . $fileExtension; + $targetFile = $targetDir . $newFileName; + + // Check if image file is a actual image or fake image + $check = getimagesize($file['tmp_name']); + if($check === false) { + return null; + } + + // Allow certain file formats + $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; + if (!in_array($fileExtension, $allowedExtensions)) { + return null; + } + + if (move_uploaded_file($file['tmp_name'], $targetFile)) { + return $targetFile; + } + + return null; +} + +function deleteOldImage($imageUrl) { + if ($imageUrl && strpos($imageUrl, 'assets/images/items/') === 0) { + if (file_exists($imageUrl)) { + unlink($imageUrl); + } + } +} + +// Handle Actions +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { + if ($_POST['action'] === 'add_item') { + $name_en = $_POST['name_en']; + $name_ar = $_POST['name_ar']; + $category_id = $_POST['category_id'] ?: null; + $vat_percent = $_POST['vat_percent'] ?: 0.00; + + $image_url = handleImageUpload($_FILES['image'] ?? null); + + $stmt = db()->prepare("INSERT INTO items (category_id, name_en, name_ar, image_url, vat_percent) VALUES (?, ?, ?, ?, ?)"); + $stmt->execute([$category_id, $name_en, $name_ar, $image_url, $vat_percent]); + header('Location: items.php?success=item_added'); + exit; + } elseif ($_POST['action'] === 'edit_item') { + $id = $_POST['id']; + $name_en = $_POST['name_en']; + $name_ar = $_POST['name_ar']; + $category_id = $_POST['category_id'] ?: null; + $vat_percent = $_POST['vat_percent'] ?: 0.00; + + // Get current image to delete it if new one is uploaded + $stmt = db()->prepare("SELECT image_url FROM items WHERE id = ?"); + $stmt->execute([$id]); + $currentItem = $stmt->fetch(); + $image_url = $currentItem['image_url']; + + $new_image = handleImageUpload($_FILES['image'] ?? null); + if ($new_image) { + deleteOldImage($image_url); + $image_url = $new_image; + } + + $stmt = db()->prepare("UPDATE items SET category_id = ?, name_en = ?, name_ar = ?, image_url = ?, vat_percent = ? WHERE id = ?"); + $stmt->execute([$category_id, $name_en, $name_ar, $image_url, $vat_percent, $id]); + header('Location: items.php?success=item_updated'); + exit; + } elseif ($_POST['action'] === 'delete_item') { + $id = $_POST['id']; + + // Delete image file if exists + $stmt = db()->prepare("SELECT image_url FROM items WHERE id = ?"); + $stmt->execute([$id]); + $item = $stmt->fetch(); + deleteOldImage($item['image_url']); + + $stmt = db()->prepare("DELETE FROM items WHERE id = ?"); + $stmt->execute([$id]); + header('Location: items.php?success=item_deleted'); + exit; + } elseif ($_POST['action'] === 'add_category') { + $name_en = $_POST['cat_name_en']; + $name_ar = $_POST['cat_name_ar']; + $stmt = db()->prepare("INSERT INTO categories (name_en, name_ar) VALUES (?, ?)"); + $stmt->execute([$name_en, $name_ar]); + header('Location: items.php?success=category_added'); + exit; + } elseif ($_POST['action'] === 'edit_category') { + $id = $_POST['id']; + $name_en = $_POST['cat_name_en']; + $name_ar = $_POST['cat_name_ar']; + $stmt = db()->prepare("UPDATE categories SET name_en = ?, name_ar = ? WHERE id = ?"); + $stmt->execute([$name_en, $name_ar, $id]); + header('Location: items.php?success=category_updated'); + exit; + } elseif ($_POST['action'] === 'delete_category') { + $id = $_POST['id']; + $stmt = db()->prepare("DELETE FROM categories WHERE id = ?"); + $stmt->execute([$id]); + header('Location: items.php?success=category_deleted'); + exit; + } elseif ($_POST['action'] === 'add_service') { + $name_en = $_POST['svc_name_en']; + $name_ar = $_POST['svc_name_ar']; + $stmt = db()->prepare("INSERT INTO services (name_en, name_ar) VALUES (?, ?)"); + $stmt->execute([$name_en, $name_ar]); + header('Location: items.php?success=service_added'); + exit; + } elseif ($_POST['action'] === 'edit_service') { + $id = $_POST['id']; + $name_en = $_POST['svc_name_en']; + $name_ar = $_POST['svc_name_ar']; + $stmt = db()->prepare("UPDATE services SET name_en = ?, name_ar = ? WHERE id = ?"); + $stmt->execute([$name_en, $name_ar, $id]); + header('Location: items.php?success=service_updated'); + exit; + } elseif ($_POST['action'] === 'delete_service') { + $id = $_POST['id']; + $stmt = db()->prepare("DELETE FROM services WHERE id = ?"); + $stmt->execute([$id]); + header('Location: items.php?success=service_deleted'); + exit; + } elseif ($_POST['action'] === 'update_price') { + $item_id = $_POST['item_id']; + $service_id = $_POST['service_id']; + $variant_id = $_POST['variant_id'] ?: null; + $price = $_POST['price']; + + $stmt = db()->prepare("INSERT INTO prices (branch_id, item_id, variant_id, service_id, price) + VALUES (?, ?, ?, ?, ?) + ON DUPLICATE KEY UPDATE price = ?"); + $stmt->execute([$branch_id, $item_id, $variant_id, $service_id, $price, $price]); + + if (isset($_POST['ajax'])) { + header('Content-Type: application/json'); + echo json_encode(['success' => true]); + exit; + } + + header('Location: items.php?success=price_updated'); + exit; + } elseif ($_POST['action'] === 'add_variant') { + $item_id = $_POST['item_id']; + $name_en = $_POST['variant_name_en']; + $name_ar = $_POST['variant_name_ar']; + $stmt = db()->prepare("INSERT INTO item_variants (item_id, name_en, name_ar) VALUES (?, ?, ?)"); + $stmt->execute([$item_id, $name_en, $name_ar]); + header('Location: items.php?success=variant_added'); + exit; + } elseif ($_POST['action'] === 'edit_variant') { + $id = $_POST['id']; + $name_en = $_POST['name_en']; + $name_ar = $_POST['name_ar']; + $stmt = db()->prepare("UPDATE item_variants SET name_en = ?, name_ar = ? WHERE id = ?"); + $stmt->execute([$name_en, $name_ar, $id]); + + if (isset($_POST['ajax'])) { + header('Content-Type: application/json'); + echo json_encode(['success' => true]); + exit; + } + + header('Location: items.php?success=variant_updated'); + exit; + } elseif ($_POST['action'] === 'delete_variant') { + $id = $_POST['id']; + $stmt = db()->prepare("DELETE FROM item_variants WHERE id = ?"); + $stmt->execute([$id]); + header('Location: items.php?success=variant_deleted'); + exit; + } +} + +// NOW Include header +$title = 'items'; +require_once __DIR__ . '/includes/header.php'; + +$categories = db()->query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll(); +$items = db()->query("SELECT i.*, c.name_en as cat_en, c.name_ar as cat_ar + FROM items i + LEFT JOIN categories c ON i.category_id = c.id + ORDER BY i.name_en ASC")->fetchAll(); +$services = db()->query("SELECT * FROM services ORDER BY name_en ASC")->fetchAll(); + +$stmt = db()->prepare("SELECT * FROM prices WHERE branch_id = ?"); +$stmt->execute([$branch_id]); +$prices_raw = $stmt->fetchAll(); +$prices = []; +foreach ($prices_raw as $p) { + $v_key = $p['variant_id'] ?: 'default'; + $prices[$p['item_id']][$v_key][$p['service_id']] = $p['price']; +} + +$item_variants = db()->query("SELECT * FROM item_variants ORDER BY name_en ASC")->fetchAll(); +$variants_by_item = []; +foreach ($item_variants as $v) { + $variants_by_item[$v['item_id']][] = $v; +} +?> + +
+

+
+ + + +
+
+ + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ + + + + +
+
+
+ + + + + +
+
+
+ + + + % + + + + +
+
+
+ +
+
+ +
+
How to use Variants & Services?
+

+ Services: General actions like "Wash Only", "Urgent Wash", "Iron Only". Add them once and set prices for each item.
+ Variants: Specific garment types or materials like "Silk Dress", "Wool Suit", or "Large Carpet". Use them if an item has different versions with unique pricing. +

+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/login.php b/login.php new file mode 100644 index 0000000..48f5f6a --- /dev/null +++ b/login.php @@ -0,0 +1,86 @@ +prepare("SELECT u.*, b.name_en as branch_name_en, b.name_ar as branch_name_ar + FROM users u + LEFT JOIN branches b ON u.branch_id = b.id + WHERE u.username = ?"); + $stmt->execute([$username]); + $user = $stmt->fetch(); + + if ($user && password_verify($password, $user['password_hash'])) { + $_SESSION['user_id'] = $user['id']; + $_SESSION['branch_id'] = $user['branch_id']; + $_SESSION['company_id'] = $user['company_id']; + $_SESSION['role'] = $user['role']; + $_SESSION['full_name'] = $lang === 'ar' ? ($user['full_name_ar'] ?: $user['full_name_en']) : $user['full_name_en']; + $_SESSION['branch_name'] = $lang === 'ar' ? ($user['branch_name_ar'] ?: $user['branch_name_en']) : $user['branch_name_en']; + + header('Location: admin.php'); + exit; + } else { + $error = 'Invalid username or password'; + } +} +?> + + + + + + <?= __('login') ?> + + + + + + + diff --git a/logout.php b/logout.php new file mode 100644 index 0000000..37bc5ab --- /dev/null +++ b/logout.php @@ -0,0 +1,5 @@ +prepare("SELECT o.*, c.name_en as customer_name_en, c.name_ar as customer_name_ar, c.phone as customer_phone, c.address_en as customer_address_en, c.address_ar as customer_address_ar + FROM orders o + LEFT JOIN customers c ON o.customer_id = c.id + WHERE o.id = ?"); +$stmt->execute([$order_id]); +$order = $stmt->fetch(); + +if (!$order) { + echo "Order not found"; + exit; +} + +// Handle status updates +if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action'])) { + if ($_POST['action'] === 'update_status') { + $new_status = $_POST['status']; + $stmt = db()->prepare("UPDATE orders SET status = ? WHERE id = ?"); + $stmt->execute([$new_status, $order_id]); + header("Location: order_details.php?id=$order_id"); + exit; + } elseif ($_POST['action'] === 'add_payment') { + $amount = $_POST['amount']; + $method = $_POST['payment_method']; + $stmt = db()->prepare("INSERT INTO payments (order_id, amount, payment_method) VALUES (?, ?, ?)"); + $stmt->execute([$order_id, $amount, $method]); + + $stmt = db()->prepare("SELECT SUM(amount) as total_paid FROM payments WHERE order_id = ?"); + $stmt->execute([$order_id]); + $total_paid = $stmt->fetch()['total_paid'] ?? 0; + + $payment_status = $total_paid >= $order['total_price'] ? 'paid' : ($total_paid > 0 ? 'partially_paid' : 'unpaid'); + $stmt = db()->prepare("UPDATE orders SET payment_status = ? WHERE id = ?"); + $stmt->execute([$payment_status, $order_id]); + + header("Location: order_details.php?id=$order_id"); + exit; + } +} + +// NOW Include header +$title = 'order_details'; +require_once __DIR__ . '/includes/header.php'; + +$stmt = db()->prepare("SELECT oi.*, i.name_en as item_en, i.name_ar as item_ar, + s.name_en as service_en, s.name_ar as service_ar, + v.name_en as variant_en, v.name_ar as variant_ar + FROM order_items oi + JOIN items i ON oi.item_id = i.id + JOIN services s ON oi.service_id = s.id + LEFT JOIN item_variants v ON oi.variant_id = v.id + WHERE oi.order_id = ?"); +$stmt->execute([$order_id]); +$order_items = $stmt->fetchAll(); + +$stmt = db()->prepare("SELECT * FROM payments WHERE order_id = ?"); +$stmt->execute([$order_id]); +$payments = $stmt->fetchAll(); + +?> + +
+
+
+
+
#
+ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
SAR SAR SAR
SAR
SAR
SAR
+
+ +
+
+
+

+

+

+
+
+
+

+
+
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
SAR
+
+
+
+ +
+
+
+
+ + +
+ + +
+
+
+ prepare("SELECT SUM(amount) as total_paid FROM payments WHERE order_id = ?"); + $stmt->execute([$order_id]); + $total_paid = $stmt->fetch()['total_paid'] ?? 0; + $remaining = $order['total_price'] - $total_paid; + ?> +
+ : SAR +
+ 0): ?> +
+ +
+ + +
+
+ + +
+ +
+ + +
+
+
+ + 'secondary', + 'processing' => 'primary', + 'ready' => 'success', + 'delivered' => 'dark', + 'cancelled' => 'danger', + ][$status] ?? 'info'; +} +require_once __DIR__ . '/includes/footer.php'; +?> diff --git a/orders.php b/orders.php new file mode 100644 index 0000000..6b62c92 --- /dev/null +++ b/orders.php @@ -0,0 +1,122 @@ +prepare($sql); +$stmt->execute($params); +$orders = $stmt->fetchAll(); + +?> + +
+
+
+
+
+ + +
+ + + +
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#
+
+
+
+ + + +
+ + +
+
+
+ + 'secondary', + 'processing' => 'primary', + 'ready' => 'success', + 'delivered' => 'dark', + 'cancelled' => 'danger', + ][$status] ?? 'info'; +} +function getPaymentStatusColor($status) { + return [ + 'unpaid' => 'danger', + 'partially_paid' => 'warning', + 'paid' => 'success', + ][$status] ?? 'info'; +} +require_once __DIR__ . '/includes/footer.php'; +?> diff --git a/pos.php b/pos.php new file mode 100644 index 0000000..9e373c2 --- /dev/null +++ b/pos.php @@ -0,0 +1,468 @@ +query("SELECT * FROM categories ORDER BY name_en ASC")->fetchAll(); + +// Get all items with details +$stmt = db()->prepare("SELECT i.*, c.name_en as cat_en, c.name_ar as cat_ar + FROM items i + LEFT JOIN categories c ON i.category_id = c.id + ORDER BY i.name_en ASC"); +$stmt->execute(); +$items_raw = $stmt->fetchAll(); + +// Get all services and prices for this branch +$stmt = db()->prepare("SELECT p.item_id, p.variant_id, p.service_id, p.price, + s.name_en as service_en, s.name_ar as service_ar, + v.name_en as variant_en, v.name_ar as variant_ar + FROM prices p + JOIN services s ON p.service_id = s.id + LEFT JOIN item_variants v ON p.variant_id = v.id + WHERE p.branch_id = ?"); +$stmt->execute([$branch_id]); +$all_prices = $stmt->fetchAll(); + +$items = []; +foreach ($items_raw as $i) { + $items[$i['id']] = [ + 'id' => $i['id'], + 'name_en' => $i['name_en'], + 'name_ar' => $i['name_ar'], + 'category_id' => $i['category_id'], + 'image_url' => $i['image_url'], + 'vat_percent' => (float)$i['vat_percent'], + 'variants' => [], + 'default_services' => [] + ]; +} + +foreach ($all_prices as $p) { + if (!isset($items[$p['item_id']])) continue; + + if ($p['variant_id']) { + if (!isset($items[$p['item_id']]['variants'][$p['variant_id']])) { + $items[$p['item_id']]['variants'][$p['variant_id']] = [ + 'id' => $p['variant_id'], + 'name_en' => $p['variant_en'], + 'name_ar' => $p['variant_ar'], + 'services' => [] + ]; + } + $items[$p['item_id']]['variants'][$p['variant_id']]['services'][] = [ + 'id' => $p['service_id'], + 'name_en' => $p['service_en'], + 'name_ar' => $p['service_ar'], + 'price' => (float)$p['price'] + ]; + } else { + $items[$p['item_id']]['default_services'][] = [ + 'id' => $p['service_id'], + 'name_en' => $p['service_en'], + 'name_ar' => $p['service_ar'], + 'price' => (float)$p['price'] + ]; + } +} + +// Get all customers for this branch +$stmt = db()->prepare("SELECT * FROM customers WHERE branch_id = ? ORDER BY name_en ASC"); +$stmt->execute([$branch_id]); +$customers = $stmt->fetchAll(); +?> + +
+
+ +
+ + + + +
+ +
+
+
+
+ + +
+
+ +
+ + +
+
+
+ + + +
+ +
+ +
+ % VAT +
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+ +
+ +
+ +
+ + +
+
+ +
+
+ +

+
+
+ +
+
+ + 0.00 SAR +
+
+ + 0.00 SAR +
+
+ + 0.00 SAR +
+ +
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/users.php b/users.php new file mode 100644 index 0000000..cbdfa21 --- /dev/null +++ b/users.php @@ -0,0 +1,123 @@ +prepare("INSERT INTO users (username, password_hash, full_name_en, full_name_ar, role, branch_id, company_id) VALUES (?, ?, ?, ?, ?, ?, ?)"); + $stmt->execute([$username, $password, $full_name_en, $full_name_ar, $role, $branch_id, $company_id]); + header('Location: users.php'); + exit; + } +} + +// NOW Include header +$title = 'users'; +require_once __DIR__ . '/includes/header.php'; + +$users = db()->query("SELECT u.*, b.name_en as branch_name_en FROM users u LEFT JOIN branches b ON u.branch_id = b.id")->fetchAll(); +$branches = db()->query("SELECT * FROM branches")->fetchAll(); +?> + +
+
+
+
+
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + +
#
+ + + +
+
+
+
+
+ + + + \ No newline at end of file