query('SELECT id, name, phone FROM customers ORDER BY name ASC')->fetchAll(); } catch (Throwable $e) { $customers = []; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $submitAction = trim((string) ($_POST['submit_action'] ?? 'save')); if (!in_array($submitAction, ['save', 'save_print'], true)) { $submitAction = 'save'; } $branchCode = trim((string) ($_POST['branch_code'] ?? '')); $customerId = isset($_POST['customer_id']) && $_POST['customer_id'] !== '' ? (int)$_POST['customer_id'] : null; $customerName = trim((string) ($_POST['customer_name'] ?? '')); $paymentMethod = trim((string) ($_POST['payment_method'] ?? 'cash')); $paymentAmountInput = trim((string) ($_POST['payment_amount'] ?? '')); $saleStatus = trim((string) ($_POST['sale_status'] ?? ($isEidOrder ? 'order' : 'completed'))); $saleStatusInput = $saleStatus; $notes = trim((string) ($_POST['notes'] ?? '')); $notesInput = $notes; $deliveryStatus = trim((string) ($_POST['delivery_status'] ?? ($isEidOrder ? 'pending' : ''))); $selectedDeliveryStatus = $deliveryStatus; $deliveryDate = trim((string) ($_POST['delivery_date'] ?? '')); $deliveryDateInput = $deliveryDate; $cartJson = (string) ($_POST['cart_json'] ?? '[]'); $items = json_decode($cartJson, true); if (!in_array($branchCode, $allowedBranches, true)) { $error = tr('اختر فرعاً صالحاً لهذه الصلاحية.', 'Choose a valid branch for this role.'); } elseif (!in_array($paymentMethod, ['cash', 'card', 'transfer', 'pay_later'], true)) { $error = tr('اختر طريقة دفع صحيحة.', 'Choose a valid payment method.'); } elseif ($saleStatus === 'order' && !$customerId) { $error = tr('يجب اختيار عميل للطلب المسبق.', 'You must select a customer for a pre-order.'); } elseif ($isEidOrder && !isset($deliveryOptions[$deliveryStatus])) { $error = tr('اختر حالة تجهيز صحيحة لطلب العيد.', 'Choose a valid prep status for the Eid order.'); } elseif ($isEidOrder && ($deliveryDate === '' || !preg_match('/^\d{4}-\d{2}-\d{2}$/', $deliveryDate))) { $error = tr('حدد تاريخ تسليم صحيح لطلب العيد.', 'Choose a valid delivery date for the Eid order.'); } elseif (!is_array($items) || $items === []) { $error = tr('أضف صنفاً واحداً على الأقل إلى الفاتورة.', 'Add at least one item to the invoice.'); } else { $normalized = []; $subtotal = 0.0; $totalVat = 0.0; $itemCount = 0; foreach ($items as $item) { $sku = (string) ($item['sku'] ?? ''); $qty = (int) ($item['qty'] ?? 0); if (!isset($catalog[$sku]) || $qty < 1) { continue; } $product = $catalog[$sku]; $editedName = trim((string) ($item['name'] ?? '')); $finalName = $editedName !== '' ? $editedName : trim((string) ($product['name_' . current_lang()] ?? '')); if ($finalName === '') { $finalName = trim((string) ($product['name_ar'] ?? '')); } if ($finalName === '') { $finalName = trim((string) ($product['name_en'] ?? '')); } if ($finalName === '') { $finalName = $sku; } $price = isset($item['price']) && is_numeric($item['price']) ? max(0, (float) $item['price']) : (float) $product['price']; $lineTotal = $price * $qty; $vatPercent = (float) ($product['vat'] ?? 0); // Assuming price is inclusive of VAT: $itemVat = $lineTotal * ($vatPercent / 100); $totalVat += $itemVat; $normalized[] = [ 'sku' => $sku, 'name_ar' => $finalName, 'name_en' => $finalName, 'qty' => $qty, 'price' => $price, 'line_total' => $lineTotal, 'vat_percent' => $vatPercent, 'vat_amount' => $itemVat ]; $subtotal += $lineTotal; $itemCount += $qty; } if ($normalized === []) { $error = tr('الفاتورة غير صالحة بعد التحقق من الأصناف.', 'The invoice is invalid after product validation.'); } else { $totalAmount = $subtotal + $totalVat; if ($paymentAmountInput !== '' && !is_numeric($paymentAmountInput)) { $error = tr('أدخل مبلغاً مدفوعاً صحيحاً.', 'Enter a valid paid amount.'); } else { $paymentMeta = sale_payment_breakdown($totalAmount, $paymentMethod, $paymentAmountInput); if ($paymentMeta['due_amount'] > 0.0005 && !$customerId) { $error = tr('يجب اختيار عميل مسجل عند وجود مبلغ متبقٍ أو دفعة جزئية.', 'Select a registered customer when there is a remaining balance or partial payment.'); } } } if ($error === '') { $cashierName = current_lang() === 'ar' ? $user['name_ar'] : $user['name_en']; $saleId = create_sale([ 'sale_mode' => $saleMode, 'branch_code' => $branchCode, 'cashier_username' => $user['username'], 'cashier_name' => $cashierName, 'role_name' => $user['role'], 'customer_id' => $customerId, 'customer_name' => $customerName !== '' ? $customerName : null, 'payment_method' => $paymentMethod, 'payment_status' => $paymentMeta['payment_status'], 'paid_amount' => $paymentMeta['paid_amount'], 'due_amount' => $paymentMeta['due_amount'], 'items' => $normalized, 'item_count' => $itemCount, 'subtotal' => $subtotal, 'vat_amount' => $totalVat, 'total_amount' => $totalAmount, 'status' => $saleStatus, 'order_type' => $orderType, 'delivery_status' => $isEidOrder ? $deliveryStatus : null, 'delivery_date' => $isEidOrder ? $deliveryDate : null, 'notes' => $notes !== '' ? $notes : null, ]); wablas_notify_sale_invoice($saleId); set_flash('success', $isEidOrder ? tr('تم حفظ طلب العيد بنجاح.', 'Eid order saved successfully.') : ($saleMode === 'normal' ? tr('تم حفظ الفاتورة بنجاح.', 'Invoice saved successfully.') : tr('تم حفظ عملية POS بنجاح.', 'POS sale saved successfully.'))); if ($submitAction === 'save') { if ($isEidOrder) { redirect_to('eid_sale.php'); } if ($saleMode === 'normal') { redirect_to('normal_sale.php'); } redirect_to('pos.php'); } $redirectParams = ['id' => $saleId, 'print' => 1]; if ($isEidOrder) { redirect_to('print_receipt.php', $redirectParams); } redirect_to('sale.php', $redirectParams); } } } require __DIR__ . '/header.php'; ?>