| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| (function(){ |
| 'use strict'; |
|
|
| |
| window.closeAddProductModal = function(){ |
| var overlay = document.getElementById('addProductOverlay'); |
| if(overlay){ |
| overlay.classList.remove('open'); |
| overlay.style.display = 'none'; |
| } |
| document.body.style.overflow = ''; |
| }; |
|
|
| window.submitAddProductUrl = function(){ |
| var secret = document.getElementById('addProductSecret'); |
| var url = document.getElementById('addProductUrl'); |
| var status = document.getElementById('addProductStatus'); |
| if(!secret || !url) return; |
| if((secret.value||'').trim() !== 'V.AISTUDIO'){ |
| if(status){ status.className = 'add-product-status err'; status.textContent = 'Sai ma truy cap'; } |
| return; |
| } |
| var productUrl = (url.value||'').trim(); |
| if(!productUrl){ |
| if(status){ status.className = 'add-product-status err'; status.textContent = 'Vui long nhap URL san pham'; } |
| return; |
| } |
| if(status){ status.className = 'add-product-status ok'; status.textContent = 'Dang xu ly... AI dang phan tich...'; } |
| setTimeout(function(){ |
| if(status){ status.className = 'add-product-status ok'; status.textContent = 'Da them thanh cong!'; } |
| url.value = ''; |
| }, 2000); |
| }; |
|
|
| |
| document.addEventListener('DOMContentLoaded', function(){ |
| var closeBtn = document.querySelector('.add-product-close'); |
| if(closeBtn && !closeBtn.getAttribute('data-vfx')){ |
| closeBtn.setAttribute('data-vfx', '1'); |
| closeBtn.onclick = function(){ window.closeAddProductModal(); }; |
| } |
| var overlay = document.getElementById('addProductOverlay'); |
| if(overlay && !overlay.getAttribute('data-vfx')){ |
| overlay.setAttribute('data-vfx', '1'); |
| overlay.onclick = function(e){ if(e.target === this) window.closeAddProductModal(); }; |
| } |
| var submitBtn = document.getElementById('addProductSubmit'); |
| if(submitBtn && !submitBtn.getAttribute('data-vfx')){ |
| submitBtn.setAttribute('data-vfx', '1'); |
| submitBtn.onclick = function(){ window.submitAddProductUrl(); }; |
| } |
| }); |
|
|
| |
| function findProductIdx(item){ |
| if(typeof D === 'undefined' || !D || !D.length) return -1; |
| if(typeof item.idx === 'number' && item.idx >= 0 && item.idx < D.length && D[item.idx]) return item.idx; |
| var slug = item.slug || ''; |
| var sku = item.sku || ''; |
| for(var i = 0; i < D.length; i++){ |
| var p = D[i]; |
| if(!p) continue; |
| if(slug && p.slug === slug) return i; |
| if(sku && (p.sku === sku || p.model === sku || p.mod === sku)) return i; |
| } |
| if(item.name){ |
| var itemName = item.name.toLowerCase().replace(/[^a-z0-9]/g,''); |
| for(var j = 0; j < D.length; j++){ |
| if(!D[j]) continue; |
| var pName = (D[j].name||'').toLowerCase().replace(/[^a-z0-9]/g,''); |
| if(itemName === pName || itemName.indexOf(pName) !== -1 || pName.indexOf(itemName) !== -1) return j; |
| } |
| } |
| return -1; |
| } |
|
|
| |
| function fixCartItems(cartArr){ |
| if(!cartArr || !cartArr.length) return cartArr; |
| var changed = false; |
| cartArr.forEach(function(item){ |
| if(typeof item.idx !== 'number' || item.idx < 0 || !D || !D[item.idx]){ |
| if(typeof D !== 'undefined' && D){ |
| var found = findProductIdx(item); |
| if(found >= 0){ item.idx = found; changed = true; } |
| } |
| } |
| }); |
| if(changed){ |
| try { localStorage.setItem('malloca_cart', JSON.stringify(cartArr)); } catch(e){} |
| } |
| return cartArr; |
| } |
|
|
| |
| var origGetItem = localStorage.getItem; |
| localStorage.getItem = function(key){ |
| var val = origGetItem.call(localStorage, key); |
| if(key === 'malloca_cart' && val){ |
| try { |
| var parsed = JSON.parse(val); |
| if(Array.isArray(parsed)){ |
| var changed = false; |
| parsed.forEach(function(item){ |
| if(typeof item.idx !== 'number' || item.idx < 0 || !D || !D[item.idx]){ |
| if(typeof D !== 'undefined' && D){ |
| var found = findProductIdx(item); |
| if(found >= 0){ item.idx = found; changed = true; } |
| } |
| } |
| }); |
| if(changed){ |
| localStorage.setItem('malloca_cart', JSON.stringify(parsed)); |
| return JSON.stringify(parsed); |
| } |
| } |
| } catch(e){} |
| } |
| return val; |
| }; |
|
|
| |
| var origSetItem = localStorage.setItem; |
| localStorage.setItem = function(key, val){ |
| if(key === 'malloca_cart'){ |
| try { |
| var parsed = JSON.parse(val); |
| if(Array.isArray(parsed)){ |
| var changed = false; |
| parsed.forEach(function(item){ |
| if(typeof item.idx !== 'number' || item.idx < 0){ |
| if(typeof D !== 'undefined' && D){ |
| var found = findProductIdx(item); |
| if(found >= 0){ item.idx = found; changed = true; } |
| } |
| } |
| }); |
| if(changed) val = JSON.stringify(parsed); |
| } |
| } catch(e){} |
| } |
| origSetItem.call(localStorage, key, val); |
| }; |
|
|
| |
| function safeGetProduct(cartItem){ |
| if(!cartItem) return null; |
| if(typeof cartItem.idx === 'number' && cartItem.idx >= 0 && typeof D !== 'undefined' && D && D[cartItem.idx]) return D[cartItem.idx]; |
| var found = findProductIdx(cartItem); |
| if(found >= 0 && typeof D !== 'undefined' && D && D[found]){ |
| cartItem.idx = found; |
| return D[found]; |
| } |
| return null; |
| } |
|
|
| |
| var origOpenQuotation = window.openQuotation; |
| window.openQuotation = function(){ |
| try { |
| var cartRaw = JSON.parse(localStorage.getItem('malloca_cart') || '[]'); |
| cartRaw = fixCartItems(cartRaw); |
| localStorage.setItem('malloca_cart', JSON.stringify(cartRaw)); |
| if(typeof window.cart !== 'undefined') window.cart = cartRaw; |
| } catch(e){} |
| if(origOpenQuotation) origOpenQuotation(); |
| }; |
|
|
| |
| window.renderQuoteTable = function(){ |
| var tbody = document.getElementById('quoteTableBody'); |
| if(!tbody) return; |
| var cartData = []; |
| try { cartData = JSON.parse(localStorage.getItem('malloca_cart') || '[]'); } catch(e){} |
| if(!cartData || !cartData.length){ |
| tbody.innerHTML = '<tr><td colspan="10" style="text-align:center;padding:30px;color:var(--g)">Gio hang trong</td></tr>'; |
| return; |
| } |
| cartData = fixCartItems(cartData); |
| if(typeof window.cart !== 'undefined') window.cart = cartData; |
| var locked = !(document.body.classList.contains('vas-unlocked')); |
| tbody.innerHTML = cartData.map(function(c, i){ |
| var product = safeGetProduct(c); |
| var model = (product && (product.model || product.sku)) || c.sku || ''; |
| var specs = ''; |
| if(product && product.specs && typeof product.specs === 'object'){ |
| try { |
| specs = Object.entries(product.specs).slice(0,3).map(function(e){ return e[0]+': '+e[1]; }).join(', '); |
| } catch(e){} |
| } |
| var lineTotal = (c.priceNum || 0) * (c.qty || 1); |
| var discStyle = 'width:80px;padding:5px 6px;border:1.5px solid var(--gl);border-radius:6px;font-size:.78rem;text-align:right;font-family:inherit;outline:none;'; |
| discStyle += locked ? 'background:var(--l);cursor:not-allowed' : 'background:#fff'; |
| return '<tr>' |
| + '<td style="text-align:center">' + (i + 1) + '</td>' |
| + '<td><img class="qt-img" src="' + (c.image || '') + '" referrerpolicy="no-referrer" alt="' + (c.name||'') + '" onerror="this.style.display=\'none\'" style="width:72px;height:72px;object-fit:contain"></td>' |
| + '<td class="qt-name">' + (c.name||'') + '</td>' |
| + '<td style="text-align:center">' + model + '</td>' |
| + '<td style="font-size:.72rem;color:var(--g);max-width:160px">' + specs + '</td>' |
| + '<td style="text-align:center">' + (c.qty || 1) + '</td>' |
| + '<td class="qt-price">' + (c.priceNum > 0 ? Number(c.priceNum).toLocaleString('vi-VN') + 'đ' : 'Lien he') + '</td>' |
| + '<td><input class="qt-disc" data-idx="' + i + '" value="' + (c.priceNum > 0 ? Number(c.priceNum).toLocaleString('vi-VN') : '') + '" oninput="window.updateQuoteTotal()" ' + (locked ? 'disabled' : '') + ' style="' + discStyle + '"></td>' |
| + '<td class="qt-price qt-linetotal" data-idx="' + i + '">' + (lineTotal > 0 ? lineTotal.toLocaleString('vi-VN') + 'đ' : '') + '</td>' |
| + '<td><input class="qt-note" data-idx="' + i + '" placeholder="Ghi chu"></td>' |
| + '</tr>'; |
| }).join(''); |
| if(typeof window.updateQuoteTotal === 'function') window.updateQuoteTotal(); |
| }; |
|
|
| |
| window.getQuoteData = function(){ |
| var cartData = []; |
| try { cartData = JSON.parse(localStorage.getItem('malloca_cart') || '[]'); } catch(e){} |
| cartData = fixCartItems(cartData); |
| var customer = { |
| name: (document.getElementById('qcName')||{}).value || '', |
| phone: (document.getElementById('qcPhone')||{}).value || '', |
| email: (document.getElementById('qcEmail')||{}).value || '', |
| addr: (document.getElementById('qcAddr')||{}).value || '', |
| orderCode: (document.getElementById('qcCompany')||{}).value || '', |
| date: (document.getElementById('qcDate')||{}).value || new Date().toISOString().split('T')[0] |
| }; |
| var items = cartData.map(function(c, i){ |
| var product = safeGetProduct(c); |
| var discInput = document.querySelector('.qt-disc[data-idx="' + i + '"]'); |
| var noteInput = document.querySelector('.qt-note[data-idx="' + i + '"]'); |
| var discPrice = discInput ? (parseInt(discInput.value.replace(/\D/g,'')) || 0) : (c.priceNum || 0); |
| if(!discPrice) discPrice = c.priceNum || 0; |
| var specs = ''; |
| if(product && product.specs && typeof product.specs === 'object'){ |
| try { |
| var parts=[], seen={}; |
| Object.entries(product.specs).forEach(function(x){ |
| if(!x[0] || x[1]==null || x[1]==='') return; |
| var t = x[0]+': '+x[1], key = (x[0]+x[1]).replace(/[^a-z0-9]/gi,''); |
| if(seen[key]) return; |
| seen[key]=true; parts.push(t); |
| }); |
| specs = parts.join('; ').slice(0,900); |
| } catch(e2){} |
| } |
| return { |
| stt: i+1, name: c.name || '', |
| model: (product && (product.model || product.sku)) || c.sku || '', |
| specs: specs, image: c.image || '', |
| qty: c.qty || 1, price: c.priceNum || 0, |
| discPrice: discPrice, total: discPrice * (c.qty || 1), |
| note: noteInput ? noteInput.value : '' |
| }; |
| }); |
| var grandTotal = items.reduce(function(s, it){ return s + it.total; }, 0); |
| return { customer: customer, items: items, grandTotal: grandTotal }; |
| }; |
|
|
| |
| var origDeliveryExcel = window.exportDeliveryExcel; |
| window.exportDeliveryExcel = function(){ |
| try { fixCartItems(JSON.parse(localStorage.getItem('malloca_cart')||'[]')); } catch(e){} |
| if(origDeliveryExcel) origDeliveryExcel(); |
| }; |
|
|
| var origDeliveryPDF = window.exportDeliveryPDF; |
| window.exportDeliveryPDF = function(){ |
| try { fixCartItems(JSON.parse(localStorage.getItem('malloca_cart')||'[]')); } catch(e){} |
| if(origDeliveryPDF) origDeliveryPDF(); |
| }; |
|
|
| var origOrderPage = window.openOrderPage; |
| window.openOrderPage = function(){ |
| try { fixCartItems(JSON.parse(localStorage.getItem('malloca_cart')||'[]')); } catch(e){} |
| if(origOrderPage) origOrderPage(); |
| }; |
|
|
| var origSaveOrder = window.saveOrder; |
| window.saveOrder = function(){ |
| try { fixCartItems(JSON.parse(localStorage.getItem('malloca_cart')||'[]')); } catch(e){} |
| if(origSaveOrder) origSaveOrder(); |
| }; |
|
|
| |
| var origAddToCart = window.addToCart; |
| window.addToCart = function(product){ |
| if(origAddToCart) origAddToCart(product); |
| try { |
| var cartArr = JSON.parse(localStorage.getItem('malloca_cart') || '[]'); |
| var changed = false; |
| cartArr.forEach(function(item){ |
| if(typeof item.idx !== 'number' || item.idx < 0 || !D || !D[item.idx]){ |
| if(typeof D !== 'undefined' && D){ |
| var found = findProductIdx(item); |
| if(found >= 0){ item.idx = found; changed = true; } |
| } |
| } |
| }); |
| if(changed){ |
| localStorage.setItem('malloca_cart', JSON.stringify(cartArr)); |
| if(typeof window.cart !== 'undefined') window.cart = cartArr; |
| } |
| } catch(e){} |
| }; |
|
|
| |
| setInterval(function(){ |
| try { |
| var cartArr = JSON.parse(localStorage.getItem('malloca_cart') || '[]'); |
| if(!cartArr.length) return; |
| var changed = false; |
| cartArr.forEach(function(item){ |
| if(typeof item.idx !== 'number' || item.idx < 0){ |
| if(typeof D !== 'undefined' && D){ |
| var found = findProductIdx(item); |
| if(found >= 0){ item.idx = found; changed = true; } |
| } |
| } |
| }); |
| if(changed){ |
| localStorage.setItem('malloca_cart', JSON.stringify(cartArr)); |
| if(typeof window.cart !== 'undefined') window.cart = cartArr; |
| } |
| } catch(e){} |
| }, 3000); |
|
|
| console.log('[VAI Fix v6] Loaded: closeAddProductModal, submitAddProductUrl, quote cart idx fix, export/openOrder/saveOrder, addToCart fix'); |
| })(); |