diff --git a/index.php b/index.php index 66cdf7a..7aafa23 100644 --- a/index.php +++ b/index.php @@ -8332,6 +8332,11 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]); const paid = this.payments.reduce((sum, p) => sum + p.amount, 0); return total - paid; }, + setCompleteOrderButtonsDisabled(disabled) { + document.querySelectorAll('.pos-complete-order-btn').forEach(button => { + button.disabled = !!disabled; + }); + }, renderPayments() { const container = document.getElementById('paymentList'); const methodLabels = { @@ -8379,14 +8384,14 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]); if (remaining <= 0.0001 || currentInput >= remaining - 0.0001) { display.classList.remove('text-danger'); display.classList.add('text-success'); - document.getElementById('confirmPaymentBtn').disabled = false; + this.setCompleteOrderButtonsDisabled(false); } else { display.classList.remove('text-success'); display.classList.add('text-danger'); - document.getElementById('confirmPaymentBtn').disabled = true; + this.setCompleteOrderButtonsDisabled(true); } }, - async completeOrder() { + async completeOrder(autoPrint = true) { if (this.items.length === 0) { Swal.fire(= json_encode($lang === 'ar' ? 'خطأ' : 'Error', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>, = json_encode($lang === 'ar' ? 'السلة فارغة' : 'Cart is empty', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>, 'error'); return; @@ -8421,10 +8426,34 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]); return; } - const btn = document.getElementById('confirmPaymentBtn'); - const originalText = btn.innerText; - btn.disabled = true; - btn.innerText = = json_encode($lang === 'ar' ? 'جارٍ المعالجة...' : 'PROCESSING...', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; + const activeBtn = document.getElementById(autoPrint ? 'confirmPaymentPrintBtn' : 'confirmPaymentSaveBtn'); + const actionButtons = Array.from(document.querySelectorAll('.pos-complete-order-btn')); + const originalButtonHtml = actionButtons.reduce((carry, button) => { + carry[button.id] = button.innerHTML; + return carry; + }, {}); + + actionButtons.forEach(button => { + button.disabled = true; + }); + + if (activeBtn) { + activeBtn.innerText = = json_encode($lang === 'ar' ? 'جارٍ المعالجة...' : 'PROCESSING...', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; + } + + const restoreActionButtons = () => { + actionButtons.forEach(button => { + if (Object.prototype.hasOwnProperty.call(originalButtonHtml, button.id)) { + button.innerHTML = originalButtonHtml[button.id]; + } + button.disabled = false; + }); + }; + + const savedTitle = = json_encode($lang === 'ar' ? 'تم الحفظ' : 'Saved', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; + const savedWithoutPrintText = = json_encode($lang === 'ar' ? 'تم حفظ الفاتورة بدون طباعة' : 'Invoice saved without printing', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; + const savedWithoutPrintPrefix = = json_encode($lang === 'ar' ? 'تم حفظ الفاتورة بدون طباعة. الرقم:' : 'Invoice saved without printing. No:', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; + const okText = = json_encode($lang === 'ar' ? 'حسنًا' : 'OK', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; const subtotal = this.items.reduce((sum, item) => sum + (parseFloat(item.price) * item.qty), 0); const totalVat = this.items.reduce((sum, item) => { @@ -8465,22 +8494,34 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]); } if (result.success) { - const payModal = bootstrap.Modal.getInstance(document.getElementById('posPaymentModal')); + const payModalEl = document.getElementById('posPaymentModal'); + const payModal = payModalEl ? bootstrap.Modal.getInstance(payModalEl) : null; if (payModal) payModal.hide(); - this.showReceipt(result.invoice_id, discountAmount, loyaltyRedeemed, result.transaction_no); + + if (autoPrint) { + this.showReceipt(result.invoice_id, discountAmount, loyaltyRedeemed, result.transaction_no, true); + } else { + this.clear(); + Swal.fire({ + icon: 'success', + title: savedTitle, + text: result.transaction_no ? `${savedWithoutPrintPrefix} ${result.transaction_no}` : savedWithoutPrintText, + confirmButtonText: okText + }).then(() => { + location.reload(); + }); + } } else { Swal.fire(= json_encode($lang === 'ar' ? 'خطأ' : 'Error', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>, result.error, 'error'); - btn.disabled = false; - btn.innerText = originalText; + restoreActionButtons(); } } catch (err) { console.error(err); Swal.fire(= json_encode($lang === 'ar' ? 'خطأ' : 'Error', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>, err.message || = json_encode($lang === 'ar' ? 'حدث خطأ ما' : 'Something went wrong', JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>, 'error'); - btn.disabled = false; - btn.innerText = originalText; + restoreActionButtons(); } }, - showReceipt(invId, discountAmount, loyaltyRedeemed, transactionNo) { + showReceipt(invId, discountAmount, loyaltyRedeemed, transactionNo, autoPrint = false) { const container = document.getElementById('posReceiptContent'); const customerSelect = document.getElementById('posCustomer'); const customerName = (customerSelect && customerSelect.selectedIndex >= 0 && customerSelect.value !== '') ? customerSelect.options[customerSelect.selectedIndex].text : = json_encode(__('walk_in_customer'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; @@ -8589,14 +8630,23 @@ runtime_debug_mark('page:rendering', ['page' => (string)$page]); `; - const modal = new bootstrap.Modal(document.getElementById('posReceiptModal')); + const receiptModalEl = document.getElementById('posReceiptModal'); + const modal = bootstrap.Modal.getOrCreateInstance(receiptModalEl); modal.show(); this.clear(); - document.getElementById('posReceiptModal').addEventListener('hidden.bs.modal', function () { + receiptModalEl.addEventListener('hidden.bs.modal', function () { location.reload(); }, { once: true }); + + if (autoPrint) { + setTimeout(() => { + if (typeof window.printPosReceipt === 'function') { + window.printPosReceipt(); + } + }, 250); + } }, async syncCustomer(val) { @@ -12198,7 +12248,9 @@ document.addEventListener('DOMContentLoaded', function() { #posPaymentModal .form-control { font-size: 0.85rem; padding: 0.35rem 0.6rem; } #posPaymentModal .btn-primary { padding: 0.35rem 0.8rem; font-size: 0.85rem; } #posPaymentModal .modal-header { padding: 0.75rem 1rem 0.25rem; } - #posPaymentModal .modal-footer { padding: 0.25rem 1rem 0.75rem; } + #posPaymentModal .modal-footer { padding: 0.25rem 1rem 0.75rem; gap: 0.5rem; flex-wrap: wrap; } + #posPaymentModal .modal-footer .btn-light { min-width: 110px; } + #posPaymentModal .modal-footer .pos-complete-order-btn { flex: 1 1 180px; } @@ -12299,8 +12351,11 @@ document.addEventListener('DOMContentLoaded', function() {
diff --git a/pages/barcode_pos_script.php b/pages/barcode_pos_script.php index 35c6cf2..4b4305a 100644 --- a/pages/barcode_pos_script.php +++ b/pages/barcode_pos_script.php @@ -852,14 +852,158 @@ printArea.innerHTML = `