@danielrebolledo/cafe-ipdh-lib 1.0.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 ADDED
@@ -0,0 +1,78 @@
1
+ # cafe-ipdh-lib
2
+
3
+ Librería NPM para gestionar impresoras fiscales y de recibos. Simplifica la construcción de comandos para diferentes modelos de impresoras.
4
+
5
+ ## Modelos soportados
6
+
7
+ - **AEG-R1**: Impresora fiscal vía HTTP (comandos JSON)
8
+
9
+ ## Instalación
10
+
11
+ ```bash
12
+ npm install cafe-ipdh-lib
13
+ ```
14
+
15
+ ## Uso
16
+
17
+ ### Imprimir factura fiscal (AEG-R1)
18
+
19
+ ```ts
20
+ import { aegPrinter } from "cafe-ipdh-lib";
21
+
22
+ const order = {
23
+ client: { id: "V12345678", name: "Cliente", email: "c@mail.com" },
24
+ items: [{ id: "1", name: "Producto", sku: "SKU1", price: 10, quantity: 1, total: 10, taxes: [{ id: "IVA_G" }] }],
25
+ payments: [{ amount: 10, paymentMethod: "cash_nat" }],
26
+ total: 10,
27
+ };
28
+
29
+ const commands = aegPrinter.buildInvoiceCommands(order, {
30
+ paymentMethodId: "cash_nat",
31
+ storeName: "Mi Tienda",
32
+ });
33
+
34
+ // Enviar commands a tu API/impresora (HTTP, etc.)
35
+ ```
36
+
37
+ ### Imprimir recibo de pago
38
+
39
+ ```ts
40
+ const receiptCommands = aegPrinter.buildReceiptCommands({
41
+ orderId: "ORD-123",
42
+ amountPaid: 150.5,
43
+ paymentMethod: "Tarjeta débito",
44
+ organizationName: "Mi Negocio",
45
+ });
46
+ ```
47
+
48
+ ## API
49
+
50
+ ### `aegPrinter`
51
+
52
+ Driver para impresora AEG-R1.
53
+
54
+ - `buildInvoiceCommands(order, options)` → comandos para factura fiscal
55
+ - `buildReceiptCommands(options)` → comandos para recibo DNF
56
+
57
+ ### Tipos exportados
58
+
59
+ - `Order`, `OrderItem`, `FiscalClient`, `OrderPayment`
60
+ - `AegPrinterCommand`
61
+ - `BuildInvoiceOptions`, `BuildReceiptOptions`
62
+ - `PaymentMethodId`, `PrinterTaxValues`, `TaxValues`
63
+
64
+ ## Scripts
65
+
66
+ ```bash
67
+ npm run build # Compilar con tsup
68
+ npm run dev # Watch mode
69
+ npm run lint # Biome check
70
+ npm run test # Vitest
71
+ ```
72
+
73
+ ## Stack
74
+
75
+ - TypeScript
76
+ - tsup (bundle)
77
+ - Biome (lint/format)
78
+ - Vitest (tests)
package/dist/index.cjs ADDED
@@ -0,0 +1,350 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ PaymentMethodId: () => PaymentMethodId,
24
+ PrinterTaxValues: () => PrinterTaxValues,
25
+ TaxValues: () => TaxValues,
26
+ aegPrinter: () => aegPrinter,
27
+ sendPrinterCommands: () => sendPrinterCommands
28
+ });
29
+ module.exports = __toCommonJS(index_exports);
30
+
31
+ // src/types/enums.ts
32
+ var TaxValues = /* @__PURE__ */ ((TaxValues2) => {
33
+ TaxValues2[TaxValues2["EXENTO_E"] = 0] = "EXENTO_E";
34
+ TaxValues2[TaxValues2["BI_G"] = 16] = "BI_G";
35
+ TaxValues2[TaxValues2["IVA_G"] = 16] = "IVA_G";
36
+ TaxValues2[TaxValues2["BI_R"] = 8] = "BI_R";
37
+ TaxValues2[TaxValues2["IVA_R"] = 8] = "IVA_R";
38
+ TaxValues2[TaxValues2["BI_A"] = 31] = "BI_A";
39
+ TaxValues2[TaxValues2["IVA_A"] = 31] = "IVA_A";
40
+ TaxValues2[TaxValues2["PERCIBIDO"] = 0] = "PERCIBIDO";
41
+ TaxValues2[TaxValues2["BI_IGTF"] = 3] = "BI_IGTF";
42
+ TaxValues2[TaxValues2["IVA_IGTF"] = 3] = "IVA_IGTF";
43
+ return TaxValues2;
44
+ })(TaxValues || {});
45
+ var PrinterTaxValues = /* @__PURE__ */ ((PrinterTaxValues2) => {
46
+ PrinterTaxValues2[PrinterTaxValues2["EXENTO_E"] = 1] = "EXENTO_E";
47
+ PrinterTaxValues2[PrinterTaxValues2["BI_G"] = 2] = "BI_G";
48
+ PrinterTaxValues2[PrinterTaxValues2["IVA_G"] = 2] = "IVA_G";
49
+ PrinterTaxValues2[PrinterTaxValues2["BI_R"] = 3] = "BI_R";
50
+ PrinterTaxValues2[PrinterTaxValues2["IVA_R"] = 3] = "IVA_R";
51
+ PrinterTaxValues2[PrinterTaxValues2["BI_A"] = 4] = "BI_A";
52
+ PrinterTaxValues2[PrinterTaxValues2["IVA_A"] = 4] = "IVA_A";
53
+ PrinterTaxValues2[PrinterTaxValues2["PERCIBIDO"] = 5] = "PERCIBIDO";
54
+ PrinterTaxValues2[PrinterTaxValues2["BI_IGTF"] = 5] = "BI_IGTF";
55
+ PrinterTaxValues2[PrinterTaxValues2["IVA_IGTF"] = 5] = "IVA_IGTF";
56
+ return PrinterTaxValues2;
57
+ })(PrinterTaxValues || {});
58
+ var PaymentMethodId = /* @__PURE__ */ ((PaymentMethodId2) => {
59
+ PaymentMethodId2[PaymentMethodId2["CASH"] = 1] = "CASH";
60
+ PaymentMethodId2[PaymentMethodId2["POS_DEBIT"] = 2] = "POS_DEBIT";
61
+ PaymentMethodId2[PaymentMethodId2["POS_CREDIT"] = 3] = "POS_CREDIT";
62
+ PaymentMethodId2[PaymentMethodId2["PAGO_MOVIL"] = 5] = "PAGO_MOVIL";
63
+ PaymentMethodId2[PaymentMethodId2["POS_DEBIT_CREDIT_INT"] = 11] = "POS_DEBIT_CREDIT_INT";
64
+ PaymentMethodId2[PaymentMethodId2["CASH_INT"] = 12] = "CASH_INT";
65
+ return PaymentMethodId2;
66
+ })(PaymentMethodId || {});
67
+
68
+ // src/printers/aeg/aeg-printer.ts
69
+ function truncateString(str, maxLength = 64) {
70
+ if (!str) return "";
71
+ return str.length > maxLength ? str.substring(0, maxLength) : str;
72
+ }
73
+ var ISO_8859_1_REGEX = new RegExp("[^\\u0000-\\u00FF]", "g");
74
+ function normalizeIso88591(str) {
75
+ return str.replace(ISO_8859_1_REGEX, "?");
76
+ }
77
+ function formatDate(date) {
78
+ const day = date.getDate().toString().padStart(2, "0");
79
+ const month = (date.getMonth() + 1).toString().padStart(2, "0");
80
+ const year = date.getFullYear();
81
+ return `${day}/${month}/${year}`;
82
+ }
83
+ function formatTime(date) {
84
+ const hours = date.getHours().toString().padStart(2, "0");
85
+ const minutes = date.getMinutes().toString().padStart(2, "0");
86
+ return `${hours}:${minutes}`;
87
+ }
88
+ function mapTaxIdToPrinterCode(taxId) {
89
+ if (!taxId) {
90
+ return 1 /* EXENTO_E */;
91
+ }
92
+ const taxIdUpper = taxId.toUpperCase();
93
+ const printerTaxValue = PrinterTaxValues[taxIdUpper];
94
+ if (printerTaxValue !== void 0) {
95
+ return printerTaxValue;
96
+ }
97
+ return 1 /* EXENTO_E */;
98
+ }
99
+ function mapPaymentMethod(method) {
100
+ if (method === "pos_debit") return 2 /* POS_DEBIT */;
101
+ if (method === "pos_credit") return 3 /* POS_CREDIT */;
102
+ if (method === "pos_debit_credit_int")
103
+ return 11 /* POS_DEBIT_CREDIT_INT */;
104
+ if (method === "cash_int") return 12 /* CASH_INT */;
105
+ if (method === "cash_nat") return 1 /* CASH */;
106
+ throw new Error(
107
+ `M\xE9todo de pago inv\xE1lido: ${method}. Debe ser "pos_debit", "pos_credit", "pos_debit_credit_int", "cash_int" o "cash_nat"`
108
+ );
109
+ }
110
+ var aegPrinter = {
111
+ model: "aeg-r1",
112
+ buildInvoiceCommands(order, options) {
113
+ const commands = [];
114
+ if (!order) {
115
+ throw new Error("Order es requerido");
116
+ }
117
+ if (!order.client) {
118
+ throw new Error("Order debe tener un cliente asociado");
119
+ }
120
+ if (!order.items || order.items.length === 0) {
121
+ throw new Error("Order debe tener al menos un item");
122
+ }
123
+ const { paymentMethodId, storeName = "N/A" } = options;
124
+ const clientRifCI = order.client.id || "";
125
+ const clientName = order.client.name || "";
126
+ const clientEmail = order.client.email || "";
127
+ const clientPhone = order.client.phone || "";
128
+ const clientAddress = order.client.address || "";
129
+ const razSoc = [clientName, clientEmail, clientPhone].filter(Boolean).map((v) => truncateString(v, 64));
130
+ const storeLine = `Tienda: ${storeName}`;
131
+ const LineAd = [storeLine, clientAddress].filter(Boolean).map((v) => truncateString(v, 64));
132
+ commands.push({
133
+ cmd: "cliF",
134
+ data: { rifCI: clientRifCI, razSoc, LineAd }
135
+ });
136
+ let subtotalWithoutTaxes = 0;
137
+ for (const item of order.items) {
138
+ if (!item.name) continue;
139
+ const taxId = item.taxes && item.taxes.length > 0 ? item.taxes[0].id : null;
140
+ const imp = mapTaxIdToPrinterCode(taxId);
141
+ const price = item.price || 0;
142
+ const pre = Math.round(Math.max(price, 0) * 100);
143
+ const quantity = item.selectedQuantity ?? item.quantity ?? 1;
144
+ const cant = Math.round(Math.max(quantity, 1) * 1e3);
145
+ const des01 = truncateString(item.name, 64);
146
+ subtotalWithoutTaxes += price * Math.max(quantity, 1);
147
+ commands.push({
148
+ cmd: "proF",
149
+ data: { imp, pre, cant, des01 }
150
+ });
151
+ }
152
+ const isForeignCurrency = paymentMethodId === "pos_debit_credit_int" || paymentMethodId === "cash_int";
153
+ if (isForeignCurrency && subtotalWithoutTaxes > 0) {
154
+ const roundedSubtotal = Math.round((subtotalWithoutTaxes + Number.EPSILON) * 100) / 100;
155
+ const igtfPercentage = 3 /* BI_IGTF */ / 100;
156
+ const igtfAmount = Math.round((roundedSubtotal * igtfPercentage + Number.EPSILON) * 100) / 100;
157
+ commands.push({
158
+ cmd: "proF",
159
+ data: {
160
+ imp: 5 /* PERCIBIDO */,
161
+ pre: Math.round(igtfAmount * 100),
162
+ cant: 1e3,
163
+ des01: "IGTF 3% pago en divisas"
164
+ }
165
+ });
166
+ }
167
+ commands.push({ cmd: "subToF", data: 1, valor: 0 });
168
+ if (!order.payments?.length) {
169
+ throw new Error("Order debe tener al menos un pago exitoso");
170
+ }
171
+ for (const payment of order.payments) {
172
+ const paymentType = mapPaymentMethod(payment.paymentMethod);
173
+ const paymentAmount = Math.round(payment.amount * 100);
174
+ commands.push({
175
+ cmd: "fpaF",
176
+ data: {
177
+ tipo: paymentType,
178
+ monto: paymentAmount,
179
+ tasaConv: 0
180
+ }
181
+ });
182
+ }
183
+ commands.push({ cmd: "endFac", data: 1 });
184
+ return commands;
185
+ },
186
+ buildReceiptCommands(options) {
187
+ const {
188
+ orderId,
189
+ amountPaid,
190
+ paymentMethod,
191
+ paidAt,
192
+ cardLast4,
193
+ organizationName
194
+ } = options;
195
+ if (!orderId) {
196
+ throw new Error("OrderId es requerido");
197
+ }
198
+ if (!Number.isFinite(amountPaid) || amountPaid <= 0) {
199
+ throw new Error("Monto pagado inv\xE1lido");
200
+ }
201
+ const paidDate = paidAt ?? /* @__PURE__ */ new Date();
202
+ const amountLabel = `Bs ${amountPaid}`;
203
+ const paymentLabel = `Medio de pago: ${paymentMethod}`;
204
+ const dateLabel = `Fecha del pago: ${formatDate(paidDate)}`;
205
+ const timeLabel = `Hora del pago: ${formatTime(paidDate)}`;
206
+ const cardLabel = `Tarjeta ${cardLast4 ?? "N/A"}`;
207
+ const orgLabel = organizationName?.trim() || "N/A";
208
+ return [
209
+ {
210
+ cmd: "encDNF",
211
+ data: [
212
+ normalizeIso88591(truncateString("RECIBO DE PAGO")),
213
+ normalizeIso88591(truncateString(orderId))
214
+ ]
215
+ },
216
+ {
217
+ cmd: "aperDNF",
218
+ data: normalizeIso88591(truncateString("Recibo de pago"))
219
+ },
220
+ {
221
+ cmd: "efeNorJuIzDNF",
222
+ data: normalizeIso88591(truncateString(orgLabel))
223
+ },
224
+ {
225
+ cmd: "efeNorJuIzDNF",
226
+ data: normalizeIso88591(truncateString(amountLabel))
227
+ },
228
+ {
229
+ cmd: "efeNorJuIzDNF",
230
+ data: normalizeIso88591(truncateString(paymentLabel))
231
+ },
232
+ {
233
+ cmd: "efeNorJuIzDNF",
234
+ data: normalizeIso88591(truncateString(cardLabel))
235
+ },
236
+ {
237
+ cmd: "efeNorJuIzDNF",
238
+ data: normalizeIso88591(truncateString(timeLabel))
239
+ },
240
+ {
241
+ cmd: "efeNorJuIzDNF",
242
+ data: normalizeIso88591(truncateString(dateLabel))
243
+ },
244
+ {
245
+ cmd: "endDNF",
246
+ data: normalizeIso88591("Cierre del Documento No Fiscal")
247
+ }
248
+ ];
249
+ }
250
+ };
251
+
252
+ // src/runner/send-printer-commands.ts
253
+ function normalizeBaseUrl(address) {
254
+ const trimmed = address.trim();
255
+ if (!trimmed) return trimmed;
256
+ const withProtocol = /^https?:\/\//i.test(trimmed) ? trimmed : `http://${trimmed}`;
257
+ return withProtocol.replace(/\/+$/, "");
258
+ }
259
+ async function sendPrinterCommands(args, options) {
260
+ const { brand, model, commands } = args;
261
+ if (!commands || commands.length === 0) {
262
+ throw new Error("No hay comandos para enviar");
263
+ }
264
+ switch (brand) {
265
+ case "AEG":
266
+ if (model !== "R1") {
267
+ throw new Error(
268
+ `Modelo inv\xE1lido para AEG: "${model}". Solo se soporta "R1".`
269
+ );
270
+ }
271
+ return sendAegCommands(args, options);
272
+ case "DTP":
273
+ if (model !== "80i") {
274
+ throw new Error(
275
+ `Modelo inv\xE1lido para DTP: "${model}". Solo se soporta "80i".`
276
+ );
277
+ }
278
+ throw new Error(
279
+ "DTP-80i requiere el m\xF3dulo nativo ExpoDtpFiscalPrinter. Use la conexi\xF3n TCP directamente desde su aplicaci\xF3n."
280
+ );
281
+ default: {
282
+ const _exhaustive = brand;
283
+ throw new Error(
284
+ `Marca de impresora no soportada: ${String(_exhaustive)}`
285
+ );
286
+ }
287
+ }
288
+ }
289
+ async function sendAegCommands(args, options) {
290
+ const { ip, commands } = args;
291
+ const baseUrl = normalizeBaseUrl(ip);
292
+ const url = `${baseUrl}/cmdoJson`;
293
+ const controller = new AbortController();
294
+ const timeoutId = options?.timeout != null ? setTimeout(() => controller.abort(), options.timeout) : void 0;
295
+ try {
296
+ const response = await fetch(url, {
297
+ method: "POST",
298
+ headers: {
299
+ "Content-Type": "application/json"
300
+ },
301
+ body: JSON.stringify(commands),
302
+ signal: controller.signal
303
+ });
304
+ if (!response.ok) {
305
+ throw new Error(`Error HTTP ${response.status}: ${response.statusText}`);
306
+ }
307
+ const data = await response.json();
308
+ if (!Array.isArray(data)) {
309
+ throw new Error(
310
+ `Respuesta inv\xE1lida de la impresora: se esperaba un array, se recibi\xF3 ${typeof data}`
311
+ );
312
+ }
313
+ const result = data;
314
+ const failedCommands = [];
315
+ for (const commandResponse of result) {
316
+ const codeValue = typeof commandResponse.code === "string" ? Number.parseInt(commandResponse.code, 10) : commandResponse.code;
317
+ if (Number.isNaN(codeValue) || codeValue !== 0) {
318
+ failedCommands.push(commandResponse);
319
+ }
320
+ }
321
+ if (failedCommands.length > 0) {
322
+ const errorMessages = failedCommands.map(
323
+ (cmd) => `Comando ${cmd.cmd}: c\xF3digo ${cmd.code}${cmd.message ? ` - ${cmd.message}` : ""}`
324
+ ).join("; ");
325
+ throw new Error(
326
+ `Error en la impresora: ${failedCommands.length} comando(s) fallaron. ${errorMessages}`
327
+ );
328
+ }
329
+ return result;
330
+ } catch (error) {
331
+ if (error instanceof Error) {
332
+ if (error.name === "AbortError") {
333
+ throw new Error("Timeout al enviar comandos a la impresora");
334
+ }
335
+ throw error;
336
+ }
337
+ throw new Error("Error desconocido al enviar comandos a la impresora");
338
+ } finally {
339
+ if (timeoutId) clearTimeout(timeoutId);
340
+ }
341
+ }
342
+ // Annotate the CommonJS export names for ESM import in node:
343
+ 0 && (module.exports = {
344
+ PaymentMethodId,
345
+ PrinterTaxValues,
346
+ TaxValues,
347
+ aegPrinter,
348
+ sendPrinterCommands
349
+ });
350
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/types/enums.ts","../src/printers/aeg/aeg-printer.ts","../src/runner/send-printer-commands.ts"],"sourcesContent":["/**\n * cafe-ipdh-lib\n * Librería para gestionar impresoras fiscales y de recibos.\n *\n * Soporta:\n * - AEG-R1: impresora fiscal vía HTTP (comandos JSON)\n *\n * Uso:\n * ```ts\n * import { aegPrinter } from \"cafe-ipdh-lib\";\n *\n * const commands = aegPrinter.buildInvoiceCommands(order, {\n * paymentMethodId: \"pos_credit\",\n * storeName: \"Mi Tienda\"\n * });\n * // Enviar commands a la impresora vía tu API/transport\n * ```\n */\n\nexport type {\n\tBuildInvoiceOptions,\n\tBuildReceiptOptions,\n\tDocumentType,\n\tDtpPrinterCommand,\n\tExecuteDtpCommandsResult,\n\tPrinterCommandResponse,\n\tPrinterDriver,\n} from \"./printers/index.js\";\nexport { aegPrinter } from \"./printers/index.js\";\nexport type {\n\tAegModel,\n\tDtpModel,\n\tPrinterBrand,\n\tSendPrinterCommandsAeg,\n\tSendPrinterCommandsArgs,\n\tSendPrinterCommandsDtp,\n} from \"./runner/index.js\";\nexport { sendPrinterCommands } from \"./runner/index.js\";\nexport type {\n\tAegPrinterCommand,\n\tFiscalClient,\n\tItemTax,\n\tOrder,\n\tOrderItem,\n\tOrderPayment,\n} from \"./types/index.js\";\nexport {\n\tPaymentMethodId,\n\tPrinterTaxValues,\n\tTaxValues,\n} from \"./types/index.js\";\n","/**\n * Valores de impuestos (porcentajes) según legislación venezolana.\n */\nexport enum TaxValues {\n\tEXENTO_E = 0,\n\tBI_G = 16.0,\n\tIVA_G = 16.0,\n\tBI_R = 8.0,\n\tIVA_R = 8.0,\n\tBI_A = 31.0,\n\tIVA_A = 31.0,\n\tPERCIBIDO = 0,\n\tBI_IGTF = 3.0,\n\tIVA_IGTF = 3.0,\n}\n\n/**\n * Códigos de impuesto para impresora fiscal AEG-R1.\n */\nexport enum PrinterTaxValues {\n\tEXENTO_E = 1,\n\tBI_G = 2,\n\tIVA_G = 2,\n\tBI_R = 3,\n\tIVA_R = 3,\n\tBI_A = 4,\n\tIVA_A = 4,\n\tPERCIBIDO = 5,\n\tBI_IGTF = 5,\n\tIVA_IGTF = 5,\n}\n\n/**\n * IDs de método de pago para impresora fiscal AEG-R1.\n * Efectivo: 1, Débito: 2, Crédito: 3, Pago Móvil: 5,\n * Débito/Crédito int: 11, Efectivo int: 12\n */\nexport enum PaymentMethodId {\n\tCASH = 1,\n\tPOS_DEBIT = 2,\n\tPOS_CREDIT = 3,\n\tPAGO_MOVIL = 5,\n\tPOS_DEBIT_CREDIT_INT = 11,\n\tCASH_INT = 12,\n}\n","import type { AegPrinterCommand } from \"../../types/aeg-commands.js\";\nimport {\n\tPaymentMethodId,\n\tPrinterTaxValues,\n\tTaxValues,\n} from \"../../types/enums.js\";\nimport type { Order } from \"../../types/order.js\";\nimport type {\n\tBuildInvoiceOptions,\n\tBuildReceiptOptions,\n\tPrinterDriver,\n} from \"../printer.types.js\";\n\nfunction truncateString(str: string, maxLength = 64): string {\n\tif (!str) return \"\";\n\treturn str.length > maxLength ? str.substring(0, maxLength) : str;\n}\n\n// biome-ignore lint: avoid control char in literal\nconst ISO_8859_1_REGEX = new RegExp(\"[^\\\\u0000-\\\\u00FF]\", \"g\");\n\nfunction normalizeIso88591(str: string): string {\n\treturn str.replace(ISO_8859_1_REGEX, \"?\");\n}\n\nfunction formatDate(date: Date): string {\n\tconst day = date.getDate().toString().padStart(2, \"0\");\n\tconst month = (date.getMonth() + 1).toString().padStart(2, \"0\");\n\tconst year = date.getFullYear();\n\treturn `${day}/${month}/${year}`;\n}\n\nfunction formatTime(date: Date): string {\n\tconst hours = date.getHours().toString().padStart(2, \"0\");\n\tconst minutes = date.getMinutes().toString().padStart(2, \"0\");\n\treturn `${hours}:${minutes}`;\n}\n\nfunction mapTaxIdToPrinterCode(taxId: string | null | undefined): number {\n\tif (!taxId) {\n\t\treturn PrinterTaxValues.EXENTO_E;\n\t}\n\tconst taxIdUpper = taxId.toUpperCase();\n\tconst printerTaxValue =\n\t\tPrinterTaxValues[taxIdUpper as keyof typeof PrinterTaxValues];\n\tif (printerTaxValue !== undefined) {\n\t\treturn printerTaxValue;\n\t}\n\treturn PrinterTaxValues.EXENTO_E;\n}\n\nfunction mapPaymentMethod(method: string): PaymentMethodId {\n\tif (method === \"pos_debit\") return PaymentMethodId.POS_DEBIT;\n\tif (method === \"pos_credit\") return PaymentMethodId.POS_CREDIT;\n\tif (method === \"pos_debit_credit_int\")\n\t\treturn PaymentMethodId.POS_DEBIT_CREDIT_INT;\n\tif (method === \"cash_int\") return PaymentMethodId.CASH_INT;\n\tif (method === \"cash_nat\") return PaymentMethodId.CASH;\n\tthrow new Error(\n\t\t`Método de pago inválido: ${method}. Debe ser \"pos_debit\", \"pos_credit\", \"pos_debit_credit_int\", \"cash_int\" o \"cash_nat\"`,\n\t);\n}\n\n/**\n * Driver para impresora fiscal AEG-R1.\n * Construye comandos JSON según documentación oficial.\n */\nexport const aegPrinter: PrinterDriver<AegPrinterCommand> = {\n\tmodel: \"aeg-r1\",\n\n\tbuildInvoiceCommands(\n\t\torder: Order,\n\t\toptions: BuildInvoiceOptions,\n\t): AegPrinterCommand[] {\n\t\tconst commands: AegPrinterCommand[] = [];\n\n\t\tif (!order) {\n\t\t\tthrow new Error(\"Order es requerido\");\n\t\t}\n\t\tif (!order.client) {\n\t\t\tthrow new Error(\"Order debe tener un cliente asociado\");\n\t\t}\n\t\tif (!order.items || order.items.length === 0) {\n\t\t\tthrow new Error(\"Order debe tener al menos un item\");\n\t\t}\n\n\t\tconst { paymentMethodId, storeName = \"N/A\" } = options;\n\n\t\t// 1. cliF - Datos del cliente\n\t\tconst clientRifCI = order.client.id || \"\";\n\t\tconst clientName = order.client.name || \"\";\n\t\tconst clientEmail = order.client.email || \"\";\n\t\tconst clientPhone = order.client.phone || \"\";\n\t\tconst clientAddress = order.client.address || \"\";\n\t\tconst razSoc = [clientName, clientEmail, clientPhone]\n\t\t\t.filter(Boolean)\n\t\t\t.map((v) => truncateString(v, 64));\n\t\tconst storeLine = `Tienda: ${storeName}`;\n\t\tconst LineAd = [storeLine, clientAddress]\n\t\t\t.filter(Boolean)\n\t\t\t.map((v) => truncateString(v, 64));\n\n\t\tcommands.push({\n\t\t\tcmd: \"cliF\",\n\t\t\tdata: { rifCI: clientRifCI, razSoc, LineAd },\n\t\t});\n\n\t\t// 2. proF - Productos\n\t\tlet subtotalWithoutTaxes = 0;\n\n\t\tfor (const item of order.items) {\n\t\t\tif (!item.name) continue;\n\n\t\t\tconst taxId =\n\t\t\t\titem.taxes && item.taxes.length > 0 ? item.taxes[0].id : null;\n\t\t\tconst imp = mapTaxIdToPrinterCode(taxId);\n\t\t\tconst price = item.price || 0;\n\t\t\tconst pre = Math.round(Math.max(price, 0) * 100);\n\t\t\tconst quantity = item.selectedQuantity ?? item.quantity ?? 1;\n\t\t\tconst cant = Math.round(Math.max(quantity, 1) * 1000);\n\t\t\tconst des01 = truncateString(item.name, 64);\n\n\t\t\tsubtotalWithoutTaxes += price * Math.max(quantity, 1);\n\n\t\t\tcommands.push({\n\t\t\t\tcmd: \"proF\",\n\t\t\t\tdata: { imp, pre, cant, des01 },\n\t\t\t});\n\t\t}\n\n\t\t// 2.1 IGTF si pago en divisas\n\t\tconst isForeignCurrency =\n\t\t\tpaymentMethodId === \"pos_debit_credit_int\" ||\n\t\t\tpaymentMethodId === \"cash_int\";\n\n\t\tif (isForeignCurrency && subtotalWithoutTaxes > 0) {\n\t\t\tconst roundedSubtotal =\n\t\t\t\tMath.round((subtotalWithoutTaxes + Number.EPSILON) * 100) / 100;\n\t\t\tconst igtfPercentage = TaxValues.BI_IGTF / 100;\n\t\t\tconst igtfAmount =\n\t\t\t\tMath.round((roundedSubtotal * igtfPercentage + Number.EPSILON) * 100) /\n\t\t\t\t100;\n\n\t\t\tcommands.push({\n\t\t\t\tcmd: \"proF\",\n\t\t\t\tdata: {\n\t\t\t\t\timp: PrinterTaxValues.PERCIBIDO,\n\t\t\t\t\tpre: Math.round(igtfAmount * 100),\n\t\t\t\t\tcant: 1000,\n\t\t\t\t\tdes01: \"IGTF 3% pago en divisas\",\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// 3. subToF - Subtotal\n\t\tcommands.push({ cmd: \"subToF\", data: 1, valor: 0 });\n\n\t\t// 4. fpaF - Forma de pago\n\t\tif (!order.payments?.length) {\n\t\t\tthrow new Error(\"Order debe tener al menos un pago exitoso\");\n\t\t}\n\n\t\tfor (const payment of order.payments) {\n\t\t\tconst paymentType = mapPaymentMethod(payment.paymentMethod);\n\t\t\tconst paymentAmount = Math.round(payment.amount * 100);\n\t\t\tcommands.push({\n\t\t\t\tcmd: \"fpaF\",\n\t\t\t\tdata: {\n\t\t\t\t\ttipo: paymentType,\n\t\t\t\t\tmonto: paymentAmount,\n\t\t\t\t\ttasaConv: 0,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\n\t\t// 5. endFac - Cierre\n\t\tcommands.push({ cmd: \"endFac\", data: 1 });\n\n\t\treturn commands;\n\t},\n\n\tbuildReceiptCommands(options: BuildReceiptOptions): AegPrinterCommand[] {\n\t\tconst {\n\t\t\torderId,\n\t\t\tamountPaid,\n\t\t\tpaymentMethod,\n\t\t\tpaidAt,\n\t\t\tcardLast4,\n\t\t\torganizationName,\n\t\t} = options;\n\n\t\tif (!orderId) {\n\t\t\tthrow new Error(\"OrderId es requerido\");\n\t\t}\n\t\tif (!Number.isFinite(amountPaid) || amountPaid <= 0) {\n\t\t\tthrow new Error(\"Monto pagado inválido\");\n\t\t}\n\n\t\tconst paidDate = paidAt ?? new Date();\n\t\tconst amountLabel = `Bs ${amountPaid}`;\n\t\tconst paymentLabel = `Medio de pago: ${paymentMethod}`;\n\t\tconst dateLabel = `Fecha del pago: ${formatDate(paidDate)}`;\n\t\tconst timeLabel = `Hora del pago: ${formatTime(paidDate)}`;\n\t\tconst cardLabel = `Tarjeta ${cardLast4 ?? \"N/A\"}`;\n\t\tconst orgLabel = organizationName?.trim() || \"N/A\";\n\n\t\treturn [\n\t\t\t{\n\t\t\t\tcmd: \"encDNF\",\n\t\t\t\tdata: [\n\t\t\t\t\tnormalizeIso88591(truncateString(\"RECIBO DE PAGO\")),\n\t\t\t\t\tnormalizeIso88591(truncateString(orderId)),\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"aperDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(\"Recibo de pago\")),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"efeNorJuIzDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(orgLabel)),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"efeNorJuIzDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(amountLabel)),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"efeNorJuIzDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(paymentLabel)),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"efeNorJuIzDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(cardLabel)),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"efeNorJuIzDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(timeLabel)),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"efeNorJuIzDNF\",\n\t\t\t\tdata: normalizeIso88591(truncateString(dateLabel)),\n\t\t\t},\n\t\t\t{\n\t\t\t\tcmd: \"endDNF\",\n\t\t\t\tdata: normalizeIso88591(\"Cierre del Documento No Fiscal\"),\n\t\t\t},\n\t\t];\n\t},\n};\n","import type {\n\tPrinterCommandResponse,\n\tPrinterResponse,\n\tSendPrinterCommandsAeg,\n\tSendPrinterCommandsArgs,\n} from \"./types.js\";\n\nfunction normalizeBaseUrl(address: string): string {\n\tconst trimmed = address.trim();\n\tif (!trimmed) return trimmed;\n\tconst withProtocol = /^https?:\\/\\//i.test(trimmed)\n\t\t? trimmed\n\t\t: `http://${trimmed}`;\n\treturn withProtocol.replace(/\\/+$/, \"\");\n}\n\n/**\n * Envía comandos a una impresora fiscal.\n *\n * - **AEG-R1**: POST HTTP a {ip}/cmdoJson con body = commands (JSON)\n * - **DTP-80i**: No soportado en esta librería (usa TCP vía módulo nativo).\n * El consumidor debe usar ExpoDtpFiscalPrinter directamente.\n */\nexport async function sendPrinterCommands(\n\targs: SendPrinterCommandsArgs,\n\toptions?: { timeout?: number },\n): Promise<PrinterResponse> {\n\tconst { brand, model, commands } = args;\n\n\tif (!commands || commands.length === 0) {\n\t\tthrow new Error(\"No hay comandos para enviar\");\n\t}\n\n\tswitch (brand) {\n\t\tcase \"AEG\":\n\t\t\tif (model !== \"R1\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Modelo inválido para AEG: \"${model}\". Solo se soporta \"R1\".`,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn sendAegCommands(args as SendPrinterCommandsAeg, options);\n\t\tcase \"DTP\":\n\t\t\tif (model !== \"80i\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Modelo inválido para DTP: \"${model}\". Solo se soporta \"80i\".`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new Error(\n\t\t\t\t\"DTP-80i requiere el módulo nativo ExpoDtpFiscalPrinter. \" +\n\t\t\t\t\t\"Use la conexión TCP directamente desde su aplicación.\",\n\t\t\t);\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = brand;\n\t\t\tthrow new Error(\n\t\t\t\t`Marca de impresora no soportada: ${String(_exhaustive)}`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nasync function sendAegCommands(\n\targs: SendPrinterCommandsAeg,\n\toptions?: { timeout?: number },\n): Promise<PrinterResponse> {\n\tconst { ip, commands } = args;\n\tconst baseUrl = normalizeBaseUrl(ip);\n\tconst url = `${baseUrl}/cmdoJson`;\n\tconst controller = new AbortController();\n\tconst timeoutId =\n\t\toptions?.timeout != null\n\t\t\t? setTimeout(() => controller.abort(), options.timeout)\n\t\t\t: undefined;\n\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t},\n\t\t\tbody: JSON.stringify(commands),\n\t\t\tsignal: controller.signal,\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Error HTTP ${response.status}: ${response.statusText}`);\n\t\t}\n\n\t\tconst data = (await response.json()) as unknown;\n\n\t\tif (!Array.isArray(data)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Respuesta inválida de la impresora: se esperaba un array, se recibió ${typeof data}`,\n\t\t\t);\n\t\t}\n\n\t\tconst result = data as PrinterCommandResponse[];\n\n\t\tconst failedCommands: PrinterCommandResponse[] = [];\n\t\tfor (const commandResponse of result) {\n\t\t\tconst codeValue =\n\t\t\t\ttypeof commandResponse.code === \"string\"\n\t\t\t\t\t? Number.parseInt(commandResponse.code, 10)\n\t\t\t\t\t: commandResponse.code;\n\n\t\t\tif (Number.isNaN(codeValue) || codeValue !== 0) {\n\t\t\t\tfailedCommands.push(commandResponse);\n\t\t\t}\n\t\t}\n\n\t\tif (failedCommands.length > 0) {\n\t\t\tconst errorMessages = failedCommands\n\t\t\t\t.map(\n\t\t\t\t\t(cmd) =>\n\t\t\t\t\t\t`Comando ${cmd.cmd}: código ${cmd.code}${cmd.message ? ` - ${cmd.message}` : \"\"}`,\n\t\t\t\t)\n\t\t\t\t.join(\"; \");\n\t\t\tthrow new Error(\n\t\t\t\t`Error en la impresora: ${failedCommands.length} comando(s) fallaron. ${errorMessages}`,\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t} catch (error) {\n\t\tif (error instanceof Error) {\n\t\t\tif (error.name === \"AbortError\") {\n\t\t\t\tthrow new Error(\"Timeout al enviar comandos a la impresora\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tthrow new Error(\"Error desconocido al enviar comandos a la impresora\");\n\t} finally {\n\t\tif (timeoutId) clearTimeout(timeoutId);\n\t}\n}\n"],"mappings":"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","names":["TaxValues","PrinterTaxValues","PaymentMethodId"]}