document.addEventListener('DOMContentLoaded', () => { // SweetAlert2 Toast Mixin const Toast = Swal.mixin({ toast: true, position: 'top-end', showConfirmButton: false, timer: 3000, timerProgressBar: true, didOpen: (toast) => { toast.addEventListener('mouseenter', Swal.stopTimer); toast.addEventListener('mouseleave', Swal.resumeTimer); } }); // Global settings with fallbacks const settings = (typeof COMPANY_SETTINGS !== 'undefined') ? COMPANY_SETTINGS : { currency_symbol: '$', currency_decimals: 2, vat_rate: 0 }; let cart = []; let currentOrderId = null; // Track order ID for updates const cartItemsContainer = document.getElementById('cart-items'); const cartTotalPrice = document.getElementById('cart-total-price'); const cartSubtotal = document.getElementById('cart-subtotal'); const cartVatInput = document.getElementById('cart-vat-input'); // Updated Button References const quickOrderBtn = document.getElementById('quick-order-btn'); const placeOrderBtn = document.getElementById('place-order-btn'); const recallBtn = document.getElementById('recall-bill-btn'); const reprintReceiptBtn = document.getElementById('reprint-receipt-btn'); // Recall Modal const recallModalEl = document.getElementById('recallOrderModal'); const recallModal = recallModalEl ? new bootstrap.Modal(recallModalEl) : null; const recallList = document.getElementById('recall-orders-list'); // Loyalty State let isLoyaltyRedemption = false; const loyaltySection = document.getElementById('loyalty-section'); const loyaltyPointsDisplay = document.getElementById('loyalty-points-display'); const loyaltyMessage = document.getElementById('loyalty-message'); const redeemLoyaltyBtn = document.getElementById('redeem-loyalty-btn'); const viewPointsHistoryBtn = document.getElementById('view-points-history-btn'); // Points History Modal const pointsHistoryModalEl = document.getElementById('pointsHistoryModal'); const pointsHistoryModal = pointsHistoryModalEl ? new bootstrap.Modal(pointsHistoryModalEl) : null; const pointsHistoryBody = document.getElementById('points-history-body'); const pointsHistoryEmpty = document.getElementById('points-history-empty'); // Table Management let currentTableId = null; let currentTableName = null; const tableDisplay = document.getElementById('current-table-display'); const tableModalEl = document.getElementById('tableSelectionModal'); const tableSelectionModal = tableModalEl ? new bootstrap.Modal(tableModalEl) : null; // Variant Management const variantModalEl = document.getElementById('variantSelectionModal'); const variantSelectionModal = variantModalEl ? new bootstrap.Modal(variantModalEl) : null; let pendingProduct = null; // Customer Search Elements const customerSearchInput = document.getElementById('customer-search'); const customerResults = document.getElementById('customer-results'); const selectedCustomerId = document.getElementById('selected-customer-id'); const clearCustomerBtn = document.getElementById('clear-customer'); const customerInfo = document.getElementById('customer-info'); const customerNameDisplay = document.getElementById('customer-name-display'); let currentCustomer = null; // Payment Modal const paymentModalEl = document.getElementById('paymentSelectionModal'); const paymentSelectionModal = paymentModalEl ? new bootstrap.Modal(paymentModalEl) : null; const paymentMethodsContainer = document.getElementById('payment-methods-container'); // Product Search & Filter const productSearchInput = document.getElementById('product-search-input'); let currentCategory = 'all'; let currentSearchQuery = ''; // Helper for currency function formatCurrency(amount) { const symbol = settings.currency_symbol || '$'; const decimals = parseInt(settings.currency_decimals || 2); return symbol + parseFloat(amount).toFixed(decimals); } // --- Product Filtering (Category + Search) --- function filterProducts() { const items = document.querySelectorAll('.product-item'); items.forEach(item => { const matchesCategory = (currentCategory == 'all' || item.dataset.categoryId == currentCategory); const name = item.querySelector('.card-title').textContent.toLowerCase(); const matchesSearch = name.includes(currentSearchQuery); if (matchesCategory && matchesSearch) { item.style.display = 'block'; } else { item.style.display = 'none'; } }); } window.filterCategory = function(categoryId, btnElement) { currentCategory = categoryId; // Update Active Button State if (btnElement) { document.querySelectorAll('.category-btn').forEach(btn => btn.classList.remove('active')); btnElement.classList.add('active'); } filterProducts(); }; if (productSearchInput) { productSearchInput.addEventListener('input', (e) => { currentSearchQuery = e.target.value.trim().toLowerCase(); filterProducts(); }); } // --- Recall Order Logic --- if (recallBtn) { recallBtn.addEventListener('click', () => { fetchRecallOrders(); }); } function fetchRecallOrders() { if (!recallList) return; recallList.innerHTML = '
'; if (recallModal) recallModal.show(); const outletId = new URLSearchParams(window.location.search).get('outlet_id') || 1; fetch(`api/recall_orders.php?action=list&outlet_id=${outletId}`) .then(res => res.json()) .then(data => { recallList.innerHTML = ''; if (data.success && data.orders.length > 0) { data.orders.forEach(order => { const item = document.createElement('button'); item.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center'; item.innerHTML = `
Order #${order.id} ${order.order_type}
${order.customer_name || 'Guest'} ${order.table_number ? ' • Table ' + order.table_number : ''} • ${order.time_formatted}
${formatCurrency(order.total_amount)}
${order.item_count} items
`; item.onclick = () => loadRecalledOrder(order.id); recallList.appendChild(item); }); } else { recallList.innerHTML = '
No unpaid bills found.
'; } }) .catch(err => { recallList.innerHTML = '
Error fetching orders.
'; }); } function loadRecalledOrder(orderId) { fetch(`api/recall_orders.php?action=details&id=${orderId}`) .then(res => res.json()) .then(data => { if (data.success) { // Set Order ID currentOrderId = data.order.id; // Set Customer if (data.customer) { selectCustomer(data.customer); } else { if (clearCustomerBtn) clearCustomerBtn.click(); } // Set Table/Order Type const otInput = document.querySelector(`input[name="order_type"][value="${data.order.order_type}"]`); if (otInput) { otInput.checked = true; if (data.order.order_type === 'dine-in' && data.order.table_id) { selectTable(data.order.table_id, data.order.table_number); } else { checkOrderType(); } } // Populate Cart cart = data.items; updateCart(); if (recallModal) recallModal.hide(); showToast(`Order #${orderId} loaded!`, 'success'); } else { showToast(data.error || 'Failed to load order', 'danger'); } }) .catch(err => showToast('Error loading order details', 'danger')); } // --- Customer Search --- let searchTimeout; if (customerSearchInput) { customerSearchInput.addEventListener('input', (e) => { const query = e.target.value.trim(); clearTimeout(searchTimeout); if (query.length < 2) { customerResults.style.display = 'none'; return; } searchTimeout = setTimeout(() => { fetch(`api/search_customers.php?q=${encodeURIComponent(query)}`) .then(res => res.json()) .then(data => { customerResults.innerHTML = ''; if (data.length > 0) { data.forEach(cust => { const a = document.createElement('a'); a.href = '#'; a.className = 'list-group-item list-group-item-action'; a.innerHTML = `
${cust.name}
${cust.phone || ''}
`; a.onclick = (ev) => { ev.preventDefault(); selectCustomer(cust); }; customerResults.appendChild(a); }); customerResults.style.display = 'block'; } else { customerResults.innerHTML = '
No results found
'; customerResults.style.display = 'block'; } }); }, 300); }); // Close search on click outside document.addEventListener('click', (e) => { if (!customerSearchInput.contains(e.target) && !customerResults.contains(e.target)) { customerResults.style.display = 'none'; } }); } function selectCustomer(cust) { currentCustomer = cust; selectedCustomerId.value = cust.id; customerNameDisplay.textContent = cust.name; customerSearchInput.value = cust.name; // Show name in input customerSearchInput.disabled = true; // Lock input customerResults.style.display = 'none'; clearCustomerBtn.classList.remove('d-none'); // Loyalty Logic if (loyaltySection && typeof LOYALTY_SETTINGS !== 'undefined' && LOYALTY_SETTINGS.is_enabled) { loyaltySection.classList.remove('d-none'); loyaltyPointsDisplay.textContent = cust.points + ' pts'; if (cust.eligible_for_free_meal) { redeemLoyaltyBtn.disabled = false; loyaltyMessage.innerHTML = 'Eligible for Free Meal!'; } else { redeemLoyaltyBtn.disabled = true; const needed = cust.points_needed || 0; loyaltyMessage.textContent = `${needed} pts away from a free meal.`; } } isLoyaltyRedemption = false; } if (clearCustomerBtn) { clearCustomerBtn.addEventListener('click', () => { currentCustomer = null; selectedCustomerId.value = ''; customerSearchInput.value = ''; customerSearchInput.disabled = false; clearCustomerBtn.classList.add('d-none'); if (customerInfo) customerInfo.classList.add('d-none'); if (loyaltySection) loyaltySection.classList.add('d-none'); isLoyaltyRedemption = false; updateCart(); customerSearchInput.focus(); }); } // Loyalty Redeem Click if (redeemLoyaltyBtn) { redeemLoyaltyBtn.addEventListener('click', () => { if (typeof LOYALTY_SETTINGS === 'undefined' || !LOYALTY_SETTINGS.is_enabled) return; if (cart.length === 0) { showToast("Cart is empty!", "warning"); return; } if (cart.length > 1) { showToast("Can only redeem a free meal with exactly one item in cart!", "warning"); return; } if (!currentCustomer || !currentCustomer.eligible_for_free_meal) return; Swal.fire({ title: 'Redeem Loyalty?', text: "Redeem points for a free meal? This will finalize the order immediately.", icon: 'question', showCancelButton: true, confirmButtonColor: '#198754', cancelButtonColor: '#6c757d', confirmButtonText: 'Yes, redeem and finish!' }).then((result) => { if (result.isConfirmed) { isLoyaltyRedemption = true; updateCart(); processOrder(null, 'Loyalty Redeem'); } }); }); } // Points History View if (viewPointsHistoryBtn) { viewPointsHistoryBtn.addEventListener('click', () => { if (!currentCustomer) return; fetchPointsHistory(currentCustomer.id); }); } function fetchPointsHistory(customerId) { if (!pointsHistoryBody || !pointsHistoryModal) return; pointsHistoryBody.innerHTML = '
Loading...'; pointsHistoryEmpty.classList.add('d-none'); pointsHistoryModal.show(); fetch(`api/customer_loyalty_history.php?customer_id=${customerId}`) .then(res => res.json()) .then(data => { pointsHistoryBody.innerHTML = ''; if (data.success && data.history.length > 0) { data.history.forEach(item => { const tr = document.createElement('tr'); const dateObj = new Date(item.created_at); const date = dateObj.toLocaleDateString('en-GB', { day: '2-digit', month: 'short' }) + ' ' + dateObj.toLocaleTimeString('en-GB', { hour: '2-digit', minute: '2-digit' }); const pointsClass = item.points_change > 0 ? 'text-success' : 'text-danger'; const pointsPrefix = item.points_change > 0 ? '+' : ''; tr.innerHTML = ` ${date}
${item.reason}
${item.order_id ? `
Order #${item.order_id}
` : ''} ${pointsPrefix}${item.points_change} `; pointsHistoryBody.appendChild(tr); }); } else { pointsHistoryEmpty.classList.remove('d-none'); } }) .catch(err => { pointsHistoryBody.innerHTML = 'Error loading history'; }); } // --- Table & Order Type Logic --- const orderTypeInputs = document.querySelectorAll('input[name="order_type"]'); function checkOrderType() { const checked = document.querySelector('input[name="order_type"]:checked'); if (!checked) return; const selected = checked.value; if (selected === 'dine-in') { if (!currentTableId && tableSelectionModal) openTableSelectionModal(); if (tableDisplay) tableDisplay.style.display = 'inline-block'; } else { if (tableDisplay) tableDisplay.style.display = 'none'; } } orderTypeInputs.forEach(input => { input.addEventListener('change', checkOrderType); }); function openTableSelectionModal() { if (!tableSelectionModal) return; const container = document.getElementById('table-list-container'); if (!container) return; container.innerHTML = '
'; // Update Modal Title const modalTitle = document.querySelector('#tableSelectionModal .modal-title'); if (modalTitle && typeof CURRENT_OUTLET !== 'undefined') { modalTitle.textContent = `Select Table - ${CURRENT_OUTLET.name}`; } tableSelectionModal.show(); const outletId = new URLSearchParams(window.location.search).get('outlet_id') || 1; fetch(`api/tables.php?outlet_id=${outletId}`) .then(res => res.json()) .then(data => { if (data.success) { renderTables(data.tables); } else { container.innerHTML = `
${data.error}
`; } }) .catch(() => { container.innerHTML = `
Error loading tables.
`; }); } function renderTables(tables) { const container = document.getElementById('table-list-container'); if (!container) return; container.innerHTML = ''; if (tables.length === 0) { const outletName = (typeof CURRENT_OUTLET !== 'undefined') ? CURRENT_OUTLET.name : 'this outlet'; container.innerHTML = `
No tables found for ${outletName}.
`; return; } tables.forEach(table => { const isOccupied = table.is_occupied; const col = document.createElement('div'); col.className = 'col-6 col-md-4 col-lg-3'; col.innerHTML = `
${table.name}
${table.capacity} Pax
${isOccupied ? 'Occupied' : 'Available'}
`; container.appendChild(col); }); } window.selectTable = function(id, name) { currentTableId = id; currentTableName = name; if (tableDisplay) { tableDisplay.innerHTML = `Table: ${name}`; tableDisplay.style.display = 'block'; } if (tableSelectionModal) tableSelectionModal.hide(); showToast(`Selected Table: ${name}`, 'success'); }; // --- Cart Logic --- document.querySelectorAll('.add-to-cart').forEach(card => { card.addEventListener('click', (e) => { const target = e.currentTarget; const product = { id: target.dataset.id, name: target.dataset.name, name_ar: target.dataset.nameAr || '', price: parseFloat(target.dataset.price), base_price: parseFloat(target.dataset.price), hasVariants: target.dataset.hasVariants === 'true', quantity: 1, variant_id: null, variant_name: null }; if (product.hasVariants) { openVariantModal(product); } else { addToCart(product); } }); }); function openVariantModal(product) { if (!variantSelectionModal) return; pendingProduct = product; const variants = (typeof PRODUCT_VARIANTS !== 'undefined') ? (PRODUCT_VARIANTS[product.id] || []) : []; const list = document.getElementById('variant-list'); const title = document.getElementById('variantModalTitle'); if (title) title.textContent = `Select option for ${product.name}`; if (!list) return; list.innerHTML = ''; variants.forEach(v => { const btn = document.createElement('button'); btn.className = 'list-group-item list-group-item-action d-flex justify-content-between align-items-center'; const adj = parseFloat(v.price_adjustment); const finalPrice = product.base_price + adj; btn.innerHTML = ` ${v.name} ${formatCurrency(finalPrice)} `; btn.onclick = () => { pendingProduct.variant_id = v.id; pendingProduct.variant_name = v.name; pendingProduct.price = finalPrice; addToCart(pendingProduct); variantSelectionModal.hide(); }; list.appendChild(btn); }); variantSelectionModal.show(); } function addToCart(product) { const existing = cart.find(item => item.id === product.id && item.variant_id === product.variant_id); if (existing) { existing.quantity++; } else { cart.push({...product}); } updateCart(); } window.changeQuantity = function(index, delta) { if (cart[index]) { cart[index].quantity += delta; if (cart[index].quantity <= 0) { removeFromCart(index); } else { updateCart(); } } }; function updateCart() { if (reprintReceiptBtn) { if (currentOrderId) reprintReceiptBtn.classList.remove('d-none'); else reprintReceiptBtn.classList.add('d-none'); } if (cart.length === 0) { if (cartItemsContainer) { cartItemsContainer.innerHTML = `

Cart is empty

`; } if (cartSubtotal) cartSubtotal.innerText = formatCurrency(0); if (cartVatInput) cartVatInput.value = 0; if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(0); if (quickOrderBtn) quickOrderBtn.disabled = true; if (placeOrderBtn) placeOrderBtn.disabled = true; return; } if (cartItemsContainer) cartItemsContainer.innerHTML = ''; let subtotal = 0; cart.forEach((item, index) => { const itemTotal = item.price * item.quantity; subtotal += itemTotal; if (cartItemsContainer) { const row = document.createElement('div'); row.className = 'd-flex justify-content-between align-items-center mb-3 border-bottom pb-2'; const variantLabel = item.variant_name ? `${item.variant_name}` : ''; const arabicNameDisplay = item.name_ar ? `
${item.name_ar}
` : ''; row.innerHTML = `
${item.name}
${arabicNameDisplay}
${formatCurrency(item.price)} ${variantLabel}
${item.quantity}
${formatCurrency(itemTotal)}
`; cartItemsContainer.appendChild(row); } }); if (cartSubtotal) cartSubtotal.innerText = formatCurrency(subtotal); let vat = 0; if (isLoyaltyRedemption) { vat = -subtotal; } else { const vatRate = parseFloat(settings.vat_rate) || 0; vat = subtotal * (vatRate / 100); } if (cartVatInput) cartVatInput.value = vat.toFixed(2); let total = subtotal + vat; if (total < 0) total = 0; if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(total); if (quickOrderBtn) quickOrderBtn.disabled = false; if (placeOrderBtn) placeOrderBtn.disabled = false; } window.removeFromCart = function(index) { cart.splice(index, 1); updateCart(); }; window.clearCart = function() { if (cart.length === 0) return; Swal.fire({ title: 'Clear Cart?', text: "Are you sure you want to remove all items from the cart?", icon: 'warning', showCancelButton: true, confirmButtonColor: '#dc3545', cancelButtonColor: '#6c757d', confirmButtonText: 'Yes, clear it!' }).then((result) => { if (result.isConfirmed) { cart = []; if (cartVatInput) cartVatInput.value = 0; currentOrderId = null; isLoyaltyRedemption = false; updateCart(); showToast("Cart cleared", "success"); } }); }; // --- Payment Selection Logic --- function renderPaymentMethods() { if (!paymentMethodsContainer) return; paymentMethodsContainer.innerHTML = ''; if (typeof PAYMENT_TYPES !== 'undefined' && PAYMENT_TYPES.length > 0) { PAYMENT_TYPES.forEach(pt => { const col = document.createElement('div'); col.className = 'col-6'; col.innerHTML = ` `; paymentMethodsContainer.appendChild(col); }); } else { paymentMethodsContainer.innerHTML = '
No payment methods configured.
'; } } function getPaymentIcon(name) { const n = name.toLowerCase(); if (n.includes('cash')) return 'bi-cash-coin'; if (n.includes('card') || n.includes('visa') || n.includes('master')) return 'bi-credit-card'; if (n.includes('qr') || n.includes('scan')) return 'bi-qr-code'; if (n.includes('bank') || n.includes('transfer')) return 'bi-building-columns'; return 'bi-wallet2'; } renderPaymentMethods(); // --- Checkout Flow (Quick Order) --- function validateOrder() { if (cart.length === 0) return false; const orderTypeInput = document.querySelector('input[name="order_type"]:checked'); const orderType = orderTypeInput ? orderTypeInput.value : 'takeaway'; if (orderType === 'dine-in' && !currentTableId) { showToast('Please select a table first', 'warning'); openTableSelectionModal(); return false; } return true; } if (quickOrderBtn) { quickOrderBtn.addEventListener('click', () => { if (validateOrder() && paymentSelectionModal) { paymentSelectionModal.show(); } }); } // --- Place Order (Pay Later) Flow --- if (placeOrderBtn) { placeOrderBtn.addEventListener('click', () => { if (validateOrder()) { Swal.fire({ title: 'Place Order?', text: "Place order without immediate payment?", icon: 'warning', showCancelButton: true, confirmButtonColor: '#ffc107', cancelButtonColor: '#6c757d', confirmButtonText: 'Yes, place order' }).then((result) => { if (result.isConfirmed) { processOrder(null, 'Pay Later'); } }); } }); } window.processOrder = function(paymentTypeId, paymentTypeName) { const orderTypeInput = document.querySelector('input[name="order_type"]:checked'); const orderType = orderTypeInput ? orderTypeInput.value : 'takeaway'; const subtotal = cart.reduce((acc, item) => acc + (item.price * item.quantity), 0); const vat = parseFloat(cartVatInput ? cartVatInput.value : 0) || 0; const totalAmount = Math.max(0, subtotal + vat); const custId = selectedCustomerId ? selectedCustomerId.value : null; const orderData = { order_id: currentOrderId, table_number: (orderType === 'dine-in') ? currentTableId : null, order_type: orderType, customer_id: custId || null, outlet_id: new URLSearchParams(window.location.search).get('outlet_id') || 1, payment_type_id: paymentTypeId, total_amount: totalAmount, vat: vat, redeem_loyalty: isLoyaltyRedemption, items: cart.map(item => ({ product_id: item.id, quantity: item.quantity, unit_price: item.price, variant_id: item.variant_id })) }; // Disable buttons if (paymentMethodsContainer) { const btns = paymentMethodsContainer.querySelectorAll('button'); btns.forEach(b => b.disabled = true); } if (quickOrderBtn) quickOrderBtn.disabled = true; if (placeOrderBtn) placeOrderBtn.disabled = true; fetch('api/order.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }) .then(res => res.json()) .then(data => { if (paymentMethodsContainer) { const btns = paymentMethodsContainer.querySelectorAll('button'); btns.forEach(b => b.disabled = false); } if (quickOrderBtn) quickOrderBtn.disabled = false; if (placeOrderBtn) placeOrderBtn.disabled = false; if (paymentSelectionModal) paymentSelectionModal.hide(); if (data.success) { // Print Receipt printReceipt({ orderId: data.order_id, customer: currentCustomer, items: [...cart], total: totalAmount, vat: vat, orderType: orderType, tableNumber: (orderType === 'dine-in') ? currentTableName : null, date: new Date().toLocaleString(), paymentMethod: paymentTypeName, loyaltyRedeemed: isLoyaltyRedemption }); cart = []; if (cartVatInput) cartVatInput.value = 0; currentOrderId = null; isLoyaltyRedemption = false; updateCart(); if (clearCustomerBtn) clearCustomerBtn.click(); showToast(`Order #${data.order_id} placed!`, 'success'); } else { showToast(`Error: ${data.error}`, 'danger'); } }) .catch(err => { if (paymentMethodsContainer) { const btns = paymentMethodsContainer.querySelectorAll('button'); btns.forEach(b => b.disabled = false); } if (quickOrderBtn) quickOrderBtn.disabled = false; if (placeOrderBtn) placeOrderBtn.disabled = false; if (paymentSelectionModal) paymentSelectionModal.hide(); showToast('Network Error', 'danger'); }); }; function showToast(msg, type = 'primary') { let icon = 'info'; if (type === 'success') icon = 'success'; if (type === 'danger') icon = 'error'; if (type === 'warning') icon = 'warning'; Toast.fire({ icon: icon, title: msg }); } window.reprintCurrentReceipt = function() { if (!currentOrderId) return; const subtotal = cart.reduce((acc, item) => acc + (item.price * item.quantity), 0); const vat = parseFloat(cartVatInput ? cartVatInput.value : 0) || 0; const totalAmount = Math.max(0, subtotal + vat); const orderType = document.querySelector('input[name="order_type"]:checked').value; printReceipt({ orderId: currentOrderId, customer: currentCustomer, items: [...cart], total: totalAmount, vat: vat, orderType: orderType, tableNumber: (orderType === 'dine-in') ? currentTableName : null, date: new Date().toLocaleString() + ' (Reprint)', paymentMethod: 'Previously Settled', loyaltyRedeemed: isLoyaltyRedemption }); }; function printReceipt(data) { const width = 400; const height = 800; const left = (screen.width - width) / 2; const top = (screen.height - height) / 2; const win = window.open('', '_blank', `width=${width},height=${height},top=${top},left=${left}`); if (!win) { alert('Please allow popups for this website to print receipts.'); return; } const tr = { 'Order': 'الطلب', 'Type': 'النوع', 'Date': 'التاريخ', 'Staff': 'الموظف', 'Table': 'طاولة', 'Payment': 'الدفع', 'ITEM': 'الصنف', 'TOTAL': 'المجموع', 'Subtotal': 'المجموع الفرعي', 'VAT': 'ضريبة القيمة المضافة', 'Tax Included': 'شامل الضريبة', 'THANK YOU FOR YOUR VISIT!': 'شكراً لزيارتكم!', 'Please come again.': 'يرجى زيارتنا مرة أخرى.', 'Customer Details': 'تفاصيل العميل', 'Tel': 'هاتف', 'takeaway': 'سفري', 'dine-in': 'محلي', 'delivery': 'توصيل', 'VAT No': 'الرقم الضريبي', 'CTR No': 'رقم السجل التجاري' }; const itemsHtml = data.items.map(item => `
${item.name}
${item.name_ar ? `
${item.name_ar}
` : ''} ${item.variant_name ? `
(${item.variant_name})
` : ''}
${item.quantity} x ${formatCurrency(item.price)}
${formatCurrency(item.quantity * item.price)} `).join(''); const customerHtml = data.customer ? `
Customer Details ${tr['Customer Details']}
${data.customer.name}
${data.customer.phone ? `
Tel: ${data.customer.phone}
` : ''} ${data.customer.address ? `
${data.customer.address}
` : ''}
` : ''; const tableHtml = data.tableNumber ? `
Table: ${data.tableNumber} ${tr['Table']}: ${data.tableNumber}
` : ''; const paymentHtml = data.paymentMethod ? `
Payment: ${data.paymentMethod} ${tr['Payment']}: ${data.paymentMethod}
` : ''; const loyaltyHtml = data.loyaltyRedeemed ? `
* Loyalty Reward Applied *
` : ''; const subtotal = data.total - data.vat; const baseUrl = (typeof BASE_URL !== 'undefined') ? BASE_URL : ''; const logoHtml = settings.logo_url ? `` : ''; const outletName = (typeof CURRENT_OUTLET !== 'undefined') ? CURRENT_OUTLET.name : ''; const staffName = (typeof CURRENT_USER !== 'undefined') ? CURRENT_USER.name : ''; const html = ` Receipt #${data.orderId}
${logoHtml}

${settings.company_name}

${outletName}
${settings.address}
Tel: ${settings.phone}
${settings.vat_number ? `
VAT No / الرقم الضريبي: ${settings.vat_number}
` : ''} ${settings.ctr_number ? `
CTR No / رقم السجل: ${settings.ctr_number}
` : ''}
Order: #${data.orderId} ${tr['Order']}: #${data.orderId}
Type: ${data.orderType.toUpperCase()} ${tr['Type']}: ${tr[data.orderType] || data.orderType}
Date: ${data.date} ${tr['Date']}: ${data.date}
Staff: ${staffName} ${tr['Staff']}: ${staffName}
${tableHtml} ${paymentHtml} ${loyaltyHtml}
${customerHtml} ${itemsHtml}
ITEM / الصنف TOTAL / المجموع
${Math.abs(data.vat) > 0 ? ` ` : ''}
Subtotal / ${tr['Subtotal']} ${formatCurrency(subtotal)}
${data.vat < 0 ? 'Discount' : 'VAT'} / ${tr['VAT']} ${data.vat < 0 ? '-' : '+'}${formatCurrency(Math.abs(data.vat))}
TOTAL / ${tr['TOTAL']} ${formatCurrency(data.total)}
`; win.document.write(html); win.document.close(); } // Initialize logic const urlParams = new URLSearchParams(window.location.search); if (!urlParams.has('order_type')) { const otTakeaway = document.getElementById('ot-takeaway'); if (otTakeaway) { otTakeaway.checked = true; } } checkOrderType(); // --- Add Customer Logic --- const addCustomerModalEl = document.getElementById('addCustomerModal'); const saveCustomerBtn = document.getElementById('save-new-customer'); const newCustomerName = document.getElementById('new-customer-name'); const newCustomerPhone = document.getElementById('new-customer-phone'); if (saveCustomerBtn && newCustomerName && newCustomerPhone) { saveCustomerBtn.addEventListener('click', () => { const name = newCustomerName.value.trim(); const phone = newCustomerPhone.value.trim(); if (name === '') { showToast('Name is required', 'warning'); return; } saveCustomerBtn.disabled = true; saveCustomerBtn.textContent = 'Saving...'; fetch('api/create_customer.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name, phone: phone }) }) .then(res => res.json()) .then(data => { saveCustomerBtn.disabled = false; saveCustomerBtn.textContent = 'Save Customer'; if (data.success) { if (addCustomerModalEl) { const modal = bootstrap.Modal.getInstance(addCustomerModalEl); if (modal) modal.hide(); } selectCustomer(data.customer); showToast('Customer created successfully', 'success'); } else { showToast(data.error || 'Error creating customer', 'danger'); } }) .catch(err => { saveCustomerBtn.disabled = false; saveCustomerBtn.textContent = 'Save Customer'; showToast('Network error', 'danger'); }); }); } });