document.addEventListener('DOMContentLoaded', () => { // SweetAlert2 Toast Mixin const Toast = (typeof Swal !== 'undefined') ? 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); } }) : null; function showToast(msg, type = 'primary') { if (!Toast) { console.log(`Toast: ${msg} (${type})`); return; } let icon = 'info'; if (type === 'success') icon = 'success'; if (type === 'danger') icon = 'error'; if (type === 'warning') icon = 'warning'; Toast.fire({ icon: icon, title: msg }); } // Global settings with fallbacks const settings = (typeof COMPANY_SETTINGS !== 'undefined') ? COMPANY_SETTINGS : { currency_symbol: '$', currency_decimals: 2, currency_position: 'before', vat_rate: 0 }; let cart = []; let currentOrderId = null; const cartItemsContainer = document.getElementById('cart-items'); const cartTotalPrice = document.getElementById('cart-total-price'); const cartSubtotal = document.getElementById('cart-subtotal'); const cartVatAmount = document.getElementById('cart-vat-amount'); const cartVatRow = document.getElementById('cart-vat-row'); const cartVatInput = document.getElementById('cart-vat-input'); 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'); const recallModalEl = document.getElementById('recallOrderModal'); const recallModal = recallModalEl ? new bootstrap.Modal(recallModalEl) : null; const recallList = document.getElementById('recall-orders-list'); 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'); 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'); const addCustomerModalEl = document.getElementById('addCustomerModal'); const addCustomerModal = addCustomerModalEl ? new bootstrap.Modal(addCustomerModalEl) : null; const saveNewCustomerBtn = document.getElementById('save-new-customer'); 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; const variantModalEl = document.getElementById('variantSelectionModal'); const variantSelectionModal = variantModalEl ? new bootstrap.Modal(variantModalEl) : null; let pendingProduct = null; 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; const paymentModalEl = document.getElementById('paymentSelectionModal'); const paymentSelectionModal = paymentModalEl ? new bootstrap.Modal(paymentModalEl) : null; const paymentMethodsContainer = document.getElementById('payment-methods-container'); const productSearchInput = document.getElementById('product-search'); let currentCategory = 'all'; let currentSearchQuery = ''; // Translation helper check const _t = (key) => (typeof t === 'function') ? t(key) : key; function formatCurrency(amount) { const symbol = settings.currency_symbol || '$'; const decimals = parseInt(settings.currency_decimals || 2); const position = settings.currency_position || 'before'; const formatted = parseFloat(Math.abs(amount)).toFixed(decimals); if (position === 'after') { return formatted + ' ' + symbol; } else { return symbol + formatted; } } function filterProducts() { const items = document.querySelectorAll('.product-item'); items.forEach(item => { const matchesCategory = (currentCategory == 'all' || item.dataset.category == currentCategory); const name = (item.dataset.name || '').toLowerCase(); const name_ar = (item.dataset.nameAr || '').toLowerCase(); const sku = (item.dataset.sku || '').toLowerCase(); const matchesSearch = name.includes(currentSearchQuery) || name_ar.includes(currentSearchQuery) || sku.includes(currentSearchQuery); item.style.display = (matchesCategory && matchesSearch) ? 'block' : 'none'; }); } window.filterCategory = function(categoryId, btnElement) { currentCategory = categoryId; document.querySelectorAll('.category-btn').forEach(btn => btn.classList.remove('active')); if (btnElement) { btnElement.classList.add('active'); } else { const btn = document.querySelector(`.category-btn[data-category="${categoryId}"]`); if (btn) btn.classList.add('active'); } filterProducts(); }; document.querySelectorAll('.category-btn').forEach(btn => { btn.addEventListener('click', () => { filterCategory(btn.dataset.category, btn); }); }); if (productSearchInput) { productSearchInput.addEventListener('input', (e) => { currentSearchQuery = e.target.value.trim().toLowerCase(); filterProducts(); }); } window.openRecallOrderModal = function() { if (!recallModal) return; fetchRecallOrders(); recallModal.show(); }; function fetchRecallOrders() { if (!recallList) return; recallList.innerHTML = '
'; const outletId = CURRENT_OUTLET ? CURRENT_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 = `
${_t('none')}
`; } }) .catch(() => { recallList.innerHTML = `
${_t('error')}
`; }); } function loadRecalledOrder(orderId) { fetch(`api/recall_orders.php?action=details&id=${orderId}`) .then(res => res.json()) .then(data => { if (data.success) { currentOrderId = data.order.id; if (data.customer) selectCustomer(data.customer); else if (clearCustomerBtn) clearCustomerBtn.click(); 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(); } } cart = data.items; updateCart(); if (recallModal) recallModal.hide(); showToast(`Order #${orderId} loaded!`, 'success'); } else { showToast(data.error || _t('error'), 'danger'); } }); } if (customerSearchInput) { let searchTimeout; customerSearchInput.addEventListener('input', (e) => { const query = e.target.value.trim(); clearTimeout(searchTimeout); if (query.length < 2) { if (customerResults) customerResults.style.display = 'none'; return; } searchTimeout = setTimeout(() => { fetch(`api/search_customers.php?q=${encodeURIComponent(query)}`) .then(res => res.json()) .then(data => { if (!customerResults) return; 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 = `
${_t('none')}
`; customerResults.style.display = 'block'; } }); }, 300); }); document.addEventListener('click', (e) => { if (customerResults && !customerSearchInput.contains(e.target) && !customerResults.contains(e.target)) { customerResults.style.display = 'none'; } }); } function updateLoyaltyUI() { if (!loyaltySection || typeof LOYALTY_SETTINGS === 'undefined' || !LOYALTY_SETTINGS.is_enabled) return; if (currentCustomer) { loyaltySection.classList.remove('d-none'); if (loyaltyPointsDisplay) loyaltyPointsDisplay.textContent = currentCustomer.points + ' pts'; if (redeemLoyaltyBtn) { const totalLoyaltyQuantity = cart.reduce((sum, item) => item.is_loyalty ? sum + item.quantity : sum, 0); const hasLoyaltyItem = totalLoyaltyQuantity > 0; const hasNonLoyaltyItem = cart.some(item => !item.is_loyalty); const eligibleCount = currentCustomer.eligible_count || 1; const isOverLimit = totalLoyaltyQuantity > eligibleCount; redeemLoyaltyBtn.disabled = !currentCustomer.eligible_for_free_meal || !hasLoyaltyItem || hasNonLoyaltyItem || isOverLimit; if (loyaltyMessage) { if (currentCustomer.eligible_for_free_meal) { loyaltyMessage.innerHTML = `Eligible for ${eligibleCount} Free Product${eligibleCount > 1 ? 's' : ''}!`; if (hasNonLoyaltyItem) { loyaltyMessage.innerHTML += '
(Remove non-loyalty products to redeem)
'; } else if (!hasLoyaltyItem) { loyaltyMessage.innerHTML += '
(Add a loyalty product to redeem)
'; } else if (isOverLimit) { loyaltyMessage.innerHTML += `
(Maximum ${eligibleCount} free products allowed)
`; } } else { loyaltyMessage.textContent = `${currentCustomer.points_needed || 0} pts away from a free product.`; } } } } else { loyaltySection.classList.add('d-none'); } } function selectCustomer(cust) { currentCustomer = cust; if (selectedCustomerId) selectedCustomerId.value = cust.id; if (customerNameDisplay) customerNameDisplay.textContent = cust.name; if (customerSearchInput) { customerSearchInput.value = cust.name; customerSearchInput.disabled = true; } if (customerResults) customerResults.style.display = 'none'; if (clearCustomerBtn) clearCustomerBtn.classList.remove('d-none'); updateLoyaltyUI(); isLoyaltyRedemption = false; } if (clearCustomerBtn) { clearCustomerBtn.addEventListener('click', () => { currentCustomer = null; if (selectedCustomerId) selectedCustomerId.value = ''; if (customerSearchInput) { customerSearchInput.value = ''; customerSearchInput.disabled = false; } clearCustomerBtn.classList.add('d-none'); if (customerInfo) customerInfo.classList.add('d-none'); updateLoyaltyUI(); isLoyaltyRedemption = false; updateCart(); }); } if (redeemLoyaltyBtn) { redeemLoyaltyBtn.addEventListener('click', () => { if (!currentCustomer) return; isLoyaltyRedemption = true; processOrder(null, 'Loyalty Redeem'); }); } if (viewPointsHistoryBtn) { viewPointsHistoryBtn.addEventListener('click', () => { if (!currentCustomer || !pointsHistoryModal) return; pointsHistoryBody.innerHTML = '
'; pointsHistoryEmpty.classList.add('d-none'); pointsHistoryModal.show(); fetch(`api/customer_loyalty_history.php?customer_id=${currentCustomer.id}`) .then(res => res.json()) .then(data => { pointsHistoryBody.innerHTML = ''; if (data.success && data.history.length > 0) { data.history.forEach(h => { const item = document.createElement('div'); item.className = 'list-group-item px-0 border-0 border-bottom'; const badgeClass = h.points_change > 0 ? 'bg-success' : 'bg-danger'; item.innerHTML = `
${h.reason}
${h.points_change > 0 ? '+' : ''}${h.points_change}
${h.created_at}
`; pointsHistoryBody.appendChild(item); }); } else { pointsHistoryEmpty.classList.remove('d-none'); } }) .catch(() => { pointsHistoryBody.innerHTML = `
${_t('error')}
`; }); }); } if (saveNewCustomerBtn) { saveNewCustomerBtn.addEventListener('click', () => { const name = document.getElementById('new-customer-name').value.trim(); const phone = document.getElementById('new-customer-phone').value.trim(); if (!name || !phone) { showToast('Please fill in both name and phone', 'warning'); return; } saveNewCustomerBtn.disabled = true; saveNewCustomerBtn.innerHTML = ''; fetch('api/create_customer.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, phone }) }) .then(res => res.json()) .then(data => { saveNewCustomerBtn.disabled = false; saveNewCustomerBtn.innerHTML = 'Add Customer'; if (data.success) { showToast('Customer added successfully', 'success'); selectCustomer(data.customer); if (addCustomerModal) addCustomerModal.hide(); // Clear inputs document.getElementById('new-customer-name').value = ''; document.getElementById('new-customer-phone').value = ''; } else { showToast(data.error || 'Failed to add customer', 'danger'); } }) .catch(() => { saveNewCustomerBtn.disabled = false; saveNewCustomerBtn.innerHTML = 'Add Customer'; showToast('An error occurred', 'danger'); }); }); } window.openTableSelectionModal = function() { if (!tableSelectionModal) return; fetchTables(); tableSelectionModal.show(); }; function fetchTables() { const grid = document.getElementById("tables-grid"); if (!grid) return; grid.innerHTML = "
"; const outletId = CURRENT_OUTLET ? CURRENT_OUTLET.id : 1; fetch(`api/tables.php?outlet_id=${outletId}`) .then(res => res.json()) .then(data => { grid.innerHTML = ""; if (data.success && data.tables.length > 0) { renderTables(data.tables); } else { grid.innerHTML = `
${_t("none")}
`; } }) .catch(() => { grid.innerHTML = `
${_t("error")}
`; }); } function renderTables(tables) { const grid = document.getElementById("tables-grid"); if (!grid) return; grid.innerHTML = ""; const areas = {}; tables.forEach(t => { const area = t.area_name || "General"; if (!areas[area]) areas[area] = []; areas[area].push(t); }); for (const area in areas) { const areaHeader = document.createElement("div"); areaHeader.className = "col-12 mt-3"; areaHeader.innerHTML = `
${area}
`; grid.appendChild(areaHeader); areas[area].forEach(table => { const col = document.createElement("div"); col.className = "col-3 col-sm-2"; const statusClass = table.is_occupied ? "btn-outline-danger" : "btn-outline-success"; col.innerHTML = ` `; grid.appendChild(col); }); } } window.selectTable = function(id, name) { currentTableId = id; currentTableName = name; const nameDisplay = document.getElementById("selected-table-name"); if (nameDisplay) nameDisplay.textContent = name; if (tableSelectionModal) tableSelectionModal.hide(); const dineInInput = document.getElementById("ot-dine-in"); if (dineInInput) { dineInInput.checked = true; checkOrderType(); } }; window.checkOrderType = function() { 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'; } }; document.querySelectorAll('input[name="order_type"]').forEach(input => { input.addEventListener('change', checkOrderType); }); window.handleProductClick = function(product, variants) { if (variants && variants.length > 0) { openVariantModal(product, variants); } else { addToCart({ id: product.id, name: product.name, name_ar: product.name_ar || "", price: parseFloat(product.price), base_price: parseFloat(product.price), hasVariants: false, quantity: 1, variant_id: null, variant_name: null, is_loyalty: parseInt(product.is_loyalty) === 1, vat_percent: parseFloat(product.vat_percent || settings.vat_rate || 0) }); } }; function openVariantModal(product, variants) { if (!variantSelectionModal) return; const list = document.getElementById('variant-list'); const title = document.getElementById('variantModalTitle'); if (title) title.textContent = `${_t('variant')}: ${LANG === 'ar' && product.name_ar ? product.name_ar : 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 finalPrice = parseFloat(product.price) + parseFloat(v.price_adjustment); const vName = (LANG === 'ar' && v.name_ar) ? v.name_ar : v.name; btn.innerHTML = `${vName}${formatCurrency(finalPrice)}`; btn.onclick = () => { addToCart({ id: product.id, name: product.name, name_ar: product.name_ar || "", price: finalPrice, base_price: parseFloat(product.price), hasVariants: true, quantity: 1, variant_id: v.id, variant_name: v.name, is_loyalty: parseInt(product.is_loyalty) === 1, vat_percent: parseFloat(product.vat_percent || settings.vat_rate || 0) }); variantSelectionModal.hide(); }; list.appendChild(btn); }); variantSelectionModal.show(); } window.addToCart = function(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) cart.splice(index, 1); updateCart(); } }; window.removeFromCart = function(index) { cart.splice(index, 1); updateCart(); }; window.clearCart = function() { if (cart.length === 0) return; cart = []; currentOrderId = null; isLoyaltyRedemption = false; updateCart(); showToast("Cart cleared", "success"); }; function updateCart() { if (!cartItemsContainer) return; updateLoyaltyUI(); if (cart.length === 0) { cartItemsContainer.innerHTML = `

${_t('cart_empty')}

`; if (cartSubtotal) cartSubtotal.innerText = formatCurrency(0); if (cartVatAmount) cartVatAmount.innerText = formatCurrency(0); // Always show VAT row even if 0 if (cartVatRow) cartVatRow.classList.remove('d-none'); if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(0); if (quickOrderBtn) { quickOrderBtn.disabled = true; quickOrderBtn.innerText = _t('quick_pay'); } if (placeOrderBtn) { placeOrderBtn.disabled = true; placeOrderBtn.innerText = _t('save_bill'); } return; } cartItemsContainer.innerHTML = ''; let subtotal = 0; let totalVat = 0; cart.forEach((item, index) => { const itemTotal = item.price * item.quantity; const itemVat = itemTotal * (item.vat_percent / 100); subtotal += itemTotal; totalVat += itemVat; const row = document.createElement('div'); row.className = 'd-flex justify-content-between align-items-center mb-3 border-bottom pb-2'; const itemName = (LANG === 'ar' && item.name_ar) ? item.name_ar : item.name; const otherName = (LANG === 'ar') ? item.name : item.name_ar; row.innerHTML = `
${itemName}
${otherName ? `
${otherName}
` : ''}
${formatCurrency(item.price)} ${item.vat_percent > 0 ? `${item.vat_percent}% VAT` : ''}
${item.quantity}
${formatCurrency(itemTotal)}
`; cartItemsContainer.appendChild(row); }); if (cartSubtotal) cartSubtotal.innerText = formatCurrency(subtotal); if (cartVatAmount) cartVatAmount.innerText = formatCurrency(totalVat); // Always show VAT row if (cartVatRow) cartVatRow.classList.remove('d-none'); if (cartVatInput) cartVatInput.value = totalVat.toFixed(3); const total = subtotal + totalVat; if (cartTotalPrice) cartTotalPrice.innerText = formatCurrency(total); if (quickOrderBtn) { quickOrderBtn.disabled = false; quickOrderBtn.innerText = _t('quick_pay'); } if (placeOrderBtn) { placeOrderBtn.disabled = false; placeOrderBtn.innerText = _t('save_bill'); } } if (quickOrderBtn) { quickOrderBtn.addEventListener('click', () => { if (cart.length > 0 && paymentSelectionModal) { renderPaymentMethods(); paymentSelectionModal.show(); } }); } if (placeOrderBtn) { placeOrderBtn.addEventListener('click', () => { if (cart.length > 0) processOrder(null, 'Pay Later'); }); } function renderPaymentMethods() { if (!paymentMethodsContainer) return; paymentMethodsContainer.innerHTML = ''; if (typeof PAYMENT_TYPES !== 'undefined') { PAYMENT_TYPES.forEach(pt => { const col = document.createElement('div'); col.className = 'col-12'; col.innerHTML = ``; paymentMethodsContainer.appendChild(col); }); } } window.processOrder = function(paymentTypeId, paymentTypeName) { const orderTypeInput = document.querySelector('input[name="order_type"]:checked'); const orderType = orderTypeInput ? orderTypeInput.value : 'takeaway'; let subtotal = 0; let totalVat = 0; const itemsData = cart.map(item => { const itemTotal = item.price * item.quantity; const itemVat = itemTotal * (item.vat_percent / 100); subtotal += itemTotal; totalVat += itemVat; return { product_id: item.id, quantity: item.quantity, unit_price: item.price, variant_id: item.variant_id, vat_percent: item.vat_percent, vat_amount: itemVat }; }); const orderData = { order_id: currentOrderId, table_number: (orderType === 'dine-in') ? currentTableId : null, order_type: orderType, customer_id: selectedCustomerId ? selectedCustomerId.value : null, outlet_id: CURRENT_OUTLET ? CURRENT_OUTLET.id : 1, payment_type_id: paymentTypeId, total_amount: isLoyaltyRedemption ? 0 : (subtotal + totalVat), // If loyalty redeemed, total is 0 for this transaction vat: isLoyaltyRedemption ? 0 : totalVat, items: itemsData, redeem_loyalty: isLoyaltyRedemption }; // Prepare receipt data before clearing cart const receiptData = { orderId: null, customer: currentCustomer ? { name: currentCustomer.name, phone: currentCustomer.phone, address: currentCustomer.address || '' } : null, items: cart.map(item => ({ name: item.name, variant_name: item.variant_name, quantity: item.quantity, price: isLoyaltyRedemption ? 0 : item.price, // If loyalty redeemed, price is 0 for this transaction vat_percent: isLoyaltyRedemption ? 0 : item.vat_percent, vat_amount: isLoyaltyRedemption ? 0 : ((item.price * item.quantity) * (item.vat_percent / 100)) })), subtotal: isLoyaltyRedemption ? 0 : subtotal, total: isLoyaltyRedemption ? 0 : (subtotal + totalVat), vat: isLoyaltyRedemption ? 0 : totalVat, orderType: orderType, tableNumber: (orderType === 'dine-in') ? currentTableName : null, date: new Date().toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }), paymentMethod: paymentTypeName || (isLoyaltyRedemption ? 'Loyalty Redeem' : 'Unpaid'), loyaltyRedeemed: isLoyaltyRedemption }; fetch('api/order.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) }) .then(res => res.json()) .then(data => { if (data.success) { receiptData.orderId = data.order_id; // Show receipt for both Quick Pay and Place Order printThermalReceipt(receiptData); showToast(`${_t('order_placed')} #${data.order_id}`, 'success'); clearCart(); if (paymentSelectionModal) paymentSelectionModal.hide(); if (clearCustomerBtn) clearCustomerBtn.click(); } else showToast(data.error, 'danger'); }); }; window.printThermalReceipt = function(data) { const width = 450; 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 thermal 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.variant_name ? `
(${item.variant_name})
` : ''}
${item.quantity} x ${formatCurrency(item.price)}
${item.vat_percent > 0 ? item.vat_percent + '%' : '-'} ${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 && data.orderType === 'dine-in' ? `
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 logoHtml = settings.logo_url ? `` : ''; const vatRate = settings.vat_rate || 0; const html = ` Receipt #${data.orderId}
${logoHtml}

${settings.company_name}

${CURRENT_OUTLET.name}
${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: ${CURRENT_USER.name}${tr['Staff']}: ${CURRENT_USER.name}
${tableHtml}${paymentHtml}${loyaltyHtml}
${customerHtml} ${itemsHtml}
ITEM / الصنف VAT / الضريبة TOTAL / المجموع
Subtotal / ${tr['Subtotal']}${formatCurrency(data.subtotal)}
VAT (${vatRate}%) / ${tr['VAT']}${formatCurrency(Math.abs(data.vat))}
TOTAL / ${tr['TOTAL']}${formatCurrency(data.total)}
`; win.document.write(html); win.document.close(); }; window.openRatingQRModal = function() { const qrContainer = document.getElementById('rating-qr-container'); const ratingUrl = BASE_URL + '/rate.php'; const qrCodeUrl = "https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=" + encodeURIComponent(ratingUrl); qrContainer.innerHTML = 'Rating QR Code'; const modal = new bootstrap.Modal(document.getElementById('qrRatingModal')); modal.show(); }; });