V.AISTUDIO2 / triple-bug-fix.js
bep40's picture
Upload triple-bug-fix.js
48a06db verified
Raw
History Blame Contribute Delete
6.86 kB
/**
* 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);
}
})();