From 40fd435ffd66454558d6e63728fd700164f0e06c Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Thu, 7 May 2026 09:39:42 +0000 Subject: [PATCH] update pos --- index.php | 93 ++++++++--- pages/barcode_pos_script.php | 152 +++++++++++++++++- ...sales_purchases_invoice_actions_script.php | 35 ++-- 3 files changed, 243 insertions(+), 37 deletions(-) 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(, , '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 = ; + 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 = ; + } + + const restoreActionButtons = () => { + actionButtons.forEach(button => { + if (Object.prototype.hasOwnProperty.call(originalButtonHtml, button.id)) { + button.innerHTML = originalButtonHtml[button.id]; + } + button.disabled = false; + }); + }; + + const savedTitle = ; + const savedWithoutPrintText = ; + const savedWithoutPrintPrefix = ; + const okText = ; 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(, result.error, 'error'); - btn.disabled = false; - btn.innerText = originalText; + restoreActionButtons(); } } catch (err) { console.error(err); Swal.fire(, err.message || , '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 : ; @@ -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 = `
${sourceHtml || ''}
`; }; - function printPosReceipt() { - const content = document.getElementById('posReceiptContent').innerHTML; + window.printReceiptHtml = function(sourceHtml, options = {}) { + const rawHtml = (sourceHtml || '').trim(); + if (!rawHtml) { + return; + } + + const wrapper = document.createElement('div'); + wrapper.innerHTML = rawHtml; + + const receipt = wrapper.querySelector('.thermal-receipt'); + const receiptHtml = receipt ? receipt.outerHTML : `
${rawHtml}
`; + const docTitle = String(options.title || 'Receipt').replace(/[<>"']/g, ''); + const pageLang = document.documentElement.getAttribute('lang') || 'en'; + const pageDir = document.documentElement.getAttribute('dir') || (receipt && receipt.classList.contains('rtl') ? 'rtl' : 'ltr'); + + const iframe = document.createElement('iframe'); + iframe.setAttribute('aria-hidden', 'true'); + iframe.style.position = 'fixed'; + iframe.style.right = '0'; + iframe.style.bottom = '0'; + iframe.style.width = '0'; + iframe.style.height = '0'; + iframe.style.border = '0'; + document.body.appendChild(iframe); + + const frameDoc = iframe.contentWindow.document; + frameDoc.open(); + frameDoc.write(` + + + +${docTitle} + + +${receiptHtml} +`); + frameDoc.close(); + + setTimeout(() => { + iframe.contentWindow.focus(); + iframe.contentWindow.print(); + setTimeout(() => { + document.body.removeChild(iframe); + }, 2000); + }, 350); + }; + + window.printPosReceipt = function(options = {}) { + const contentEl = document.getElementById('posReceiptContent'); + if (!contentEl) { + return; + } + + const content = contentEl.innerHTML; + if (!(content || '').trim()) { + return; + } + + if (typeof window.printReceiptHtml === 'function') { + window.printReceiptHtml(content, { + title: options.title || + }); + return; + } + const printArea = document.getElementById('posPrintArea'); window.prepareReceiptPrintArea(content, printArea); - + document.body.classList.add('printing-receipt'); window.print(); document.body.classList.remove('printing-receipt'); - location.reload(); + if (printArea) { + printArea.innerHTML = ''; + } } diff --git a/pages/sales_purchases_invoice_actions_script.php b/pages/sales_purchases_invoice_actions_script.php index 3186161..f8127f8 100644 --- a/pages/sales_purchases_invoice_actions_script.php +++ b/pages/sales_purchases_invoice_actions_script.php @@ -200,27 +200,34 @@ setTimeout(() => { const receiptContent = document.getElementById('posReceiptContent'); - const printArea = document.getElementById('posPrintArea'); - - if (!receiptContent || !printArea) { + if (!receiptContent) { return; } - if (typeof window.prepareReceiptPrintArea === 'function') { - window.prepareReceiptPrintArea(receiptContent.innerHTML, printArea); + if (typeof window.printReceiptHtml === 'function') { + window.printReceiptHtml(receiptContent.innerHTML, { + title: data.document_no || data.transaction_no || 'Sale Receipt' + }); } else { - printArea.innerHTML = receiptContent.innerHTML; - const receipt = printArea.querySelector('.thermal-receipt'); - if (receipt) { - receipt.classList.add('thermal-receipt-print'); + const printArea = document.getElementById('posPrintArea'); + if (printArea) { + if (typeof window.prepareReceiptPrintArea === 'function') { + window.prepareReceiptPrintArea(receiptContent.innerHTML, printArea); + } else { + printArea.innerHTML = receiptContent.innerHTML; + const receipt = printArea.querySelector('.thermal-receipt'); + if (receipt) { + receipt.classList.add('thermal-receipt-print'); + } + } + + document.body.classList.add('printing-receipt'); + window.print(); + document.body.classList.remove('printing-receipt'); + printArea.innerHTML = ''; } } - document.body.classList.add('printing-receipt'); - window.print(); - document.body.classList.remove('printing-receipt'); - printArea.innerHTML = ''; - const receiptModalEl = document.getElementById('posReceiptModal'); const receiptModal = receiptModalEl ? bootstrap.Modal.getInstance(receiptModalEl) : null; if (receiptModal) {