diff --git a/api/settings.php b/api/settings.php index f214b57..35a9216 100644 --- a/api/settings.php +++ b/api/settings.php @@ -36,6 +36,13 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { return $referer; }; $pdo = db(); + $action = trim((string) ($_POST['action'] ?? '')); + if ($action === 'reset_eid_serial') { + ensure_sales_table(); + reset_eid_serial_next($pdo, 1); + $respond(true, 'success', tr('تمت إعادة تعيين الرقم التسلسلي القادم لطلبات العيد إلى 1. سيُستخدم هذا للطلبات الجديدة فقط.', 'The next Eid order serial has been reset to 1. This applies to new Eid orders only.'), $redirectBack()); + } + $keys = [ 'timezone', 'company_name_ar', 'company_name_en', 'vat_percentage', 'company_vat_number', 'company_phone', 'company_email', 'company_address', diff --git a/db/schema.sql b/db/schema.sql index 56d8a52..7221d8b 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -128,6 +128,7 @@ CREATE TABLE IF NOT EXISTS `purchase_orders` ( CREATE TABLE IF NOT EXISTS `sales_orders` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `receipt_no` varchar(50) NOT NULL, + `eid_serial_no` int(10) unsigned DEFAULT NULL, `sale_mode` varchar(20) NOT NULL, `branch_code` varchar(30) NOT NULL, `cashier_username` varchar(60) NOT NULL, diff --git a/eid_orders.php b/eid_orders.php index 0a1fedf..502b547 100644 --- a/eid_orders.php +++ b/eid_orders.php @@ -441,12 +441,8 @@ require __DIR__ . '/includes/header.php'; - -
+ +
# ·
"ALTER TABLE sales_orders ADD COLUMN order_type varchar(30) NOT NULL DEFAULT 'standard' AFTER status", 'delivery_status' => "ALTER TABLE sales_orders ADD COLUMN delivery_status varchar(30) NOT NULL DEFAULT 'pending' AFTER order_type", 'delivery_date' => "ALTER TABLE sales_orders ADD COLUMN delivery_date date DEFAULT NULL AFTER delivery_status", + 'eid_serial_no' => "ALTER TABLE sales_orders ADD COLUMN eid_serial_no int(10) unsigned DEFAULT NULL AFTER receipt_no", ]; foreach ($requiredColumns as $column => $columnSql) { $exists = $pdo->query("SHOW COLUMNS FROM sales_orders LIKE " . $pdo->quote($column))->fetchColumn(); @@ -1867,6 +1868,83 @@ function ensure_sales_table(): void $pdo->exec("UPDATE sales_orders SET order_type = 'standard' WHERE order_type IS NULL OR order_type = ''"); $pdo->exec("UPDATE sales_orders SET delivery_status = CASE WHEN COALESCE(status, 'completed') = 'completed' THEN 'delivered' ELSE 'pending' END WHERE delivery_status IS NULL OR delivery_status = ''"); + + $hasEidSerialColumn = $pdo->query("SHOW COLUMNS FROM sales_orders LIKE 'eid_serial_no'")->fetchColumn(); + if ($hasEidSerialColumn) { + $existingAssignedStmt = $pdo->query("SELECT COUNT(*) FROM sales_orders WHERE order_type = 'eid' AND eid_serial_no IS NOT NULL AND eid_serial_no > 0"); + $existingAssigned = (int) $existingAssignedStmt->fetchColumn(); + $nextSerial = $existingAssigned > 0 + ? max(1, (int) $pdo->query("SELECT COALESCE(MAX(eid_serial_no), 0) + 1 FROM sales_orders WHERE order_type = 'eid'")->fetchColumn()) + : 1; + + $missingStmt = $pdo->query("SELECT id FROM sales_orders WHERE order_type = 'eid' AND (eid_serial_no IS NULL OR eid_serial_no <= 0) ORDER BY id ASC"); + $assignStmt = $pdo->prepare("UPDATE sales_orders SET eid_serial_no = :serial WHERE id = :id"); + while ($row = $missingStmt->fetch()) { + $assignStmt->bindValue(':serial', $nextSerial, PDO::PARAM_INT); + $assignStmt->bindValue(':id', (int) $row['id'], PDO::PARAM_INT); + $assignStmt->execute(); + $nextSerial++; + } + } +} + +function eid_serial_setting_key(): string +{ + return 'eid_serial_sequence_next'; +} + +function current_eid_serial_next(PDO $pdo): int +{ + ensure_sales_table(); + + $seedStmt = $pdo->query("SELECT COALESCE(MAX(eid_serial_no), 0) + 1 FROM sales_orders WHERE order_type = 'eid'"); + $seed = max(1, (int) $seedStmt->fetchColumn()); + + $stmt = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = :key LIMIT 1"); + $stmt->bindValue(':key', eid_serial_setting_key()); + $stmt->execute(); + $current = (int) $stmt->fetchColumn(); + + return $current > 0 ? $current : $seed; +} + +function reset_eid_serial_next(PDO $pdo, int $nextNumber = 1): void +{ + $stmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:key, :value) ON DUPLICATE KEY UPDATE setting_value = VALUES(setting_value)"); + $stmt->bindValue(':key', eid_serial_setting_key()); + $stmt->bindValue(':value', (string) max(1, $nextNumber)); + $stmt->execute(); +} + +function next_eid_serial_no(PDO $pdo): int +{ + ensure_sales_table(); + + $settingKey = eid_serial_setting_key(); + $seedValue = current_eid_serial_next($pdo); + + $seedStmt = $pdo->prepare("INSERT INTO settings (setting_key, setting_value) VALUES (:key, :value) ON DUPLICATE KEY UPDATE setting_key = VALUES(setting_key)"); + $seedStmt->bindValue(':key', $settingKey); + $seedStmt->bindValue(':value', (string) $seedValue); + $seedStmt->execute(); + + $selectStmt = $pdo->prepare("SELECT setting_value FROM settings WHERE setting_key = :key FOR UPDATE"); + $selectStmt->bindValue(':key', $settingKey); + $selectStmt->execute(); + + $nextNumber = max(1, (int) $selectStmt->fetchColumn()); + + $updateStmt = $pdo->prepare("UPDATE settings SET setting_value = :next_value WHERE setting_key = :key"); + $updateStmt->bindValue(':next_value', (string) ($nextNumber + 1)); + $updateStmt->bindValue(':key', $settingKey); + $updateStmt->execute(); + + return $nextNumber; +} + +function eid_serial_label($serial): string +{ + return 'E-' . str_pad((string) max(1, (int) $serial), 4, '0', STR_PAD_LEFT); } function create_sale(array $data): int @@ -1885,6 +1963,8 @@ function create_sale(array $data): int $orderType = 'standard'; } + $eidSerialNo = $orderType === 'eid' ? next_eid_serial_no($pdo) : null; + $defaultDeliveryStatus = (($data['status'] ?? 'completed') === 'completed') ? 'delivered' : 'pending'; $deliveryStatus = trim((string) ($data['delivery_status'] ?? $defaultDeliveryStatus)); if (!array_key_exists($deliveryStatus, eid_delivery_status_options())) { @@ -1897,11 +1977,12 @@ function create_sale(array $data): int } $stmt = $pdo->prepare('INSERT INTO sales_orders - (receipt_no, sale_mode, branch_code, cashier_username, cashier_name, role_name, customer_id, customer_name, payment_method, payment_status, items_json, item_count, subtotal, vat_amount, total_amount, paid_amount, due_amount, status, order_type, delivery_status, delivery_date, notes, sale_date) + (receipt_no, eid_serial_no, sale_mode, branch_code, cashier_username, cashier_name, role_name, customer_id, customer_name, payment_method, payment_status, items_json, item_count, subtotal, vat_amount, total_amount, paid_amount, due_amount, status, order_type, delivery_status, delivery_date, notes, sale_date) VALUES - (:receipt_no, :sale_mode, :branch_code, :cashier_username, :cashier_name, :role_name, :customer_id, :customer_name, :payment_method, :payment_status, :items_json, :item_count, :subtotal, :vat_amount, :total_amount, :paid_amount, :due_amount, :status, :order_type, :delivery_status, :delivery_date, :notes, NOW())'); + (:receipt_no, :eid_serial_no, :sale_mode, :branch_code, :cashier_username, :cashier_name, :role_name, :customer_id, :customer_name, :payment_method, :payment_status, :items_json, :item_count, :subtotal, :vat_amount, :total_amount, :paid_amount, :due_amount, :status, :order_type, :delivery_status, :delivery_date, :notes, NOW())'); $stmt->bindValue(':receipt_no', $receiptNo); + $stmt->bindValue(':eid_serial_no', $eidSerialNo, $eidSerialNo === null ? PDO::PARAM_NULL : PDO::PARAM_INT); $stmt->bindValue(':sale_mode', $data['sale_mode']); $stmt->bindValue(':branch_code', $data['branch_code']); $stmt->bindValue(':cashier_username', $data['cashier_username']); diff --git a/includes/footer_settings.php b/includes/footer_settings.php index a5d3886..e7f8b73 100644 --- a/includes/footer_settings.php +++ b/includes/footer_settings.php @@ -9,6 +9,7 @@ $wablasDailyAutoEnabled = (string) get_setting('wablas_daily_auto_send', '0') === '1'; $wablasDailyAutoTime = wablas_format_time_setting((string) get_setting('wablas_daily_auto_time', '21:00')); $wablasDailyAutoLastDate = (string) get_setting('wablas_daily_auto_last_date', ''); + $eidSerialNext = current_eid_serial_next(db()); ?> - +