bep40 commited on
Commit
b7a0c52
·
verified ·
1 Parent(s): 989d896

Fix quotation: CK discount calc + Excel formulas + Eurogold images

Browse files
Files changed (1) hide show
  1. quote-fix.js +180 -0
quote-fix.js ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * V.AI STUDIO - Quote Fix Script
3
+ * Fixes: 1) CK discount not applying 2) Excel values not formulas 3) Missing Eurogold images
4
+ * This script overrides the quotation functions after page load.
5
+ */
6
+ (function(){
7
+ // Wait for page to fully load
8
+ window.addEventListener('load', function(){
9
+ setTimeout(patchQuotation, 2000);
10
+ });
11
+
12
+ function patchQuotation(){
13
+ // Patch 1: Fix discount calculation in quote table
14
+ // When user types CK% in .qt-disc input, recalculate "Đơn giá CK" column
15
+ document.addEventListener('input', function(e){
16
+ if(e.target.classList.contains('qt-disc')){
17
+ const row = e.target.closest('tr');
18
+ if(!row) return;
19
+ const discVal = parseFloat(e.target.value) || 0;
20
+ const priceCell = row.querySelector('.qt-price-original');
21
+ const ckCell = row.querySelector('.qt-price-ck');
22
+ const totalCell = row.querySelector('.qt-total');
23
+ const qtyCell = row.querySelector('.qt-qty');
24
+ if(priceCell && ckCell){
25
+ const originalPrice = parseInt(priceCell.dataset.value) || 0;
26
+ const qty = parseInt(qtyCell ? qtyCell.textContent : '1') || 1;
27
+ const discountedPrice = Math.round(originalPrice * (1 - discVal/100));
28
+ ckCell.textContent = discountedPrice.toLocaleString('vi-VN') + 'đ';
29
+ ckCell.dataset.value = discountedPrice;
30
+ if(totalCell){
31
+ const total = discountedPrice * qty;
32
+ totalCell.textContent = total.toLocaleString('vi-VN') + 'đ';
33
+ totalCell.dataset.value = total;
34
+ }
35
+ }
36
+ // Recalculate grand total
37
+ recalcGrandTotal();
38
+ }
39
+ });
40
+
41
+ // Patch 2: Override Excel export to use formulas and number format
42
+ const origExcelExport = window.exportQuoteExcel;
43
+ window.exportQuoteExcel = function(){
44
+ if(typeof ExcelJS === 'undefined') return alert('ExcelJS not loaded');
45
+ const wb = new ExcelJS.Workbook();
46
+ const ws = wb.addWorksheet('BÁO GIÁ');
47
+
48
+ // Header
49
+ ws.mergeCells('A1:H1');
50
+ ws.getCell('A1').value = 'BÁO GIÁ - V.AI STUDIO';
51
+ ws.getCell('A1').font = {size:14, bold:true};
52
+ ws.getCell('A1').alignment = {horizontal:'center'};
53
+
54
+ // Customer info
55
+ const custName = document.querySelector('#quoteCustName')?.value || '';
56
+ const custPhone = document.querySelector('#quoteCustPhone')?.value || '';
57
+ ws.getCell('A3').value = 'Khách hàng: ' + custName;
58
+ ws.getCell('A4').value = 'SĐT: ' + custPhone;
59
+ ws.getCell('A5').value = 'Ngày: ' + new Date().toLocaleDateString('vi-VN');
60
+
61
+ // Table headers row 7
62
+ const headers = ['STT','Hình ảnh','Tên SP','Mã SP','SL','Đơn giá','CK%','Đơn giá CK','Thành tiền'];
63
+ headers.forEach((h,i) => {
64
+ const cell = ws.getCell(7, i+1);
65
+ cell.value = h;
66
+ cell.font = {bold:true, color:{argb:'FFFFFFFF'}};
67
+ cell.fill = {type:'pattern', pattern:'solid', fgColor:{argb:'FF1F4E79'}};
68
+ cell.alignment = {horizontal:'center'};
69
+ });
70
+
71
+ // Data rows from quote table
72
+ const rows = document.querySelectorAll('.quote-table tbody tr:not(.quote-total-row)');
73
+ let dataStartRow = 8;
74
+ rows.forEach((row, idx) => {
75
+ const r = dataStartRow + idx;
76
+ const cells = row.querySelectorAll('td');
77
+ // STT
78
+ ws.getCell(r, 1).value = idx + 1;
79
+ // Image - try to get URL
80
+ const img = row.querySelector('img.qt-img');
81
+ const imgUrl = img ? img.src : '';
82
+ ws.getCell(r, 2).value = imgUrl ? {text: 'Xem ảnh', hyperlink: imgUrl} : '';
83
+ // Name
84
+ const nameEl = row.querySelector('.qt-name');
85
+ ws.getCell(r, 3).value = nameEl ? nameEl.textContent.trim() : '';
86
+ // SKU
87
+ const skuEl = row.querySelector('.qt-sku');
88
+ ws.getCell(r, 4).value = skuEl ? skuEl.textContent.trim() : '';
89
+ // Qty
90
+ const qtyEl = row.querySelector('.qt-qty');
91
+ const qty = parseInt(qtyEl ? qtyEl.textContent : '1') || 1;
92
+ ws.getCell(r, 5).value = qty;
93
+ // Unit price (NUMBER, not string)
94
+ const priceEl = row.querySelector('.qt-price-original');
95
+ const price = parseInt(priceEl ? priceEl.dataset.value : '0') || 0;
96
+ ws.getCell(r, 6).value = price;
97
+ ws.getCell(r, 6).numFmt = '#,##0';
98
+ // CK%
99
+ const discEl = row.querySelector('.qt-disc');
100
+ const disc = parseFloat(discEl ? discEl.value : '0') || 0;
101
+ ws.getCell(r, 7).value = disc/100;
102
+ ws.getCell(r, 7).numFmt = '0%';
103
+ // Đơn giá CK = FORMULA: =F{r}*(1-G{r})
104
+ ws.getCell(r, 8).value = {formula: `F${r}*(1-G${r})`};
105
+ ws.getCell(r, 8).numFmt = '#,##0';
106
+ // Thành tiền = FORMULA: =E{r}*H{r}
107
+ ws.getCell(r, 9).value = {formula: `E${r}*H${r}`};
108
+ ws.getCell(r, 9).numFmt = '#,##0';
109
+ });
110
+
111
+ // Total row with SUM formula
112
+ const totalRow = dataStartRow + rows.length;
113
+ ws.getCell(totalRow, 8).value = 'TỔNG CỘNG:';
114
+ ws.getCell(totalRow, 8).font = {bold:true};
115
+ ws.getCell(totalRow, 9).value = {formula: `SUM(I${dataStartRow}:I${totalRow-1})`};
116
+ ws.getCell(totalRow, 9).numFmt = '#,##0';
117
+ ws.getCell(totalRow, 9).font = {bold:true, size:12};
118
+
119
+ // Column widths
120
+ [5,15,35,15,5,12,6,12,14].forEach((w,i) => {ws.getColumn(i+1).width = w});
121
+
122
+ // Download
123
+ wb.xlsx.writeBuffer().then(buffer => {
124
+ const blob = new Blob([buffer], {type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
125
+ const url = URL.createObjectURL(blob);
126
+ const a = document.createElement('a');
127
+ a.href = url;
128
+ a.download = 'BaoGia_VAISTUDIO_' + new Date().toISOString().slice(0,10) + '.xlsx';
129
+ a.click();
130
+ URL.revokeObjectURL(url);
131
+ });
132
+ };
133
+
134
+ // Patch 3: Fix Eurogold image URLs in quotation
135
+ // The issue: when building quote table, image src might use relative URL or wrong path
136
+ // Override the function that builds quote rows to ensure full image URL
137
+ const origBuildQuoteRow = window.buildQuoteRow;
138
+ window.buildQuoteRow = function(item, idx){
139
+ // Ensure image URL is absolute
140
+ let imgSrc = item.image || '';
141
+ if(imgSrc && !imgSrc.startsWith('http')){
142
+ imgSrc = 'https://bep40-v-aistudio.static.hf.space/' + imgSrc.replace(/^\//,'');
143
+ }
144
+ // If no image, try from product data
145
+ if(!imgSrc && typeof D !== 'undefined'){
146
+ const found = D.find(p => p.sku === item.sku || p.model === item.sku);
147
+ if(found && found.image) imgSrc = found.image;
148
+ }
149
+
150
+ const price = item.priceNum || 0;
151
+ const qty = item.qty || 1;
152
+ return `<tr>
153
+ <td>${idx+1}</td>
154
+ <td><img class="qt-img" src="${imgSrc}" onerror="this.style.display='none'" alt=""></td>
155
+ <td><span class="qt-name">${item.name||''}</span></td>
156
+ <td><span class="qt-sku">${item.sku||''}</span></td>
157
+ <td class="qt-qty">${qty}</td>
158
+ <td class="qt-price-original" data-value="${price}">${price.toLocaleString('vi-VN')}đ</td>
159
+ <td><input class="qt-disc" type="number" value="0" min="0" max="100" step="1"></td>
160
+ <td class="qt-price-ck" data-value="${price}">${price.toLocaleString('vi-VN')}đ</td>
161
+ <td class="qt-total" data-value="${price*qty}">${(price*qty).toLocaleString('vi-VN')}đ</td>
162
+ </tr>`;
163
+ };
164
+
165
+ // Recalculate grand total
166
+ window.recalcGrandTotal = function(){
167
+ let total = 0;
168
+ document.querySelectorAll('.qt-total').forEach(cell => {
169
+ total += parseInt(cell.dataset.value) || 0;
170
+ });
171
+ const totalEl = document.querySelector('.quote-grand-total');
172
+ if(totalEl){
173
+ totalEl.textContent = total.toLocaleString('vi-VN') + 'đ';
174
+ totalEl.dataset.value = total;
175
+ }
176
+ };
177
+
178
+ console.log('[V.AI] Quote fix loaded: CK calc + Excel formulas + Image fix');
179
+ }
180
+ })();