@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.
- package/.medusa/server/src/admin/index.js +512 -7
- package/.medusa/server/src/admin/index.mjs +513 -10
- package/.medusa/server/src/api/admin/invoice-config/route.js +26 -0
- package/.medusa/server/src/api/admin/invoice-templates/[id]/preview/route.js +119 -0
- package/.medusa/server/src/api/admin/invoice-templates/[id]/restore/route.js +21 -0
- package/.medusa/server/src/api/admin/invoice-templates/[id]/route.js +31 -0
- package/.medusa/server/src/api/admin/invoice-templates/route.js +20 -0
- package/.medusa/server/src/api/admin/invoice-templates/validators.js +18 -0
- package/.medusa/server/src/api/middlewares.js +36 -0
- package/.medusa/server/src/index.js +16 -1
- package/.medusa/server/src/modules/invoice-generator/errors.js +30 -0
- package/.medusa/server/src/modules/invoice-generator/index.js +15 -0
- package/.medusa/server/src/modules/invoice-generator/loaders/create-default-config.js +34 -0
- package/.medusa/server/src/modules/invoice-generator/migrations/Migration20250728094738.js +18 -0
- package/.medusa/server/src/modules/invoice-generator/migrations/Migration20250728124134.js +14 -0
- package/.medusa/server/src/modules/invoice-generator/migrations/Migration20250728151454.js +14 -0
- package/.medusa/server/src/modules/invoice-generator/migrations/Migration20260120005559.js +14 -0
- package/.medusa/server/src/modules/invoice-generator/migrations/Migration20260216191700.js +14 -0
- package/.medusa/server/src/modules/invoice-generator/migrations/Migration20260601120000.js +17 -0
- package/.medusa/server/src/modules/invoice-generator/models/invoice-config.js +16 -0
- package/.medusa/server/src/modules/invoice-generator/models/invoice-template.js +19 -0
- package/.medusa/server/src/modules/invoice-generator/models/invoice.js +17 -0
- package/.medusa/server/src/modules/invoice-generator/service.js +84 -0
- package/.medusa/server/src/modules/invoice-generator/templates/defaults/index.js +380 -0
- package/.medusa/server/src/modules/invoice-generator/templates/order-invoice.js +348 -0
- package/.medusa/server/src/modules/invoice-generator/templates/quote-proforma.js +468 -0
- package/.medusa/server/src/modules/invoice-generator/templates/strategy.js +110 -0
- package/LICENSE +21 -0
- package/README.md +204 -0
- package/index.d.ts +138 -0
- 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyYXRlZ3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbW9kdWxlcy9pbnZvaWNlLWdlbmVyYXRvci90ZW1wbGF0ZXMvc3RyYXRlZ3kudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0Esc0NBQWlEO0FBbUJqRCxpRkFBaUY7QUFFakYscUVBQXFFO0FBQ3JFLE1BQU0sbUJBQW1CLEdBQXFDO0lBQzFELEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87SUFDWixHQUFHLEVBQUUsT0FBTztJQUNaLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87SUFDWixHQUFHLEVBQUUsT0FBTztJQUNaLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLE9BQU87SUFDWixHQUFHLEVBQUUsT0FBTztDQUNOLENBQUE7QUFFVixNQUFzQixvQkFBb0I7SUFFNUIsb0JBQW9CLENBQUMsWUFBb0I7UUFDL0MsT0FBTyxtQkFBbUIsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxPQUFPLENBQUE7SUFDckUsQ0FBQztJQUVELHlFQUF5RTtJQUMvRCxZQUFZLENBQUMsTUFBYyxFQUFFLFFBQWdCO1FBQ25ELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQTtRQUNsRCxPQUFPLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7WUFDakMsS0FBSyxFQUFFLFVBQVU7WUFDakIsUUFBUTtTQUNYLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDckIsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ08sS0FBSyxDQUFDLGdCQUFnQixDQUFDLEdBQVc7UUFDeEMsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUVoRCxNQUFNLE9BQU8sR0FBRyxH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
|