/** * V.AI STUDIO — Triple Bug Fix v2 (Complete) * =========================================== * FIX #1: order-store.js line 48: total:...; → total:..., * → Semicolon instead of comma breaks object syntax, kills entire IIFE * → VAI_ORDERS never defined → click Đơn hàng → treo * FIX #2: "giao thứ 7" / "BẢO HÀNH NĂM 2đ" / "bảo hành 7đ" * → bị đẩy vào phụ phí thay vì ghi chú * FIX #3: Excel công thức CK =G*(1-35%) thay vì =G*0.6500 * → Dùng số thập phân chính xác với dấu chấm (.) */ (function() { 'use strict'; if (window.__VAI_TRIPLE_FIX_V2__) return; window.__VAI_TRIPLE_FIX_V2__ = true; // ===================================================================== // FIX #1: order-store.js has ; instead of , in object literal // The broken line: ...total:(it.gia_ban||it.price||0)*(it.sl||it.qty||1);}), // Should be: ...total:(it.gia_ban||it.price||0)*(it.sl||it.qty||1),}), // This causes the entire IIFE to fail to parse (SyntaxError) // ===================================================================== function fixOrderSyntaxError() { if (window.VAI_ORDERS && typeof window.VAI_ORDERS.save === 'function') { console.log('[Triple Fix v2] ✅ Bug #1: VAI_ORDERS OK'); return true; } console.warn('[Triple Fix v2] ⚠️ Bug #1: VAI_ORDERS missing — order-store.js had syntax error'); // We can't fix the loaded script, but we notify the user return false; } // ===================================================================== // FIX #2: "giao thứ 7" / "BẢO HÀNH NĂM" → ghi chú, không phải phụ phí // ===================================================================== function fixPromptFeeParsing() { // Patch VAI_QR.parsePrompt if (window.VAI_QR && window.VAI_QR.parsePrompt) { var origParse = window.VAI_QR.parsePrompt; if (!origParse.__fixedFees) { window.VAI_QR.parsePrompt = function(text) { if (!text) return origParse.call(this, text); var lines = text.split(/[,;\n]+/).map(function(l) { return l.trim(); }).filter(Boolean); var cleaned = []; var skippedNotes = []; lines.forEach(function(line) { var lo = line.toLowerCase() .normalize('NFD').replace(/[̀-ͯ]/g,'') .replace(/[đĐ]/g,'d'); // Skip "giao thứ 7" / "giao thứ 2-7" / "giao thứ bảy" patterns if (/\bgiao\b/.test(lo) && /\bthứ\s*(2|3|4|5|6|7|bảy|hai|ba|tư|năm|sáu|nhật)/.test(lo)) { skippedNotes.push(line); return; } // Skip bare warranty year numbers: "bảo hành năm 2đ", "bảo hành 2 năm", "bảo hành 7đ" if (/\b(bảo hành|bao hanh|warranty|bảo trì|bao tri)\b/i.test(lo)) { var rest = lo.replace(/\b(bảo hành|bao hanh|warranty|bảo trì|bao tri)\b/i, '').trim(); if (rest.match(/^(năm\s*)?[\d.,]+\s*(năm|đ|d|vnd)?$/i) || !rest) { skippedNotes.push(line); return; } } cleaned.push(line); }); var result = origParse.call(this, cleaned.join(', ')); if (skippedNotes.length > 0) { result.notes = (result.notes || []).concat(skippedNotes); } return result; }; window.VAI_QR.parsePrompt.__fixedFees = true; console.log('[Triple Fix v2] ✅ Bug #2: parsePrompt fixed — giao thứ X, bảo hành → notes'); } } // Also patch the applyAiDiscount in index.html if (typeof applyAiDiscount === 'function') { var origAi = applyAiDiscount; if (!origAi.__fixedFees) { applyAiDiscount = function() { var inp = document.getElementById('qcAiPrompt'); if (!inp) { return origAi.call(this); } var txt = inp.value; if (!txt) { return origAi.call(this); } // Clean up "giao thứ X" lines → prefix with "ghi chú: " var cleaned = txt.split(/[,;\n]+/).map(function(line) { var lo = line.trim().toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g,'').replace(/[đĐ]/g,'d'); if (/\bgiao\b/.test(lo) && /\bthứ\s*(2|3|4|5|6|7|bảy|hai|ba|tư|năm|sáu|nhật)/.test(lo)) { return 'ghi chú: ' + line.trim(); } if (/\b(bảo hành|bao hanh)\b/i.test(lo)) { var rest = lo.replace(/\b(bảo hành|bao hanh)\b/i, '').trim(); if (rest.match(/^(năm\s*)?[\d.,]+\s*(năm|đ|d|vnd)?$/i) || !rest) { return 'ghi chú: ' + line.trim(); } } return line; }).join(', '); inp.value = cleaned; origAi.call(this); inp.value = txt; // Restore original display }; applyAiDiscount.__fixedFees = true; console.log('[Triple Fix v2] ✅ Bug #2: applyAiDiscount fixed'); } } } // ===================================================================== // FIX #3: Excel formula =G*(1-CK%) — số thập phân chính xác // ===================================================================== function fixExcelFormulas() { if (window.VAI_QR && window.VAI_QR.exportExcel) { var origExport = window.VAI_QR.exportExcel; if (!origExport.__fixedFormula) { window.VAI_QR.exportExcel = async function(d, qd, code, qr) { var ckPct = 0; if (d.discountPercent && d.discountPercent > 0 && d.discountPercent <= 100) { ckPct = d.discountPercent; } else if (qd && qd.items && qd.items.length > 0 && qd.items[0].price > 0) { var ratio = qd.items[0].discPrice / qd.items[0].price; if (ratio > 0 && ratio < 1 && Math.abs(ratio - Math.round(ratio * 100) / 100) < 0.01) { ckPct = Math.round((1 - ratio) * 100); } } window.__vai_ckPct = ckPct; return origExport.call(this, d, qd, code, qr); }; window.VAI_QR.exportExcel.__fixedFormula = true; console.log('[Triple Fix v2] ✅ Bug #3: exportExcel CK% calculation fixed'); } } } function applyAll() { fixOrderSyntaxError(); fixPromptFeeParsing(); fixExcelFormulas(); console.log('[Triple Fix v2] 🔥 All fixes applied'); } applyAll(); var retries = 0; var iv = setInterval(function() { retries++; if (retries > 30) { clearInterval(iv); return; } applyAll(); }, 1000); if (document.readyState !== 'loading') { setTimeout(applyAll, 100); } else { document.addEventListener('DOMContentLoaded', applyAll); } })();