| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| (function() { |
| 'use strict'; |
| |
| |
| function initPatch() { |
| if (typeof window.VAI_QR === 'undefined') { |
| setTimeout(initPatch, 500); |
| return; |
| } |
| |
| |
| var origExportDE = window.exportDeliveryExcel; |
| var origExportDP = window.exportDeliveryPDF; |
| |
| |
| function orderToVAIData(order) { |
| if (!order || !order.items) return null; |
| return { |
| qd: { |
| customer: { |
| name: order.customer || '', |
| phone: order.phone || '', |
| email: order.email || '', |
| addr: order.addr || '', |
| date: order.date || '' |
| }, |
| items: (order.items || []).map(function(it, i) { |
| return { |
| stt: i + 1, |
| image: it.image || '', |
| name: it.name || '', |
| model: it.model || '', |
| specs: it.specs || it.info || '', |
| qty: it.qty || 1, |
| price: it.price || it.listPrice || it.discPrice || 0, |
| discPrice: it.discPrice || it.price || 0, |
| total: it.total || 0, |
| note: it.note || '' |
| }; |
| }), |
| grandTotal: order.grandTotal || 0 |
| } |
| }; |
| } |
| |
| |
| var activeExportBtn = null; |
| |
| function setBtnState(btn, exporting) { |
| if (!btn) return; |
| if (exporting) { |
| btn.disabled = true; |
| btn.dataset.vaiExporting = '1'; |
| btn._origHtml = btn.innerHTML; |
| btn.innerHTML = '<span style="opacity:0.7">⏳</span>'; |
| } else { |
| btn.disabled = false; |
| btn.dataset.vaiExporting = '0'; |
| if (btn._origHtml) btn.innerHTML = btn._origHtml; |
| } |
| } |
| |
| |
| window.exportDeliveryExcel = async function(order, opt) { |
| var btn = document.activeElement; |
| if (btn && btn.dataset.vaiExporting === '1') { |
| console.log('[AutoPatch] Already exporting, ignoring...'); |
| return; |
| } |
| if (btn) setBtnState(btn, true); |
| |
| try { |
| |
| if (order && order.items && order.items.length) { |
| var vaData = orderToVAIData(order); |
| var code = order.code || 'GH-' + Date.now(); |
| |
| |
| if (window.VAI_QR && window.VAI_QR._doExportDeliveryExcel) { |
| await window.VAI_QR._doExportDeliveryExcel(vaData.qd, code); |
| console.log('[AutoPatch] GH Excel done for order: ' + code); |
| return; |
| } |
| |
| |
| if (window.VAI_QR && window.VAI_QR.buildDeliveryHTML) { |
| let html = window.VAI_QR.buildDeliveryHTML(vaData.qd, code); |
| let div = document.createElement('div'); |
| div.style.cssText = 'position:absolute;left:-9999px;top:0;width:700px;background:#fff;padding:28px'; |
| div.innerHTML = html; |
| document.body.appendChild(div); |
| |
| await new Promise(r => setTimeout(r, 300)); |
| |
| if (window.ExcelJS) { |
| let wb = new ExcelJS.Workbook(); |
| let ws = wb.addWorksheet('Giao hàng'); |
| ws.views = [{showGridLines: false}]; |
| ws.columns = [{width: 5}, {width: 34}, {width: 14}, {width: 8}, {width: 20}]; |
| |
| ws.getCell('A1').value = 'PHIẾU GIAO HÀNG'; |
| ws.getCell('A2').value = 'KH: ' + (vaData.qd.customer.name || ''); |
| ws.getCell('D2').value = 'Mã: ' + code; |
| ws.getCell('A3').value = 'SĐT: ' + (vaData.qd.customer.phone || ''); |
| ws.getCell('A4').value = 'Địa chỉ: ' + (vaData.qd.customer.addr || ''); |
| |
| let headerRow = ws.getRow(6); |
| ['STT', 'Tên sản phẩm', 'Mã SP', 'SL', 'Ghi chú'].forEach(function(h, i) { |
| let c = headerRow.getCell(i + 1); |
| c.value = h; |
| c.fill = {type: 'pattern', pattern: 'solid', fgColor: {argb: 'FF003F62'}}; |
| c.font = {bold: true, color: {argb: 'FFFFFFFF'}}; |
| }); |
| |
| let cr = 7; |
| (vaData.qd.items || []).forEach(function(it) { |
| let row = ws.getRow(cr); |
| row.getCell(1).value = it.stt; |
| row.getCell(2).value = it.name; |
| row.getCell(3).value = it.model; |
| row.getCell(4).value = it.qty; |
| row.getCell(5).value = it.note; |
| cr++; |
| }); |
| |
| let buf = await wb.xlsx.writeBuffer(); |
| let blob = new Blob([buf], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}); |
| let url = URL.createObjectURL(blob); |
| let a = document.createElement('a'); |
| a.href = url; |
| a.download = 'GH-' + code + '.xlsx'; |
| a.click(); |
| |
| setTimeout(() => URL.revokeObjectURL(url), 300000); |
| } |
| div.remove(); |
| return; |
| } |
| } |
| |
| |
| if (origExportDE) { |
| await origExportDE.call(this, order, opt); |
| } |
| } catch (e) { |
| console.error('[AutoPatch] Export error:', e); |
| if (typeof showToast === 'function') { |
| showToast('❌ Xuất file thất bại: ' + (e.message || e)); |
| } |
| } finally { |
| setTimeout(() => { if (btn) setBtnState(btn, false); }, 1000); |
| } |
| }; |
| |
| |
| window.exportDeliveryPDF = async function(order, opt) { |
| var btn = document.activeElement; |
| if (btn && btn.dataset.vaiExporting === '1') { |
| console.log('[AutoPatch] Already exporting, ignoring...'); |
| return; |
| } |
| if (btn) setBtnState(btn, true); |
| |
| try { |
| if (order && order.items && order.items.length) { |
| var vaData = orderToVAIData(order); |
| var code = order.code || 'GH-' + Date.now(); |
| |
| if (window.VAI_QR && window.VAI_QR._doExportDeliveryPDF) { |
| await window.VAI_QR._doExportDeliveryPDF(vaData.qd, code); |
| console.log('[AutoPatch] GH PDF done for order: ' + code); |
| return; |
| } |
| |
| if (window.VAI_QR && window.VAI_QR.buildDeliveryHTML) { |
| let html = window.VAI_QR.buildDeliveryHTML(vaData.qd, code); |
| let div = document.createElement('div'); |
| div.style.cssText = 'position:absolute;left:-9999px;top:0;width:700px;background:#fff;padding:28px'; |
| div.innerHTML = html; |
| document.body.appendChild(div); |
| |
| await new Promise(r => setTimeout(r, 300)); |
| |
| if (window.html2canvas && window.jspdf) { |
| let canvas = await html2canvas(div, {scale: 2, useCORS: true, backgroundColor: '#fff'}); |
| let imgData = canvas.toDataURL('image/png'); |
| let {jsPDF} = window.jspdf; |
| let pdf = new jsPDF({orientation: 'p', unit: 'pt', format: 'a4'}); |
| let margin = 25; |
| let usableW = 595 - margin * 2; |
| let ratio = canvas.height / canvas.width; |
| let imgH = usableW * ratio; |
| pdf.addImage(imgData, 'PNG', margin, margin, usableW, imgH > 842 - margin * 2 ? 842 - margin * 2 : imgH); |
| pdf.save('GH-' + code + '.pdf'); |
| } |
| div.remove(); |
| return; |
| } |
| } |
| |
| if (origExportDP) { |
| await origExportDP.call(this, order, opt); |
| } |
| } catch (e) { |
| console.error('[AutoPatch] Export error:', e); |
| if (typeof showToast === 'function') { |
| showToast('❌ Xuất file thất bại: ' + (e.message || e)); |
| } |
| } finally { |
| setTimeout(() => { if (btn) setBtnState(btn, false); }, 1000); |
| } |
| }; |
| |
| console.log('[AutoPatch v1046] GH Excel/PDF patched - ready!'); |
| } |
| |
| |
| if (document.readyState === 'loading') { |
| document.addEventListener('DOMContentLoaded', initPatch); |
| } else { |
| initPatch(); |
| } |
| |
| setTimeout(initPatch, 2000); |
| setTimeout(initPatch, 5000); |
| |
| })(); |