Spaces:
Running
Running
File size: 6,863 Bytes
099053f 48a06db 099053f 48a06db 099053f 48a06db 099053f 48a06db 099053f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | /**
* 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);
}
})(); |