bep40 commited on
Commit
96ac982
·
1 Parent(s): cb2b89d

fix: CK input on order-detail accepts % / k / tr like quote modal; all ?kh= discount links point to canonical bep40-vai-avatar.hf.space

Browse files
Files changed (4) hide show
  1. index.html +2 -2
  2. index.ts +1 -1
  3. src/app.js +1 -1
  4. src/greeting-news.js +37 -7
index.html CHANGED
@@ -556,9 +556,9 @@
556
  <script defer src="./src/cart-quote.js?gc=29"></script> <!-- Cart + Quote module (Giỏ hàng / Báo giá) -->
557
  <script defer src="./src/customers.js?gc=15"></script> <!-- Customer list (Danh sách khách hàng) -->
558
  <script defer src="./src/vaix-rag.js?gc=53"></script> <!-- V.AI STUDIO RAG Module - loads FASTER via light index; lazy galleries; spec-aware search -->
559
- <script defer src="./src/greeting-news.js?gc=36"></script> <!-- Greeting HOT news cards + source links -->
560
  <script defer src="./src/order-sync.js?gc=16"></script> <!-- Order sync with V.AISTUDIO backend -->
561
- <script type="module" src="./src/app.js?gc=57"></script>
562
  <script defer src="./src/greeting-source-cards.js?gc=15"></script> <!-- FIX: Nguồn tin cards under greeting -->
563
  <script defer src="./src/avatar-picker.js?gc=13"></script> <!-- ✨ Circular avatar picker (Mr V / Lisamy) + loading progress bar -->
564
  <!-- BIG SALE Floating Promotion Module -->
 
556
  <script defer src="./src/cart-quote.js?gc=29"></script> <!-- Cart + Quote module (Giỏ hàng / Báo giá) -->
557
  <script defer src="./src/customers.js?gc=15"></script> <!-- Customer list (Danh sách khách hàng) -->
558
  <script defer src="./src/vaix-rag.js?gc=53"></script> <!-- V.AI STUDIO RAG Module - loads FASTER via light index; lazy galleries; spec-aware search -->
559
+ <script defer src="./src/greeting-news.js?gc=37"></script> <!-- Greeting HOT news cards + source links -->
560
  <script defer src="./src/order-sync.js?gc=16"></script> <!-- Order sync with V.AISTUDIO backend -->
561
+ <script type="module" src="./src/app.js?gc=58"></script>
562
  <script defer src="./src/greeting-source-cards.js?gc=15"></script> <!-- FIX: Nguồn tin cards under greeting -->
563
  <script defer src="./src/avatar-picker.js?gc=13"></script> <!-- ✨ Circular avatar picker (Mr V / Lisamy) + loading progress bar -->
564
  <!-- BIG SALE Floating Promotion Module -->
index.ts CHANGED
@@ -1415,7 +1415,7 @@ const server = Bun.serve({
1415
  const exp = Math.floor(Date.now() / 1000) + 3600;
1416
  const crypto = await import("node:crypto");
1417
  const tk = crypto.createHmac("sha256", secret).update(maKh + ":" + exp).digest("hex").slice(0, 24);
1418
- const link = url.origin + "/?kh=" + encodeURIComponent(maKh) + "&tk=" + tk + "&exp=" + exp;
1419
  const ck = rec.ck != null ? String(rec.ck) : null;
1420
  return Response.json({ ok: true, kh: maKh, ck: ck, customer: rec.name || "", link: link });
1421
  } catch (e: any) {
 
1415
  const exp = Math.floor(Date.now() / 1000) + 3600;
1416
  const crypto = await import("node:crypto");
1417
  const tk = crypto.createHmac("sha256", secret).update(maKh + ":" + exp).digest("hex").slice(0, 24);
1418
+ const link = "https://bep40-vai-avatar.hf.space/?kh=" + encodeURIComponent(maKh) + "&tk=" + tk + "&exp=" + exp;
1419
  const ck = rec.ck != null ? String(rec.ck) : null;
1420
  return Response.json({ ok: true, kh: maKh, ck: ck, customer: rec.name || "", link: link });
1421
  } catch (e: any) {
src/app.js CHANGED
@@ -1153,7 +1153,7 @@ async function initDiscountLink() {
1153
  const maKh = signed.kh;
1154
  const ck = signed.ck != null ? String(signed.ck) : "";
1155
  const custName = signed.customer || "";
1156
- const linkUrl = _servedLink || (location.origin + location.pathname + "?kh=" + encodeURIComponent(maKh) + "&tk=" + encodeURIComponent(signed.tk || "") + "&exp=" + encodeURIComponent(signed.exp || ""));
1157
  _discountLink = { kh: maKh, url: linkUrl };
1158
  _discountCustomer = { ma_kh: maKh, ck: ck, name: custName };
1159
  // Remember the customer for the quote/order exports (customers.js format).
 
1153
  const maKh = signed.kh;
1154
  const ck = signed.ck != null ? String(signed.ck) : "";
1155
  const custName = signed.customer || "";
1156
+ const linkUrl = _servedLink || ("https://bep40-vai-avatar.hf.space/?kh=" + encodeURIComponent(maKh) + "&tk=" + encodeURIComponent(signed.tk || "") + "&exp=" + encodeURIComponent(signed.exp || ""));
1157
  _discountLink = { kh: maKh, url: linkUrl };
1158
  _discountCustomer = { ma_kh: maKh, ck: ck, name: custName };
1159
  // Remember the customer for the quote/order exports (customers.js format).
src/greeting-news.js CHANGED
@@ -742,12 +742,40 @@
742
  var isEcoLine = false;
743
  try { isEcoLine = typeof window.isEcoKitchen === 'function' && window.isEcoKitchen({ name: item.name, title_clean: item.name, model: item.model || item.sku || '', sku: item.sku || '', slug: item.slug || '' }); } catch (_e) {}
744
  var discEl = ov.querySelector('[data-edit="disc"][data-idx="' + idx + '"]');
745
- var val = isEcoLine ? (Number(item.price) || 0)
746
- : ((discEl && discEl.value) ? (parseInt(String(discEl.value).replace(/[^\d]/g, ''), 10) || 0) : 0);
747
- if (val <= 0) val = Number(item.price) || 0;
748
- item.discPrice = val;
749
- item.total = val * (Number(item.qty) || 1);
750
- if (isEcoLine) item.ck_percent = undefined;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
751
  recomputeTotals(ord);
752
  var li = list.findIndex(function (x) { return String(x.code) === String(order.code); });
753
  if (li >= 0) list[li] = ord; saveOrders(list);
@@ -757,7 +785,9 @@
757
  if (gt) gt.textContent = money(ord.grandTotal || ord.total || 0);
758
  var sll = ov.querySelector('#od-total-sll');
759
  if (sll) sll.textContent = (ord.items || []).reduce(function (a, it) { return a + (Number(it.qty) || 0); }, 0);
760
- if (window.showToast) window.showToast('✅ Đã cập nhật CK');
 
 
761
  } catch (e) { console.warn('[od] disc error:', e); }
762
  };
763
  // Parse an AI discount prompt like the quote modal (CK %, fees, cọc, ghi chú).
 
742
  var isEcoLine = false;
743
  try { isEcoLine = typeof window.isEcoKitchen === 'function' && window.isEcoKitchen({ name: item.name, title_clean: item.name, model: item.model || item.sku || '', sku: item.sku || '', slug: item.slug || '' }); } catch (_e) {}
744
  var discEl = ov.querySelector('[data-edit="disc"][data-idx="' + idx + '"]');
745
+ var raw = (discEl && discEl.value != null) ? String(discEl.value).trim() : '';
746
+ if (isEcoLine) {
747
+ // Force full list price.
748
+ item.discPrice = Number(item.price) || 0;
749
+ item.ck_percent = undefined;
750
+ } else {
751
+ // Accept BOTH absolute VND ("2.000.000", "2tr", "200k") AND a
752
+ // chiết khấu PERCENT ("35%", "35") — parity with the quote modal's
753
+ // CK input / __applyCkPercent. A % applies minus that percent off the
754
+ // line's listed price; otherwise the raw number is the discounted price.
755
+ var price = Number(item.price) || 0;
756
+ var hasUnit = /(k|tr|trieu|m|nghin)$/i.test(raw);
757
+ var isPct = /%/.test(raw) || (/^\s*\d+(?:[.,]\d+)?\s*$/.test(raw) && price > 0 && parseFloat(raw.replace(',', '.')) <= 100 && price / parseFloat(raw.replace(',', '.')) >= 10 && !hasUnit);
758
+ if (isPct) {
759
+ var pct = parseFloat(raw.replace('%', '').replace(',', '.'));
760
+ if (!(pct > 0 && pct <= 90)) pct = 0;
761
+ item.discPrice = Math.round(price * (1 - pct / 100));
762
+ item.ck_percent = pct;
763
+ } else {
764
+ var num = 0;
765
+ if (hasUnit) {
766
+ var unit2 = String(raw).match(/(k|tr|trieu|m|nghin)$/i);
767
+ num = parseFloat(String(raw).replace(/[^\d.]/g, '')) || 0;
768
+ if (unit2) { var us2 = unit2[1].toLowerCase(); if (us2 === 'k' || us2 === 'nghin') num *= 1000; else if (us2 === 'tr' || us2 === 'trieu' || us2 === 'm') num *= 1000000; }
769
+ } else {
770
+ num = parseFloat(String(raw).replace(/[.,](?=\d{3})/g, '').replace(/[^\d.]/g, ''));
771
+ }
772
+ if (!(num > 0)) num = price || 0;
773
+ item.discPrice = Math.round(num);
774
+ var pp = Math.round((1 - num / (price || 1)) * 100);
775
+ item.ck_percent = (price > 0 && pp > 0 && pp <= 90) ? pp : undefined;
776
+ }
777
+ }
778
+ item.total = item.discPrice * (Number(item.qty) || 1);
779
  recomputeTotals(ord);
780
  var li = list.findIndex(function (x) { return String(x.code) === String(order.code); });
781
  if (li >= 0) list[li] = ord; saveOrders(list);
 
785
  if (gt) gt.textContent = money(ord.grandTotal || ord.total || 0);
786
  var sll = ov.querySelector('#od-total-sll');
787
  if (sll) sll.textContent = (ord.items || []).reduce(function (a, it) { return a + (Number(it.qty) || 0); }, 0);
788
+ // Reflect the (possibly %-normalised) discounted price back into the input.
789
+ if (discEl && !isEcoLine && item.discPrice > 0) discEl.value = item.discPrice.toLocaleString('vi-VN');
790
+ if (window.showToast) window.showToast('✅ Đã cập nhật CK' + (item.ck_percent ? ' ' + item.ck_percent + '%' : ''));
791
  } catch (e) { console.warn('[od] disc error:', e); }
792
  };
793
  // Parse an AI discount prompt like the quote modal (CK %, fees, cọc, ghi chú).