@asteby/storefront-react 0.26.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -2
- package/dist/account-server.cjs +533 -83
- package/dist/account-server.cjs.map +1 -1
- package/dist/account-server.d.cts +13 -2
- package/dist/account-server.d.ts +13 -2
- package/dist/account-server.js +23 -6
- package/dist/account-server.js.map +1 -1
- package/dist/account.cjs +572 -96
- package/dist/account.cjs.map +1 -1
- package/dist/account.d.cts +82 -45
- package/dist/account.d.ts +82 -45
- package/dist/account.js +53 -14
- package/dist/account.js.map +1 -1
- package/dist/checkout.cjs +114 -38
- package/dist/checkout.cjs.map +1 -1
- package/dist/checkout.d.cts +24 -1
- package/dist/checkout.d.ts +24 -1
- package/dist/checkout.js +114 -38
- package/dist/checkout.js.map +1 -1
- package/dist/chunk-BXKV2KWZ.js +291 -0
- package/dist/chunk-BXKV2KWZ.js.map +1 -0
- package/dist/chunk-LIUEQENV.js +156 -0
- package/dist/chunk-LIUEQENV.js.map +1 -0
- package/dist/voucher-document-FWH4DQ5N.js +72 -0
- package/dist/voucher-document-FWH4DQ5N.js.map +1 -0
- package/dist/voucher-pdf-LQC333AB.js +213 -0
- package/dist/voucher-pdf-LQC333AB.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-TXEYBDFG.js +0 -182
- package/dist/chunk-TXEYBDFG.js.map +0 -1
- package/dist/voucher-document-SFWJCLTN.js +0 -124
- package/dist/voucher-document-SFWJCLTN.js.map +0 -1
package/dist/account.cjs
CHANGED
|
@@ -15,6 +15,52 @@ var __export = (target, all) => {
|
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
// src/account/voucher.ts
|
|
18
|
+
function formatOf(v) {
|
|
19
|
+
const f = typeof v === "string" ? v.toLowerCase().replace(/[^a-z0-9]/g, "") : "";
|
|
20
|
+
if (f === "code128" || f === "c128" || f === "code128b" || f === "code128c") return "code128";
|
|
21
|
+
if (f === "code39" || f === "c39") return "code39";
|
|
22
|
+
if (f === "itf" || f === "itf14" || f === "i25" || f === "interleaved2of5") return "itf";
|
|
23
|
+
if (f === "ean13") return "ean13";
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
function barcodeOf(ext, raw) {
|
|
27
|
+
if ("barcode_data" in ext) {
|
|
28
|
+
const d = ext.barcode_data;
|
|
29
|
+
if (d && typeof d === "object") {
|
|
30
|
+
const o = d;
|
|
31
|
+
const value2 = text(o.value);
|
|
32
|
+
const format = formatOf(o.format);
|
|
33
|
+
if (value2 && format && barcodeModules(value2, format)) return { draw: { value: value2, format }, text: null };
|
|
34
|
+
return { draw: null, text: value2 ?? text(raw) };
|
|
35
|
+
}
|
|
36
|
+
return { draw: null, text: text(raw) };
|
|
37
|
+
}
|
|
38
|
+
if (raw && typeof raw === "object") {
|
|
39
|
+
const o = raw;
|
|
40
|
+
const value2 = text(o.value);
|
|
41
|
+
const format = formatOf(o.format ?? "code128");
|
|
42
|
+
return { draw: value2 && format ? { value: value2, format } : null, text: null };
|
|
43
|
+
}
|
|
44
|
+
const value = text(raw);
|
|
45
|
+
return { draw: value ? { value, format: "code128" } : null, text: null };
|
|
46
|
+
}
|
|
47
|
+
function instructionsKeyOf(raw) {
|
|
48
|
+
const k = raw?.replace(/^payment\.voucher\.instructions\./, "").toLowerCase() ?? "";
|
|
49
|
+
return !k ? null : k === "other" ? "generic" : k;
|
|
50
|
+
}
|
|
51
|
+
function httpsUrl(v) {
|
|
52
|
+
const s = typeof v === "string" ? v.trim() : "";
|
|
53
|
+
return /^https:\/\//i.test(s) && s.length <= 2048 ? s : null;
|
|
54
|
+
}
|
|
55
|
+
function kindOf(kind, method, key) {
|
|
56
|
+
for (const c of [kind, method, key]) {
|
|
57
|
+
const k = c?.toLowerCase();
|
|
58
|
+
if (!k || k === "other" || k === "generic") continue;
|
|
59
|
+
if (k === "oxxo" || k === "cash" || CASH_METHODS.has(k)) return "cash";
|
|
60
|
+
if (k === "spei" || k === "transfer" || TRANSFER_METHODS.has(k)) return "transfer";
|
|
61
|
+
}
|
|
62
|
+
return "generic";
|
|
63
|
+
}
|
|
18
64
|
function text(v) {
|
|
19
65
|
if (typeof v === "number" && Number.isFinite(v)) return String(v);
|
|
20
66
|
if (typeof v !== "string") return null;
|
|
@@ -31,19 +77,33 @@ function moneyOf(v) {
|
|
|
31
77
|
function voucherOf(p) {
|
|
32
78
|
const pay = p?.payment;
|
|
33
79
|
if (!pay || typeof pay !== "object") return null;
|
|
80
|
+
const ext = pay;
|
|
81
|
+
const method = text(pay.method ?? pay.provider);
|
|
82
|
+
const key = instructionsKeyOf(text(ext.instructions_key));
|
|
83
|
+
const bc = barcodeOf(ext, pay.barcode);
|
|
84
|
+
const clabe = text(pay.clabe);
|
|
85
|
+
let reference = text(pay.reference);
|
|
86
|
+
if (clabe && reference && digits(reference) === digits(clabe)) reference = null;
|
|
34
87
|
const v = {
|
|
35
|
-
method
|
|
36
|
-
reference
|
|
37
|
-
barcode:
|
|
38
|
-
|
|
88
|
+
method,
|
|
89
|
+
reference,
|
|
90
|
+
barcode: bc.draw?.value ?? null,
|
|
91
|
+
barcode_format: bc.draw?.format ?? null,
|
|
92
|
+
barcode_text: bc.text && bc.text !== reference ? bc.text : null,
|
|
93
|
+
clabe,
|
|
94
|
+
beneficiary: text(ext.beneficiary),
|
|
95
|
+
bank: text(ext.bank),
|
|
96
|
+
kind: kindOf(text(ext.kind), method, key),
|
|
97
|
+
instructions_key: key,
|
|
98
|
+
ticket_url: httpsUrl(ext.ticket_url) ?? httpsUrl(ext.voucher_url),
|
|
39
99
|
expires_at: text(pay.expires_at) ?? text(p?.expires_at),
|
|
40
100
|
amount: moneyOf(pay.amount) ?? moneyOf(p?.total),
|
|
41
101
|
instructions: text(pay.instructions)
|
|
42
102
|
};
|
|
43
|
-
return v.reference || v.barcode || v.clabe ? v : null;
|
|
103
|
+
return v.reference || v.barcode || v.barcode_text || v.clabe ? v : null;
|
|
44
104
|
}
|
|
45
105
|
function barcodeValue(v) {
|
|
46
|
-
return v.barcode
|
|
106
|
+
return v.barcode;
|
|
47
107
|
}
|
|
48
108
|
function code128Modules(value) {
|
|
49
109
|
if (!value || value.length > 80) return null;
|
|
@@ -64,8 +124,44 @@ function code128Modules(value) {
|
|
|
64
124
|
codes.push(sum % 103);
|
|
65
125
|
return codes.map((c) => BARS[c]).join("") + STOP;
|
|
66
126
|
}
|
|
127
|
+
function code39Modules(value) {
|
|
128
|
+
if (!value || value.length > 40) return null;
|
|
129
|
+
let out = "";
|
|
130
|
+
for (const ch of `*${value}*`) {
|
|
131
|
+
const p = Object.prototype.hasOwnProperty.call(CODE39_PATTERNS, ch) ? CODE39_PATTERNS[ch] : void 0;
|
|
132
|
+
if (!p || ch === "*" && value.includes("*")) return null;
|
|
133
|
+
for (let i = 0; i < 9; i++) out += (i % 2 === 0 ? "1" : "0").repeat(p[i] === "w" ? 3 : 1);
|
|
134
|
+
out += "0";
|
|
135
|
+
}
|
|
136
|
+
return out.slice(0, -1);
|
|
137
|
+
}
|
|
138
|
+
function itfModules(value) {
|
|
139
|
+
if (!value || value.length > 80 || value.length % 2 !== 0 || !/^\d+$/.test(value)) return null;
|
|
140
|
+
let out = "1010";
|
|
141
|
+
for (let i = 0; i < value.length; i += 2) {
|
|
142
|
+
const bars = ITF_DIGITS[Number(value[i])];
|
|
143
|
+
const spaces = ITF_DIGITS[Number(value[i + 1])];
|
|
144
|
+
for (let e = 0; e < 5; e++) out += "1".repeat(bars[e] === "w" ? 3 : 1) + "0".repeat(spaces[e] === "w" ? 3 : 1);
|
|
145
|
+
}
|
|
146
|
+
return out + "11101";
|
|
147
|
+
}
|
|
148
|
+
function ean13Modules(value) {
|
|
149
|
+
if (!/^\d{13}$/.test(value)) return null;
|
|
150
|
+
const d = [...value].map(Number);
|
|
151
|
+
const sum = d.slice(0, 12).reduce((a, n2, i) => a + n2 * (i % 2 === 0 ? 1 : 3), 0);
|
|
152
|
+
if ((10 - sum % 10) % 10 !== d[12]) return null;
|
|
153
|
+
const parity = EAN_PARITY[d[0]];
|
|
154
|
+
let out = "101";
|
|
155
|
+
for (let i = 0; i < 6; i++) out += (parity[i] === "L" ? EAN_L : EAN_G)[d[i + 1]];
|
|
156
|
+
out += "01010";
|
|
157
|
+
for (let i = 7; i < 13; i++) out += EAN_R[d[i]];
|
|
158
|
+
return out + "101";
|
|
159
|
+
}
|
|
160
|
+
function barcodeModules(value, format = "code128") {
|
|
161
|
+
return format === "code39" ? code39Modules(value) : format === "itf" ? itfModules(value) : format === "ean13" ? ean13Modules(value) : code128Modules(value);
|
|
162
|
+
}
|
|
67
163
|
function barcodeGeometry(value, opts = {}) {
|
|
68
|
-
const bits =
|
|
164
|
+
const bits = barcodeModules(value, opts.format);
|
|
69
165
|
if (!bits) return null;
|
|
70
166
|
const mod = opts.module ?? 2;
|
|
71
167
|
const quiet = 10;
|
|
@@ -82,10 +178,13 @@ function barcodeGeometry(value, opts = {}) {
|
|
|
82
178
|
}
|
|
83
179
|
return { width: (bits.length + quiet * 2) * mod, height: opts.height ?? 70, rects };
|
|
84
180
|
}
|
|
85
|
-
var MAX, BARS, STOP;
|
|
181
|
+
var MAX, CASH_METHODS, TRANSFER_METHODS, digits, BARS, STOP, C39_CHARS, C39_WIDE, CODE39_PATTERNS, ITF_DIGITS, EAN_L, EAN_R, EAN_G, EAN_PARITY;
|
|
86
182
|
var init_voucher = __esm({
|
|
87
183
|
"src/account/voucher.ts"() {
|
|
88
184
|
MAX = 256;
|
|
185
|
+
CASH_METHODS = /* @__PURE__ */ new Set(["oxxo", "cash", "store", "convenience_store", "efectivo", "bank_deposit", "deposit", "paynet", "paycash", "bancomer", "7eleven", "seven_eleven", "farmacias_guadalajara", "circle_k"]);
|
|
186
|
+
TRANSFER_METHODS = /* @__PURE__ */ new Set(["spei", "bank_transfer", "transfer", "wire", "clabe"]);
|
|
187
|
+
digits = (s) => s ? s.replace(/\D/g, "") : "";
|
|
89
188
|
BARS = [
|
|
90
189
|
"11011001100",
|
|
91
190
|
"11001101100",
|
|
@@ -195,17 +294,33 @@ var init_voucher = __esm({
|
|
|
195
294
|
"11010011100"
|
|
196
295
|
];
|
|
197
296
|
STOP = "1100011101011";
|
|
297
|
+
C39_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. */+%$";
|
|
298
|
+
C39_WIDE = "346038238023348034234368036236058258025458045245568056256456078278027478047247678067267467018128012148014124168016126146137157357135";
|
|
299
|
+
CODE39_PATTERNS = Object.fromEntries(
|
|
300
|
+
[...C39_CHARS].map((ch, i) => [ch, [...Array(9).keys()].map((e) => C39_WIDE.slice(i * 3, i * 3 + 3).includes(String(e)) ? "w" : "n").join("")])
|
|
301
|
+
);
|
|
302
|
+
ITF_DIGITS = ["nnwwn", "wnnnw", "nwnnw", "wwnnn", "nnwnw", "wnwnn", "nwwnn", "nnnww", "wnnwn", "nwnwn"];
|
|
303
|
+
EAN_L = ["0001101", "0011001", "0010011", "0111101", "0100011", "0110001", "0101111", "0111011", "0110111", "0001011"];
|
|
304
|
+
EAN_R = EAN_L.map((c) => [...c].map((b) => b === "1" ? "0" : "1").join(""));
|
|
305
|
+
EAN_G = EAN_R.map((c) => [...c].reverse().join(""));
|
|
306
|
+
EAN_PARITY = ["LLLLLL", "LLGLGG", "LLGGLG", "LLGGGL", "LGLLGG", "LGGLLG", "LGGGLL", "LGLGLG", "LGLGGL", "LGGLGL"];
|
|
198
307
|
}
|
|
199
308
|
});
|
|
200
309
|
|
|
201
|
-
// src/account/voucher-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
310
|
+
// src/account/voucher-text.ts
|
|
311
|
+
function docText(locale) {
|
|
312
|
+
return isEnglish(locale) ? EN5 : ES5;
|
|
313
|
+
}
|
|
314
|
+
function methodName(v, t) {
|
|
315
|
+
return v.method ? own(t.methods, v.method) ?? v.method : t.cash;
|
|
316
|
+
}
|
|
317
|
+
function voucherSteps(v, t) {
|
|
318
|
+
const fn = own(t.steps, v.instructions_key) ?? own(t.steps, v.method) ?? (v.kind === "cash" ? t.steps.cash : v.kind === "transfer" ? t.steps.transfer : t.steps.generic);
|
|
319
|
+
return fn(v);
|
|
320
|
+
}
|
|
321
|
+
function voucherFields(v, t) {
|
|
322
|
+
const f = (key, label, value) => value ? [{ key, label, value }] : [];
|
|
323
|
+
return v.kind === "transfer" ? [...f("beneficiary", t.beneficiary, v.beneficiary), ...f("bank", t.bank, v.bank), ...f("clabe", t.clabe, v.clabe), ...f("reference", t.reference, v.reference), ...f("code", t.code, v.barcode_text)] : [...f("reference", t.reference, v.reference), ...f("clabe", t.clabe, v.clabe), ...f("beneficiary", t.beneficiary, v.beneficiary), ...f("bank", t.bank, v.bank), ...f("code", t.code, v.barcode_text)];
|
|
209
324
|
}
|
|
210
325
|
function formatMoney3(m, locale) {
|
|
211
326
|
if (!m) return "";
|
|
@@ -225,85 +340,401 @@ function formatDate2(iso, locale, timeZone) {
|
|
|
225
340
|
return d.toISOString();
|
|
226
341
|
}
|
|
227
342
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
function renderVoucherDocument(v, opts = {}) {
|
|
235
|
-
const locale = opts.locale ?? "es-MX";
|
|
236
|
-
const t = locale.toLowerCase().startsWith("en") ? EN5 : ES5;
|
|
237
|
-
const shop = opts.shopName || "";
|
|
238
|
-
const method = v.method ? Object.prototype.hasOwnProperty.call(t.methods, v.method.toLowerCase()) ? t.methods[v.method.toLowerCase()] : v.method : t.cash;
|
|
239
|
-
const isSpei = !!v.clabe && !v.reference;
|
|
240
|
-
const code = barcodeValue(v);
|
|
241
|
-
const svg = code ? barcodeSvg(code, t.barcode) : null;
|
|
242
|
-
const expires = formatDate2(v.expires_at, locale, opts.timeZone);
|
|
243
|
-
const field = (label, value) => value ? `<div class="box"><div class="label">${esc(label)}</div><div class="value">${esc(value)}</div></div>` : "";
|
|
244
|
-
const steps = isSpei ? t.stepsSpei : t.stepsCash;
|
|
245
|
-
const subtitle = [shop, method, opts.number ? `${t.order} ${opts.number}` : ""].filter(Boolean).map(esc).join(" \xB7 ");
|
|
246
|
-
return `<!doctype html>
|
|
247
|
-
<html lang="${esc(locale)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
248
|
-
<meta name="robots" content="noindex"><title>${esc(t.title)}${shop ? ` - ${esc(shop)}` : ""}</title><style>${CSS}</style></head>
|
|
249
|
-
<body><main>
|
|
250
|
-
<div class="head"><div><h1>${esc(t.title)}</h1><div class="muted">${subtitle}</div></div>
|
|
251
|
-
${v.amount ? `<div><div class="label" style="text-align:right">${esc(t.total)}</div><div class="amount">${esc(formatMoney3(v.amount, locale))}</div></div>` : ""}</div>
|
|
252
|
-
${field(t.reference, v.reference)}${field(t.clabe, v.clabe)}
|
|
253
|
-
${svg ? `<div class="bar">${svg}<div class="muted" style="font-family:ui-monospace,monospace">${esc(code)}</div></div>` : ""}
|
|
254
|
-
${expires ? `<p><strong>${esc(t.expires)}:</strong> ${esc(expires)}. ${esc(t.expiresNote)}</p>` : ""}
|
|
255
|
-
<ol class="steps">${steps.map((s) => `<li>${esc(s)}</li>`).join("")}</ol>
|
|
256
|
-
${v.instructions ? `<p class="note pre muted">${esc(v.instructions)}</p>` : ""}
|
|
257
|
-
<p class="note muted">${esc(t.footer)}</p>
|
|
258
|
-
${opts.printButton ? `<div class="actions"><button type="button" id="print">${esc(t.print)}</button></div>` : ""}
|
|
259
|
-
</main>
|
|
260
|
-
${opts.printButton || opts.autoPrint ? `<script${opts.nonce ? ` nonce="${esc(opts.nonce)}"` : ""}>(function(){var b=document.getElementById("print");if(b)b.addEventListener("click",function(){window.print()});${opts.autoPrint ? 'window.addEventListener("load",function(){setTimeout(function(){window.print()},300)});' : ""}})();</script>` : ""}
|
|
261
|
-
</body></html>`;
|
|
262
|
-
}
|
|
263
|
-
var ES5, EN5, CSS;
|
|
264
|
-
var init_voucher_document = __esm({
|
|
265
|
-
"src/account/voucher-document.ts"() {
|
|
266
|
-
init_voucher();
|
|
343
|
+
var KEEP_ES, KEEP_EN, ES5, EN5, isEnglish, own;
|
|
344
|
+
var init_voucher_text = __esm({
|
|
345
|
+
"src/account/voucher-text.ts"() {
|
|
346
|
+
KEEP_ES = "Conserva tu comprobante: confirmaremos tu pago autom\xE1ticamente.";
|
|
347
|
+
KEEP_EN = "Keep your receipt: we will confirm your payment automatically.";
|
|
267
348
|
ES5 = {
|
|
268
349
|
title: "Ficha de pago",
|
|
269
350
|
total: "Total a pagar",
|
|
270
351
|
reference: "Referencia",
|
|
271
352
|
clabe: "CLABE",
|
|
353
|
+
beneficiary: "Beneficiario",
|
|
354
|
+
bank: "Banco",
|
|
272
355
|
expires: "Vence",
|
|
273
356
|
expiresNote: "Pasada esa fecha la ficha deja de ser v\xE1lida.",
|
|
274
357
|
order: "Pedido",
|
|
275
358
|
barcode: "C\xF3digo de barras",
|
|
276
|
-
|
|
359
|
+
code: "C\xF3digo",
|
|
360
|
+
print: "Imprimir",
|
|
361
|
+
downloadPdf: "Descargar PDF",
|
|
362
|
+
noScript: "Para imprimir usa la opci\xF3n Imprimir de tu navegador (Ctrl+P) o descarga el PDF.",
|
|
363
|
+
stepsTitle: "C\xF3mo pagar",
|
|
277
364
|
footer: "Tu pedido se genera cuando se confirma el pago. Esta ficha es de un solo uso; no la compartas.",
|
|
278
|
-
stepsCash: [
|
|
279
|
-
"Acude a la tienda OXXO (o el comercio indicado) y di que vas a hacer un pago de servicio en efectivo.",
|
|
280
|
-
"Muestra el c\xF3digo de barras o dicta la referencia y paga el monto exacto.",
|
|
281
|
-
"Conserva tu comprobante: confirmaremos tu pago autom\xE1ticamente."
|
|
282
|
-
],
|
|
283
|
-
stepsSpei: ["Entra a la banca en l\xEDnea o app de tu banco.", "Haz una transferencia SPEI a la CLABE indicada por el monto exacto.", "Conserva tu comprobante: confirmaremos tu pago autom\xE1ticamente."],
|
|
284
365
|
methods: { oxxo: "OXXO", spei: "Transferencia SPEI", bank_transfer: "Transferencia bancaria", bank_deposit: "Dep\xF3sito bancario", cash: "Pago en efectivo" },
|
|
285
|
-
cash: "Pago en efectivo"
|
|
366
|
+
cash: "Pago en efectivo",
|
|
367
|
+
steps: {
|
|
368
|
+
oxxo: (v) => [
|
|
369
|
+
"Acude a cualquier tienda OXXO y di que vas a hacer un pago de servicio en efectivo.",
|
|
370
|
+
v.barcode ? "Muestra el c\xF3digo de barras en caja o dicta la referencia, y paga el monto exacto." : "Dicta la referencia en caja y paga el monto exacto.",
|
|
371
|
+
KEEP_ES
|
|
372
|
+
],
|
|
373
|
+
cash: (v) => [
|
|
374
|
+
"Acude a la tienda o comercio indicado y di que vas a hacer un pago en efectivo.",
|
|
375
|
+
v.barcode ? "Muestra el c\xF3digo de barras o dicta la referencia, y paga el monto exacto." : "Dicta la referencia y paga el monto exacto.",
|
|
376
|
+
KEEP_ES
|
|
377
|
+
],
|
|
378
|
+
spei: (v) => [
|
|
379
|
+
"Entra a la banca en l\xEDnea o a la app de tu banco.",
|
|
380
|
+
"Haz una transferencia SPEI a la CLABE indicada, por el monto exacto.",
|
|
381
|
+
...v.reference ? ["Escribe la referencia de esta ficha en el concepto o referencia de la transferencia."] : [],
|
|
382
|
+
KEEP_ES
|
|
383
|
+
],
|
|
384
|
+
bank_transfer: (v) => [
|
|
385
|
+
"Entra a la banca en l\xEDnea o a la app de tu banco.",
|
|
386
|
+
"Haz una transferencia a la cuenta o CLABE indicada, por el monto exacto.",
|
|
387
|
+
...v.reference ? ["Escribe la referencia de esta ficha en el concepto de la transferencia."] : [],
|
|
388
|
+
KEEP_ES
|
|
389
|
+
],
|
|
390
|
+
bank_deposit: (v) => [
|
|
391
|
+
"Acude a una sucursal del banco indicado o a su cajero con dep\xF3sitos.",
|
|
392
|
+
`Deposita el monto exacto a la cuenta${v.reference ? " con la referencia de esta ficha" : " indicada"}.`,
|
|
393
|
+
KEEP_ES
|
|
394
|
+
],
|
|
395
|
+
transfer: (v) => [
|
|
396
|
+
"Entra a la banca en l\xEDnea o a la app de tu banco.",
|
|
397
|
+
"Haz una transferencia a la CLABE indicada, por el monto exacto.",
|
|
398
|
+
...v.reference ? ["Escribe la referencia de esta ficha en el concepto de la transferencia."] : [],
|
|
399
|
+
KEEP_ES
|
|
400
|
+
],
|
|
401
|
+
generic: () => ["Realiza el pago con los datos de esta ficha, por el monto exacto y antes de que venza.", KEEP_ES]
|
|
402
|
+
}
|
|
286
403
|
};
|
|
287
404
|
EN5 = {
|
|
288
405
|
title: "Payment voucher",
|
|
289
406
|
total: "Amount to pay",
|
|
290
407
|
reference: "Reference",
|
|
291
408
|
clabe: "CLABE",
|
|
409
|
+
beneficiary: "Beneficiary",
|
|
410
|
+
bank: "Bank",
|
|
292
411
|
expires: "Expires",
|
|
293
412
|
expiresNote: "After that date the voucher is no longer valid.",
|
|
294
413
|
order: "Order",
|
|
295
414
|
barcode: "Barcode",
|
|
296
|
-
|
|
415
|
+
code: "Code",
|
|
416
|
+
print: "Print",
|
|
417
|
+
downloadPdf: "Download PDF",
|
|
418
|
+
noScript: "To print, use your browser's Print option (Ctrl+P) or download the PDF.",
|
|
419
|
+
stepsTitle: "How to pay",
|
|
297
420
|
footer: "Your order is created when the payment is confirmed. This voucher is single-use; do not share it.",
|
|
298
|
-
stepsCash: [
|
|
299
|
-
"Go to an OXXO store (or the store indicated) and say you want to make a cash service payment.",
|
|
300
|
-
"Show the barcode or read out the reference and pay the exact amount.",
|
|
301
|
-
"Keep your receipt: we will confirm your payment automatically."
|
|
302
|
-
],
|
|
303
|
-
stepsSpei: ["Open your bank online or app.", "Make a SPEI transfer to the CLABE below for the exact amount.", "Keep your receipt: we will confirm your payment automatically."],
|
|
304
421
|
methods: { oxxo: "OXXO", spei: "SPEI transfer", bank_transfer: "Bank transfer", bank_deposit: "Bank deposit", cash: "Cash payment" },
|
|
305
|
-
cash: "Cash payment"
|
|
422
|
+
cash: "Cash payment",
|
|
423
|
+
steps: {
|
|
424
|
+
oxxo: (v) => [
|
|
425
|
+
"Go to any OXXO store and say you want to make a cash service payment.",
|
|
426
|
+
v.barcode ? "Show the barcode at the register or read out the reference, and pay the exact amount." : "Read out the reference at the register and pay the exact amount.",
|
|
427
|
+
KEEP_EN
|
|
428
|
+
],
|
|
429
|
+
cash: (v) => [
|
|
430
|
+
"Go to the store indicated and say you want to make a cash payment.",
|
|
431
|
+
v.barcode ? "Show the barcode or read out the reference, and pay the exact amount." : "Read out the reference and pay the exact amount.",
|
|
432
|
+
KEEP_EN
|
|
433
|
+
],
|
|
434
|
+
spei: (v) => [
|
|
435
|
+
"Open your online banking or your bank app.",
|
|
436
|
+
"Make a SPEI transfer to the CLABE below for the exact amount.",
|
|
437
|
+
...v.reference ? ["Enter the reference of this voucher as the transfer concept or reference."] : [],
|
|
438
|
+
KEEP_EN
|
|
439
|
+
],
|
|
440
|
+
bank_transfer: (v) => [
|
|
441
|
+
"Open your online banking or your bank app.",
|
|
442
|
+
"Make a transfer to the account or CLABE below for the exact amount.",
|
|
443
|
+
...v.reference ? ["Enter the reference of this voucher as the transfer concept."] : [],
|
|
444
|
+
KEEP_EN
|
|
445
|
+
],
|
|
446
|
+
bank_deposit: (v) => [
|
|
447
|
+
"Go to a branch of the bank indicated or to one of its deposit ATMs.",
|
|
448
|
+
`Deposit the exact amount to the account${v.reference ? " with the reference of this voucher" : " indicated"}.`,
|
|
449
|
+
KEEP_EN
|
|
450
|
+
],
|
|
451
|
+
transfer: (v) => [
|
|
452
|
+
"Open your online banking or your bank app.",
|
|
453
|
+
"Make a transfer to the CLABE below for the exact amount.",
|
|
454
|
+
...v.reference ? ["Enter the reference of this voucher as the transfer concept."] : [],
|
|
455
|
+
KEEP_EN
|
|
456
|
+
],
|
|
457
|
+
generic: () => ["Make the payment with the details of this voucher, for the exact amount and before it expires.", KEEP_EN]
|
|
458
|
+
}
|
|
459
|
+
};
|
|
460
|
+
isEnglish = (locale) => locale.toLowerCase().startsWith("en");
|
|
461
|
+
own = (o, k) => {
|
|
462
|
+
const key = k?.toLowerCase();
|
|
463
|
+
return key && Object.prototype.hasOwnProperty.call(o, key) ? o[key] : void 0;
|
|
306
464
|
};
|
|
465
|
+
}
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
// src/account/voucher-pdf.ts
|
|
469
|
+
var voucher_pdf_exports = {};
|
|
470
|
+
__export(voucher_pdf_exports, {
|
|
471
|
+
MAX_VOUCHER_PDF_BYTES: () => MAX_VOUCHER_PDF_BYTES,
|
|
472
|
+
pdfString: () => pdfString,
|
|
473
|
+
renderVoucherPdf: () => renderVoucherPdf
|
|
474
|
+
});
|
|
475
|
+
function toBytes(s) {
|
|
476
|
+
const out = [];
|
|
477
|
+
for (const ch of s) {
|
|
478
|
+
const c = ch.codePointAt(0);
|
|
479
|
+
if (c < 32 || c === 127) out.push(32);
|
|
480
|
+
else if (c < 127 || c >= 160 && c <= 255) out.push(c);
|
|
481
|
+
else out.push(CP1252[c] ?? 63);
|
|
482
|
+
}
|
|
483
|
+
return out;
|
|
484
|
+
}
|
|
485
|
+
function pdfString(s) {
|
|
486
|
+
let o = "(";
|
|
487
|
+
for (const b of toBytes(s)) o += b >= 32 && b < 127 && b !== 40 && b !== 41 && b !== 92 ? String.fromCharCode(b) : `\\${b.toString(8).padStart(3, "0")}`;
|
|
488
|
+
return o + ")";
|
|
489
|
+
}
|
|
490
|
+
function charWidth(font, ch) {
|
|
491
|
+
if (font === "F3" || font === "F4") return 600;
|
|
492
|
+
const c = ch.codePointAt(0);
|
|
493
|
+
const table = font === "F2" ? HELV_B : HELV;
|
|
494
|
+
if (c >= 32 && c < 127) return table[c - 32];
|
|
495
|
+
const base = ch.normalize("NFD")[0].codePointAt(0);
|
|
496
|
+
return base >= 32 && base < 127 ? table[base - 32] : 556;
|
|
497
|
+
}
|
|
498
|
+
function wrap(font, size, text2, max) {
|
|
499
|
+
const lines = [];
|
|
500
|
+
for (const para of text2.split(/\r?\n/)) {
|
|
501
|
+
let line = "";
|
|
502
|
+
for (const word of para.split(/\s+/).filter(Boolean)) {
|
|
503
|
+
let w = word;
|
|
504
|
+
while (textWidth(font, size, w) > max) {
|
|
505
|
+
let n2 = 1;
|
|
506
|
+
while (n2 < w.length && textWidth(font, size, w.slice(0, n2 + 1)) <= max) n2++;
|
|
507
|
+
if (line) lines.push(line), line = "";
|
|
508
|
+
lines.push(w.slice(0, n2));
|
|
509
|
+
w = w.slice(n2);
|
|
510
|
+
}
|
|
511
|
+
const next = line ? `${line} ${w}` : w;
|
|
512
|
+
if (line && textWidth(font, size, next) > max) lines.push(line), line = w;
|
|
513
|
+
else line = next;
|
|
514
|
+
}
|
|
515
|
+
lines.push(line);
|
|
516
|
+
}
|
|
517
|
+
return lines;
|
|
518
|
+
}
|
|
519
|
+
function renderVoucherPdf(v, opts = {}) {
|
|
520
|
+
const locale = opts.locale ?? "es-MX";
|
|
521
|
+
const t = docText(locale);
|
|
522
|
+
const [W, H] = opts.paper === "letter" ? [612, 792] : [595.28, 841.89];
|
|
523
|
+
const M = 54;
|
|
524
|
+
const right = W - M;
|
|
525
|
+
const inner = right - M;
|
|
526
|
+
const pages = [];
|
|
527
|
+
let ops = "";
|
|
528
|
+
let y = H - M;
|
|
529
|
+
const newPage = () => {
|
|
530
|
+
if (pages.length >= MAX_PAGES) return false;
|
|
531
|
+
if (ops) pages.push(ops);
|
|
532
|
+
ops = "";
|
|
533
|
+
y = H - M;
|
|
534
|
+
return true;
|
|
535
|
+
};
|
|
536
|
+
const text2 = (font, size, x, s, gray = 0) => {
|
|
537
|
+
ops += `BT ${n(gray)} g /${font} ${size} Tf ${n(x)} ${n(y)} Td ${pdfString(s)} Tj ET
|
|
538
|
+
`;
|
|
539
|
+
};
|
|
540
|
+
const ensure = (h) => {
|
|
541
|
+
if (y - h < M) newPage();
|
|
542
|
+
};
|
|
543
|
+
const paragraph = (font, size, s, opt = {}) => {
|
|
544
|
+
const lead = opt.lead ?? size * 1.4;
|
|
545
|
+
for (const line of wrap(font, size, s, opt.width ?? inner)) {
|
|
546
|
+
ensure(lead);
|
|
547
|
+
y -= lead;
|
|
548
|
+
if (line) text2(font, size, opt.x ?? M, line, opt.gray ?? 0);
|
|
549
|
+
}
|
|
550
|
+
};
|
|
551
|
+
const amount = formatMoney3(v.amount, locale);
|
|
552
|
+
const top = y;
|
|
553
|
+
y -= 20;
|
|
554
|
+
text2("F2", 20, M, t.title);
|
|
555
|
+
const subtitle = [opts.shopName, methodName(v, t), opts.number ? `${t.order} ${opts.number}` : ""].filter(Boolean).join(" \xB7 ");
|
|
556
|
+
if (subtitle) {
|
|
557
|
+
y -= 15;
|
|
558
|
+
paragraph("F1", 10, subtitle, { width: amount ? inner * 0.6 : inner, gray: 0.33, lead: 12 });
|
|
559
|
+
}
|
|
560
|
+
const afterTitle = y;
|
|
561
|
+
if (amount) {
|
|
562
|
+
y = top - 10;
|
|
563
|
+
const label = t.total.toUpperCase();
|
|
564
|
+
text2("F1", 8, right - textWidth("F1", 8, label), label, 0.33);
|
|
565
|
+
y -= 22;
|
|
566
|
+
text2("F2", 22, right - textWidth("F2", 22, amount), amount);
|
|
567
|
+
}
|
|
568
|
+
y = Math.min(afterTitle, y) - 10;
|
|
569
|
+
ops += `0 g 2 w ${n(M)} ${n(y)} m ${n(right)} ${n(y)} l S
|
|
570
|
+
`;
|
|
571
|
+
y -= 8;
|
|
572
|
+
for (const f of voucherFields(v, t)) {
|
|
573
|
+
const size = f.value.length > 36 ? 12 : 16;
|
|
574
|
+
const lines = wrap("F3", size, f.value, inner - 24);
|
|
575
|
+
const h = 14 + 12 + lines.length * size * 1.3 + 8;
|
|
576
|
+
ensure(h + 12);
|
|
577
|
+
y -= 12;
|
|
578
|
+
ops += `0 G 0.8 w ${n(M)} ${n(y - h)} ${n(inner)} ${n(h)} re S
|
|
579
|
+
`;
|
|
580
|
+
const boxTop = y;
|
|
581
|
+
y -= 16;
|
|
582
|
+
text2("F1", 8, M + 12, f.label.toUpperCase(), 0.33);
|
|
583
|
+
y -= 4;
|
|
584
|
+
for (const line of lines) {
|
|
585
|
+
y -= size * 1.3;
|
|
586
|
+
text2("F3", size, M + 12, line);
|
|
587
|
+
}
|
|
588
|
+
y = boxTop - h;
|
|
589
|
+
}
|
|
590
|
+
const g = v.barcode ? barcodeGeometry(v.barcode, { ...v.barcode_format ? { format: v.barcode_format } : {}, height: 60 }) : null;
|
|
591
|
+
if (g && v.barcode) {
|
|
592
|
+
const scale = Math.min(1, inner / g.width) * 0.75;
|
|
593
|
+
const bw = g.width * scale;
|
|
594
|
+
const bh = 60;
|
|
595
|
+
ensure(bh + 40);
|
|
596
|
+
y -= 18;
|
|
597
|
+
ops += `0 g
|
|
598
|
+
`;
|
|
599
|
+
const x0 = M + (inner - bw) / 2;
|
|
600
|
+
for (const r of g.rects) ops += `${n(x0 + r.x * scale)} ${n(y - bh)} ${n(r.w * scale)} ${n(bh)} re f
|
|
601
|
+
`;
|
|
602
|
+
y -= bh + 12;
|
|
603
|
+
const cw = textWidth("F4", 10, v.barcode);
|
|
604
|
+
text2("F4", 10, M + (inner - Math.min(cw, inner)) / 2, v.barcode.slice(0, Math.floor(inner / 6)));
|
|
605
|
+
y -= 4;
|
|
606
|
+
}
|
|
607
|
+
const expires = formatDate2(v.expires_at, locale, opts.timeZone);
|
|
608
|
+
if (expires) {
|
|
609
|
+
y -= 8;
|
|
610
|
+
paragraph("F2", 10, `${t.expires}: ${expires.replace(/\.$/, "")}.`);
|
|
611
|
+
paragraph("F1", 10, t.expiresNote);
|
|
612
|
+
}
|
|
613
|
+
y -= 10;
|
|
614
|
+
ensure(40);
|
|
615
|
+
paragraph("F2", 12, t.stepsTitle, { lead: 16 });
|
|
616
|
+
voucherSteps(v, t).forEach((s, i) => {
|
|
617
|
+
const lines = wrap("F1", 10, s, inner - 18);
|
|
618
|
+
ensure(lines.length * 14 + 2);
|
|
619
|
+
y -= 2;
|
|
620
|
+
lines.forEach((line, j) => {
|
|
621
|
+
y -= 14;
|
|
622
|
+
if (j === 0) text2("F1", 10, M, `${i + 1}.`);
|
|
623
|
+
text2("F1", 10, M + 18, line);
|
|
624
|
+
});
|
|
625
|
+
});
|
|
626
|
+
if (v.instructions) {
|
|
627
|
+
y -= 6;
|
|
628
|
+
paragraph("F1", 9, v.instructions, { gray: 0.33, lead: 12 });
|
|
629
|
+
}
|
|
630
|
+
y -= 8;
|
|
631
|
+
paragraph("F1", 8, t.footer, { gray: 0.33, lead: 11 });
|
|
632
|
+
pages.push(ops);
|
|
633
|
+
const objs = [];
|
|
634
|
+
const kids = pages.map((_, i) => `${8 + i * 2} 0 R`).join(" ");
|
|
635
|
+
objs[1] = "<< /Type /Catalog /Pages 2 0 R >>";
|
|
636
|
+
objs[2] = `<< /Type /Pages /Kids [${kids}] /Count ${pages.length} >>`;
|
|
637
|
+
["F1", "F2", "F3", "F4"].forEach((f, i) => objs[3 + i] = `<< /Type /Font /Subtype /Type1 /BaseFont /${FONT_NAMES[f]} /Encoding /WinAnsiEncoding >>`);
|
|
638
|
+
objs[7] = `<< /Title ${pdfString(`${t.title}${opts.shopName ? ` - ${opts.shopName}` : ""}`)} /Producer ${pdfString("@asteby/storefront-react")} >>`;
|
|
639
|
+
pages.forEach((content, i) => {
|
|
640
|
+
objs[8 + i * 2] = `<< /Type /Page /Parent 2 0 R /MediaBox [0 0 ${n(W)} ${n(H)}] /Resources << /Font << /F1 3 0 R /F2 4 0 R /F3 5 0 R /F4 6 0 R >> >> /Contents ${9 + i * 2} 0 R >>`;
|
|
641
|
+
objs[9 + i * 2] = `<< /Length ${content.length} >>
|
|
642
|
+
stream
|
|
643
|
+
${content}endstream`;
|
|
644
|
+
});
|
|
645
|
+
let out = "%PDF-1.4\n%\xE2\xE3\xCF\xD3\n";
|
|
646
|
+
const offsets = [];
|
|
647
|
+
for (let i = 1; i < objs.length; i++) {
|
|
648
|
+
offsets[i] = out.length;
|
|
649
|
+
out += `${i} 0 obj
|
|
650
|
+
${objs[i]}
|
|
651
|
+
endobj
|
|
652
|
+
`;
|
|
653
|
+
}
|
|
654
|
+
const xref = out.length;
|
|
655
|
+
out += `xref
|
|
656
|
+
0 ${objs.length}
|
|
657
|
+
0000000000 65535 f
|
|
658
|
+
`;
|
|
659
|
+
for (let i = 1; i < objs.length; i++) out += `${String(offsets[i]).padStart(10, "0")} 00000 n
|
|
660
|
+
`;
|
|
661
|
+
out += `trailer
|
|
662
|
+
<< /Size ${objs.length} /Root 1 0 R /Info 7 0 R >>
|
|
663
|
+
startxref
|
|
664
|
+
${xref}
|
|
665
|
+
%%EOF
|
|
666
|
+
`;
|
|
667
|
+
if (out.length > MAX_VOUCHER_PDF_BYTES) throw new RangeError("voucher PDF too large");
|
|
668
|
+
const bytes = new Uint8Array(out.length);
|
|
669
|
+
for (let i = 0; i < out.length; i++) bytes[i] = out.charCodeAt(i) & 255;
|
|
670
|
+
return bytes;
|
|
671
|
+
}
|
|
672
|
+
var MAX_VOUCHER_PDF_BYTES, MAX_PAGES, HELV, HELV_B, FONT_NAMES, CP1252, textWidth, n;
|
|
673
|
+
var init_voucher_pdf = __esm({
|
|
674
|
+
"src/account/voucher-pdf.ts"() {
|
|
675
|
+
init_voucher();
|
|
676
|
+
init_voucher_text();
|
|
677
|
+
MAX_VOUCHER_PDF_BYTES = 256 * 1024;
|
|
678
|
+
MAX_PAGES = 3;
|
|
679
|
+
HELV = [278, 278, 355, 556, 556, 889, 667, 191, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 278, 278, 584, 584, 584, 556, 1015, 667, 667, 722, 722, 667, 611, 778, 722, 278, 500, 667, 556, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 278, 278, 278, 469, 556, 333, 556, 556, 500, 556, 556, 278, 556, 556, 222, 222, 500, 222, 833, 556, 556, 556, 556, 333, 500, 278, 556, 500, 722, 500, 500, 500, 334, 260, 334, 584];
|
|
680
|
+
HELV_B = [278, 333, 474, 556, 556, 889, 722, 238, 333, 333, 389, 584, 278, 333, 278, 278, 556, 556, 556, 556, 556, 556, 556, 556, 556, 556, 333, 333, 584, 584, 584, 611, 975, 722, 722, 722, 722, 667, 611, 778, 722, 278, 556, 722, 611, 833, 722, 778, 667, 778, 722, 667, 611, 722, 667, 944, 667, 667, 611, 333, 278, 333, 584, 556, 333, 556, 611, 556, 611, 556, 333, 611, 611, 278, 278, 556, 278, 889, 611, 611, 611, 611, 389, 556, 333, 611, 556, 778, 556, 556, 500, 389, 280, 389, 584];
|
|
681
|
+
FONT_NAMES = { F1: "Helvetica", F2: "Helvetica-Bold", F3: "Courier-Bold", F4: "Courier" };
|
|
682
|
+
CP1252 = { 8364: 128, 8216: 145, 8217: 146, 8220: 147, 8221: 148, 8226: 149, 8211: 150, 8212: 151 };
|
|
683
|
+
textWidth = (font, size, s) => [...s].reduce((w, ch) => w + charWidth(font, ch), 0) * size / 1e3;
|
|
684
|
+
n = (x) => String(Math.round(x * 100) / 100);
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
// src/account/voucher-document.ts
|
|
689
|
+
var voucher_document_exports = {};
|
|
690
|
+
__export(voucher_document_exports, {
|
|
691
|
+
esc: () => esc,
|
|
692
|
+
renderVoucherDocument: () => renderVoucherDocument
|
|
693
|
+
});
|
|
694
|
+
function esc(s) {
|
|
695
|
+
return s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
696
|
+
}
|
|
697
|
+
function barcodeSvg(value, format, label) {
|
|
698
|
+
const g = barcodeGeometry(value, { ...format ? { format } : {} });
|
|
699
|
+
if (!g) return null;
|
|
700
|
+
const rects = g.rects.map((r) => `<rect x="${r.x}" y="0" width="${r.w}" height="${g.height}"/>`).join("");
|
|
701
|
+
return `<svg viewBox="0 0 ${g.width} ${g.height}" width="${g.width}" height="${g.height}" role="img" aria-label="${esc(label)} ${esc(value)}" shape-rendering="crispEdges" fill="#000">${rects}</svg>`;
|
|
702
|
+
}
|
|
703
|
+
function renderVoucherDocument(v, opts = {}) {
|
|
704
|
+
const locale = opts.locale ?? "es-MX";
|
|
705
|
+
const t = docText(locale);
|
|
706
|
+
const shop = opts.shopName || "";
|
|
707
|
+
const method = methodName(v, t);
|
|
708
|
+
const code = v.barcode;
|
|
709
|
+
const svg = code ? barcodeSvg(code, v.barcode_format, t.barcode) : null;
|
|
710
|
+
const expires = formatDate2(v.expires_at, locale, opts.timeZone);
|
|
711
|
+
const fields = voucherFields(v, t);
|
|
712
|
+
const steps = voucherSteps(v, t);
|
|
713
|
+
const subtitle = [shop, method, opts.number ? `${t.order} ${opts.number}` : ""].filter(Boolean).map(esc).join(" \xB7 ");
|
|
714
|
+
const actions = opts.printButton || opts.pdfHref;
|
|
715
|
+
return `<!doctype html>
|
|
716
|
+
<html lang="${esc(locale)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
717
|
+
<meta name="robots" content="noindex"><title>${esc(t.title)}${shop ? ` - ${esc(shop)}` : ""}</title><style>${CSS}</style></head>
|
|
718
|
+
<body><main aria-labelledby="t">
|
|
719
|
+
<header class="head"><div><h1 id="t">${esc(t.title)}</h1><p class="muted" data-voucher-method="${esc(v.method ?? "")}">${subtitle}</p></div>
|
|
720
|
+
${v.amount ? `<div><p class="label" style="text-align:right">${esc(t.total)}</p><p class="amount">${esc(formatMoney3(v.amount, locale))}</p></div>` : ""}</header>
|
|
721
|
+
${fields.map((f) => `<section class="box" data-field="${f.key}"><h2 class="label">${esc(f.label)}</h2><p class="value">${esc(f.value)}</p></section>`).join("")}
|
|
722
|
+
${svg ? `<figure class="bar">${svg}<figcaption class="muted" style="font-family:ui-monospace,monospace">${esc(code)}</figcaption></figure>` : ""}
|
|
723
|
+
${expires ? `<p><strong>${esc(t.expires)}:</strong> ${esc(expires.replace(/\.$/, ""))}. ${esc(t.expiresNote)}</p>` : ""}
|
|
724
|
+
<h2 class="steps-title">${esc(t.stepsTitle)}</h2>
|
|
725
|
+
<ol class="steps">${steps.map((s) => `<li>${esc(s)}</li>`).join("")}</ol>
|
|
726
|
+
${v.instructions ? `<p class="note pre muted">${esc(v.instructions)}</p>` : ""}
|
|
727
|
+
<p class="note muted">${esc(t.footer)}</p>
|
|
728
|
+
${actions ? `<div class="actions" role="group" aria-label="${esc(t.title)}">${opts.pdfHref ? `<a class="btn" href="${esc(opts.pdfHref)}" download="ficha-de-pago.pdf" data-voucher-pdf>${esc(t.downloadPdf)}</a>` : ""}${opts.printButton ? `<button type="button" class="btn alt" id="print" hidden>${esc(t.print)}</button><noscript><p class="note muted">${esc(t.noScript)}</p></noscript>` : ""}</div>` : ""}
|
|
729
|
+
</main>
|
|
730
|
+
${opts.printButton || opts.autoPrint ? `<script${opts.nonce ? ` nonce="${esc(opts.nonce)}"` : ""}>(function(){var b=document.getElementById("print");if(b){b.hidden=false;b.addEventListener("click",function(){window.print()})}${opts.autoPrint ? 'window.addEventListener("load",function(){setTimeout(function(){window.print()},300)});' : ""}})();</script>` : ""}
|
|
731
|
+
</body></html>`;
|
|
732
|
+
}
|
|
733
|
+
var CSS;
|
|
734
|
+
var init_voucher_document = __esm({
|
|
735
|
+
"src/account/voucher-document.ts"() {
|
|
736
|
+
init_voucher();
|
|
737
|
+
init_voucher_text();
|
|
307
738
|
CSS = `
|
|
308
739
|
@page { size: A4; margin: 18mm; }
|
|
309
740
|
* { box-sizing: border-box; }
|
|
@@ -312,17 +743,21 @@ main { max-width: 174mm; margin: 0 auto; padding: 24px 16px; }
|
|
|
312
743
|
h1 { font-size: 22px; margin: 0; }
|
|
313
744
|
.muted { color: #555; }
|
|
314
745
|
.head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; border-bottom: 3px solid #111; padding-bottom: 12px; }
|
|
315
|
-
.amount { font-size: 28px; font-weight: 700; text-align: right; }
|
|
746
|
+
.amount { margin: 0; font-size: 28px; font-weight: 700; text-align: right; }
|
|
316
747
|
.box { border: 1px solid #111; padding: 14px 16px; margin-top: 18px; }
|
|
317
|
-
.label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #555; }
|
|
318
|
-
.value { font: 700 22px/1.3 ui-monospace, "SF Mono", Menlo, Consolas, monospace; word-break: break-all; letter-spacing: .04em; }
|
|
319
|
-
.bar {
|
|
748
|
+
.label { margin: 0; font-weight: 400; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #555; }
|
|
749
|
+
.value { margin: 0; font: 700 22px/1.3 ui-monospace, "SF Mono", Menlo, Consolas, monospace; word-break: break-all; letter-spacing: .04em; }
|
|
750
|
+
.bar { text-align: center; }
|
|
320
751
|
.bar svg { max-width: 100%; height: auto; }
|
|
321
|
-
.steps { margin: 18px 0 0; padding-left: 20px; }
|
|
322
752
|
.note { margin-top: 18px; font-size: 12px; }
|
|
323
753
|
.pre { white-space: pre-line; }
|
|
324
|
-
.
|
|
325
|
-
.
|
|
754
|
+
.steps-title { font-size: 16px; margin: 18px 0 0; }
|
|
755
|
+
.steps { margin: 6px 0 0; padding-left: 20px; }
|
|
756
|
+
.bar { margin: 18px 0 0; }
|
|
757
|
+
.actions { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
|
|
758
|
+
.btn { display: inline-block; font: inherit; padding: 10px 18px; border: 2px solid #111; background: #111; color: #fff; cursor: pointer; text-decoration: none; }
|
|
759
|
+
.btn.alt { background: #fff; color: #111; }
|
|
760
|
+
.btn:focus-visible { outline: 3px solid #1a56db; outline-offset: 2px; }
|
|
326
761
|
@media print { .actions { display: none; } main { padding: 0; } }
|
|
327
762
|
`;
|
|
328
763
|
}
|
|
@@ -359,8 +794,8 @@ var isControl = (el) => !!el && typeof el.tagName === "string" && ["INPUT", "SEL
|
|
|
359
794
|
function validationMessage(el, m = ES) {
|
|
360
795
|
const v = el.validity;
|
|
361
796
|
if (!v || v.valid) return null;
|
|
362
|
-
const
|
|
363
|
-
if (
|
|
797
|
+
const own2 = el.getAttribute("data-sf-error");
|
|
798
|
+
if (own2) return own2;
|
|
364
799
|
if (v.valueMissing) return el instanceof HTMLInputElement && (el.type === "radio" || el.type === "checkbox") ? m.choiceMissing : m.valueMissing;
|
|
365
800
|
if (v.typeMismatch && el instanceof HTMLInputElement) return el.type === "email" ? m.email : el.type === "tel" ? m.tel : m.pattern;
|
|
366
801
|
if (v.patternMismatch) return el.getAttribute("title") || (el instanceof HTMLInputElement && el.type === "tel" ? m.tel : m.pattern);
|
|
@@ -381,7 +816,7 @@ function useFieldErrors(formRef, options = {}) {
|
|
|
381
816
|
live.current = m;
|
|
382
817
|
const server = [...options.serverFields ?? []];
|
|
383
818
|
const serverKey = server.join("|");
|
|
384
|
-
const [errors, setErrors] = react.useState(() => Object.fromEntries(server.map((
|
|
819
|
+
const [errors, setErrors] = react.useState(() => Object.fromEntries(server.map((n2) => [n2, options.serverMessages?.[n2] ?? m.server])));
|
|
385
820
|
const [summary, setSummary] = react.useState(null);
|
|
386
821
|
const [summaryKey, setSummaryKey] = react.useState(0);
|
|
387
822
|
react.useEffect(() => {
|
|
@@ -487,9 +922,9 @@ function ErrorSummary({ items, focusKey, locale, messages, title, className, cla
|
|
|
487
922
|
if (has) ref.current?.focus();
|
|
488
923
|
}, [focusKey]);
|
|
489
924
|
if (!has) return null;
|
|
490
|
-
const
|
|
925
|
+
const n2 = items.length;
|
|
491
926
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref, role: "alert", tabIndex: -1, className, "data-sf-error-summary": true, "aria-labelledby": "sf-error-summary-title", children: [
|
|
492
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { id: "sf-error-summary-title", className: cx.title, "data-sf-error-summary-title": true, children: title ?? (
|
|
927
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { id: "sf-error-summary-title", className: cx.title, "data-sf-error-summary-title": true, children: title ?? (n2 === 1 ? m.summaryOne : m.summaryMany.replace("{n}", String(n2))) }),
|
|
493
928
|
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: cx.list, children: items.map((it) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
494
929
|
"a",
|
|
495
930
|
{
|
|
@@ -997,6 +1432,8 @@ var ES4 = {
|
|
|
997
1432
|
"pending.expired": "Vencida",
|
|
998
1433
|
"pending.reference": "Referencia",
|
|
999
1434
|
"pending.clabe": "CLABE",
|
|
1435
|
+
"pending.beneficiary": "Beneficiario",
|
|
1436
|
+
"pending.bank": "Banco",
|
|
1000
1437
|
"pending.expires": "Vence el {date}",
|
|
1001
1438
|
"pending.expiredOn": "Venci\xF3 el {date}",
|
|
1002
1439
|
"pending.total": "Total",
|
|
@@ -1005,9 +1442,11 @@ var ES4 = {
|
|
|
1005
1442
|
"pending.copied": "Copiada",
|
|
1006
1443
|
"pending.copyFailed": "No pudimos copiar; selecciona el texto.",
|
|
1007
1444
|
"pending.print": "Ver e imprimir ficha",
|
|
1008
|
-
"pending.download": "Descargar
|
|
1445
|
+
"pending.download": "Descargar PDF",
|
|
1009
1446
|
"pending.expiredNote": "Esta ficha ya no es v\xE1lida. Haz tu pedido de nuevo.",
|
|
1010
1447
|
"pending.barcode": "C\xF3digo de barras {code}",
|
|
1448
|
+
"pending.code": "C\xF3digo",
|
|
1449
|
+
"pending.ticket": "Ver comprobante del proveedor",
|
|
1011
1450
|
"pending.method.oxxo": "OXXO",
|
|
1012
1451
|
"pending.method.spei": "Transferencia SPEI",
|
|
1013
1452
|
"pending.method.bank_transfer": "Transferencia bancaria",
|
|
@@ -1170,6 +1609,8 @@ var EN4 = {
|
|
|
1170
1609
|
"pending.expired": "Expired",
|
|
1171
1610
|
"pending.reference": "Reference",
|
|
1172
1611
|
"pending.clabe": "CLABE",
|
|
1612
|
+
"pending.beneficiary": "Beneficiary",
|
|
1613
|
+
"pending.bank": "Bank",
|
|
1173
1614
|
"pending.expires": "Expires on {date}",
|
|
1174
1615
|
"pending.expiredOn": "Expired on {date}",
|
|
1175
1616
|
"pending.total": "Total",
|
|
@@ -1178,9 +1619,11 @@ var EN4 = {
|
|
|
1178
1619
|
"pending.copied": "Copied",
|
|
1179
1620
|
"pending.copyFailed": "We could not copy; select the text.",
|
|
1180
1621
|
"pending.print": "View and print voucher",
|
|
1181
|
-
"pending.download": "Download
|
|
1622
|
+
"pending.download": "Download PDF",
|
|
1182
1623
|
"pending.expiredNote": "This voucher is no longer valid. Place your order again.",
|
|
1183
1624
|
"pending.barcode": "Barcode {code}",
|
|
1625
|
+
"pending.code": "Code",
|
|
1626
|
+
"pending.ticket": "View provider receipt",
|
|
1184
1627
|
"pending.method.oxxo": "OXXO",
|
|
1185
1628
|
"pending.method.spei": "SPEI transfer",
|
|
1186
1629
|
"pending.method.bank_transfer": "Bank transfer",
|
|
@@ -1246,7 +1689,7 @@ var defaultImageLoader = (src, width, height) => {
|
|
|
1246
1689
|
};
|
|
1247
1690
|
function parseRatio(ratio) {
|
|
1248
1691
|
if (!ratio) return null;
|
|
1249
|
-
const [w, h] = ratio.split(/[/:]/).map((
|
|
1692
|
+
const [w, h] = ratio.split(/[/:]/).map((n2) => Number.parseFloat(n2));
|
|
1250
1693
|
return w && h ? w / h : null;
|
|
1251
1694
|
}
|
|
1252
1695
|
function Image({
|
|
@@ -1642,7 +2085,7 @@ function OrderCard({ order, orderHref, actionHref, onAction, headingLevel = 3, c
|
|
|
1642
2085
|
const { m, date, locale } = useAccountText(text2);
|
|
1643
2086
|
const Heading = `h${headingLevel}`;
|
|
1644
2087
|
const progress = storefront.orderProgress(order);
|
|
1645
|
-
const items = (Array.isArray(order.lines) ? order.lines : []).reduce((
|
|
2088
|
+
const items = (Array.isArray(order.lines) ? order.lines : []).reduce((n2, l) => n2 + (Number.isFinite(l?.quantity) ? l.quantity : 0), 0);
|
|
1646
2089
|
const summary = order.shipments_summary && typeof order.shipments_summary === "object" ? order.shipments_summary : null;
|
|
1647
2090
|
const shipments = Array.isArray(order.shipments) ? order.shipments : [];
|
|
1648
2091
|
const showShipment = !!summary && typeof summary.count === "number" && summary.count > 0 && !(shipments.length > 0 && shipments.every(storefront.isTestShipment)) && !["pending_payment", "cancelled", "refunded"].includes(progress.stage);
|
|
@@ -1909,11 +2352,23 @@ function InvoiceList({ invoices, summary, renderSummary, fileHref, onDownload, d
|
|
|
1909
2352
|
] });
|
|
1910
2353
|
}
|
|
1911
2354
|
init_voucher();
|
|
1912
|
-
function Barcode({ value, label, height = 56, className }) {
|
|
1913
|
-
const g = react.useMemo(() => barcodeGeometry(value, { height }), [value, height]);
|
|
2355
|
+
function Barcode({ value, label, height = 56, className, format }) {
|
|
2356
|
+
const g = react.useMemo(() => barcodeGeometry(value, { height, ...format ? { format } : {} }), [value, height, format]);
|
|
1914
2357
|
if (!g) return null;
|
|
1915
2358
|
return /* @__PURE__ */ jsxRuntime.jsx("svg", { className, viewBox: `0 0 ${g.width} ${g.height}`, width: g.width, height: g.height, role: "img", "aria-label": label, shapeRendering: "crispEdges", fill: "#000", "data-sf-voucher-barcode-svg": true, children: g.rects.map((r) => /* @__PURE__ */ jsxRuntime.jsx("rect", { x: r.x, y: 0, width: r.w, height: g.height }, r.x)) });
|
|
1916
2359
|
}
|
|
2360
|
+
async function downloadPdf(payment, opts) {
|
|
2361
|
+
const v = voucherOf(payment);
|
|
2362
|
+
if (!v) return;
|
|
2363
|
+
const { renderVoucherPdf: renderVoucherPdf2 } = await Promise.resolve().then(() => (init_voucher_pdf(), voucher_pdf_exports));
|
|
2364
|
+
const bytes = renderVoucherPdf2(v, { locale: opts.locale, ...opts.shopName ? { shopName: opts.shopName } : {}, ...opts.timeZone ? { timeZone: opts.timeZone } : {} });
|
|
2365
|
+
const url = URL.createObjectURL(new Blob([bytes], { type: "application/pdf" }));
|
|
2366
|
+
const a = document.createElement("a");
|
|
2367
|
+
a.href = url;
|
|
2368
|
+
a.download = "ficha-de-pago.pdf";
|
|
2369
|
+
a.click();
|
|
2370
|
+
setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
2371
|
+
}
|
|
1917
2372
|
async function openDocument(payment, mode, opts) {
|
|
1918
2373
|
const v = voucherOf(payment);
|
|
1919
2374
|
if (!v) return;
|
|
@@ -1926,11 +2381,11 @@ async function openDocument(payment, mode, opts) {
|
|
|
1926
2381
|
a.download = "ficha-de-pago.html";
|
|
1927
2382
|
a.click();
|
|
1928
2383
|
};
|
|
1929
|
-
|
|
2384
|
+
{
|
|
1930
2385
|
const w = window.open(url, "_blank");
|
|
1931
2386
|
if (w) w.opener = null;
|
|
1932
2387
|
else download();
|
|
1933
|
-
}
|
|
2388
|
+
}
|
|
1934
2389
|
setTimeout(() => URL.revokeObjectURL(url), 6e4);
|
|
1935
2390
|
}
|
|
1936
2391
|
function PendingPaymentCard({ payment, voucherHref, shopName, headingLevel = 3, classNames: cx = {}, children, ...text2 }) {
|
|
@@ -1940,7 +2395,7 @@ function PendingPaymentCard({ payment, voucherHref, shopName, headingLevel = 3,
|
|
|
1940
2395
|
if (!v) return null;
|
|
1941
2396
|
const expired = payment.status === "expired";
|
|
1942
2397
|
const Heading = `h${headingLevel}`;
|
|
1943
|
-
const code =
|
|
2398
|
+
const code = v.barcode;
|
|
1944
2399
|
const methodLabel = enumText(m, "pending.method", v.method?.toLowerCase());
|
|
1945
2400
|
const total = moneyText(payment.total, locale) ?? moneyText(v.amount, locale);
|
|
1946
2401
|
const copyValue = v.reference ?? v.clabe;
|
|
@@ -1954,11 +2409,23 @@ function PendingPaymentCard({ payment, voucherHref, shopName, headingLevel = 3,
|
|
|
1954
2409
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.label, children: m["pending.reference"] }),
|
|
1955
2410
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.value, "data-sf-voucher-value": true, children: v.reference })
|
|
1956
2411
|
] }) : null,
|
|
2412
|
+
v.beneficiary ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.field, "data-sf-voucher-beneficiary": true, children: [
|
|
2413
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.label, children: m["pending.beneficiary"] }),
|
|
2414
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.value, "data-sf-voucher-value": true, children: v.beneficiary })
|
|
2415
|
+
] }) : null,
|
|
2416
|
+
v.bank ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.field, "data-sf-voucher-bank": true, children: [
|
|
2417
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.label, children: m["pending.bank"] }),
|
|
2418
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.value, "data-sf-voucher-value": true, children: v.bank })
|
|
2419
|
+
] }) : null,
|
|
1957
2420
|
v.clabe ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.field, "data-sf-voucher-clabe": true, children: [
|
|
1958
2421
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.label, children: m["pending.clabe"] }),
|
|
1959
2422
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.value, "data-sf-voucher-value": true, children: v.clabe })
|
|
1960
2423
|
] }) : null,
|
|
1961
|
-
|
|
2424
|
+
v.barcode_text && !expired ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.field, "data-sf-voucher-code": true, children: [
|
|
2425
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.label, children: m["pending.code"] }),
|
|
2426
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.value, "data-sf-voucher-value": true, children: v.barcode_text })
|
|
2427
|
+
] }) : null,
|
|
2428
|
+
code && !expired ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx.barcode, "data-sf-voucher-barcode": true, children: /* @__PURE__ */ jsxRuntime.jsx(Barcode, { value: code, format: v.barcode_format ?? "code128", label: fill(m["pending.barcode"], { code }) }) }) : null,
|
|
1962
2429
|
expires ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.expiry, "data-sf-voucher-expiry": true, children: /* @__PURE__ */ jsxRuntime.jsx(Time, { value: v.expires_at ?? payment.expires_at, text: fill(m[expired ? "pending.expiredOn" : "pending.expires"], { date: expires }) }) }) : null,
|
|
1963
2430
|
total ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: cx.total, "data-sf-voucher-total": true, children: [
|
|
1964
2431
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
@@ -1969,18 +2436,25 @@ function PendingPaymentCard({ payment, voucherHref, shopName, headingLevel = 3,
|
|
|
1969
2436
|
] }) : null,
|
|
1970
2437
|
expired ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: cx.note, "data-sf-voucher-expired-note": true, children: m["pending.expiredNote"] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx.actions, "data-sf-voucher-actions": true, children: [
|
|
1971
2438
|
voucherHref ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1972
|
-
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: voucherHref(payment, { download: false }), target: "_blank", rel: "noopener", className: cx.primary, "data-sf-voucher-print": true, children: [
|
|
2439
|
+
/* @__PURE__ */ jsxRuntime.jsxs("a", { href: voucherHref(payment, { download: false, format: "html" }), target: "_blank", rel: "noopener", className: cx.primary, "data-sf-voucher-print": true, children: [
|
|
1973
2440
|
m["pending.print"],
|
|
1974
2441
|
/* @__PURE__ */ jsxRuntime.jsxs(Hidden, { children: [
|
|
1975
2442
|
" ",
|
|
1976
2443
|
m["action.newTab"]
|
|
1977
2444
|
] })
|
|
1978
2445
|
] }),
|
|
1979
|
-
/* @__PURE__ */ jsxRuntime.jsx("a", { href: voucherHref(payment, { download: true }), download: true, className: cx.secondary, "data-sf-voucher-download": true, children: m["pending.download"] })
|
|
2446
|
+
/* @__PURE__ */ jsxRuntime.jsx("a", { href: voucherHref(payment, { download: true, format: "pdf" }), download: true, className: cx.secondary, "data-sf-voucher-download": true, children: m["pending.download"] })
|
|
1980
2447
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1981
2448
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cx.primary, onClick: () => void openDocument(payment, "print", { locale, shopName, timeZone }), "data-sf-voucher-print": true, children: m["pending.print"] }),
|
|
1982
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cx.secondary, onClick: () => void
|
|
2449
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: cx.secondary, onClick: () => void downloadPdf(payment, { locale, shopName, timeZone }), "data-sf-voucher-download": true, children: m["pending.download"] })
|
|
1983
2450
|
] }),
|
|
2451
|
+
v.ticket_url ? /* @__PURE__ */ jsxRuntime.jsxs("a", { href: v.ticket_url, target: "_blank", rel: "noopener noreferrer", className: cx.secondary, "data-sf-voucher-ticket": true, children: [
|
|
2452
|
+
m["pending.ticket"],
|
|
2453
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Hidden, { children: [
|
|
2454
|
+
" ",
|
|
2455
|
+
m["action.newTab"]
|
|
2456
|
+
] })
|
|
2457
|
+
] }) : null,
|
|
1984
2458
|
copyValue ? /* @__PURE__ */ jsxRuntime.jsx(CopyButton, { value: copyValue, label: v.reference ? m["pending.copyReference"] : m["pending.copyClabe"], copiedLabel: m["pending.copied"], failedLabel: m["pending.copyFailed"], className: cx.secondary, "data-sf-copy": "voucher" }) : null
|
|
1985
2459
|
] }),
|
|
1986
2460
|
children
|
|
@@ -2526,8 +3000,10 @@ exports.ShipmentCard = ShipmentCard;
|
|
|
2526
3000
|
exports.accountAuthMessages = accountAuthMessages;
|
|
2527
3001
|
exports.accountMessages = accountMessages;
|
|
2528
3002
|
exports.barcodeGeometry = barcodeGeometry;
|
|
3003
|
+
exports.barcodeModules = barcodeModules;
|
|
2529
3004
|
exports.barcodeValue = barcodeValue;
|
|
2530
3005
|
exports.code128Modules = code128Modules;
|
|
3006
|
+
exports.code39Modules = code39Modules;
|
|
2531
3007
|
exports.enumText = enumText;
|
|
2532
3008
|
exports.lineImage = lineImage;
|
|
2533
3009
|
exports.paymentLabel = paymentLabel;
|