From 6e3e0c556acef128da91005e07c316ada90b8dad Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Sun, 19 Apr 2026 10:09:23 +0000 Subject: [PATCH] Autosave: 20260419-100930 --- api/customers.php | 2 +- api/settings.php | 2 +- api/suppliers.php | 2 +- categories.php | 2 +- customers.php | 2 +- edit_sale.php | 2 +- includes/app.php | 1 + includes/header.php | 18 ++- pos.php | 2 +- print_labels.php | 278 ++++++++++++++++++++++++++++++++++++++++++++ print_receipt.php | 2 +- purchases.php | 2 +- reports.php | 2 +- sale.php | 2 +- sales.php | 2 +- stock.php | 51 +++++++- suppliers.php | 2 +- units.php | 2 +- users.php | 91 ++++++++++++--- 19 files changed, 427 insertions(+), 40 deletions(-) create mode 100644 print_labels.php diff --git a/api/customers.php b/api/customers.php index f7682e1..c1255d2 100644 --- a/api/customers.php +++ b/api/customers.php @@ -1,6 +1,6 @@ ["name_ar" => "نقاط البيع", "name_en" => "POS", "actions" => ["show", "add"]], "normal_sale" => ["name_ar" => "بيع عادي", "name_en" => "Normal Sale", "actions" => ["show", "add"]], "sales" => ["name_ar" => "المبيعات", "name_en" => "Sales", "actions" => ["show", "edit", "del"]], "purchases" => ["name_ar" => "المشتريات", "name_en" => "Purchases", "actions" => ["show", "add", "edit", "del"]], "stock" => ["name_ar" => "المخزون", "name_en" => "Stock", "actions" => ["show", "add", "edit", "del"]], "reports" => ["name_ar" => "التقارير", "name_en" => "Reports", "actions" => ["show"]], "customers" => ["name_ar" => "العملاء", "name_en" => "Customers", "actions" => ["show", "add", "edit", "del"]], "suppliers" => ["name_ar" => "الموردين", "name_en" => "Suppliers", "actions" => ["show", "add", "edit", "del"]], "categories" => ["name_ar" => "التصنيفات", "name_en" => "Categories", "actions" => ["show", "add", "edit", "del"]], "units" => ["name_ar" => "الوحدات", "name_en" => "Units", "actions" => ["show", "add", "edit", "del"]], "users" => ["name_ar" => "المستخدمين", "name_en" => "Users", "actions" => ["show", "add", "edit", "del"]], "settings" => ["name_ar" => "الإعدادات", "name_en" => "Settings", "actions" => ["show", "edit"]]]; } function has_permission(string $m, string $a = "show"): bool { $u = current_user(); if (!$u) return false; if ($u["role"] === "owner") return true; $p = !empty($u["permissions"]) ? (is_array($u["permissions"]) ? $u["permissions"] : json_decode($u["permissions"], true)) : []; return !empty($p[$m][$a]); } function require_permission(string $m, string $a = "show"): array { $u = require_auth(); if (!has_permission($m, $a)) { set_flash("warning", tr("ليس لديك صلاحية.", "You do not have permission.")); redirect_to("index.php"); } return $u; } function require_roles(array $roles): array { $user = require_auth(); diff --git a/includes/header.php b/includes/header.php index 86cb7ae..a860e12 100644 --- a/includes/header.php +++ b/includes/header.php @@ -71,7 +71,8 @@ $isPublic = !isset($user) || !$user; - + +
@@ -91,8 +92,10 @@ $isPublic = !isset($user) || !$user;
+ - + +
@@ -112,8 +115,10 @@ $isPublic = !isset($user) || !$user;
+ - + +
@@ -129,24 +134,25 @@ $isPublic = !isset($user) || !$user;
+ - + - + - + diff --git a/pos.php b/pos.php index e0b2815..1a08240 100644 --- a/pos.php +++ b/pos.php @@ -1,7 +1,7 @@ prepare("SELECT * FROM items WHERE sku IN ($placeholders)"); + $stmt->execute($skus); + $results = $stmt->fetchAll(); + // Index by SKU + foreach ($results as $row) { + $items[$row['sku']] = $row; + } +} + +// Templates configuration +$templates = [ + 'avery_65' => [ + 'name' => 'Avery L7651 - 65 Labels (38.1 x 21.2 mm)', + 'cols' => 5, + 'rows' => 13, + 'width' => '38.1mm', + 'height' => '21.2mm', + 'margin_top' => '10.5mm', + 'margin_left' => '4.7mm', + 'gap_x' => '2.5mm', + 'gap_y' => '0mm', + ], + 'avery_54' => [ + 'name' => 'Avery 54 Labels (32 x 25.4 mm)', + 'cols' => 6, + 'rows' => 9, + 'width' => '32mm', + 'height' => '25.4mm', + 'margin_top' => '10mm', + 'margin_left' => '5mm', + 'gap_x' => '2mm', + 'gap_y' => '0mm', + ], + 'avery_45' => [ + 'name' => 'Avery 45 Labels (38.1 x 29.6 mm)', + 'cols' => 5, + 'rows' => 9, + 'width' => '38.1mm', + 'height' => '29.6mm', + 'margin_top' => '15mm', + 'margin_left' => '5mm', + 'gap_x' => '2mm', + 'gap_y' => '0mm', + ] +]; + +$templateId = $_REQUEST['template'] ?? 'avery_65'; +$tpl = $templates[$templateId] ?? $templates['avery_65']; + +// Prepare labels to print +$labelsToPrint = []; +if (!empty($items)) { + // Check if quantities are posted + if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($_POST['qty'])) { + foreach ($_POST['qty'] as $sku => $qty) { + if (isset($items[$sku])) { + for ($i = 0; $i < (int)$qty; $i++) { + $labelsToPrint[] = $items[$sku]; + } + } + } + } else { + // Default 1 per item + foreach ($skus as $sku) { + if (isset($items[$sku])) { + $labelsToPrint[] = $items[$sku]; + } + } + } +} + +?> + + + + + <?= h(tr('طباعة ملصقات', 'Print Labels')) ?> + + + + + + +
+
+
+
+ +
+
+
+
+
+ + +
+
+ +
+
+ +
+ + + + + + + + + + + + $item): ?> + + + + + + + + + + + + + + +
SKU
+ + + + + + +
+ + +
+
+ +
+ +
+ +
+
+
+
+ + + + + + + + diff --git a/print_receipt.php b/print_receipt.php index acd5442..5bc9c1b 100644 --- a/print_receipt.php +++ b/print_receipt.php @@ -1,6 +1,6 @@

+ @@ -198,6 +201,9 @@ require __DIR__ . '/includes/header.php'; + @@ -212,11 +218,14 @@ require __DIR__ . '/includes/header.php'; - + - + + - - - + @@ -149,15 +155,13 @@ require __DIR__ . '/includes/header.php'; - - - +
+ + SKU
+ + pic @@ -243,6 +252,9 @@ require __DIR__ . '/includes/header.php'; + + + @@ -533,6 +545,37 @@ function deleteItem(sku) { } }); } + +function toggleAllCheckboxes(source) { + const checkboxes = document.querySelectorAll(".item-checkbox"); + for (let i = 0; i < checkboxes.length; i++) { + checkboxes[i].checked = source.checked; + } +} + +function printBulkLabels() { + const checkboxes = document.querySelectorAll(".item-checkbox:checked"); + if (checkboxes.length === 0) { + Swal.fire('', '', 'warning inaly); + return; + } + + let skus = []; + checkboxes.forEach((cb) => skus.push(cb.value)); + + const form = document.createElement('form'); + form.method = 'POST'; + form.action = 'print_labels.php'; + + const input = document.createElement('input'); + input.type = 'hidden'; + input.name = 'skus'; + input.value = skus.join(\",\"); + + form.appendChild(input); + document.body.appendChild(form); + form.submit(); +} - \ No newline at end of file + \ No newline at end of file diff --git a/suppliers.php b/suppliers.php index b6cd5e5..6da55f0 100644 --- a/suppliers.php +++ b/suppliers.php @@ -1,6 +1,6 @@ prepare("INSERT INTO users (username, password, role, branch_code, name_ar, name_en) VALUES (?, ?, ?, ?, ?, ?)"); - $stmt->execute([$username, $hash, $role, $branch_code, $name_ar, $name_en]); + $stmt = db()->prepare("INSERT INTO users (username, password, role, branch_code, name_ar, name_en, permissions) VALUES (?, ?, ?, ?, ?, ?, ?)"); + $perms = isset($_POST["permissions"]) ? json_encode($_POST["permissions"]) : "{}"; + $stmt->execute([$username, $hash, $role, $branch_code, $name_ar, $name_en, $perms]); set_flash('success', tr('تمت إضافة المستخدم بنجاح.', 'User added successfully.')); } catch (PDOException $e) { set_flash('error', tr('حدث خطأ، قد يكون اسم المستخدم موجوداً مسبقاً.', 'Error occurred, username might already exist.')); @@ -34,6 +36,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } if ($action === 'edit') { + if (!has_permission('users', 'edit')) { set_flash('error', tr('ليس لديك صلاحية', 'No permission')); redirect_to('users.php'); } $id = (int)($_POST['id'] ?? 0); $username = trim($_POST['username'] ?? ''); $name_ar = trim($_POST['name_ar'] ?? ''); @@ -46,11 +49,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { if ($password) { $hash = password_hash($password, PASSWORD_DEFAULT); - $stmt = db()->prepare("UPDATE users SET username=?, password=?, role=?, branch_code=?, name_ar=?, name_en=? WHERE id=?"); - $stmt->execute([$username, $hash, $role, $branch_code, $name_ar, $name_en, $id]); + $stmt = db()->prepare("UPDATE users SET username=?, password=?, role=?, branch_code=?, name_ar=?, name_en=?, permissions=? WHERE id=?"); + $perms = isset($_POST["permissions"]) ? json_encode($_POST["permissions"]) : "{}"; + $stmt->execute([$username, $hash, $role, $branch_code, $name_ar, $name_en, $perms, $id]); } else { - $stmt = db()->prepare("UPDATE users SET username=?, role=?, branch_code=?, name_ar=?, name_en=? WHERE id=?"); - $stmt->execute([$username, $role, $branch_code, $name_ar, $name_en, $id]); + $stmt = db()->prepare("UPDATE users SET username=?, role=?, branch_code=?, name_ar=?, name_en=?, permissions=? WHERE id=?"); + $perms = isset($_POST["permissions"]) ? json_encode($_POST["permissions"]) : "{}"; + $stmt->execute([$username, $role, $branch_code, $name_ar, $name_en, $perms, $id]); } set_flash('success', tr('تم تعديل المستخدم بنجاح.', 'User updated successfully.')); } catch (PDOException $e) { @@ -61,6 +66,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { } if ($action === 'delete') { + if (!has_permission('users', 'del')) { set_flash('error', tr('ليس لديك صلاحية', 'No permission')); redirect_to('users.php'); } $id = (int)($_POST['id'] ?? 0); if ($id && $id !== $user['id']) { $stmt = db()->prepare("DELETE FROM users WHERE id=?"); @@ -103,9 +109,11 @@ require __DIR__ . '/includes/header.php';

+ +
@@ -131,9 +139,7 @@ require __DIR__ . '/includes/header.php';
POS
- + @@ -232,7 +236,43 @@ require __DIR__ . '/includes/header.php'; + + + +
+
+ + + + + + + + + + + + $module): ?> + + + + + + + + +
+ +
+ +
+ + - + +
+