| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| (function() { |
| 'use strict'; |
| console.log('[VAI EXPORT FIX] === LOADING ==='); |
|
|
| |
| function waitForLibs(cb, maxWait) { |
| var waited = 0; |
| var interval = 200; |
| maxWait = maxWait || 15000; |
| var timer = setInterval(function() { |
| waited += interval; |
| if (typeof ExcelJS !== 'undefined' && typeof html2canvas !== 'undefined' && typeof jspdf !== 'undefined') { |
| clearInterval(timer); |
| console.log('[VAI EXPORT FIX] All libraries loaded after ' + waited + 'ms'); |
| cb(); |
| } else if (waited >= maxWait) { |
| clearInterval(timer); |
| console.warn('[VAI EXPORT FIX] Libraries not fully loaded after ' + maxWait + 'ms, proceeding anyway'); |
| cb(); |
| } |
| }, interval); |
| } |
|
|
| |
| function overrideExportExcel() { |
| if (window.__vaiExportFixed) return; |
| window.__vaiExportFixed = true; |
|
|
| |
| var origExportExcel = window.exportExcel; |
|
|
| window.exportExcel = async function() { |
| console.log('[VAI EXPORT FIX] exportExcel called'); |
| |
| if (typeof ExcelJS === 'undefined') { |
| console.warn('[VAI EXPORT FIX] ExcelJS not loaded yet, waiting...'); |
| |
| return new Promise(function(resolve) { |
| var w = 0; |
| var t = setInterval(function() { |
| w += 200; |
| if (typeof ExcelJS !== 'undefined') { |
| clearInterval(t); |
| console.log('[VAI EXPORT FIX] ExcelJS loaded, retrying...'); |
| resolve(doExport()); |
| } |
| if (w >= 10000) { |
| clearInterval(t); |
| console.error('[VAI EXPORT FIX] ExcelJS timeout, using fallback'); |
| resolve(doFallbackExport()); |
| } |
| }, 200); |
| }); |
| } |
| |
| return doExport(); |
| }; |
|
|
| async function doExport() { |
| try { |
| |
| var d = null; |
| if (window.VAI_QR && typeof window.VAI_QR.getData === 'function') { |
| d = window.VAI_QR.getData(); |
| } else if (typeof getData === 'function') { |
| d = getData(); |
| } else if (typeof window.getQuoteData === 'function') { |
| var qd = window.getQuoteData(); |
| var parsed = { fees: [], notes: [], deposit: 0, discountPercent: 0, itemDiscounts: {} }; |
| d = { qd: qd, fees: [], notes: [], deposit: 0, discountPercent: 0, itemDiscounts: {}, grandTotal: qd.grandTotal || 0, remaining: qd.grandTotal || 0, productTotal: qd.grandTotal || 0 }; |
| } |
|
|
| if (!d || !d.qd) { |
| console.error('[VAI EXPORT FIX] No data available'); |
| alert('⚠️ Không có dữ liệu để xuất. Vui lòng thêm sản phẩm vào giỏ hàng.'); |
| return; |
| } |
|
|
| var code = (window.VAI_QR && typeof window.VAI_QR.getEffectiveOrderCode === 'function') |
| ? window.VAI_QR.getEffectiveOrderCode() : 'BAOGIA'; |
|
|
| var qrUrl = (window.VAI_QR && typeof window.VAI_QR.getQRUrl === 'function') |
| ? window.VAI_QR.getQRUrl(d.deposit > 0 ? d.remaining : d.grandTotal, code) : ''; |
|
|
| |
| if (typeof _doExportExcel === 'function') { |
| console.log('[VAI EXPORT FIX] Calling _doExportExcel directly'); |
| await _doExportExcel(d, d.qd, code, qrUrl); |
| console.log('[VAI EXPORT FIX] _doExportExcel completed'); |
| return; |
| } |
|
|
| |
| if (window.VAI_QR && typeof window.VAI_QR.exportExcel === 'function') { |
| console.log('[VAI EXPORT FIX] Calling VAI_QR.exportExcel'); |
| await window.VAI_QR.exportExcel(d, d.qd, code, qrUrl); |
| return; |
| } |
|
|
| |
| console.warn('[VAI EXPORT FIX] No export function found, using fallback'); |
| await doFallbackExport(); |
| } catch(e) { |
| console.error('[VAI EXPORT FIX] Export error:', e); |
| try { |
| await doFallbackExport(); |
| } catch(e2) { |
| console.error('[VAI EXPORT FIX] Fallback also failed:', e2); |
| alert('❌ Lỗi xuất Excel. Vui lòng thử lại sau.'); |
| } |
| } |
| } |
|
|
| async function doFallbackExport() { |
| console.log('[VAI EXPORT FIX] Using fallback HTML table export'); |
| var qd = null; |
| var code = 'BAOGIA'; |
| |
| try { |
| if (window.VAI_QR && typeof window.VAI_QR.getData === 'function') { |
| var d = window.VAI_QR.getData(); |
| qd = d.qd; |
| code = window.VAI_QR.getEffectiveOrderCode(); |
| } else if (typeof getQuoteData === 'function') { |
| qd = getQuoteData(); |
| } else if (typeof window.getQuoteData === 'function') { |
| qd = window.getQuoteData(); |
| } |
| } catch(e) { |
| qd = { customer: {}, items: [] }; |
| } |
|
|
| if (!qd) qd = { customer: {}, items: [] }; |
| if (!qd.items) qd.items = []; |
| if (!qd.customer) qd.customer = {}; |
|
|
| var html = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel">' |
| + '<head><meta charset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook>' |
| + '<x:ExcelWorksheets><x:ExcelWorksheet><x:Name>BaoGia</x:Name>' |
| + '<x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions>' |
| + '</x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head>' |
| + '<body><table border="1" cellpadding="4" cellspacing="0" style="font-family:Arial;font-size:12px">'; |
| html += '<tr><th colspan="7" style="font-size:18px;color:#db9815;background:#003f62;color:#fff;text-align:center">BẢNG BÁO GIÁ</th></tr>'; |
| html += '<tr><td colspan="2"><b>KH:</b> ' + (qd.customer.name || '') + '</td><td colspan="3"><b>Mã:</b> ' + code + '</td></tr>'; |
| html += '<tr style="background:#003f62;color:#fff"><th>STT</th><th>Tên SP</th><th>Mã</th><th>SL</th><th>Đơn giá</th><th>Giá CK</th><th>Thành tiền</th></tr>'; |
| |
| var total = 0; |
| (qd.items || []).forEach(function(it, i) { |
| var lineTotal = (it.discPrice || it.price || 0) * (it.qty || 1); |
| total += lineTotal; |
| html += '<tr>' |
| + '<td style="text-align:center">' + (it.stt || (i + 1)) + '</td>' |
| + '<td>' + (it.name || '') + '</td>' |
| + '<td style="text-align:center">' + (it.model || '') + '</td>' |
| + '<td style="text-align:center">' + (it.qty || 1) + '</td>' |
| + '<td style="text-align:right">' + Number(it.price || 0).toLocaleString('vi-VN') + 'đ</td>' |
| + '<td style="text-align:right">' + Number(it.discPrice || it.price || 0).toLocaleString('vi-VN') + 'đ</td>' |
| + '<td style="text-align:right">' + Number(lineTotal).toLocaleString('vi-VN') + 'đ</td>' |
| + '</tr>'; |
| }); |
| |
| html += '<tr style="font-weight:bold;background:#003f62;color:#fff">' |
| + '<td colspan="6" style="text-align:right">TỔNG CỘNG</td>' |
| + '<td style="text-align:right;color:#f0b840">' + Number(total).toLocaleString('vi-VN') + 'đ</td>' |
| + '</tr>'; |
| html += '</table></body></html>'; |
|
|
| var blob = new Blob([html], { type: 'application/vnd.ms-excel' }); |
| var url = URL.createObjectURL(blob); |
| var a = document.createElement('a'); |
| a.href = url; |
| a.download = code + '.xls'; |
| a.style.display = 'none'; |
| document.body.appendChild(a); |
| a.click(); |
| setTimeout(function() { |
| document.body.removeChild(a); |
| URL.revokeObjectURL(url); |
| }, 1000); |
| console.log('[VAI EXPORT FIX] Fallback download initiated: ' + code + '.xls'); |
| } |
| } |
|
|
| |
| function bindExcelButtons() { |
| document.querySelectorAll('button, a, [role="button"]').forEach(function(btn) { |
| var text = (btn.textContent || '').toLowerCase(); |
| var cls = (btn.className || '').toLowerCase(); |
| var id = (btn.id || '').toLowerCase(); |
|
|
| |
| var isExcel = (text.indexOf('excel') >= 0 || cls.indexOf('excel') >= 0 || id === 'od-xl') |
| && (text.indexOf('xuất') >= 0 || text.indexOf('export') >= 0 || cls.indexOf('quote-btn-excel') >= 0 || id === 'od-xl'); |
|
|
| if (!isExcel) return; |
| if (btn.dataset.vaiExportCaptureBound) return; |
| btn.dataset.vaiExportCaptureBound = 'true'; |
|
|
| console.log('[VAI EXPORT FIX] Binding Excel button:', (btn.textContent || '').trim()); |
|
|
| |
| btn.addEventListener('click', function(e) { |
| console.log('[VAI EXPORT FIX] Excel button clicked (capture phase)'); |
| e.stopImmediatePropagation(); |
| |
| |
| |
| if (typeof window.exportExcel === 'function') { |
| window.exportExcel(); |
| } else { |
| console.error('[VAI EXPORT FIX] window.exportExcel not available'); |
| alert('⚠️ Chức năng xuất chưa sẵn sàng. Vui lòng thử lại.'); |
| } |
| }, true); |
| }); |
| } |
|
|
| |
| var observer = new MutationObserver(function() { |
| bindExcelButtons(); |
| }); |
| observer.observe(document.body, { childList: true, subtree: true }); |
|
|
| |
| function init() { |
| console.log('[VAI EXPORT FIX] Initializing...'); |
| overrideExportExcel(); |
| bindExcelButtons(); |
| console.log('[VAI EXPORT FIX] ✅ Ready'); |
| } |
|
|
| waitForLibs(function() { |
| init(); |
| }); |
|
|
| |
| setInterval(function() { |
| bindExcelButtons(); |
| }, 2000); |
|
|
| console.log('[VAI EXPORT FIX] Module loaded'); |
| })(); |