@asteby/storefront-react 0.26.0 → 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/fiscal-server.cjs +27 -2
- package/dist/fiscal-server.cjs.map +1 -1
- package/dist/fiscal-server.d.cts +10 -1
- package/dist/fiscal-server.d.ts +10 -1
- package/dist/fiscal-server.js +26 -3
- package/dist/fiscal-server.js.map +1 -1
- 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-server.cjs
CHANGED
|
@@ -13,6 +13,52 @@ var __export = (target, all) => {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
// src/account/voucher.ts
|
|
16
|
+
function formatOf(v) {
|
|
17
|
+
const f = typeof v === "string" ? v.toLowerCase().replace(/[^a-z0-9]/g, "") : "";
|
|
18
|
+
if (f === "code128" || f === "c128" || f === "code128b" || f === "code128c") return "code128";
|
|
19
|
+
if (f === "code39" || f === "c39") return "code39";
|
|
20
|
+
if (f === "itf" || f === "itf14" || f === "i25" || f === "interleaved2of5") return "itf";
|
|
21
|
+
if (f === "ean13") return "ean13";
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function barcodeOf(ext, raw) {
|
|
25
|
+
if ("barcode_data" in ext) {
|
|
26
|
+
const d = ext.barcode_data;
|
|
27
|
+
if (d && typeof d === "object") {
|
|
28
|
+
const o = d;
|
|
29
|
+
const value2 = text(o.value);
|
|
30
|
+
const format = formatOf(o.format);
|
|
31
|
+
if (value2 && format && barcodeModules(value2, format)) return { draw: { value: value2, format }, text: null };
|
|
32
|
+
return { draw: null, text: value2 ?? text(raw) };
|
|
33
|
+
}
|
|
34
|
+
return { draw: null, text: text(raw) };
|
|
35
|
+
}
|
|
36
|
+
if (raw && typeof raw === "object") {
|
|
37
|
+
const o = raw;
|
|
38
|
+
const value2 = text(o.value);
|
|
39
|
+
const format = formatOf(o.format ?? "code128");
|
|
40
|
+
return { draw: value2 && format ? { value: value2, format } : null, text: null };
|
|
41
|
+
}
|
|
42
|
+
const value = text(raw);
|
|
43
|
+
return { draw: value ? { value, format: "code128" } : null, text: null };
|
|
44
|
+
}
|
|
45
|
+
function instructionsKeyOf(raw) {
|
|
46
|
+
const k = raw?.replace(/^payment\.voucher\.instructions\./, "").toLowerCase() ?? "";
|
|
47
|
+
return !k ? null : k === "other" ? "generic" : k;
|
|
48
|
+
}
|
|
49
|
+
function httpsUrl(v) {
|
|
50
|
+
const s = typeof v === "string" ? v.trim() : "";
|
|
51
|
+
return /^https:\/\//i.test(s) && s.length <= 2048 ? s : null;
|
|
52
|
+
}
|
|
53
|
+
function kindOf(kind, method, key) {
|
|
54
|
+
for (const c of [kind, method, key]) {
|
|
55
|
+
const k = c?.toLowerCase();
|
|
56
|
+
if (!k || k === "other" || k === "generic") continue;
|
|
57
|
+
if (k === "oxxo" || k === "cash" || CASH_METHODS.has(k)) return "cash";
|
|
58
|
+
if (k === "spei" || k === "transfer" || TRANSFER_METHODS.has(k)) return "transfer";
|
|
59
|
+
}
|
|
60
|
+
return "generic";
|
|
61
|
+
}
|
|
16
62
|
function text(v) {
|
|
17
63
|
if (typeof v === "number" && Number.isFinite(v)) return String(v);
|
|
18
64
|
if (typeof v !== "string") return null;
|
|
@@ -29,19 +75,30 @@ function moneyOf(v) {
|
|
|
29
75
|
function voucherOf(p) {
|
|
30
76
|
const pay = p?.payment;
|
|
31
77
|
if (!pay || typeof pay !== "object") return null;
|
|
78
|
+
const ext = pay;
|
|
79
|
+
const method = text(pay.method ?? pay.provider);
|
|
80
|
+
const key = instructionsKeyOf(text(ext.instructions_key));
|
|
81
|
+
const bc = barcodeOf(ext, pay.barcode);
|
|
82
|
+
const clabe = text(pay.clabe);
|
|
83
|
+
let reference = text(pay.reference);
|
|
84
|
+
if (clabe && reference && digits(reference) === digits(clabe)) reference = null;
|
|
32
85
|
const v = {
|
|
33
|
-
method
|
|
34
|
-
reference
|
|
35
|
-
barcode:
|
|
36
|
-
|
|
86
|
+
method,
|
|
87
|
+
reference,
|
|
88
|
+
barcode: bc.draw?.value ?? null,
|
|
89
|
+
barcode_format: bc.draw?.format ?? null,
|
|
90
|
+
barcode_text: bc.text && bc.text !== reference ? bc.text : null,
|
|
91
|
+
clabe,
|
|
92
|
+
beneficiary: text(ext.beneficiary),
|
|
93
|
+
bank: text(ext.bank),
|
|
94
|
+
kind: kindOf(text(ext.kind), method, key),
|
|
95
|
+
instructions_key: key,
|
|
96
|
+
ticket_url: httpsUrl(ext.ticket_url) ?? httpsUrl(ext.voucher_url),
|
|
37
97
|
expires_at: text(pay.expires_at) ?? text(p?.expires_at),
|
|
38
98
|
amount: moneyOf(pay.amount) ?? moneyOf(p?.total),
|
|
39
99
|
instructions: text(pay.instructions)
|
|
40
100
|
};
|
|
41
|
-
return v.reference || v.barcode || v.clabe ? v : null;
|
|
42
|
-
}
|
|
43
|
-
function barcodeValue(v) {
|
|
44
|
-
return v.barcode ?? (v.method?.toLowerCase() === "oxxo" ? v.reference : null);
|
|
101
|
+
return v.reference || v.barcode || v.barcode_text || v.clabe ? v : null;
|
|
45
102
|
}
|
|
46
103
|
function code128Modules(value) {
|
|
47
104
|
if (!value || value.length > 80) return null;
|
|
@@ -62,8 +119,44 @@ function code128Modules(value) {
|
|
|
62
119
|
codes.push(sum % 103);
|
|
63
120
|
return codes.map((c) => BARS[c]).join("") + STOP;
|
|
64
121
|
}
|
|
122
|
+
function code39Modules(value) {
|
|
123
|
+
if (!value || value.length > 40) return null;
|
|
124
|
+
let out = "";
|
|
125
|
+
for (const ch of `*${value}*`) {
|
|
126
|
+
const p = Object.prototype.hasOwnProperty.call(CODE39_PATTERNS, ch) ? CODE39_PATTERNS[ch] : void 0;
|
|
127
|
+
if (!p || ch === "*" && value.includes("*")) return null;
|
|
128
|
+
for (let i = 0; i < 9; i++) out += (i % 2 === 0 ? "1" : "0").repeat(p[i] === "w" ? 3 : 1);
|
|
129
|
+
out += "0";
|
|
130
|
+
}
|
|
131
|
+
return out.slice(0, -1);
|
|
132
|
+
}
|
|
133
|
+
function itfModules(value) {
|
|
134
|
+
if (!value || value.length > 80 || value.length % 2 !== 0 || !/^\d+$/.test(value)) return null;
|
|
135
|
+
let out = "1010";
|
|
136
|
+
for (let i = 0; i < value.length; i += 2) {
|
|
137
|
+
const bars = ITF_DIGITS[Number(value[i])];
|
|
138
|
+
const spaces = ITF_DIGITS[Number(value[i + 1])];
|
|
139
|
+
for (let e = 0; e < 5; e++) out += "1".repeat(bars[e] === "w" ? 3 : 1) + "0".repeat(spaces[e] === "w" ? 3 : 1);
|
|
140
|
+
}
|
|
141
|
+
return out + "11101";
|
|
142
|
+
}
|
|
143
|
+
function ean13Modules(value) {
|
|
144
|
+
if (!/^\d{13}$/.test(value)) return null;
|
|
145
|
+
const d = [...value].map(Number);
|
|
146
|
+
const sum = d.slice(0, 12).reduce((a, n2, i) => a + n2 * (i % 2 === 0 ? 1 : 3), 0);
|
|
147
|
+
if ((10 - sum % 10) % 10 !== d[12]) return null;
|
|
148
|
+
const parity = EAN_PARITY[d[0]];
|
|
149
|
+
let out = "101";
|
|
150
|
+
for (let i = 0; i < 6; i++) out += (parity[i] === "L" ? EAN_L : EAN_G)[d[i + 1]];
|
|
151
|
+
out += "01010";
|
|
152
|
+
for (let i = 7; i < 13; i++) out += EAN_R[d[i]];
|
|
153
|
+
return out + "101";
|
|
154
|
+
}
|
|
155
|
+
function barcodeModules(value, format = "code128") {
|
|
156
|
+
return format === "code39" ? code39Modules(value) : format === "itf" ? itfModules(value) : format === "ean13" ? ean13Modules(value) : code128Modules(value);
|
|
157
|
+
}
|
|
65
158
|
function barcodeGeometry(value, opts = {}) {
|
|
66
|
-
const bits =
|
|
159
|
+
const bits = barcodeModules(value, opts.format);
|
|
67
160
|
if (!bits) return null;
|
|
68
161
|
const mod = opts.module ?? 2;
|
|
69
162
|
const quiet = 10;
|
|
@@ -80,10 +173,13 @@ function barcodeGeometry(value, opts = {}) {
|
|
|
80
173
|
}
|
|
81
174
|
return { width: (bits.length + quiet * 2) * mod, height: opts.height ?? 70, rects };
|
|
82
175
|
}
|
|
83
|
-
var MAX, BARS, STOP;
|
|
176
|
+
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;
|
|
84
177
|
var init_voucher = __esm({
|
|
85
178
|
"src/account/voucher.ts"() {
|
|
86
179
|
MAX = 256;
|
|
180
|
+
CASH_METHODS = /* @__PURE__ */ new Set(["oxxo", "cash", "store", "convenience_store", "efectivo", "bank_deposit", "deposit", "paynet", "paycash", "bancomer", "7eleven", "seven_eleven", "farmacias_guadalajara", "circle_k"]);
|
|
181
|
+
TRANSFER_METHODS = /* @__PURE__ */ new Set(["spei", "bank_transfer", "transfer", "wire", "clabe"]);
|
|
182
|
+
digits = (s) => s ? s.replace(/\D/g, "") : "";
|
|
87
183
|
BARS = [
|
|
88
184
|
"11011001100",
|
|
89
185
|
"11001101100",
|
|
@@ -193,17 +289,33 @@ var init_voucher = __esm({
|
|
|
193
289
|
"11010011100"
|
|
194
290
|
];
|
|
195
291
|
STOP = "1100011101011";
|
|
292
|
+
C39_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. */+%$";
|
|
293
|
+
C39_WIDE = "346038238023348034234368036236058258025458045245568056256456078278027478047247678067267467018128012148014124168016126146137157357135";
|
|
294
|
+
CODE39_PATTERNS = Object.fromEntries(
|
|
295
|
+
[...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("")])
|
|
296
|
+
);
|
|
297
|
+
ITF_DIGITS = ["nnwwn", "wnnnw", "nwnnw", "wwnnn", "nnwnw", "wnwnn", "nwwnn", "nnnww", "wnnwn", "nwnwn"];
|
|
298
|
+
EAN_L = ["0001101", "0011001", "0010011", "0111101", "0100011", "0110001", "0101111", "0111011", "0110111", "0001011"];
|
|
299
|
+
EAN_R = EAN_L.map((c) => [...c].map((b) => b === "1" ? "0" : "1").join(""));
|
|
300
|
+
EAN_G = EAN_R.map((c) => [...c].reverse().join(""));
|
|
301
|
+
EAN_PARITY = ["LLLLLL", "LLGLGG", "LLGGLG", "LLGGGL", "LGLLGG", "LGGLLG", "LGGGLL", "LGLGLG", "LGLGGL", "LGGLGL"];
|
|
196
302
|
}
|
|
197
303
|
});
|
|
198
304
|
|
|
199
|
-
// src/account/voucher-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
305
|
+
// src/account/voucher-text.ts
|
|
306
|
+
function docText(locale) {
|
|
307
|
+
return isEnglish(locale) ? EN : ES;
|
|
308
|
+
}
|
|
309
|
+
function methodName(v, t) {
|
|
310
|
+
return v.method ? own(t.methods, v.method) ?? v.method : t.cash;
|
|
311
|
+
}
|
|
312
|
+
function voucherSteps(v, t) {
|
|
313
|
+
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);
|
|
314
|
+
return fn(v);
|
|
315
|
+
}
|
|
316
|
+
function voucherFields(v, t) {
|
|
317
|
+
const f = (key, label, value) => value ? [{ key, label, value }] : [];
|
|
318
|
+
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)];
|
|
207
319
|
}
|
|
208
320
|
function formatMoney(m, locale) {
|
|
209
321
|
if (!m) return "";
|
|
@@ -223,85 +335,401 @@ function formatDate(iso, locale, timeZone) {
|
|
|
223
335
|
return d.toISOString();
|
|
224
336
|
}
|
|
225
337
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
function renderVoucherDocument(v, opts = {}) {
|
|
233
|
-
const locale = opts.locale ?? "es-MX";
|
|
234
|
-
const t = locale.toLowerCase().startsWith("en") ? EN : ES;
|
|
235
|
-
const shop = opts.shopName || "";
|
|
236
|
-
const method = v.method ? Object.prototype.hasOwnProperty.call(t.methods, v.method.toLowerCase()) ? t.methods[v.method.toLowerCase()] : v.method : t.cash;
|
|
237
|
-
const isSpei = !!v.clabe && !v.reference;
|
|
238
|
-
const code = barcodeValue(v);
|
|
239
|
-
const svg = code ? barcodeSvg(code, t.barcode) : null;
|
|
240
|
-
const expires = formatDate(v.expires_at, locale, opts.timeZone);
|
|
241
|
-
const field = (label, value) => value ? `<div class="box"><div class="label">${esc(label)}</div><div class="value">${esc(value)}</div></div>` : "";
|
|
242
|
-
const steps = isSpei ? t.stepsSpei : t.stepsCash;
|
|
243
|
-
const subtitle = [shop, method, opts.number ? `${t.order} ${opts.number}` : ""].filter(Boolean).map(esc).join(" \xB7 ");
|
|
244
|
-
return `<!doctype html>
|
|
245
|
-
<html lang="${esc(locale)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
246
|
-
<meta name="robots" content="noindex"><title>${esc(t.title)}${shop ? ` - ${esc(shop)}` : ""}</title><style>${CSS}</style></head>
|
|
247
|
-
<body><main>
|
|
248
|
-
<div class="head"><div><h1>${esc(t.title)}</h1><div class="muted">${subtitle}</div></div>
|
|
249
|
-
${v.amount ? `<div><div class="label" style="text-align:right">${esc(t.total)}</div><div class="amount">${esc(formatMoney(v.amount, locale))}</div></div>` : ""}</div>
|
|
250
|
-
${field(t.reference, v.reference)}${field(t.clabe, v.clabe)}
|
|
251
|
-
${svg ? `<div class="bar">${svg}<div class="muted" style="font-family:ui-monospace,monospace">${esc(code)}</div></div>` : ""}
|
|
252
|
-
${expires ? `<p><strong>${esc(t.expires)}:</strong> ${esc(expires)}. ${esc(t.expiresNote)}</p>` : ""}
|
|
253
|
-
<ol class="steps">${steps.map((s) => `<li>${esc(s)}</li>`).join("")}</ol>
|
|
254
|
-
${v.instructions ? `<p class="note pre muted">${esc(v.instructions)}</p>` : ""}
|
|
255
|
-
<p class="note muted">${esc(t.footer)}</p>
|
|
256
|
-
${opts.printButton ? `<div class="actions"><button type="button" id="print">${esc(t.print)}</button></div>` : ""}
|
|
257
|
-
</main>
|
|
258
|
-
${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>` : ""}
|
|
259
|
-
</body></html>`;
|
|
260
|
-
}
|
|
261
|
-
var ES, EN, CSS;
|
|
262
|
-
var init_voucher_document = __esm({
|
|
263
|
-
"src/account/voucher-document.ts"() {
|
|
264
|
-
init_voucher();
|
|
338
|
+
var KEEP_ES, KEEP_EN, ES, EN, isEnglish, own;
|
|
339
|
+
var init_voucher_text = __esm({
|
|
340
|
+
"src/account/voucher-text.ts"() {
|
|
341
|
+
KEEP_ES = "Conserva tu comprobante: confirmaremos tu pago autom\xE1ticamente.";
|
|
342
|
+
KEEP_EN = "Keep your receipt: we will confirm your payment automatically.";
|
|
265
343
|
ES = {
|
|
266
344
|
title: "Ficha de pago",
|
|
267
345
|
total: "Total a pagar",
|
|
268
346
|
reference: "Referencia",
|
|
269
347
|
clabe: "CLABE",
|
|
348
|
+
beneficiary: "Beneficiario",
|
|
349
|
+
bank: "Banco",
|
|
270
350
|
expires: "Vence",
|
|
271
351
|
expiresNote: "Pasada esa fecha la ficha deja de ser v\xE1lida.",
|
|
272
352
|
order: "Pedido",
|
|
273
353
|
barcode: "C\xF3digo de barras",
|
|
274
|
-
|
|
354
|
+
code: "C\xF3digo",
|
|
355
|
+
print: "Imprimir",
|
|
356
|
+
downloadPdf: "Descargar PDF",
|
|
357
|
+
noScript: "Para imprimir usa la opci\xF3n Imprimir de tu navegador (Ctrl+P) o descarga el PDF.",
|
|
358
|
+
stepsTitle: "C\xF3mo pagar",
|
|
275
359
|
footer: "Tu pedido se genera cuando se confirma el pago. Esta ficha es de un solo uso; no la compartas.",
|
|
276
|
-
stepsCash: [
|
|
277
|
-
"Acude a la tienda OXXO (o el comercio indicado) y di que vas a hacer un pago de servicio en efectivo.",
|
|
278
|
-
"Muestra el c\xF3digo de barras o dicta la referencia y paga el monto exacto.",
|
|
279
|
-
"Conserva tu comprobante: confirmaremos tu pago autom\xE1ticamente."
|
|
280
|
-
],
|
|
281
|
-
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."],
|
|
282
360
|
methods: { oxxo: "OXXO", spei: "Transferencia SPEI", bank_transfer: "Transferencia bancaria", bank_deposit: "Dep\xF3sito bancario", cash: "Pago en efectivo" },
|
|
283
|
-
cash: "Pago en efectivo"
|
|
361
|
+
cash: "Pago en efectivo",
|
|
362
|
+
steps: {
|
|
363
|
+
oxxo: (v) => [
|
|
364
|
+
"Acude a cualquier tienda OXXO y di que vas a hacer un pago de servicio en efectivo.",
|
|
365
|
+
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.",
|
|
366
|
+
KEEP_ES
|
|
367
|
+
],
|
|
368
|
+
cash: (v) => [
|
|
369
|
+
"Acude a la tienda o comercio indicado y di que vas a hacer un pago en efectivo.",
|
|
370
|
+
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.",
|
|
371
|
+
KEEP_ES
|
|
372
|
+
],
|
|
373
|
+
spei: (v) => [
|
|
374
|
+
"Entra a la banca en l\xEDnea o a la app de tu banco.",
|
|
375
|
+
"Haz una transferencia SPEI a la CLABE indicada, por el monto exacto.",
|
|
376
|
+
...v.reference ? ["Escribe la referencia de esta ficha en el concepto o referencia de la transferencia."] : [],
|
|
377
|
+
KEEP_ES
|
|
378
|
+
],
|
|
379
|
+
bank_transfer: (v) => [
|
|
380
|
+
"Entra a la banca en l\xEDnea o a la app de tu banco.",
|
|
381
|
+
"Haz una transferencia a la cuenta o CLABE indicada, por el monto exacto.",
|
|
382
|
+
...v.reference ? ["Escribe la referencia de esta ficha en el concepto de la transferencia."] : [],
|
|
383
|
+
KEEP_ES
|
|
384
|
+
],
|
|
385
|
+
bank_deposit: (v) => [
|
|
386
|
+
"Acude a una sucursal del banco indicado o a su cajero con dep\xF3sitos.",
|
|
387
|
+
`Deposita el monto exacto a la cuenta${v.reference ? " con la referencia de esta ficha" : " indicada"}.`,
|
|
388
|
+
KEEP_ES
|
|
389
|
+
],
|
|
390
|
+
transfer: (v) => [
|
|
391
|
+
"Entra a la banca en l\xEDnea o a la app de tu banco.",
|
|
392
|
+
"Haz una transferencia a la CLABE indicada, por el monto exacto.",
|
|
393
|
+
...v.reference ? ["Escribe la referencia de esta ficha en el concepto de la transferencia."] : [],
|
|
394
|
+
KEEP_ES
|
|
395
|
+
],
|
|
396
|
+
generic: () => ["Realiza el pago con los datos de esta ficha, por el monto exacto y antes de que venza.", KEEP_ES]
|
|
397
|
+
}
|
|
284
398
|
};
|
|
285
399
|
EN = {
|
|
286
400
|
title: "Payment voucher",
|
|
287
401
|
total: "Amount to pay",
|
|
288
402
|
reference: "Reference",
|
|
289
403
|
clabe: "CLABE",
|
|
404
|
+
beneficiary: "Beneficiary",
|
|
405
|
+
bank: "Bank",
|
|
290
406
|
expires: "Expires",
|
|
291
407
|
expiresNote: "After that date the voucher is no longer valid.",
|
|
292
408
|
order: "Order",
|
|
293
409
|
barcode: "Barcode",
|
|
294
|
-
|
|
410
|
+
code: "Code",
|
|
411
|
+
print: "Print",
|
|
412
|
+
downloadPdf: "Download PDF",
|
|
413
|
+
noScript: "To print, use your browser's Print option (Ctrl+P) or download the PDF.",
|
|
414
|
+
stepsTitle: "How to pay",
|
|
295
415
|
footer: "Your order is created when the payment is confirmed. This voucher is single-use; do not share it.",
|
|
296
|
-
stepsCash: [
|
|
297
|
-
"Go to an OXXO store (or the store indicated) and say you want to make a cash service payment.",
|
|
298
|
-
"Show the barcode or read out the reference and pay the exact amount.",
|
|
299
|
-
"Keep your receipt: we will confirm your payment automatically."
|
|
300
|
-
],
|
|
301
|
-
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."],
|
|
302
416
|
methods: { oxxo: "OXXO", spei: "SPEI transfer", bank_transfer: "Bank transfer", bank_deposit: "Bank deposit", cash: "Cash payment" },
|
|
303
|
-
cash: "Cash payment"
|
|
417
|
+
cash: "Cash payment",
|
|
418
|
+
steps: {
|
|
419
|
+
oxxo: (v) => [
|
|
420
|
+
"Go to any OXXO store and say you want to make a cash service payment.",
|
|
421
|
+
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.",
|
|
422
|
+
KEEP_EN
|
|
423
|
+
],
|
|
424
|
+
cash: (v) => [
|
|
425
|
+
"Go to the store indicated and say you want to make a cash payment.",
|
|
426
|
+
v.barcode ? "Show the barcode or read out the reference, and pay the exact amount." : "Read out the reference and pay the exact amount.",
|
|
427
|
+
KEEP_EN
|
|
428
|
+
],
|
|
429
|
+
spei: (v) => [
|
|
430
|
+
"Open your online banking or your bank app.",
|
|
431
|
+
"Make a SPEI transfer to the CLABE below for the exact amount.",
|
|
432
|
+
...v.reference ? ["Enter the reference of this voucher as the transfer concept or reference."] : [],
|
|
433
|
+
KEEP_EN
|
|
434
|
+
],
|
|
435
|
+
bank_transfer: (v) => [
|
|
436
|
+
"Open your online banking or your bank app.",
|
|
437
|
+
"Make a transfer to the account or CLABE below for the exact amount.",
|
|
438
|
+
...v.reference ? ["Enter the reference of this voucher as the transfer concept."] : [],
|
|
439
|
+
KEEP_EN
|
|
440
|
+
],
|
|
441
|
+
bank_deposit: (v) => [
|
|
442
|
+
"Go to a branch of the bank indicated or to one of its deposit ATMs.",
|
|
443
|
+
`Deposit the exact amount to the account${v.reference ? " with the reference of this voucher" : " indicated"}.`,
|
|
444
|
+
KEEP_EN
|
|
445
|
+
],
|
|
446
|
+
transfer: (v) => [
|
|
447
|
+
"Open your online banking or your bank app.",
|
|
448
|
+
"Make a transfer to the CLABE below for the exact amount.",
|
|
449
|
+
...v.reference ? ["Enter the reference of this voucher as the transfer concept."] : [],
|
|
450
|
+
KEEP_EN
|
|
451
|
+
],
|
|
452
|
+
generic: () => ["Make the payment with the details of this voucher, for the exact amount and before it expires.", KEEP_EN]
|
|
453
|
+
}
|
|
304
454
|
};
|
|
455
|
+
isEnglish = (locale) => locale.toLowerCase().startsWith("en");
|
|
456
|
+
own = (o, k) => {
|
|
457
|
+
const key = k?.toLowerCase();
|
|
458
|
+
return key && Object.prototype.hasOwnProperty.call(o, key) ? o[key] : void 0;
|
|
459
|
+
};
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
// src/account/voucher-pdf.ts
|
|
464
|
+
var voucher_pdf_exports = {};
|
|
465
|
+
__export(voucher_pdf_exports, {
|
|
466
|
+
MAX_VOUCHER_PDF_BYTES: () => MAX_VOUCHER_PDF_BYTES,
|
|
467
|
+
pdfString: () => pdfString,
|
|
468
|
+
renderVoucherPdf: () => renderVoucherPdf
|
|
469
|
+
});
|
|
470
|
+
function toBytes(s) {
|
|
471
|
+
const out = [];
|
|
472
|
+
for (const ch of s) {
|
|
473
|
+
const c = ch.codePointAt(0);
|
|
474
|
+
if (c < 32 || c === 127) out.push(32);
|
|
475
|
+
else if (c < 127 || c >= 160 && c <= 255) out.push(c);
|
|
476
|
+
else out.push(CP1252[c] ?? 63);
|
|
477
|
+
}
|
|
478
|
+
return out;
|
|
479
|
+
}
|
|
480
|
+
function pdfString(s) {
|
|
481
|
+
let o = "(";
|
|
482
|
+
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")}`;
|
|
483
|
+
return o + ")";
|
|
484
|
+
}
|
|
485
|
+
function charWidth(font, ch) {
|
|
486
|
+
if (font === "F3" || font === "F4") return 600;
|
|
487
|
+
const c = ch.codePointAt(0);
|
|
488
|
+
const table = font === "F2" ? HELV_B : HELV;
|
|
489
|
+
if (c >= 32 && c < 127) return table[c - 32];
|
|
490
|
+
const base = ch.normalize("NFD")[0].codePointAt(0);
|
|
491
|
+
return base >= 32 && base < 127 ? table[base - 32] : 556;
|
|
492
|
+
}
|
|
493
|
+
function wrap(font, size, text2, max) {
|
|
494
|
+
const lines = [];
|
|
495
|
+
for (const para of text2.split(/\r?\n/)) {
|
|
496
|
+
let line = "";
|
|
497
|
+
for (const word of para.split(/\s+/).filter(Boolean)) {
|
|
498
|
+
let w = word;
|
|
499
|
+
while (textWidth(font, size, w) > max) {
|
|
500
|
+
let n2 = 1;
|
|
501
|
+
while (n2 < w.length && textWidth(font, size, w.slice(0, n2 + 1)) <= max) n2++;
|
|
502
|
+
if (line) lines.push(line), line = "";
|
|
503
|
+
lines.push(w.slice(0, n2));
|
|
504
|
+
w = w.slice(n2);
|
|
505
|
+
}
|
|
506
|
+
const next = line ? `${line} ${w}` : w;
|
|
507
|
+
if (line && textWidth(font, size, next) > max) lines.push(line), line = w;
|
|
508
|
+
else line = next;
|
|
509
|
+
}
|
|
510
|
+
lines.push(line);
|
|
511
|
+
}
|
|
512
|
+
return lines;
|
|
513
|
+
}
|
|
514
|
+
function renderVoucherPdf(v, opts = {}) {
|
|
515
|
+
const locale = opts.locale ?? "es-MX";
|
|
516
|
+
const t = docText(locale);
|
|
517
|
+
const [W, H] = opts.paper === "letter" ? [612, 792] : [595.28, 841.89];
|
|
518
|
+
const M = 54;
|
|
519
|
+
const right = W - M;
|
|
520
|
+
const inner = right - M;
|
|
521
|
+
const pages = [];
|
|
522
|
+
let ops = "";
|
|
523
|
+
let y = H - M;
|
|
524
|
+
const newPage = () => {
|
|
525
|
+
if (pages.length >= MAX_PAGES) return false;
|
|
526
|
+
if (ops) pages.push(ops);
|
|
527
|
+
ops = "";
|
|
528
|
+
y = H - M;
|
|
529
|
+
return true;
|
|
530
|
+
};
|
|
531
|
+
const text2 = (font, size, x, s, gray = 0) => {
|
|
532
|
+
ops += `BT ${n(gray)} g /${font} ${size} Tf ${n(x)} ${n(y)} Td ${pdfString(s)} Tj ET
|
|
533
|
+
`;
|
|
534
|
+
};
|
|
535
|
+
const ensure = (h) => {
|
|
536
|
+
if (y - h < M) newPage();
|
|
537
|
+
};
|
|
538
|
+
const paragraph = (font, size, s, opt = {}) => {
|
|
539
|
+
const lead = opt.lead ?? size * 1.4;
|
|
540
|
+
for (const line of wrap(font, size, s, opt.width ?? inner)) {
|
|
541
|
+
ensure(lead);
|
|
542
|
+
y -= lead;
|
|
543
|
+
if (line) text2(font, size, opt.x ?? M, line, opt.gray ?? 0);
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
const amount = formatMoney(v.amount, locale);
|
|
547
|
+
const top = y;
|
|
548
|
+
y -= 20;
|
|
549
|
+
text2("F2", 20, M, t.title);
|
|
550
|
+
const subtitle = [opts.shopName, methodName(v, t), opts.number ? `${t.order} ${opts.number}` : ""].filter(Boolean).join(" \xB7 ");
|
|
551
|
+
if (subtitle) {
|
|
552
|
+
y -= 15;
|
|
553
|
+
paragraph("F1", 10, subtitle, { width: amount ? inner * 0.6 : inner, gray: 0.33, lead: 12 });
|
|
554
|
+
}
|
|
555
|
+
const afterTitle = y;
|
|
556
|
+
if (amount) {
|
|
557
|
+
y = top - 10;
|
|
558
|
+
const label = t.total.toUpperCase();
|
|
559
|
+
text2("F1", 8, right - textWidth("F1", 8, label), label, 0.33);
|
|
560
|
+
y -= 22;
|
|
561
|
+
text2("F2", 22, right - textWidth("F2", 22, amount), amount);
|
|
562
|
+
}
|
|
563
|
+
y = Math.min(afterTitle, y) - 10;
|
|
564
|
+
ops += `0 g 2 w ${n(M)} ${n(y)} m ${n(right)} ${n(y)} l S
|
|
565
|
+
`;
|
|
566
|
+
y -= 8;
|
|
567
|
+
for (const f of voucherFields(v, t)) {
|
|
568
|
+
const size = f.value.length > 36 ? 12 : 16;
|
|
569
|
+
const lines = wrap("F3", size, f.value, inner - 24);
|
|
570
|
+
const h = 14 + 12 + lines.length * size * 1.3 + 8;
|
|
571
|
+
ensure(h + 12);
|
|
572
|
+
y -= 12;
|
|
573
|
+
ops += `0 G 0.8 w ${n(M)} ${n(y - h)} ${n(inner)} ${n(h)} re S
|
|
574
|
+
`;
|
|
575
|
+
const boxTop = y;
|
|
576
|
+
y -= 16;
|
|
577
|
+
text2("F1", 8, M + 12, f.label.toUpperCase(), 0.33);
|
|
578
|
+
y -= 4;
|
|
579
|
+
for (const line of lines) {
|
|
580
|
+
y -= size * 1.3;
|
|
581
|
+
text2("F3", size, M + 12, line);
|
|
582
|
+
}
|
|
583
|
+
y = boxTop - h;
|
|
584
|
+
}
|
|
585
|
+
const g = v.barcode ? barcodeGeometry(v.barcode, { ...v.barcode_format ? { format: v.barcode_format } : {}, height: 60 }) : null;
|
|
586
|
+
if (g && v.barcode) {
|
|
587
|
+
const scale = Math.min(1, inner / g.width) * 0.75;
|
|
588
|
+
const bw = g.width * scale;
|
|
589
|
+
const bh = 60;
|
|
590
|
+
ensure(bh + 40);
|
|
591
|
+
y -= 18;
|
|
592
|
+
ops += `0 g
|
|
593
|
+
`;
|
|
594
|
+
const x0 = M + (inner - bw) / 2;
|
|
595
|
+
for (const r of g.rects) ops += `${n(x0 + r.x * scale)} ${n(y - bh)} ${n(r.w * scale)} ${n(bh)} re f
|
|
596
|
+
`;
|
|
597
|
+
y -= bh + 12;
|
|
598
|
+
const cw = textWidth("F4", 10, v.barcode);
|
|
599
|
+
text2("F4", 10, M + (inner - Math.min(cw, inner)) / 2, v.barcode.slice(0, Math.floor(inner / 6)));
|
|
600
|
+
y -= 4;
|
|
601
|
+
}
|
|
602
|
+
const expires = formatDate(v.expires_at, locale, opts.timeZone);
|
|
603
|
+
if (expires) {
|
|
604
|
+
y -= 8;
|
|
605
|
+
paragraph("F2", 10, `${t.expires}: ${expires.replace(/\.$/, "")}.`);
|
|
606
|
+
paragraph("F1", 10, t.expiresNote);
|
|
607
|
+
}
|
|
608
|
+
y -= 10;
|
|
609
|
+
ensure(40);
|
|
610
|
+
paragraph("F2", 12, t.stepsTitle, { lead: 16 });
|
|
611
|
+
voucherSteps(v, t).forEach((s, i) => {
|
|
612
|
+
const lines = wrap("F1", 10, s, inner - 18);
|
|
613
|
+
ensure(lines.length * 14 + 2);
|
|
614
|
+
y -= 2;
|
|
615
|
+
lines.forEach((line, j) => {
|
|
616
|
+
y -= 14;
|
|
617
|
+
if (j === 0) text2("F1", 10, M, `${i + 1}.`);
|
|
618
|
+
text2("F1", 10, M + 18, line);
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
if (v.instructions) {
|
|
622
|
+
y -= 6;
|
|
623
|
+
paragraph("F1", 9, v.instructions, { gray: 0.33, lead: 12 });
|
|
624
|
+
}
|
|
625
|
+
y -= 8;
|
|
626
|
+
paragraph("F1", 8, t.footer, { gray: 0.33, lead: 11 });
|
|
627
|
+
pages.push(ops);
|
|
628
|
+
const objs = [];
|
|
629
|
+
const kids = pages.map((_, i) => `${8 + i * 2} 0 R`).join(" ");
|
|
630
|
+
objs[1] = "<< /Type /Catalog /Pages 2 0 R >>";
|
|
631
|
+
objs[2] = `<< /Type /Pages /Kids [${kids}] /Count ${pages.length} >>`;
|
|
632
|
+
["F1", "F2", "F3", "F4"].forEach((f, i) => objs[3 + i] = `<< /Type /Font /Subtype /Type1 /BaseFont /${FONT_NAMES[f]} /Encoding /WinAnsiEncoding >>`);
|
|
633
|
+
objs[7] = `<< /Title ${pdfString(`${t.title}${opts.shopName ? ` - ${opts.shopName}` : ""}`)} /Producer ${pdfString("@asteby/storefront-react")} >>`;
|
|
634
|
+
pages.forEach((content, i) => {
|
|
635
|
+
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 >>`;
|
|
636
|
+
objs[9 + i * 2] = `<< /Length ${content.length} >>
|
|
637
|
+
stream
|
|
638
|
+
${content}endstream`;
|
|
639
|
+
});
|
|
640
|
+
let out = "%PDF-1.4\n%\xE2\xE3\xCF\xD3\n";
|
|
641
|
+
const offsets = [];
|
|
642
|
+
for (let i = 1; i < objs.length; i++) {
|
|
643
|
+
offsets[i] = out.length;
|
|
644
|
+
out += `${i} 0 obj
|
|
645
|
+
${objs[i]}
|
|
646
|
+
endobj
|
|
647
|
+
`;
|
|
648
|
+
}
|
|
649
|
+
const xref = out.length;
|
|
650
|
+
out += `xref
|
|
651
|
+
0 ${objs.length}
|
|
652
|
+
0000000000 65535 f
|
|
653
|
+
`;
|
|
654
|
+
for (let i = 1; i < objs.length; i++) out += `${String(offsets[i]).padStart(10, "0")} 00000 n
|
|
655
|
+
`;
|
|
656
|
+
out += `trailer
|
|
657
|
+
<< /Size ${objs.length} /Root 1 0 R /Info 7 0 R >>
|
|
658
|
+
startxref
|
|
659
|
+
${xref}
|
|
660
|
+
%%EOF
|
|
661
|
+
`;
|
|
662
|
+
if (out.length > MAX_VOUCHER_PDF_BYTES) throw new RangeError("voucher PDF too large");
|
|
663
|
+
const bytes = new Uint8Array(out.length);
|
|
664
|
+
for (let i = 0; i < out.length; i++) bytes[i] = out.charCodeAt(i) & 255;
|
|
665
|
+
return bytes;
|
|
666
|
+
}
|
|
667
|
+
var MAX_VOUCHER_PDF_BYTES, MAX_PAGES, HELV, HELV_B, FONT_NAMES, CP1252, textWidth, n;
|
|
668
|
+
var init_voucher_pdf = __esm({
|
|
669
|
+
"src/account/voucher-pdf.ts"() {
|
|
670
|
+
init_voucher();
|
|
671
|
+
init_voucher_text();
|
|
672
|
+
MAX_VOUCHER_PDF_BYTES = 256 * 1024;
|
|
673
|
+
MAX_PAGES = 3;
|
|
674
|
+
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];
|
|
675
|
+
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];
|
|
676
|
+
FONT_NAMES = { F1: "Helvetica", F2: "Helvetica-Bold", F3: "Courier-Bold", F4: "Courier" };
|
|
677
|
+
CP1252 = { 8364: 128, 8216: 145, 8217: 146, 8220: 147, 8221: 148, 8226: 149, 8211: 150, 8212: 151 };
|
|
678
|
+
textWidth = (font, size, s) => [...s].reduce((w, ch) => w + charWidth(font, ch), 0) * size / 1e3;
|
|
679
|
+
n = (x) => String(Math.round(x * 100) / 100);
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
|
|
683
|
+
// src/account/voucher-document.ts
|
|
684
|
+
var voucher_document_exports = {};
|
|
685
|
+
__export(voucher_document_exports, {
|
|
686
|
+
esc: () => esc,
|
|
687
|
+
renderVoucherDocument: () => renderVoucherDocument
|
|
688
|
+
});
|
|
689
|
+
function esc(s) {
|
|
690
|
+
return s.replace(/[&<>"']/g, (c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]);
|
|
691
|
+
}
|
|
692
|
+
function barcodeSvg(value, format, label) {
|
|
693
|
+
const g = barcodeGeometry(value, { ...format ? { format } : {} });
|
|
694
|
+
if (!g) return null;
|
|
695
|
+
const rects = g.rects.map((r) => `<rect x="${r.x}" y="0" width="${r.w}" height="${g.height}"/>`).join("");
|
|
696
|
+
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>`;
|
|
697
|
+
}
|
|
698
|
+
function renderVoucherDocument(v, opts = {}) {
|
|
699
|
+
const locale = opts.locale ?? "es-MX";
|
|
700
|
+
const t = docText(locale);
|
|
701
|
+
const shop = opts.shopName || "";
|
|
702
|
+
const method = methodName(v, t);
|
|
703
|
+
const code = v.barcode;
|
|
704
|
+
const svg = code ? barcodeSvg(code, v.barcode_format, t.barcode) : null;
|
|
705
|
+
const expires = formatDate(v.expires_at, locale, opts.timeZone);
|
|
706
|
+
const fields = voucherFields(v, t);
|
|
707
|
+
const steps = voucherSteps(v, t);
|
|
708
|
+
const subtitle = [shop, method, opts.number ? `${t.order} ${opts.number}` : ""].filter(Boolean).map(esc).join(" \xB7 ");
|
|
709
|
+
const actions = opts.printButton || opts.pdfHref;
|
|
710
|
+
return `<!doctype html>
|
|
711
|
+
<html lang="${esc(locale)}"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
|
|
712
|
+
<meta name="robots" content="noindex"><title>${esc(t.title)}${shop ? ` - ${esc(shop)}` : ""}</title><style>${CSS}</style></head>
|
|
713
|
+
<body><main aria-labelledby="t">
|
|
714
|
+
<header class="head"><div><h1 id="t">${esc(t.title)}</h1><p class="muted" data-voucher-method="${esc(v.method ?? "")}">${subtitle}</p></div>
|
|
715
|
+
${v.amount ? `<div><p class="label" style="text-align:right">${esc(t.total)}</p><p class="amount">${esc(formatMoney(v.amount, locale))}</p></div>` : ""}</header>
|
|
716
|
+
${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("")}
|
|
717
|
+
${svg ? `<figure class="bar">${svg}<figcaption class="muted" style="font-family:ui-monospace,monospace">${esc(code)}</figcaption></figure>` : ""}
|
|
718
|
+
${expires ? `<p><strong>${esc(t.expires)}:</strong> ${esc(expires.replace(/\.$/, ""))}. ${esc(t.expiresNote)}</p>` : ""}
|
|
719
|
+
<h2 class="steps-title">${esc(t.stepsTitle)}</h2>
|
|
720
|
+
<ol class="steps">${steps.map((s) => `<li>${esc(s)}</li>`).join("")}</ol>
|
|
721
|
+
${v.instructions ? `<p class="note pre muted">${esc(v.instructions)}</p>` : ""}
|
|
722
|
+
<p class="note muted">${esc(t.footer)}</p>
|
|
723
|
+
${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>` : ""}
|
|
724
|
+
</main>
|
|
725
|
+
${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>` : ""}
|
|
726
|
+
</body></html>`;
|
|
727
|
+
}
|
|
728
|
+
var CSS;
|
|
729
|
+
var init_voucher_document = __esm({
|
|
730
|
+
"src/account/voucher-document.ts"() {
|
|
731
|
+
init_voucher();
|
|
732
|
+
init_voucher_text();
|
|
305
733
|
CSS = `
|
|
306
734
|
@page { size: A4; margin: 18mm; }
|
|
307
735
|
* { box-sizing: border-box; }
|
|
@@ -310,17 +738,21 @@ main { max-width: 174mm; margin: 0 auto; padding: 24px 16px; }
|
|
|
310
738
|
h1 { font-size: 22px; margin: 0; }
|
|
311
739
|
.muted { color: #555; }
|
|
312
740
|
.head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; border-bottom: 3px solid #111; padding-bottom: 12px; }
|
|
313
|
-
.amount { font-size: 28px; font-weight: 700; text-align: right; }
|
|
741
|
+
.amount { margin: 0; font-size: 28px; font-weight: 700; text-align: right; }
|
|
314
742
|
.box { border: 1px solid #111; padding: 14px 16px; margin-top: 18px; }
|
|
315
|
-
.label { font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #555; }
|
|
316
|
-
.value { font: 700 22px/1.3 ui-monospace, "SF Mono", Menlo, Consolas, monospace; word-break: break-all; letter-spacing: .04em; }
|
|
317
|
-
.bar {
|
|
743
|
+
.label { margin: 0; font-weight: 400; font-size: 12px; letter-spacing: .08em; text-transform: uppercase; color: #555; }
|
|
744
|
+
.value { margin: 0; font: 700 22px/1.3 ui-monospace, "SF Mono", Menlo, Consolas, monospace; word-break: break-all; letter-spacing: .04em; }
|
|
745
|
+
.bar { text-align: center; }
|
|
318
746
|
.bar svg { max-width: 100%; height: auto; }
|
|
319
|
-
.steps { margin: 18px 0 0; padding-left: 20px; }
|
|
320
747
|
.note { margin-top: 18px; font-size: 12px; }
|
|
321
748
|
.pre { white-space: pre-line; }
|
|
322
|
-
.
|
|
323
|
-
.
|
|
749
|
+
.steps-title { font-size: 16px; margin: 18px 0 0; }
|
|
750
|
+
.steps { margin: 6px 0 0; padding-left: 20px; }
|
|
751
|
+
.bar { margin: 18px 0 0; }
|
|
752
|
+
.actions { margin-top: 24px; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
|
|
753
|
+
.btn { display: inline-block; font: inherit; padding: 10px 18px; border: 2px solid #111; background: #111; color: #fff; cursor: pointer; text-decoration: none; }
|
|
754
|
+
.btn.alt { background: #fff; color: #111; }
|
|
755
|
+
.btn:focus-visible { outline: 3px solid #1a56db; outline-offset: 2px; }
|
|
324
756
|
@media print { .actions { display: none; } main { padding: 0; } }
|
|
325
757
|
`;
|
|
326
758
|
}
|
|
@@ -652,16 +1084,30 @@ async function invoiceFileResponse({ storefront: storefront$1, orderId, invoiceI
|
|
|
652
1084
|
return failureResponse(err);
|
|
653
1085
|
}
|
|
654
1086
|
}
|
|
655
|
-
async function pendingVoucherResponse({ storefront, id, download = false, shopName, locale, timeZone, signal }) {
|
|
1087
|
+
async function pendingVoucherResponse({ storefront, id, download = false, format = "html", paper, pdfHref = "?formato=pdf", shopName, locale, timeZone, signal }) {
|
|
656
1088
|
try {
|
|
657
1089
|
const page = await storefront.customer.pendingPayments({ first: 100 }, signal ? { signal } : void 0);
|
|
658
1090
|
const item = page.nodes.find((p) => p.id === id);
|
|
659
1091
|
const voucher = item ? voucherOf(item) : null;
|
|
660
1092
|
if (!item || !voucher) return textResponse(404, "Ficha no encontrada");
|
|
1093
|
+
const safeId = id.replace(/[^A-Za-z0-9-]/g, "").slice(0, 8) || "ficha";
|
|
1094
|
+
if (format === "pdf") {
|
|
1095
|
+
const { renderVoucherPdf: renderVoucherPdf2 } = await Promise.resolve().then(() => (init_voucher_pdf(), voucher_pdf_exports));
|
|
1096
|
+
const bytes = renderVoucherPdf2(voucher, { ...shopName ? { shopName } : {}, ...locale ? { locale } : {}, ...timeZone ? { timeZone } : {}, ...paper ? { paper } : {} });
|
|
1097
|
+
return new Response(bytes, {
|
|
1098
|
+
status: 200,
|
|
1099
|
+
headers: {
|
|
1100
|
+
"Content-Type": "application/pdf",
|
|
1101
|
+
"Content-Length": String(bytes.byteLength),
|
|
1102
|
+
"Content-Disposition": 'attachment; filename="ficha-de-pago.pdf"',
|
|
1103
|
+
...LOCKED_HEADERS,
|
|
1104
|
+
"Content-Security-Policy": "default-src 'none'; sandbox"
|
|
1105
|
+
}
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
661
1108
|
const nonce = btoa(String.fromCharCode(...crypto.getRandomValues(new Uint8Array(16))));
|
|
662
1109
|
const { renderVoucherDocument: renderVoucherDocument2 } = await Promise.resolve().then(() => (init_voucher_document(), voucher_document_exports));
|
|
663
|
-
const html = renderVoucherDocument2(voucher, { ...shopName ? { shopName } : {}, ...locale ? { locale } : {}, ...timeZone ? { timeZone } : {}, printButton: !download, nonce });
|
|
664
|
-
const safeId = id.replace(/[^A-Za-z0-9-]/g, "").slice(0, 8) || "ficha";
|
|
1110
|
+
const html = renderVoucherDocument2(voucher, { ...shopName ? { shopName } : {}, ...locale ? { locale } : {}, ...timeZone ? { timeZone } : {}, printButton: !download, ...download ? {} : { pdfHref }, nonce });
|
|
665
1111
|
return new Response(html, {
|
|
666
1112
|
status: 200,
|
|
667
1113
|
headers: {
|
|
@@ -676,6 +1122,9 @@ async function pendingVoucherResponse({ storefront, id, download = false, shopNa
|
|
|
676
1122
|
return failureResponse(err);
|
|
677
1123
|
}
|
|
678
1124
|
}
|
|
1125
|
+
function pendingVoucherPdfResponse(options) {
|
|
1126
|
+
return pendingVoucherResponse({ ...options, format: "pdf" });
|
|
1127
|
+
}
|
|
679
1128
|
|
|
680
1129
|
exports.MAX_INVOICE_FILE_BYTES = MAX_INVOICE_FILE_BYTES;
|
|
681
1130
|
exports.SAFE_AUTH_CAPABILITIES = SAFE_AUTH_CAPABILITIES;
|
|
@@ -685,6 +1134,7 @@ exports.invoiceFileResponse = invoiceFileResponse;
|
|
|
685
1134
|
exports.loadAccountSessions = loadAccountSessions;
|
|
686
1135
|
exports.loadAccountSettings = loadAccountSettings;
|
|
687
1136
|
exports.loadAuthCapabilities = loadAuthCapabilities;
|
|
1137
|
+
exports.pendingVoucherPdfResponse = pendingVoucherPdfResponse;
|
|
688
1138
|
exports.pendingVoucherResponse = pendingVoucherResponse;
|
|
689
1139
|
exports.safeNextPath = safeNextPath;
|
|
690
1140
|
exports.toSettingsFailure = toSettingsFailure;
|