FIX V2: Thêm phí giao hàng lắp đặt vào Excel

#25
by bep40 - opened
This view is limited to 50 files because it contains too many changes. See the raw diff here.
.gitattributes DELETED
@@ -1,102 +0,0 @@
1
- grob_img/grob_p10.jpeg filter=lfs diff=lfs merge=lfs -text
2
- grob_img/grob_p101.jpeg filter=lfs diff=lfs merge=lfs -text
3
- grob_img/grob_p102.jpeg filter=lfs diff=lfs merge=lfs -text
4
- grob_img/grob_p106.jpeg filter=lfs diff=lfs merge=lfs -text
5
- grob_img/grob_p109.jpeg filter=lfs diff=lfs merge=lfs -text
6
- grob_img/grob_p11.jpeg filter=lfs diff=lfs merge=lfs -text
7
- grob_img/grob_p110.jpeg filter=lfs diff=lfs merge=lfs -text
8
- grob_img/grob_p111.jpeg filter=lfs diff=lfs merge=lfs -text
9
- grob_img/grob_p118.jpeg filter=lfs diff=lfs merge=lfs -text
10
- grob_img/grob_p119.jpeg filter=lfs diff=lfs merge=lfs -text
11
- grob_img/grob_p120.jpeg filter=lfs diff=lfs merge=lfs -text
12
- grob_img/grob_p125.jpeg filter=lfs diff=lfs merge=lfs -text
13
- grob_img/grob_p130.jpeg filter=lfs diff=lfs merge=lfs -text
14
- grob_img/grob_p131.jpeg filter=lfs diff=lfs merge=lfs -text
15
- grob_img/grob_p132.jpeg filter=lfs diff=lfs merge=lfs -text
16
- grob_img/grob_p133.jpeg filter=lfs diff=lfs merge=lfs -text
17
- grob_img/grob_p134.jpeg filter=lfs diff=lfs merge=lfs -text
18
- grob_img/grob_p140.jpeg filter=lfs diff=lfs merge=lfs -text
19
- grob_img/grob_p141.jpeg filter=lfs diff=lfs merge=lfs -text
20
- grob_img/grob_p166.jpeg filter=lfs diff=lfs merge=lfs -text
21
- grob_img/grob_p17.jpeg filter=lfs diff=lfs merge=lfs -text
22
- grob_img/grob_p174.jpeg filter=lfs diff=lfs merge=lfs -text
23
- grob_img/grob_p175.jpeg filter=lfs diff=lfs merge=lfs -text
24
- grob_img/grob_p177.jpeg filter=lfs diff=lfs merge=lfs -text
25
- grob_img/grob_p178.jpeg filter=lfs diff=lfs merge=lfs -text
26
- grob_img/grob_p179.jpeg filter=lfs diff=lfs merge=lfs -text
27
- grob_img/grob_p180.jpeg filter=lfs diff=lfs merge=lfs -text
28
- grob_img/grob_p183.jpeg filter=lfs diff=lfs merge=lfs -text
29
- grob_img/grob_p184.jpeg filter=lfs diff=lfs merge=lfs -text
30
- grob_img/grob_p185.jpeg filter=lfs diff=lfs merge=lfs -text
31
- grob_img/grob_p186.jpeg filter=lfs diff=lfs merge=lfs -text
32
- grob_img/grob_p19.jpeg filter=lfs diff=lfs merge=lfs -text
33
- grob_img/grob_p199.jpeg filter=lfs diff=lfs merge=lfs -text
34
- grob_img/grob_p2.jpeg filter=lfs diff=lfs merge=lfs -text
35
- grob_img/grob_p201.jpeg filter=lfs diff=lfs merge=lfs -text
36
- grob_img/grob_p21.jpeg filter=lfs diff=lfs merge=lfs -text
37
- grob_img/grob_p23.jpeg filter=lfs diff=lfs merge=lfs -text
38
- grob_img/grob_p24.jpeg filter=lfs diff=lfs merge=lfs -text
39
- grob_img/grob_p28.jpeg filter=lfs diff=lfs merge=lfs -text
40
- grob_img/grob_p29.jpeg filter=lfs diff=lfs merge=lfs -text
41
- grob_img/grob_p3.jpeg filter=lfs diff=lfs merge=lfs -text
42
- grob_img/grob_p30.jpeg filter=lfs diff=lfs merge=lfs -text
43
- grob_img/grob_p31.jpeg filter=lfs diff=lfs merge=lfs -text
44
- grob_img/grob_p32.jpeg filter=lfs diff=lfs merge=lfs -text
45
- grob_img/grob_p33.jpeg filter=lfs diff=lfs merge=lfs -text
46
- grob_img/grob_p34.jpeg filter=lfs diff=lfs merge=lfs -text
47
- grob_img/grob_p35.jpeg filter=lfs diff=lfs merge=lfs -text
48
- grob_img/grob_p36.jpeg filter=lfs diff=lfs merge=lfs -text
49
- grob_img/grob_p37.jpeg filter=lfs diff=lfs merge=lfs -text
50
- grob_img/grob_p38.jpeg filter=lfs diff=lfs merge=lfs -text
51
- grob_img/grob_p39.jpeg filter=lfs diff=lfs merge=lfs -text
52
- grob_img/grob_p40.jpeg filter=lfs diff=lfs merge=lfs -text
53
- grob_img/grob_p41.jpeg filter=lfs diff=lfs merge=lfs -text
54
- grob_img/grob_p42.jpeg filter=lfs diff=lfs merge=lfs -text
55
- grob_img/grob_p43.jpeg filter=lfs diff=lfs merge=lfs -text
56
- grob_img/grob_p44.jpeg filter=lfs diff=lfs merge=lfs -text
57
- grob_img/grob_p45.jpeg filter=lfs diff=lfs merge=lfs -text
58
- grob_img/grob_p46.jpeg filter=lfs diff=lfs merge=lfs -text
59
- grob_img/grob_p47.jpeg filter=lfs diff=lfs merge=lfs -text
60
- grob_img/grob_p48.jpeg filter=lfs diff=lfs merge=lfs -text
61
- grob_img/grob_p49.jpeg filter=lfs diff=lfs merge=lfs -text
62
- grob_img/grob_p50.jpeg filter=lfs diff=lfs merge=lfs -text
63
- grob_img/grob_p51.jpeg filter=lfs diff=lfs merge=lfs -text
64
- grob_img/grob_p52.jpeg filter=lfs diff=lfs merge=lfs -text
65
- grob_img/grob_p53.jpeg filter=lfs diff=lfs merge=lfs -text
66
- grob_img/grob_p54.jpeg filter=lfs diff=lfs merge=lfs -text
67
- grob_img/grob_p55.jpeg filter=lfs diff=lfs merge=lfs -text
68
- grob_img/grob_p56.jpeg filter=lfs diff=lfs merge=lfs -text
69
- grob_img/grob_p57.jpeg filter=lfs diff=lfs merge=lfs -text
70
- grob_img/grob_p58.jpeg filter=lfs diff=lfs merge=lfs -text
71
- grob_img/grob_p59.jpeg filter=lfs diff=lfs merge=lfs -text
72
- grob_img/grob_p6.jpeg filter=lfs diff=lfs merge=lfs -text
73
- grob_img/grob_p60.jpeg filter=lfs diff=lfs merge=lfs -text
74
- grob_img/grob_p61.jpeg filter=lfs diff=lfs merge=lfs -text
75
- grob_img/grob_p62.jpeg filter=lfs diff=lfs merge=lfs -text
76
- grob_img/grob_p63.jpeg filter=lfs diff=lfs merge=lfs -text
77
- grob_img/grob_p64.jpeg filter=lfs diff=lfs merge=lfs -text
78
- grob_img/grob_p65.jpeg filter=lfs diff=lfs merge=lfs -text
79
- grob_img/grob_p66.jpeg filter=lfs diff=lfs merge=lfs -text
80
- grob_img/grob_p67.jpeg filter=lfs diff=lfs merge=lfs -text
81
- grob_img/grob_p68.jpeg filter=lfs diff=lfs merge=lfs -text
82
- grob_img/grob_p69.jpeg filter=lfs diff=lfs merge=lfs -text
83
- grob_img/grob_p7.jpeg filter=lfs diff=lfs merge=lfs -text
84
- grob_img/grob_p70.jpeg filter=lfs diff=lfs merge=lfs -text
85
- grob_img/grob_p71.jpeg filter=lfs diff=lfs merge=lfs -text
86
- grob_img/grob_p72.jpeg filter=lfs diff=lfs merge=lfs -text
87
- grob_img/grob_p73.jpeg filter=lfs diff=lfs merge=lfs -text
88
- grob_img/grob_p74.jpeg filter=lfs diff=lfs merge=lfs -text
89
- grob_img/grob_p76.jpeg filter=lfs diff=lfs merge=lfs -text
90
- grob_img/grob_p77.jpeg filter=lfs diff=lfs merge=lfs -text
91
- grob_img/grob_p78.jpeg filter=lfs diff=lfs merge=lfs -text
92
- grob_img/grob_p79.jpeg filter=lfs diff=lfs merge=lfs -text
93
- grob_img/grob_p8.jpeg filter=lfs diff=lfs merge=lfs -text
94
- grob_img/grob_p80.jpeg filter=lfs diff=lfs merge=lfs -text
95
- grob_img/grob_p82.jpeg filter=lfs diff=lfs merge=lfs -text
96
- grob_img/grob_p83.jpeg filter=lfs diff=lfs merge=lfs -text
97
- grob_img/grob_p84.jpeg filter=lfs diff=lfs merge=lfs -text
98
- grob_img/grob_p85.jpeg filter=lfs diff=lfs merge=lfs -text
99
- grob_img/grob_p88.jpeg filter=lfs diff=lfs merge=lfs -text
100
- grob_img/grob_p9.jpeg filter=lfs diff=lfs merge=lfs -text
101
- grob_img/grob_p97.jpeg filter=lfs diff=lfs merge=lfs -text
102
- grob_img/grob_p98.jpeg filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.github/workflows/auto-sync.yml DELETED
@@ -1,48 +0,0 @@
1
- name: Auto-Sync Products
2
-
3
- on:
4
- schedule:
5
- # Chạy hàng ngày lúc midnight UTC (8:00 AM Việt Nam)
6
- - cron: '0 0 * * *'
7
- workflow_dispatch:
8
- inputs:
9
- dry_run:
10
- description: 'Chỉ kiểm tra mà không cập nhật'
11
- type: boolean
12
- default: false
13
- target_space:
14
- description: 'Không gian target (vai-avatar2 hoặc both)'
15
- type: choice
16
- options:
17
- - vai-avatar2
18
- - both
19
-
20
- jobs:
21
- sync-products:
22
- runs-on: ubuntu-latest
23
- steps:
24
- - name: Checkout code
25
- uses: actions/checkout@v4
26
-
27
- - name: Setup Python
28
- uses: actions/setup-python@v5
29
- with:
30
- python-version: '3.11'
31
-
32
- - name: Install dependencies
33
- run: |
34
- pip install huggingface_hub
35
-
36
- - name: Run sync products
37
- env:
38
- HF_TOKEN: ${{ secrets.HF_TOKEN }}
39
- run: |
40
- echo "Starting product auto-sync..."
41
- python3 sync_products.py
42
-
43
- if [ $? -eq 0 ]; then
44
- echo "✅ Sync completed successfully"
45
- else
46
- echo "❌ Sync failed"
47
- exit 1
48
- fi
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
.rebuild CHANGED
@@ -1 +1 @@
1
- 2026-07-21T03:40:00+00:00 - Excel Fee Rows Fix - QR payment v1043
 
1
+ 2026-07-03T08:05:09+00:00
APPLY_EXCEL_FIX.md CHANGED
@@ -1,32 +1,51 @@
1
- # Cập nhật Excel Export - Phiếu báo giá
2
-
3
- ## Thay đổi đã thực hiện
4
-
5
- ### 1. Thêm các dòng phí vào Excel báo giá
6
- Khi nhập vào ô ck: Malloca ck 35%, giao hàng 200k, lắp đặt 500k, cọc 5tr, ghi chú: giao thứ 7
7
-
8
- **Excel báo giá sẽ hiển thị:**
9
- - Bảng sản phẩm (STT, Hình, Tên SP, Mã, Thông tin, SL, Đơn giá, Giá CK, Thành tiền, Ghi chú)
10
- - Các dòng phụ phí:
11
- - Phí giao hàng: +200.000đ
12
- - ⊕ Phí lắp đặt: +500.000đ
13
- - Dòng đặt cọc: Đặt cọc: 5.000.000đ
14
- - TỔNG CỘNG: Tổng tiền sau khi trừ cọc
15
-
16
- ### 2. Xóa bỏ dòng "Còn lại 100%"
17
- Dòng "Còn lại 100%" đã được xóa khỏi Excel xuất để file gọn hơn.
18
-
19
- ## Cách hoạt động
20
-
21
- 1. Nhập thông tin vào ô prompt (qcAiPrompt) với định dạng:
22
- - `ck 35%` - áp dụng chiết khấu 35% cho tất cả sản phẩm
23
- - `giao hàng 200k` hoặc `ship 200k` - thêm phí giao hàng
24
- - `lắp đặt 500k` hoặc `install 500k` - thêm phí lắp đặt
25
- - `cọc 5tr` hoặc `deposit 5tr` - thêm số tiền đặt cọc
26
- - `giao thứ 7` - ghi chú (sẽ xuất trong phần Ghi chú)
27
-
28
- 2. Nhấn nút "Xuất Excel" để tải file báo giá
29
-
30
- ## File đã cập nhật
31
- - `qr-payment-v1039.js` - Main script (đã cập nhật)
32
- - `vai-excel-fix-v2.js` - Excel fix script (đã cập nhật)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Hướng dẫn áp dụng Fix Excel Download - CẬP NHẬT 2026
2
+
3
+ ## Vấn đề
4
+ File Excel chỉ tải được 1 lần, lần 2+ thất bại vì `URL.revokeObjectURL()` được gọi sau 60s.
5
+
6
+ ## 🎯 GIẢI PHÁP HOÀN HẢO - Fix v2.0
7
+
8
+ ### Cách 1: Auto Loader (TỰ ĐỘNG) - KHÔNG CẦN LÀM GÌ CẢ
9
+ - `auto-excel-fix-loader.js` tự động tải `vai-excel-fix-v2.js` khi trang mở
10
+ - Script đã được tích hợp sẵn trong index.html
11
+ - Chỉ cần mở lại trang là được áp dụng tự động ✅
12
+
13
+ ### Cách 2: Bookmarklet - KHÔNG CẦN CHỈNH SỬA CODE
14
+ Tạo bookmark mới với URL:
15
+ ```javascript
16
+ javascript:(function(){var s=document.createElement('script');s.src='/vai-excel-fix-v2.js?v='+Date.now();s.onload=function(){alert('✅ Excel Fix v2.0 đã tải!\nBạn có thể tải Excel bao nhiêu lần tùy thích!');};document.head.appendChild(s);})();
17
+ ```
18
+
19
+ ### Cách 3: Thêm script tag vào index.html (TỰ ĐỘNG)
20
+ Thêm đoạn sau vào trước thẻ `</body>`:
21
+ ```html
22
+ <!-- V.AI STUDIO Excel Multi-Download Fix v2.0 -->
23
+ <script src="vai-excel-fix-v2.js?v=2026"></script>
24
+ ```
25
+
26
+ ## Test
27
+ 1. Mở Space V.AISTUDIO
28
+ 2. Tạo báo giá (lập báo giá) Click 💾 Excel → tải ✅
29
+ 3. Click 💾 Excel NGAY → tải tiếp tục ✅
30
+ 4. Click nhiều lần nữa → luôn tải được ✅
31
+ 5. Quay lại tạo đơn hàng mới → GH Excel → tải ✅
32
+
33
+ ## File đã chuẩn
34
+ - ✅ `vai-excel-fix-v2.js` - Script fix chính (mới nhất)
35
+ - ✅ `auto-excel-fix-loader.js` - Tự động tải fix
36
+ - ✅ `vai-quote-excel-order-fix-v1050.js` - Backup (nếu v2 không tải được)
37
+
38
+ ## Điều kiện áp dụng
39
+ - Cần có thư viện ExcelJS (đã có trong index.html):
40
+ ```html
41
+ <script src="https://cdn.jsdelivr.net/npm/exceljs@4.4.0/dist/exceljs.min.js"></script>
42
+ ```
43
+
44
+ ## Changelog v2.0
45
+ - Thay đổi cách quản lý blob URL: registry toàn cục
46
+ - Patch URL.revokeObjectURL: không revoke khi chưa unload
47
+ - Hỗ trợ cả Quote modal và Order modal
48
+ - Toast thông báo khi xuất thành công/thất bại
49
+
50
+ ---
51
+ *Cập nhật: 14-07-2026 - ML Intern - Fix Excel multi-download hoàn hảo*
debug_export.html DELETED
@@ -1,47 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="vi"><head><meta charset="utf-8"/>
3
- <meta name="viewport" content="width=device-width, initial-scale=1"/>
4
- <title>VAI Export Debug</title>
5
- <script src="https://cdn.jsdelivr.net/npm/exceljs@4.4.0/dist/exceljs.min.js"></script>
6
- <style>body{font-family:system-ui;padding:16px;background:#f5f7fa}textarea{width:100%;height:120px;font-size:16px;padding:10px;border:2px solid #003f62;border-radius:8px}button{margin-top:12px;width:100%;padding:14px;font-size:18px;background:#003f62;color:#fff;border:0;border-radius:10px;font-weight:700}#log{margin-top:16px;white-space:pre-wrap;background:#fff;border:1px solid #ccc;border-radius:8px;padding:12px;font-size:13px;max-height:40vh;overflow:auto}</style>
7
- </head><body>
8
- <h2>VAI Export Debug</h2>
9
- <p>Nhập prompt rồi bấm nút. File sẽ có đủ dòng phí. Log hiển thị bên dưới.</p>
10
- <textarea id="prompt">Malloca ck 35%, giao hàng 200k, lắp đặt 500k, cọc 5tr, ghi chú: giao thứ 7</textarea>
11
- <button id="go">Xuất Excel Test</button>
12
- <div id="log">Log sẽ hiện ở đây...</div>
13
- <script>
14
- function L(s){var el=document.getElementById('log');el.textContent+=("\n"+s);el.scrollTop=el.scrollHeight;console.log(s);}
15
- document.getElementById('go').addEventListener('click',async function(){
16
- L("ExcelJS loaded: "+(typeof ExcelJS!=='undefined'));
17
- var txt=document.getElementById('prompt').value.trim();
18
- L("Prompt: "+txt);
19
- var fees=[];var deposit=0;var note='';
20
- var m1=txt.match(/giao hàng\s*([\d.,]+)\s*(k|tr|triệu|đ|nghìn)?/i);
21
- if(m1){var v=parseFloat(m1[1].replace(/[.,]/g,''));var u=(m1[2]||'').toLowerCase();if(u==='k')v*=1000;if(u==='tr'||u==='triệu')v*=1e6;fees.push({label:'Phí giao hàng',amount:v});}
22
- var m2=txt.match(/lắp đặt\s*([\d.,]+)\s*(k|tr|triệu|đ|nghìn)?/i);
23
- if(m2){var v=parseFloat(m2[1].replace(/[.,]/g,''));var u=(m2[2]||'').toLowerCase();if(u==='k')v*=1000;if(u==='tr'||u==='triệu')v*=1e6;fees.push({label:'Phí lắp đặt',amount:v});}
24
- var m3=txt.match(/cọc\s*([\d.,]+)\s*(k|tr|triệu|đ|nghìn)?/i);
25
- if(m3){var v=parseFloat(m3[1].replace(/[.,]/g,''));var u=(m3[2]||'').toLowerCase();if(u==='k')v*=1000;if(u==='tr'||u==='triệu')v*=1e6;deposit=v;}
26
- var mn=txt.match(/ghi chú\s*[::]?\s*(.+)$/i);
27
- if(mn)note=mn[1].trim();
28
- L("Parsed fees: "+JSON.stringify(fees)+" deposit="+deposit+" note="+note);
29
- if(typeof ExcelJS==='undefined'){L("ERROR: ExcelJS not loaded - check network/CDN");return;}
30
- try{
31
- var wb=new ExcelJS.Workbook();var ws=wb.addWorksheet('BaoGia');
32
- ws.addRow(['BẢNG BÁO GIÁ']);
33
- ws.addRow([]);
34
- ws.addRow(['1','SP Test','MH800TC',1,7350000,4777500,4777500]);
35
- fees.forEach(function(f){ws.addRow([' '+f.label, f.amount]);L("ROW: "+f.label+" "+f.amount);});
36
- var total=4777500+fees.reduce(function(a,f){return a+f.amount;},0);
37
- ws.addRow(['TỔNG CỘNG', total]);
38
- if(deposit>0){ws.addRow(['Đã cọc',deposit]);ws.addRow(['CÒN LẠI',total-deposit]);}
39
- if(note)ws.addRow(['Ghi chú: '+note]);
40
- var buf=await wb.xlsx.writeBuffer();
41
- var blob=new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
42
- var a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='VAI_debug.xlsx';a.click();
43
- L("FILE DOWNLOADED OK. Dòng phí: "+(fees.length>0?'CÓ':'KHÔNG'));
44
- }catch(e){L("EXPORT ERROR: "+e.message);}
45
- });
46
- </script>
47
- </body></html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
grob-price-fix.js DELETED
@@ -1,87 +0,0 @@
1
- /**
2
- * V.AI STUDIO — Grob Price Fix
3
- * ==============================
4
- * Fixes incorrect prices from the catalogue-based PDF price list.
5
- * Fixed as of July 2026 per Grob Vietnam catalogue.
6
- */
7
- (function() {
8
- 'use strict';
9
- if (window.__GROB_PRICE_FIX__) return;
10
- window.__GROB_PRICE_FIX__ = true;
11
-
12
- const PRICE_FIXES = {
13
- // 0203 | Grob | Bản lề inox - cánh/phủ bì 203mm: 0đ -> 67.000đ
14
- '0203': { p: '67.000đ', pn: 67000 },
15
- // 0280 | Grob | Khay chia thìa dĩa nhựa - cánh/phủ bì 280mm: 885.000đ -> 965.000đ
16
- '0280': { p: '965.000đ', pn: 965000 },
17
- // 0290 | Grob | Khay chia thìa dĩa nhựa - cánh/phủ bì 290mm: 965.000đ -> 1.018.000đ
18
- '0290': { p: '1.018.000đ', pn: 1018000 },
19
- };
20
-
21
- function patchProduct(prod) {
22
- if (!prod) return;
23
- var name = prod.n || prod.name || '';
24
- for (var code in PRICE_FIXES) {
25
- if (name.indexOf(code) === 0 && name.indexOf('Grob') !== -1) {
26
- var fix = PRICE_FIXES[code];
27
- if (prod.p) prod.p = fix.p;
28
- if (prod.pn !== undefined) prod.pn = fix.pn;
29
- if (prod.price) prod.price = fix.p;
30
- if (prod.priceNum !== undefined) prod.priceNum = fix.pn;
31
- return true;
32
- }
33
- }
34
- return false;
35
- }
36
-
37
- // Patch after D is populated
38
- function patchD() {
39
- if (typeof window.D !== 'undefined' && Array.isArray(window.D)) {
40
- var patched = 0;
41
- window.D.forEach(function(p) {
42
- if (patchProduct(p)) patched++;
43
- });
44
- if (patched > 0) {
45
- console.log('[Grob Price Fix] Patched ' + patched + ' product(s) in D');
46
- // Also sync prices for items already in cart
47
- patchCart();
48
- if (typeof window.refreshUI === 'function') window.refreshUI();
49
- }
50
- }
51
- }
52
-
53
- // Sync Grob prices in cart (localStorage)
54
- function patchCart() {
55
- try {
56
- var cart = JSON.parse(localStorage.getItem('malloca_cart') || '[]');
57
- if (!Array.isArray(cart) || !cart.length) return;
58
- var changed = false;
59
- cart.forEach(function(item) {
60
- if (patchProduct(item)) changed = true;
61
- });
62
- if (changed) {
63
- localStorage.setItem('malloca_cart', JSON.stringify(cart));
64
- window.cart = cart;
65
- console.log('[Grob Price Fix] Synced prices in cart');
66
- }
67
- } catch(e) {}
68
- }
69
-
70
- // Try patching at various intervals as data loads
71
- function onReady() {
72
- setTimeout(patchD, 200);
73
- setTimeout(patchD, 500);
74
- setTimeout(patchD, 1000);
75
- setTimeout(patchD, 2000);
76
- setTimeout(patchD, 3000);
77
- setTimeout(patchD, 5000);
78
- }
79
-
80
- if (document.readyState === 'loading') {
81
- document.addEventListener('DOMContentLoaded', onReady);
82
- } else {
83
- onReady();
84
- }
85
-
86
- console.log('[Grob Price Fix] Loaded: 02.03=67k, 02.80=965k, 02.90=1,018k');
87
- })();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
grob_img/grob_p1.jpeg DELETED
Binary file (80 kB)
 
grob_img/grob_p10.jpeg DELETED

Git LFS Details

  • SHA256: 3cf047359715058a5f1e2ae91a8a2f1163539f4712de1db357ae12e677cac638
  • Pointer size: 131 Bytes
  • Size of remote file: 222 kB
grob_img/grob_p100.jpeg DELETED
Binary file (51.6 kB)
 
grob_img/grob_p101.jpeg DELETED

Git LFS Details

  • SHA256: 5f695be82687bb3a52248ff537adb6950f73b64c21f483ff22b9e81213b1db61
  • Pointer size: 131 Bytes
  • Size of remote file: 126 kB
grob_img/grob_p102.jpeg DELETED

Git LFS Details

  • SHA256: c9c705dbb20655e160ad96fd17c5c33f505b7702f0b2c031cf49ffcf239d4e80
  • Pointer size: 131 Bytes
  • Size of remote file: 394 kB
grob_img/grob_p103.jpeg DELETED
Binary file (42 kB)
 
grob_img/grob_p104.jpeg DELETED
Binary file (20 kB)
 
grob_img/grob_p105.jpeg DELETED
Binary file (56.2 kB)
 
grob_img/grob_p106.jpeg DELETED

Git LFS Details

  • SHA256: 62afdde0435420e325e86f5162f0d637a1c53f90ca9ba3b1fb72f900086fb6a9
  • Pointer size: 131 Bytes
  • Size of remote file: 150 kB
grob_img/grob_p107.jpeg DELETED
Binary file (96 kB)
 
grob_img/grob_p108.jpeg DELETED
Binary file (86.7 kB)
 
grob_img/grob_p109.jpeg DELETED

Git LFS Details

  • SHA256: 3d45a5d7fbe20e41f181eb81adf669d9263daddb1787e9dc47bed68355637314
  • Pointer size: 131 Bytes
  • Size of remote file: 103 kB
grob_img/grob_p11.jpeg DELETED

Git LFS Details

  • SHA256: bc47b6543988f6a4074ce37aa20ea13aa03d6f2f806a823869dec4fba362be7f
  • Pointer size: 131 Bytes
  • Size of remote file: 160 kB
grob_img/grob_p110.jpeg DELETED

Git LFS Details

  • SHA256: a84e2440229ca6da6a9d924f027a39e17176fc495c74d18a0c8f8307b2d93f2c
  • Pointer size: 131 Bytes
  • Size of remote file: 101 kB
grob_img/grob_p111.jpeg DELETED

Git LFS Details

  • SHA256: 4a8c39cc23363b072d590675666c9e8b202c3030b0ced467bad694a19b197ded
  • Pointer size: 131 Bytes
  • Size of remote file: 286 kB
grob_img/grob_p112.jpeg DELETED
Binary file (54 kB)
 
grob_img/grob_p113.jpeg DELETED
Binary file (76.2 kB)
 
grob_img/grob_p114.jpeg DELETED
Binary file (92.9 kB)
 
grob_img/grob_p115.jpeg DELETED
Binary file (92.9 kB)
 
grob_img/grob_p116.jpeg DELETED
Binary file (40.1 kB)
 
grob_img/grob_p117.jpeg DELETED
Binary file (21.9 kB)
 
grob_img/grob_p118.jpeg DELETED

Git LFS Details

  • SHA256: 269778d257f719f470c89f27e83ef12c4913cc4ed7adb4a1aa181494f74c63f3
  • Pointer size: 131 Bytes
  • Size of remote file: 552 kB
grob_img/grob_p119.jpeg DELETED

Git LFS Details

  • SHA256: 269778d257f719f470c89f27e83ef12c4913cc4ed7adb4a1aa181494f74c63f3
  • Pointer size: 131 Bytes
  • Size of remote file: 552 kB
grob_img/grob_p12.jpeg DELETED
Binary file (89.4 kB)
 
grob_img/grob_p120.jpeg DELETED

Git LFS Details

  • SHA256: 74e912df9328009cdd1a040974cec3309795335536dd1c89b4d80f138f28f7a9
  • Pointer size: 131 Bytes
  • Size of remote file: 489 kB
grob_img/grob_p121.jpeg DELETED
Binary file (61.4 kB)
 
grob_img/grob_p122.jpeg DELETED
Binary file (58.4 kB)
 
grob_img/grob_p123.jpeg DELETED
Binary file (59.5 kB)
 
grob_img/grob_p124.jpeg DELETED
Binary file (59.5 kB)
 
grob_img/grob_p125.jpeg DELETED

Git LFS Details

  • SHA256: eadac8ca424066b951c6ede4fda5d234144f00f470dbf7564422f3744ae09c81
  • Pointer size: 131 Bytes
  • Size of remote file: 305 kB
grob_img/grob_p126.jpeg DELETED
Binary file (33.6 kB)
 
grob_img/grob_p127.jpeg DELETED
Binary file (64.2 kB)
 
grob_img/grob_p128.jpeg DELETED
Binary file (41.2 kB)
 
grob_img/grob_p129.jpeg DELETED
Binary file (51.6 kB)
 
grob_img/grob_p13.jpeg DELETED
Binary file (98 kB)
 
grob_img/grob_p130.jpeg DELETED

Git LFS Details

  • SHA256: 96bef100ad82f1bf948a6559608d84429e17c04086d893ca83835e7d9d2e71c3
  • Pointer size: 131 Bytes
  • Size of remote file: 382 kB
grob_img/grob_p131.jpeg DELETED

Git LFS Details

  • SHA256: 5a452d634674cdd034b4965382fd9b5b0cb59e6bf0ef156d2d043d3595e0debf
  • Pointer size: 131 Bytes
  • Size of remote file: 407 kB
grob_img/grob_p132.jpeg DELETED

Git LFS Details

  • SHA256: 7254e22d6463e5163ab1587467e6dc8a57f67a7747d5c5a5411a63d59ae6f1ee
  • Pointer size: 131 Bytes
  • Size of remote file: 264 kB
grob_img/grob_p133.jpeg DELETED

Git LFS Details

  • SHA256: 7254e22d6463e5163ab1587467e6dc8a57f67a7747d5c5a5411a63d59ae6f1ee
  • Pointer size: 131 Bytes
  • Size of remote file: 264 kB
grob_img/grob_p134.jpeg DELETED

Git LFS Details

  • SHA256: 5a452d634674cdd034b4965382fd9b5b0cb59e6bf0ef156d2d043d3595e0debf
  • Pointer size: 131 Bytes
  • Size of remote file: 407 kB
grob_img/grob_p135.jpeg DELETED
Binary file (48.5 kB)
 
grob_img/grob_p136.jpeg DELETED
Binary file (67.4 kB)
 
grob_img/grob_p137.jpeg DELETED
Binary file (24.3 kB)
 
grob_img/grob_p138.jpeg DELETED
Binary file (52.9 kB)