diff --git a/debts.php b/debts.php index 10e492b..12e1306 100644 --- a/debts.php +++ b/debts.php @@ -4,9 +4,10 @@ $user = require_auth(); $activeNav = 'debts'; $pageTitle = tr('الديون والفواتير الآجلة', 'Debts & Unpaid Bills'); -require_once 'includes/header.php'; - $pdo = db(); +$debtsLoadError = ''; +$unpaidSales = []; +$debtsByCustomer = []; // Handle Mark as Paid if (isset($_GET['mark_paid'])) { @@ -20,17 +21,67 @@ if (isset($_GET['mark_paid'])) { redirect_to('debts.php'); } -// Fetch all unpaid sales -$sqlUnpaid = "SELECT s.*, c.name as c_name, c.phone as c_phone - FROM sales_orders s - LEFT JOIN customers c ON s.customer_id = c.id - WHERE s.payment_status = 'unpaid' - ORDER BY s.sale_date DESC"; -$stmtUnpaid = $pdo->query($sqlUnpaid); -$unpaidSales = $stmtUnpaid->fetchAll(PDO::FETCH_ASSOC); +try { + $salesColumns = []; + foreach ($pdo->query('SHOW COLUMNS FROM sales_orders')->fetchAll(PDO::FETCH_ASSOC) as $column) { + $salesColumns[$column['Field']] = true; + } + + $hasCustomersTable = false; + $customerColumns = []; + $customersTable = $pdo->query("SHOW TABLES LIKE 'customers'"); + if ($customersTable && $customersTable->fetchColumn()) { + $hasCustomersTable = true; + foreach ($pdo->query('SHOW COLUMNS FROM customers')->fetchAll(PDO::FETCH_ASSOC) as $column) { + $customerColumns[$column['Field']] = true; + } + } + + $selectParts = [ + 's.id', + 's.receipt_no', + 's.sale_date', + 's.total_amount', + isset($salesColumns['customer_id']) ? 's.customer_id' : 'NULL AS customer_id', + isset($salesColumns['customer_name']) ? 's.customer_name' : 'NULL AS customer_name', + 'NULL AS c_name', + 'NULL AS c_phone', + ]; + + $joinSql = ''; + if ($hasCustomersTable && isset($salesColumns['customer_id']) && isset($customerColumns['id'])) { + $joinSql = ' LEFT JOIN customers c ON s.customer_id = c.id '; + if (isset($customerColumns['name'])) { + $selectParts[6] = 'c.name AS c_name'; + } + if (isset($customerColumns['phone'])) { + $selectParts[7] = 'c.phone AS c_phone'; + } + } + + if (isset($salesColumns['payment_status'])) { + $whereSql = " WHERE s.payment_status = 'unpaid'"; + } elseif (isset($salesColumns['payment_method'])) { + $whereSql = " WHERE s.payment_method = 'pay_later'"; + } else { + $whereSql = ' WHERE 1 = 0'; + } + + $sqlUnpaid = 'SELECT ' . implode(', ', $selectParts) + . ' FROM sales_orders s' + . $joinSql + . $whereSql + . ' ORDER BY s.sale_date DESC'; + $stmtUnpaid = $pdo->query($sqlUnpaid); + $unpaidSales = $stmtUnpaid ? $stmtUnpaid->fetchAll(PDO::FETCH_ASSOC) : []; +} catch (Throwable $e) { + $debtsLoadError = tr( + 'تعذر تحميل صفحة الديون بسبب اختلاف في هيكل قاعدة البيانات. احفظ التعديلات ثم أنشئ نسخة جديدة وأعد التحديث.', + 'The debts page could not load because the deployed database schema is older than the current code. Save these changes, create a new version, then refresh the page.' + ); +} // Aggregate by customer -$debtsByCustomer = []; foreach ($unpaidSales as $sale) { $cId = $sale['customer_id'] ?? 'unknown'; if (!isset($debtsByCustomer[$cId])) { @@ -47,12 +98,20 @@ foreach ($unpaidSales as $sale) { // Sort by highest debt uasort($debtsByCustomer, fn($a, $b) => $b['total'] <=> $a['total']); + +require_once 'includes/header.php'; ?>

+ + + +
diff --git a/includes/sale_form.php b/includes/sale_form.php index 971af87..b31ac66 100644 --- a/includes/sale_form.php +++ b/includes/sale_form.php @@ -28,6 +28,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $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 ($paymentMethod === 'pay_later' && !$customerId) { $error = tr('يجب اختيار عميل مسجل للدفع الآجل.', 'You must select a registered customer for pay later.'); } elseif (!is_array($items) || $items === []) { @@ -732,10 +734,14 @@ function updateTotals(total, vat) { // Intercept form submission to check if items exist document.getElementById('smart-sale-form').addEventListener('submit', function(e) { const paymentMethod = document.querySelector('select[name="payment_method"]').value; + const saleStatus = document.querySelector('select[name="sale_status"]').value; const customerId = document.getElementById('formCustomerId').value; if (Object.keys(invoiceItems).length === 0) { e.preventDefault(); Swal.fire({icon: 'warning', text: ''}); + } else if (saleStatus === 'order' && !customerId) { + e.preventDefault(); + Swal.fire({icon: 'warning', text: ''}); } else if (paymentMethod === 'pay_later' && !customerId) { e.preventDefault(); Swal.fire({icon: 'warning', text: ''}); @@ -743,4 +749,4 @@ document.getElementById('smart-sale-form').addEventListener('submit', function(e }); - \ No newline at end of file +