@codemind.ec/medusa-plugin-invoice 1.0.0 → 1.0.2

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.
Files changed (31) hide show
  1. package/.medusa/server/src/admin/index.js +512 -7
  2. package/.medusa/server/src/admin/index.mjs +513 -10
  3. package/.medusa/server/src/api/admin/invoice-config/route.js +26 -0
  4. package/.medusa/server/src/api/admin/invoice-templates/[id]/preview/route.js +119 -0
  5. package/.medusa/server/src/api/admin/invoice-templates/[id]/restore/route.js +21 -0
  6. package/.medusa/server/src/api/admin/invoice-templates/[id]/route.js +31 -0
  7. package/.medusa/server/src/api/admin/invoice-templates/route.js +20 -0
  8. package/.medusa/server/src/api/admin/invoice-templates/validators.js +18 -0
  9. package/.medusa/server/src/api/middlewares.js +36 -0
  10. package/.medusa/server/src/index.js +16 -1
  11. package/.medusa/server/src/modules/invoice-generator/errors.js +30 -0
  12. package/.medusa/server/src/modules/invoice-generator/index.js +15 -0
  13. package/.medusa/server/src/modules/invoice-generator/loaders/create-default-config.js +34 -0
  14. package/.medusa/server/src/modules/invoice-generator/migrations/Migration20250728094738.js +18 -0
  15. package/.medusa/server/src/modules/invoice-generator/migrations/Migration20250728124134.js +14 -0
  16. package/.medusa/server/src/modules/invoice-generator/migrations/Migration20250728151454.js +14 -0
  17. package/.medusa/server/src/modules/invoice-generator/migrations/Migration20260120005559.js +14 -0
  18. package/.medusa/server/src/modules/invoice-generator/migrations/Migration20260216191700.js +14 -0
  19. package/.medusa/server/src/modules/invoice-generator/migrations/Migration20260601120000.js +17 -0
  20. package/.medusa/server/src/modules/invoice-generator/models/invoice-config.js +16 -0
  21. package/.medusa/server/src/modules/invoice-generator/models/invoice-template.js +19 -0
  22. package/.medusa/server/src/modules/invoice-generator/models/invoice.js +17 -0
  23. package/.medusa/server/src/modules/invoice-generator/service.js +84 -0
  24. package/.medusa/server/src/modules/invoice-generator/templates/defaults/index.js +380 -0
  25. package/.medusa/server/src/modules/invoice-generator/templates/order-invoice.js +348 -0
  26. package/.medusa/server/src/modules/invoice-generator/templates/quote-proforma.js +468 -0
  27. package/.medusa/server/src/modules/invoice-generator/templates/strategy.js +110 -0
  28. package/LICENSE +21 -0
  29. package/README.md +204 -0
  30. package/index.d.ts +138 -0
  31. package/package.json +26 -2
@@ -0,0 +1,468 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuoteProformaStrategy = void 0;
4
+ const strategy_1 = require("./strategy");
5
+ // ── Design tokens ─────────────────────────────────────────────────────────────
6
+ const C = {
7
+ headerBg: "#121212",
8
+ darkBg: "#1c1c1c",
9
+ sectionBg: "#262626",
10
+ gold: "#d4af37",
11
+ goldLight: "#f5ebb4",
12
+ goldDark: "#a0821e",
13
+ white: "#ffffff",
14
+ gray100: "#f2f2f2",
15
+ gray300: "#c8c8c8",
16
+ gray500: "#8c8c8c",
17
+ gray800: "#282828",
18
+ success: "#27ae60",
19
+ warning: "#c0392b",
20
+ };
21
+ const L = {
22
+ pageHorizontal: 40,
23
+ rowPadX: 10,
24
+ rowPadY: 6,
25
+ sectionGap: 20,
26
+ sectionTitleGap: 10,
27
+ headerHeight: 96,
28
+ };
29
+ function tc(cell) {
30
+ return cell;
31
+ }
32
+ const zebra = (index) => (index % 2 === 0 ? C.gray100 : C.white);
33
+ // ── Reusable table layouts ────────────────────────────────────────────────────
34
+ const goldBorderLayout = {
35
+ hLineWidth: () => 0,
36
+ vLineWidth: (i) => (i === 0 ? 2 : 0),
37
+ vLineColor: () => C.goldDark,
38
+ paddingLeft: () => L.rowPadX,
39
+ paddingRight: () => L.rowPadX,
40
+ paddingTop: () => L.rowPadY,
41
+ paddingBottom: () => L.rowPadY,
42
+ };
43
+ const breakdownLayout = {
44
+ hLineWidth: () => 0,
45
+ vLineWidth: (i) => (i === 0 ? 2 : 0),
46
+ vLineColor: () => C.gold,
47
+ paddingLeft: () => L.rowPadX,
48
+ paddingRight: () => L.rowPadX,
49
+ paddingTop: () => L.rowPadY,
50
+ paddingBottom: () => L.rowPadY,
51
+ };
52
+ const bannerLayout = {
53
+ hLineWidth: () => 0,
54
+ vLineWidth: (i) => (i === 0 ? 3 : 0),
55
+ vLineColor: () => C.gold,
56
+ paddingLeft: () => 12,
57
+ paddingRight: () => 12,
58
+ paddingTop: () => 8,
59
+ paddingBottom: () => 8,
60
+ };
61
+ const totalLayout = {
62
+ hLineWidth: () => 0,
63
+ vLineWidth: (i) => (i === 0 ? 4 : 0),
64
+ vLineColor: () => C.gold,
65
+ paddingLeft: () => 12,
66
+ paddingRight: () => 12,
67
+ paddingTop: () => 10,
68
+ paddingBottom: () => 10,
69
+ };
70
+ // ── Strategy ──────────────────────────────────────────────────────────────────
71
+ class QuoteProformaStrategy extends strategy_1.BaseDocumentStrategy {
72
+ constructor() {
73
+ super(...arguments);
74
+ this.buildIncludeRow = (inc) => ({
75
+ columns: [
76
+ {
77
+ margin: [0, 2, 4, 0],
78
+ canvas: [{
79
+ type: "polyline",
80
+ lineWidth: 1.6,
81
+ lineColor: C.success,
82
+ lineJoin: "round",
83
+ lineCap: "round",
84
+ points: [{ x: 0.5, y: 4.5 }, { x: 4, y: 8 }, { x: 10, y: 1 }],
85
+ }],
86
+ width: 14,
87
+ },
88
+ { text: inc, color: C.gray800, fontSize: 8.5, lineHeight: 1.2, width: "*", margin: [0, 1, 0, 0] },
89
+ ],
90
+ margin: [0, 0, 0, 7],
91
+ });
92
+ }
93
+ async buildDocumentDefinition(input, _config, htmlTemplate) {
94
+ // ── If HTML template provided, render via Handlebars + html-to-pdfmake ──
95
+ if (htmlTemplate) {
96
+ return this.buildFromHtml(htmlTemplate, input, _config);
97
+ }
98
+ // ── Fallback: original pdfmake definition ──────────────────────────────
99
+ const rawContactRows = input.customerInfo ? [
100
+ ["Nombre", input.customerInfo.name],
101
+ ["Email", input.customerInfo.email],
102
+ ["Teléfono", input.customerInfo.phone],
103
+ ["Cédula / RUC", input.customerInfo.cedula],
104
+ ["Fecha del evento", input.customerInfo.eventDate],
105
+ ["Hora del evento", input.customerInfo.eventTime],
106
+ ["Provincia", input.customerInfo.province],
107
+ ["Ciudad", input.customerInfo.city],
108
+ ["Dirección", input.customerInfo.address],
109
+ ["Detalles", input.customerInfo.addressDetails],
110
+ ] : [];
111
+ const contactRows = rawContactRows.filter((row) => Boolean(row[1]) && row[1] !== "—" && row[1] !== "");
112
+ const subtotal = input.totals.subtotal ?? 0;
113
+ const extras = input.totals.extras ?? 0;
114
+ const shipping = input.totals.shipping ?? 0;
115
+ const discount = input.totals.discount ?? 0;
116
+ const taxesProvided = typeof input.totals.taxes === "number" && Number.isFinite(input.totals.taxes);
117
+ const rawTaxes = taxesProvided ? input.totals.taxes : (input.totals.total - (subtotal + extras + shipping - discount));
118
+ const taxes = Number.isFinite(rawTaxes) ? Math.max(0, Number(rawTaxes.toFixed(2))) : 0;
119
+ // IVA/impuestos se muestran solo en el resumen de costos.
120
+ const breakdownRows = input.breakdown.filter((line) => !/iva|impuesto/i.test(line.label));
121
+ const summaryRows = [
122
+ this.buildTotalRow("Subtotal de servicio", input.totals.subtotal, C.gray100),
123
+ this.buildTotalRow("Total extras", input.totals.extras, C.white),
124
+ ...(input.totals.discount ? [this.buildTotalRow("Descuento", -input.totals.discount, C.gray100)] : []),
125
+ ...(input.totals.shipping && !input.isHomeDelivery ? [this.buildTotalRow("Costo de envío (Delivery)", input.totals.shipping, C.white)] : []),
126
+ taxesProvided
127
+ ? this.buildTotalRow("Impuestos (IVA)", taxes, C.gray100)
128
+ : this.buildInfoRow("Impuestos (IVA)", "Cálculo pendiente al confirmar la reserva.", C.gray100, C.warning),
129
+ ];
130
+ const totalSummaryStack = [
131
+ {
132
+ table: {
133
+ widths: ["*", 130],
134
+ body: summaryRows,
135
+ },
136
+ layout: "noBorders",
137
+ },
138
+ {
139
+ canvas: [{ type: "line", x1: 0, y1: 4, x2: 515, y2: 4, lineWidth: 1, lineColor: C.gold }],
140
+ margin: [0, 2, 0, 6],
141
+ },
142
+ {
143
+ table: {
144
+ widths: ["*"],
145
+ body: [[
146
+ {
147
+ fillColor: C.darkBg,
148
+ border: [false, false, false, false],
149
+ columns: [
150
+ {
151
+ stack: [
152
+ { text: "TOTAL A PAGAR", color: C.gray300, fontSize: 9, bold: true },
153
+ { text: "DÓLARES AMERICANOS", color: C.gray500, fontSize: 7, margin: [0, 2, 0, 0] },
154
+ ],
155
+ margin: [4, 0, 0, 0],
156
+ },
157
+ {
158
+ text: `$${input.totals.total.toFixed(2)}`,
159
+ color: C.gold, fontSize: 31, bold: true, alignment: "right",
160
+ margin: [0, 0, 0, 0],
161
+ },
162
+ ],
163
+ },
164
+ ]],
165
+ },
166
+ layout: totalLayout,
167
+ },
168
+ ];
169
+ if (!taxesProvided) {
170
+ totalSummaryStack.push({
171
+ text: "Total referencial: el valor final se confirmará una vez aplicado el cálculo de impuestos.",
172
+ color: C.warning,
173
+ bold: true,
174
+ fontSize: 9,
175
+ alignment: "right",
176
+ margin: [0, 6, 2, 0],
177
+ });
178
+ }
179
+ const docDef = {
180
+ pageSize: "A4",
181
+ pageMargins: [L.pageHorizontal, 112, L.pageHorizontal, 88],
182
+ header: {
183
+ margin: [0, 0, 0, 0],
184
+ stack: [
185
+ // Background drawn absolutely
186
+ {
187
+ canvas: [
188
+ { type: "rect", x: 0, y: 0, w: 595.28, h: L.headerHeight, color: C.headerBg },
189
+ { type: "rect", x: 0, y: L.headerHeight - 3, w: 595.28, h: 2, color: C.gold },
190
+ ],
191
+ absolutePosition: { x: 0, y: 0 }
192
+ },
193
+ // Content respects standard margins
194
+ {
195
+ margin: [L.pageHorizontal, 20, L.pageHorizontal, 0],
196
+ columns: [
197
+ {
198
+ width: "*",
199
+ stack: [
200
+ { text: "LA TASCA", color: C.gold, fontSize: 24, bold: true, margin: [0, 0, 0, 1] },
201
+ { text: "Contacto Empresarial", color: C.gray300, fontSize: 9, margin: [0, 1, 0, 0] },
202
+ ],
203
+ },
204
+ {
205
+ width: 190,
206
+ stack: [
207
+ { text: "COTIZACIÓN", color: C.gray500, fontSize: 9, bold: true, alignment: "right", margin: [0, 2, 0, 0] },
208
+ {
209
+ canvas: [{ type: "line", x1: 0, y1: 0, x2: 28, y2: 0, lineWidth: 1.5, lineColor: C.gold }],
210
+ margin: [0, 6, 0, 8],
211
+ alignment: "right",
212
+ },
213
+ { text: `Nro. de Proforma: ${input.quoteNumber}`, color: C.gray300, fontSize: 9, lineHeight: 1.35, alignment: "right", margin: [0, 2, 0, 0] },
214
+ { text: `Fecha: ${input.dateStr}`, color: C.gray300, fontSize: 9, lineHeight: 1.35, alignment: "right", margin: [0, 2, 0, 0] },
215
+ { text: "Válida por 15 días", color: C.gray300, fontSize: 9, lineHeight: 1.35, alignment: "right", margin: [0, 2, 0, 0] },
216
+ ],
217
+ },
218
+ ],
219
+ },
220
+ ],
221
+ },
222
+ footer: (currentPage, pageCount) => ({
223
+ margin: [0, 0, 0, 0],
224
+ stack: [
225
+ {
226
+ canvas: [
227
+ { type: "rect", x: 0, y: 0, w: 595.28, h: 1.5, color: C.gold },
228
+ { type: "rect", x: 0, y: 1.5, w: 595.28, h: 80, color: C.headerBg },
229
+ ],
230
+ },
231
+ {
232
+ absolutePosition: { x: L.pageHorizontal, y: 10 },
233
+ width: 595.28 - (L.pageHorizontal * 2),
234
+ stack: [
235
+ { text: "Gracias por tu confianza. Nuestro equipo ha recibido tu solicitud y se pondrá en contacto contigo a la brevedad.", color: C.gray300, fontSize: 8, alignment: "center" },
236
+ { text: "Esta cotización es informativa y no constituye un contrato. Los precios pueden variar.", color: C.gray500, fontSize: 7, alignment: "center", margin: [0, 5, 0, 0] },
237
+ {
238
+ columnGap: 10,
239
+ columns: [
240
+ { text: "", width: "*" },
241
+ { text: "www.latasca.com.ec", color: C.gold, fontSize: 8, bold: true, alignment: "center", width: "auto" },
242
+ {
243
+ text: `Página ${currentPage} de ${pageCount} • ${input.quoteNumber}`,
244
+ color: C.gray500,
245
+ fontSize: 7,
246
+ alignment: "right",
247
+ width: "*",
248
+ margin: [0, 0, 8, 0],
249
+ },
250
+ ],
251
+ margin: [0, 5, 0, 0],
252
+ },
253
+ ],
254
+ },
255
+ ],
256
+ }),
257
+ content: [
258
+ // ── Service banner ─────────────────────────────────────────────────
259
+ {
260
+ margin: [0, 12, 0, 24],
261
+ table: {
262
+ widths: ["*"],
263
+ body: [[
264
+ {
265
+ fillColor: C.goldLight,
266
+ border: [false, false, false, false],
267
+ stack: [
268
+ { text: "TIPO DE SERVICIO", color: C.gray500, fontSize: 7, bold: true },
269
+ { text: input.serviceName.toUpperCase(), color: C.gray800, fontSize: 15, bold: true, margin: [0, 4, 0, 0] },
270
+ ],
271
+ margin: [6, 4, 6, 4],
272
+ },
273
+ ]],
274
+ },
275
+ layout: bannerLayout,
276
+ },
277
+ // ── Configuration details ──────────────────────────────────────────
278
+ ...(input.configFields.length > 0 ? [
279
+ this.buildSectionTitle("Detalles de la Configuración"),
280
+ {
281
+ margin: [0, 0, 0, L.sectionGap],
282
+ table: {
283
+ widths: ["42%", "*"],
284
+ body: input.configFields.map((f, i) => [
285
+ tc({ text: f.label, color: C.gray500, fontSize: 9, lineHeight: 1.2, fillColor: zebra(i), border: [false, false, false, false], margin: [0, 0, 0, 0] }),
286
+ tc({ text: f.value, color: C.gray800, fontSize: 9.5, lineHeight: 1.2, bold: true, alignment: "right", fillColor: zebra(i), border: [false, false, false, false], margin: [0, 0, 0, 0] }),
287
+ ]),
288
+ },
289
+ layout: goldBorderLayout,
290
+ },
291
+ ] : []),
292
+ // ── Price breakdown ────────────────────────────────────────────────
293
+ ...(input.breakdown.length > 0 ? [
294
+ this.buildSectionTitle("Desglose de Costos"),
295
+ {
296
+ margin: [0, 0, 0, L.sectionGap],
297
+ table: {
298
+ widths: ["*", "auto"],
299
+ body: breakdownRows.map((item, i) => [
300
+ tc({ text: item.label, color: C.gray800, fontSize: 9.5, lineHeight: 1.2, fillColor: zebra(i), border: [false, false, false, false], margin: [0, 0, 0, 0] }),
301
+ tc({
302
+ text: item.note ?? `$${(item.total ?? 0).toFixed(2)}`,
303
+ color: item.note ? C.warning : C.gray800,
304
+ italics: !!item.note,
305
+ fontSize: item.note ? 8.5 : 10,
306
+ bold: !item.note,
307
+ alignment: "right",
308
+ fillColor: zebra(i),
309
+ border: [false, false, false, false],
310
+ margin: [0, 0, 0, 0]
311
+ }),
312
+ ]),
313
+ },
314
+ layout: breakdownLayout,
315
+ },
316
+ ] : []),
317
+ // ── Cost summary ───────────────────────────────────────────────────
318
+ this.buildSectionTitle("Resumen de Costos"),
319
+ {
320
+ margin: [0, 0, 0, 24],
321
+ stack: totalSummaryStack,
322
+ },
323
+ ...(input.isHomeDelivery ? [{
324
+ margin: [0, 0, 0, 24],
325
+ table: {
326
+ widths: ["*"],
327
+ body: [[
328
+ {
329
+ fillColor: "#fff7e6",
330
+ border: [false, false, false, false],
331
+ stack: [
332
+ { text: "AVISO SOBRE TRANSPORTE", color: C.warning, fontSize: 8, bold: true },
333
+ {
334
+ text: "El valor de transporte no está incluido en esta proforma y deberá cotizarse aparte directamente con el vendedor.",
335
+ color: C.gray800,
336
+ fontSize: 9,
337
+ lineHeight: 1.3,
338
+ margin: [0, 4, 0, 0],
339
+ },
340
+ ],
341
+ margin: [6, 4, 6, 4],
342
+ },
343
+ ]],
344
+ },
345
+ layout: bannerLayout,
346
+ }] : []),
347
+ // ── Includes ──────────────────────────────────────────────────────
348
+ ...(input.includes.length > 0 ? [
349
+ this.buildSectionTitle("¿Qué Incluye?"),
350
+ {
351
+ margin: [0, 0, 0, 24],
352
+ columnGap: 24,
353
+ columns: [
354
+ { width: "*", stack: input.includes.filter((_, i) => i % 2 === 0).map(this.buildIncludeRow) },
355
+ { width: "*", stack: input.includes.filter((_, i) => i % 2 !== 0).map(this.buildIncludeRow) },
356
+ ],
357
+ },
358
+ ] : []),
359
+ // ── Client info ────────────────────────────────────────────────────
360
+ ...(contactRows.length > 0 ? [
361
+ this.buildSectionTitle("Información del Cliente"),
362
+ {
363
+ margin: [0, 0, 0, 18],
364
+ unbreakable: true,
365
+ table: {
366
+ widths: ["36%", "*"],
367
+ body: contactRows.map(([label, value], i) => [
368
+ tc({ text: label, color: C.gray500, fontSize: 9, lineHeight: 1.2, fillColor: zebra(i), border: [false, false, false, false], margin: [0, 0, 0, 0] }),
369
+ tc({ text: value, color: C.gray800, fontSize: 9.5, lineHeight: 1.25, bold: true, alignment: "left", fillColor: zebra(i), border: [false, false, false, false], margin: [0, 0, 0, 0] }),
370
+ ]),
371
+ },
372
+ layout: goldBorderLayout,
373
+ },
374
+ ] : []),
375
+ ],
376
+ defaultStyle: { font: "Helvetica" },
377
+ };
378
+ return docDef;
379
+ }
380
+ // ── Private helpers ─────────────────────────────────────────────────────────
381
+ buildSectionTitle(title) {
382
+ return {
383
+ margin: [0, 0, 0, L.sectionTitleGap],
384
+ table: {
385
+ widths: ["*"],
386
+ body: [[
387
+ tc({ text: title.toUpperCase(), fillColor: C.sectionBg, border: [false, false, false, false], color: C.gold, fontSize: 10, bold: true, margin: [2, 0, 0, 0] }),
388
+ ]],
389
+ },
390
+ layout: bannerLayout,
391
+ };
392
+ }
393
+ buildTotalRow(label, amount, bg) {
394
+ return [
395
+ tc({ text: label, color: C.gray500, fontSize: 9.5, lineHeight: 1.2, border: [false, false, false, false], fillColor: bg, margin: [8, 5, 8, 5] }),
396
+ tc({ text: `$${amount.toFixed(2)}`, color: C.gray800, fontSize: 10, bold: true, alignment: "right", border: [false, false, false, false], fillColor: bg, margin: [8, 5, 8, 5] }),
397
+ ];
398
+ }
399
+ buildInfoRow(label, message, bg, color = C.gray500) {
400
+ return [
401
+ tc({ text: label, color, fontSize: 9.5, lineHeight: 1.2, bold: true, border: [false, false, false, false], fillColor: bg, margin: [8, 5, 8, 5] }),
402
+ tc({ text: message, color, fontSize: 8.5, italics: true, alignment: "right", border: [false, false, false, false], fillColor: bg, margin: [8, 5, 8, 5] }),
403
+ ];
404
+ }
405
+ async buildFromHtml(htmlTemplate, input, config) {
406
+ const fmt = (n) => `$${n.toFixed(2)}`;
407
+ const taxesProvided = typeof input.totals.taxes === "number" && Number.isFinite(input.totals.taxes);
408
+ const rawTaxes = taxesProvided
409
+ ? input.totals.taxes
410
+ : (input.totals.total - (input.totals.subtotal + input.totals.extras + (input.totals.shipping ?? 0) - (input.totals.discount ?? 0)));
411
+ const taxes = Number.isFinite(rawTaxes) ? Math.max(0, Number(rawTaxes.toFixed(2))) : 0;
412
+ const breakdownRows = input.breakdown
413
+ .filter(line => !/iva|impuesto/i.test(line.label))
414
+ .map(item => ({
415
+ label: item.label,
416
+ total_formatted: fmt(item.total),
417
+ }));
418
+ const contactRows = [];
419
+ if (input.customerInfo) {
420
+ const raw = [
421
+ ["Nombre", input.customerInfo.name],
422
+ ["Email", input.customerInfo.email],
423
+ ["Teléfono", input.customerInfo.phone],
424
+ ["Cédula / RUC", input.customerInfo.cedula],
425
+ ["Fecha del evento", input.customerInfo.eventDate],
426
+ ["Hora del evento", input.customerInfo.eventTime],
427
+ ["Provincia", input.customerInfo.province],
428
+ ["Ciudad", input.customerInfo.city],
429
+ ["Dirección", input.customerInfo.address],
430
+ ["Detalles", input.customerInfo.addressDetails],
431
+ ];
432
+ for (const [label, value] of raw) {
433
+ if (value && value !== "—" && value !== "") {
434
+ contactRows.push({ label, value });
435
+ }
436
+ }
437
+ }
438
+ const includes = input.includes ?? [];
439
+ const data = {
440
+ company_name: config?.company_name ?? "Empresa",
441
+ company_website: "",
442
+ quote_number: input.quoteNumber,
443
+ date_str: input.dateStr,
444
+ service_name: input.serviceName.toUpperCase(),
445
+ config_fields: input.configFields,
446
+ breakdown: breakdownRows,
447
+ totals: {
448
+ subtotal_formatted: fmt(input.totals.subtotal),
449
+ extras_formatted: fmt(input.totals.extras),
450
+ discount: input.totals.discount ?? 0,
451
+ discount_formatted: input.totals.discount ? fmt(input.totals.discount) : "",
452
+ shipping: input.totals.shipping ?? 0,
453
+ shipping_formatted: input.totals.shipping ? fmt(input.totals.shipping) : "",
454
+ taxes_provided: taxesProvided,
455
+ taxes_formatted: fmt(taxes),
456
+ total_formatted: input.totals.total.toFixed(2),
457
+ },
458
+ is_home_delivery: input.isHomeDelivery ?? false,
459
+ includes,
460
+ includes_left: includes.filter((_, i) => i % 2 === 0),
461
+ includes_right: includes.filter((_, i) => i % 2 !== 0),
462
+ contact_rows: contactRows,
463
+ };
464
+ return this.renderHtmlTemplate(htmlTemplate, data);
465
+ }
466
+ }
467
+ exports.QuoteProformaStrategy = QuoteProformaStrategy;
468
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVvdGUtcHJvZm9ybWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9pbnZvaWNlLWdlbmVyYXRvci90ZW1wbGF0ZXMvcXVvdGUtcHJvZm9ybWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBUUEseUNBQWlEO0FBb0VqRCxpRkFBaUY7QUFFakYsTUFBTSxDQUFDLEdBQUc7SUFDTixRQUFRLEVBQUUsU0FBUztJQUNuQixNQUFNLEVBQUUsU0FBUztJQUNqQixTQUFTLEVBQUUsU0FBUztJQUNwQixJQUFJLEVBQUUsU0FBUztJQUNmLFNBQVMsRUFBRSxTQUFTO0lBQ3BCLFFBQVEsRUFBRSxTQUFTO0lBQ25CLEtBQUssRUFBRSxTQUFTO0lBQ2hCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLE9BQU8sRUFBRSxTQUFTO0lBQ2xCLE9BQU8sRUFBRSxTQUFTO0NBQ1osQ0FBQTtBQUVWLE1BQU0sQ0FBQyxHQUFHO0lBQ04sY0FBYyxFQUFFLEVBQUU7SUFDbEIsT0FBTyxFQUFFLEVBQUU7SUFDWCxPQUFPLEVBQUUsQ0FBQztJQUNWLFVBQVUsRUFBRSxFQUFFO0lBQ2QsZUFBZSxFQUFFLEVBQUU7SUFDbkIsWUFBWSxFQUFFLEVBQUU7Q0FDVixDQUFBO0FBT1YsU0FBUyxFQUFFLENBQUMsSUFBZ0Q7SUFDeEQsT0FBTyxJQUFlLENBQUE7QUFDMUIsQ0FBQztBQUVELE1BQU0sS0FBSyxHQUFHLENBQUMsS0FBYSxFQUFVLEVBQUUsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUE7QUFFaEYsaUZBQWlGO0FBRWpGLE1BQU0sZ0JBQWdCLEdBQXNCO0lBQ3hDLFVB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
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TemplateFactory = exports.BaseDocumentStrategy = void 0;
4
+ const errors_1 = require("../errors");
5
+ // ── Shared utility methods ────────────────────────────────────────────────────
6
+ /** Supported ISO currency codes with their BCP-47 locale mappings */
7
+ const CURRENCY_LOCALE_MAP = {
8
+ USD: "en-US",
9
+ EUR: "es-ES",
10
+ MXN: "es-MX",
11
+ COP: "es-CO",
12
+ PEN: "es-PE",
13
+ CLP: "es-CL",
14
+ ARS: "es-AR",
15
+ GBP: "en-GB",
16
+ BRL: "pt-BR",
17
+ };
18
+ class BaseDocumentStrategy {
19
+ getLocaleForCurrency(currencyCode) {
20
+ return CURRENCY_LOCALE_MAP[currencyCode.toUpperCase()] ?? "es-ES";
21
+ }
22
+ /** Formats a raw numeric amount into a human-readable currency string */
23
+ formatAmount(amount, currency) {
24
+ const locale = this.getLocaleForCurrency(currency);
25
+ return new Intl.NumberFormat(locale, {
26
+ style: "currency",
27
+ currency,
28
+ }).format(amount);
29
+ }
30
+ /**
31
+ * Downloads an image URL and converts it to a base64 data-URI string
32
+ * suitable for embedding in pdfmake documents.
33
+ *
34
+ * Gracefully returns an empty string on failure so rendering can continue.
35
+ */
36
+ async imageUrlToBase64(url) {
37
+ const { default: axios } = await import("axios");
38
+ const fullUrl = url.startsWith("/")
39
+ ? `${process.env.MEDUSA_BACKEND_URL ?? "http://localhost:9000"}${url}`
40
+ : url;
41
+ try {
42
+ const response = await axios.get(fullUrl, {
43
+ responseType: "arraybuffer",
44
+ });
45
+ const base64 = Buffer.from(response.data).toString("base64");
46
+ const mimeType = response.headers["content-type"] ?? "image/png";
47
+ return `data:${mimeType};base64,${base64}`;
48
+ }
49
+ catch (err) {
50
+ console.warn(`[InvoiceGen] Could not embed image from ${fullUrl}`, err);
51
+ return "";
52
+ }
53
+ }
54
+ /**
55
+ * Renders an HTML+Handlebars template string into a pdfmake
56
+ * `TDocumentDefinitions` using handlebars compilation + html-to-pdfmake.
57
+ */
58
+ async renderHtmlTemplate(htmlTemplate, data) {
59
+ const Handlebars = await import("handlebars");
60
+ const htmlToPdfmake = (await import("html-to-pdfmake")).default;
61
+ const { JSDOM } = await import("jsdom");
62
+ const compiled = Handlebars.compile(htmlTemplate);
63
+ const html = compiled(data);
64
+ const { window } = new JSDOM("");
65
+ const content = htmlToPdfmake(html, { window: window });
66
+ return {
67
+ pageSize: "A4",
68
+ pageMargins: [40, 60, 40, 60],
69
+ content,
70
+ defaultStyle: { font: "Helvetica", fontSize: 10 },
71
+ };
72
+ }
73
+ }
74
+ exports.BaseDocumentStrategy = BaseDocumentStrategy;
75
+ /**
76
+ * A static registry that maps template identifiers to their corresponding
77
+ * strategy implementations. Extend the system by calling `register()` —
78
+ * no modification to the service layer required.
79
+ */
80
+ class TemplateFactory {
81
+ /**
82
+ * Register a new template strategy.
83
+ *
84
+ * @example
85
+ * TemplateFactory.register("order_invoice", OrderInvoiceStrategy)
86
+ */
87
+ static register(templateId, strategy) {
88
+ TemplateFactory.registry.set(templateId, strategy);
89
+ }
90
+ /**
91
+ * Resolve and instantiate the strategy for the given template ID.
92
+ *
93
+ * @throws {TemplateNotFoundError} if no strategy is registered.
94
+ */
95
+ static resolve(templateId) {
96
+ const StrategyCtor = TemplateFactory.registry.get(templateId);
97
+ if (!StrategyCtor) {
98
+ throw new errors_1.TemplateNotFoundError(templateId);
99
+ }
100
+ return new StrategyCtor();
101
+ }
102
+ /** Lists all registered template IDs (useful for admin UIs / debugging) */
103
+ static listRegistered() {
104
+ return Array.from(TemplateFactory.registry.keys());
105
+ }
106
+ }
107
+ exports.TemplateFactory = TemplateFactory;
108
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
109
+ TemplateFactory.registry = new Map();
110
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9pbnZvaWNlLWdlbmVyYXRvci90ZW1wbGF0ZXMvc3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0Esc0NBQWlEO0FBbUJqRCxpRkFBaUY7QUFFakYscUVBQXFFO0FBQ3JFLE1BQU0sbUJBQW1CLEdBQXFDO0lBQzFELEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87SUFDWixHQUFHLEVBQUUsT0FBTztJQUNaLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87SUFDWixHQUFHLEVBQUUsT0FBTztJQUNaLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87SUFDWixHQUFHLEVBQUUsT0FBTztDQUNOLENBQUE7QUFFVixNQUFzQixvQkFBb0I7SUFFNUIsb0JBQW9CLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUE7SUFDckUsQ0FBQztJQUVELHlFQUF5RTtJQUMvRCxZQUFZLENBQUMsTUFBYyxFQUFFLFFBQWdCO1FBQ25ELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUNsRCxPQUFPLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7WUFDakMsS0FBSyxFQUFFLFVBQVU7WUFDakIsUUFBUTtTQUNYLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDckIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ08sS0FBSyxDQUFDLGdCQUFnQixDQUFDLEdBQVc7UUFDeEMsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUVoRCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztZQUMvQixDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixJQUFJLHVCQUF1QixHQUFHLEdBQUcsRUFBRTtZQUN0RSxDQUFDLENBQUMsR0FBRyxDQUFBO1FBRVQsSUFBSSxDQUFDO1lBQ0QsTUFBTSxRQUFRLEdBQUcsTUFBTSxLQUFLLENBQUMsR0FBRyxDQUFjLE9BQU8sRUFBRTtnQkFDbkQsWUFBWSxFQUFFLGFBQWE7YUFDOUIsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQzVELE1BQU0sUUFBUSxHQUNULFFBQVEsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUF3QixJQUFJLFdBQVcsQ0FBQTtZQUMzRSxPQUFPLFFBQVEsUUFBUSxXQUFXLE1BQU0sRUFBRSxDQUFBO1FBQzlDLENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ1gsT0FBTyxDQUFDLElBQUksQ0FBQywyQ0FBMkMsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUE7WUFDdkUsT0FBTyxFQUFFLENBQUE7UUFDYixDQUFDO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNPLEtBQUssQ0FBQyxrQkFBa0IsQ0FDOUIsWUFBb0IsRUFDcEIsSUFBNkI7UUFFN0IsTUFBTSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUE7UUFDN0MsTUFBTSxhQUFhLEdBQUcsQ0FBQyxNQUFNLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFBO1FBQy9ELE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUV2QyxNQUFNLFFBQVEsR0FBRyxVQUFVLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQ2pELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUUzQixNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDaEMsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxFQUFFLE1BQU0sRUFBRSxNQUEyQixFQUFFLENBQUMsQ0FBQTtRQUU1RSxPQUFPO1lBQ0gsUUFBUSxFQUFFLElBQUk7WUFDZCxXQUFXLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7WUFDN0IsT0FBTztZQUNQLFlBQVksRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRTtTQUNwRCxDQUFBO0lBQ0wsQ0FBQztDQU9KO0FBekVELG9EQXlFQztBQU1EOzs7O0dBSUc7QUFDSCxNQUFhLGVBQWU7SUFJeEI7Ozs7O09BS0c7SUFDSCxNQUFNLENBQUMsUUFBUSxDQUNYLFVBQWtCLEVBQ2xCLFFBQXFDO1FBRXJDLGVBQWUsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUN0RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxPQUFPLENBQVMsVUFBa0I7UUFDckMsTUFBTSxZQUFZLEdBQUcsZUFBZSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUU3QyxDQUFBO1FBRWYsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ2hCLE1BQU0sSUFBSSw4QkFBcUIsQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUMvQyxDQUFDO1FBRUQsT0FBTyxJQUFJLFlBQVksRUFBRSxDQUFBO0lBQzdCLENBQUM7SUFFRCwyRUFBMkU7SUFDM0UsTUFBTSxDQUFDLGNBQWM7UUFDakIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQTtJQUN0RCxDQUFDOztBQXJDTCwwQ0FzQ0M7QUFyQ0csOERBQThEO0FBQ3RDLHdCQUFRLEdBQUcsSUFBSSxHQUFHLEVBQW9DLENBQUEifQ==