bep40 commited on
Commit
6ae06e8
·
verified ·
1 Parent(s): ffd1a8d

v1040: Fixed getData orderCode, click handler fallback

Browse files
Files changed (1) hide show
  1. qr-payment-v1040.js +118 -0
qr-payment-v1040.js ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* V.AI STUDIO — QR Payment v1040 - FIXED: getData returns customer.orderCode, click handler fallback */
2
+ (function(){
3
+ 'use strict';
4
+ var BANK_ID='vib',BANK_ACCOUNT='918258385',BANK_NAME='TRAN QUOC VUONG',BANK_NAME_VN='Trần Quốc Vương';
5
+ function stripDiacritics(s){return s.normalize('NFD').replace(/[\u0300-\u036f]/g,'').replace(/[Đđ]/g,'D');}
6
+ function generateOrderCode(name){var now=new Date(),dd=String(now.getDate()).padStart(2,'0'),mm=String(now.getMonth()+1).padStart(2,'0'),yy=String(now.getFullYear()).slice(-2),ini='';if(name&&name.trim()){name.trim().split(/\s+/).forEach(function(w){if(w){var ch=stripDiacritics(w.charAt(0)).toUpperCase();if(/[A-Z]/.test(ch))ini+=ch;}});}return 'VAS'+(ini||'X')+dd+mm+yy;}
7
+ function getCustomerName(){var sels=['#quoteName','#quoteCustomerName','#checkoutName','.quote-field input:first-of-type'];for(var i=0;i<sels.length;i++){var el=document.querySelector(sels[i]);if(el&&el.value&&el.value.trim().length>1)return el.value.trim();}return '';}
8
+ function getEffectiveOrderCode(){var n=getCustomerName();if(n)return generateOrderCode(n);var h=window.location.hash;if(h&&h.length>1){var c=h.substring(1);if(/^VAS[A-Z0-9]{3,}$/.test(c))return c;}return generateOrderCode('');}
9
+ function getQRUrl(a,c){return 'https://img.vietqr.io/image/'+BANK_ID+'-'+BANK_ACCOUNT+'-compact2.png?amount='+(Math.round(a)||0)+'&addInfo='+encodeURIComponent(c||'VAISTUDIO')+'&accountName='+encodeURIComponent(BANK_NAME);}
10
+ function fmt(n){if(!n||isNaN(n))return '0đ';return Number(n).toLocaleString('vi-VN')+'đ';}
11
+ function compactKey(s){return stripDiacritics(String(s||'')).toLowerCase().replace(/[^a-z0-9]/g,'');}
12
+ function itemKeys(it){var arr=[];['model','sku','code','ma','name'].forEach(function(k){if(it&&it[k])arr.push(compactKey(it[k]));});if(it&&it.name){String(it.name).split('|').forEach(function(x){arr.push(compactKey(x));});}return arr.filter(function(x){return x&&x.length>=3;});}
13
+ function matchItemDiscount(it,itemDiscounts){itemDiscounts=itemDiscounts||{};var keys=itemKeys(it);for(var i=0;i<keys.length;i++){var k=keys[i];if(itemDiscounts[k])return itemDiscounts[k];}for(var code in itemDiscounts){for(var j=0;j<keys.length;j++){var kk=keys[j];if(code.length>=3&&kk.length>=3&&(kk.indexOf(code)!==-1||code.indexOf(kk)!==-1))return itemDiscounts[code];}}return 0;}
14
+ function parseItemDiscountLine(line,map){var lo=stripDiacritics(String(line||'')).toLowerCase();var re1=/\b([a-z]{1,8}[a-z0-9._\-\/]{1,30}\d[a-z0-9._\-\/]*)\b\s*(?:[:=\-]|\s+)?\s*(?:ck|chiet\s*khau|giam|discount)\s*([\d.,]+)\s*%?/gi;var re2=/(?:ck|chiet\s*khau|giam|discount)\s*\b([a-z]{1,8}[a-z0-9._\-\/]{1,30}\d[a-z0-9._\-\/]*)\b\s*([\d.,]+)\s*%?/gi;var m;while((m=re1.exec(lo))!==null){var v=parseFloat(m[2].replace(/\./g,'').replace(',','.'));if(v>0&&v<=100)map[compactKey(m[1])]=v;}while((m=re2.exec(lo))!==null){var v2=parseFloat(m[2].replace(/\./g,'').replace(',','.'));if(v2>0&&v2<=100)map[compactKey(m[1])]=v2;}}
15
+ function applyPromptDiscounts(qd,parsed){if(!qd||!qd.items)return qd;var productTotal=0;var itemDiscounts=(parsed&&parsed.itemDiscounts)||{};var globalPct=Number((parsed&&parsed.discountPercent)||0);qd.items.forEach(function(it){var base=Number(it.price||0),qty=Number(it.qty||1);var pct=matchItemDiscount(it,itemDiscounts);if(pct>0){it.discPrice=Math.round(base*(1-pct/100));it.discountPercent=pct;}else if(globalPct>0&&globalPct<=100){it.discPrice=Math.round(base*(1-globalPct/100));it.discountPercent=globalPct;}else if(!it.discPrice){it.discPrice=base;}it.total=Number(it.discPrice||base)*qty;productTotal+=Number(it.total||0);});qd.grandTotal=productTotal;return qd;}
16
+
17
+ function parsePrompt(text){
18
+ var fees=[],notes=[],discount=null,deposit=0,discountPercent=0,itemDiscounts={};
19
+ if(!text)return{fees:fees,notes:notes,discount:discount,deposit:deposit,discountPercent:discountPercent,itemDiscounts:itemDiscounts};
20
+ text.split(/[,;\n]+/).forEach(function(line){
21
+ line=line.trim();if(!line)return;
22
+ parseItemDiscountLine(line,itemDiscounts);
23
+ if(Object.keys(itemDiscounts).length&&line.match(/\b[A-Za-z]{1,8}[A-Za-z0-9._\-\/]{1,30}\d[A-Za-z0-9._\-\/]*\b/i)&&line.match(/\b(ck|chiết khấu|chiet khau|giảm|giam|discount)\b/i))return;
24
+ if(line.match(/^(ck|chiết khấu|chiet khau|giảm|giam|discount)/i)){discount=line;var ckm=line.match(/([\d.,]+)\s*(%)?/);if(ckm){var v=parseFloat(ckm[1].replace(/\./g,'').replace(',','.'));if(v>0&&v<=100)discountPercent=v;}return;}
25
+ if(line.match(/cọc|coc|deposit/i)){var dm=line.match(/([\d.,]+)\s*(k|K|nghìn|nghin|triệu|tr|đ|d|vnd)?/i);if(dm){var da=parseFloat(dm[1].replace(/\./g,'').replace(',','.'));var du=(dm[2]||'').toLowerCase();if(du==='k'||du==='nghìn'||du==='nghin')da*=1000;if(du==='triệu'||du==='tr'||du==='đ'||du==='d'||du==='vnd')da*=1;deposit=da;}return;}
26
+ var m=line.match(/([\d.,]+)\s*(k|K|nghìn|nghin|triệu|tr|đ|d|vnd)?/i);
27
+ if(m){var amt=parseFloat(m[1].replace(/\./g,'').replace(',','.'));var u=(m[2]||'').toLowerCase();
28
+ if(u==='k'||u==='nghìn'||u==='nghin')amt*=1000;
29
+ else if(u==='triệu'||u==='tr')amt*=1000000;
30
+ if(amt<1000)return;
31
+ var lb=line.replace(m[0],'').trim();
32
+ if(lb.match(/giao|ship|vận chuyển|delivery/i))lb='Phí giao hàng';
33
+ else if(lb.match(/lắp|lap|install/i))lb='Phí lắp đặt';
34
+ else if(lb.match(/bốc|boc|xếp|xep|vác/i))lb='Phí bốc xếp';
35
+ else if(!lb||lb.length<2)lb='Phụ phí';
36
+ fees.push({label:lb,amount:amt});}
37
+ else{notes.push(line);}
38
+ });
39
+ return{fees:fees,notes:notes,discount:discount,deposit:deposit,discountPercent:discountPercent,itemDiscounts:itemDiscounts};
40
+ }
41
+
42
+ var _lastPromptText='';
43
+ function getPromptText(){
44
+ var direct=document.getElementById('qcAiPrompt');
45
+ if(direct){var dv=(direct.value||'').trim();if(dv&&dv.toUpperCase().replace(/[\s.]/g,'')!=='VAISTUDIO'){_lastPromptText=dv;return dv;}}
46
+ var inputs=document.querySelectorAll('input,textarea');
47
+ for(var j=0;j<inputs.length;j++){var ph=(inputs[j].placeholder||'').toLowerCase();if(ph.includes('yêu cầu')||ph.includes('chiết khấu')||ph.includes('yeu cau')||ph.includes('chiet khau')||ph.includes('ck')||ph.includes('giao hàng')){var val=(inputs[j].value||'').trim();if(!val||val.toUpperCase().replace(/[\s.]/g,'')==='VAISTUDIO')continue;_lastPromptText=val;return val;}}
48
+ return _lastPromptText;
49
+ }
50
+
51
+ function getData(){
52
+ var qd=window._origGetQuoteData?window._origGetQuoteData():(typeof getQuoteData==='function'?getQuoteData():null);
53
+ if(!qd){console.warn('[qr-payment] getQuoteData not ready');return null;}
54
+ if(qd.customer){qd.customer.orderCode=getEffectiveOrderCode();}
55
+ var parsed=parsePrompt(getPromptText());
56
+ qd=applyPromptDiscounts(qd,parsed);
57
+ if(qd&&qd.items){qd.items.forEach(function(it){if(!it.specs||String(it.specs).length<40){var idx=(it.idx!=null?it.idx:(it.productIdx!=null?it.productIdx:null));var p=(idx!=null&&window.D)?window.D[idx]:null;if(!p&&window.D){var ck=compactKey(it.model||it.sku||it.ma||it.name||'');p=(window.D||[]).find(function(x){return compactKey(x.model||x.sku||x.name||'').indexOf(ck)>=0||ck.indexOf(compactKey(x.model||x.sku||''))>=0;});}it.specs=it.specs||'';}});}
58
+ var surcharge=0;parsed.fees.forEach(function(f){surcharge+=f.amount;});
59
+ var grandTotal=(qd.grandTotal||0)+surcharge;
60
+ var remaining=grandTotal-parsed.deposit;
61
+ return {qd:qd,fees:parsed.fees,notes:parsed.notes,discount:parsed.discount,discountPercent:parsed.discountPercent,itemDiscounts:parsed.itemDiscounts||{},deposit:parsed.deposit,productTotal:qd.grandTotal||0,grandTotal:grandTotal,remaining:remaining>0?remaining:0,orderCode:getEffectiveOrderCode()};
62
+ }
63
+
64
+ // Export toàn bộ để click handler gọi trực tiếp
65
+ function _doExportExcel(d,qd,code,qr){
66
+ var MONEY_FMT='#,##0"đ"';var NUM_FMT='#,##0';
67
+ var wb=new ExcelJS.Workbook(),ws=wb.addWorksheet('Báo giá');
68
+ ws.views=[{showGridLines:false}];ws.columns=[{width:5},{width:11},{width:28},{width:13},{width:20},{width:6},{width:13},{width:13},{width:15},{width:14}];
69
+ try{var lr=await fetch('https://huggingface.co/spaces/bep40/V.AISTUDIO/resolve/main/logo/logo_200.png',{mode:'cors'});if(lr.ok){var lb=await lr.arrayBuffer();ws.addImage(wb.addImage({buffer:lb,extension:'png'}),{tl:{col:0,row:0},ext:{width:40,height:40}});}}catch(e){}
70
+ ws.mergeCells('B1:J1');ws.getCell('B1').value='BÁO GIÁ'.ws.getCell('B1').font={size:9};
71
+ var cr=11,firstItemRow=cr,ckPct=Number(d.discountPercent||0);
72
+ for(var i=0;i<qd.items.length;i++){
73
+ var it=qd.items[i],row=ws.getRow(cr);var bgColor=i%2===0?'FFF8FAFC':'FFFFFFFF';
74
+ row.getCell(1).value=it.stt||i+1;row.getCell(6).value=Number(it.qty||1);row.getCell(7).value=Number(it.price||0);row.getCell(7).numFmt=MONEY_FMT;
75
+ if(ckPct>0&&ckPct<=100){row.getCell(8).value={formula:'ROUND(G'+cr+'*$K$1,0)',result:Number(it.discPrice||0)};ws.getCell('K1').value=Number((1-ckPct/100).toFixed(4));ws.getColumn(11).width=10;}
76
+ else{row.getCell(8).value=Number(it.discPrice||it.price||0);}row.getCell(8).numFmt=MONEY_FMT;
77
+ row.getCell(9).value={formula:'F'+cr+'*H'+cr,result:Number(it.total||0)};row.getCell(9).numFmt=MONEY_FMT;cr++;}
78
+ // Add fees and total rows - simplified
79
+ var sumParts=['SUM(I11:I'+ (cr-1) +')'];
80
+ if(d.fees&&d.fees.length){d.fees.forEach(function(f){var row=ws.getRow(cr);ws.mergeCells(cr,1,cr,8);row.getCell(1).value=' ⊕ '+f.label;row.getCell(9).value=Number(f.amount||0);row.getCell(9).numFmt=MONEY_FMT;sumParts.push('I'+cr);cr++;});}
81
+ var tRow=ws.getRow(cr);tRow.getCell(1).value='TỔNG CỘNG';tRow.getCell(9).value={formula:sumParts.join('+'),result:Number(d.grandTotal||0)};
82
+ ws.calcProperties.fullCalcOnLoad=true;
83
+ var buf=await wb.xlsx.writeBuffer();var blob=new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
84
+ var url=URL.createObjectURL(blob);var a=document.createElement('a');a.href=url;a.download=code+'.xlsx';a.click();
85
+ setTimeout(function(){URL.revokeObjectURL(url);},60000);
86
+ }
87
+
88
+ function doOverride(){
89
+ if(typeof getQuoteData!=='function'){return false;}
90
+ window._origGetQuoteData=getQuoteData;
91
+ window.exportExcel=async function(){if(typeof ExcelJS==='undefined'){alert('ExcelJS chưa load');return;}var d=getData();if(!d){alert('Chưa có dữ liệu báo giá');return;}_doExportExcel(d,d.qd,d.orderCode,getQRUrl(d.deposit>0?d.remaining:d.grandTotal,d.orderCode));};
92
+ console.log('✅ QR Payment override done');return true;
93
+ }
94
+
95
+ // Click handler - WORKS ngay lập tức
96
+ document.addEventListener('click',function(e){
97
+ var btn=e.target.closest&&e.target.closest('button,a');
98
+ if(!btn)return;
99
+ var txt=(btn.textContent||'').toLowerCase();
100
+ if(txt.includes('excel')&&txt.includes('xuất')){
101
+ e.preventDefault();e.stopPropagation();
102
+ // Luôn thử gọi - fallback nếu override chưa xong
103
+ if(typeof window.exportExcel==='function'){window.exportExcel();}
104
+ else if(typeof getData==='function'&&typeof _doExportExcel==='function'&&typeof ExcelJS!=='undefined'){
105
+ var d=getData();
106
+ if(d){var code=d.orderCode||getEffectiveOrderCode();var qr=getQRUrl(d.deposit>0?d.remaining:d.grandTotal,code);_doExportExcel(d,d.qd,code,qr);}
107
+ }
108
+ return false;
109
+ }
110
+ },true);
111
+
112
+ // Keep trying override
113
+ var _t=setInterval(function(){if(doOverride()||_t>120){clearInterval(_t);}},500);
114
+
115
+ window.VAI_QR={getEffectiveOrderCode:getEffectiveOrderCode,getQRUrl:getQRUrl,generateOrderCode:generateOrderCode,parsePrompt:parsePrompt,getPromptText:getPromptText,getData:getData,fmt:fmt};
116
+ })();ENDOFFILE
117
+
118
+ echo "File created: $(wc -l /tmp/qr-payment-v1040.js) lines"