@danielrebolledo/cafe-ipdh-lib 1.0.5 → 1.1.1
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 +173 -30
- package/dist/{dtp-printer-driver-DV3x3OdX.d.cts → dtp-printer-driver-cgh_5rBr.d.cts} +18 -1
- package/dist/{dtp-printer-driver-DV3x3OdX.d.ts → dtp-printer-driver-cgh_5rBr.d.ts} +18 -1
- package/dist/index.cjs +120 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -12
- package/dist/index.d.ts +16 -12
- package/dist/index.js +120 -3
- package/dist/index.js.map +1 -1
- package/dist/node.cjs.map +1 -1
- package/dist/node.d.cts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.js.map +1 -1
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
# cafe-ipdh-lib
|
|
2
2
|
|
|
3
|
-
Librería
|
|
3
|
+
Librería para gestionar impresoras fiscales y de recibos. Construye comandos y los envía mediante una API unificada (`sendPrinterCommands`) que soporta AEG y DTP.
|
|
4
4
|
|
|
5
5
|
## Modelos soportados
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
| Marca | Modelo | Transporte |
|
|
8
|
+
|-------|--------|------------|
|
|
9
|
+
| **AEG** | R1 | HTTP (POST a `/cmdoJson`) |
|
|
10
|
+
| **DTP** | 80i | TCP |
|
|
8
11
|
|
|
9
12
|
## Instalación
|
|
10
13
|
|
|
11
14
|
```bash
|
|
12
|
-
npm install cafe-ipdh-lib
|
|
15
|
+
npm install @danielrebolledo/cafe-ipdh-lib
|
|
13
16
|
```
|
|
14
17
|
|
|
15
|
-
## Uso
|
|
18
|
+
## Uso unificado: `sendPrinterCommands`
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
Tanto AEG como DTP usan la misma función:
|
|
18
21
|
|
|
19
22
|
```ts
|
|
20
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
aegPrinter,
|
|
25
|
+
dtpPrinter,
|
|
26
|
+
sendPrinterCommands,
|
|
27
|
+
DtpClient,
|
|
28
|
+
} from "@danielrebolledo/cafe-ipdh-lib";
|
|
21
29
|
|
|
22
30
|
const order = {
|
|
23
31
|
client: { id: "V12345678", name: "Cliente", email: "c@mail.com" },
|
|
@@ -26,53 +34,188 @@ const order = {
|
|
|
26
34
|
total: 10,
|
|
27
35
|
};
|
|
28
36
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
37
|
+
// AEG-R1 (HTTP)
|
|
38
|
+
const resultAeg = await sendPrinterCommands({
|
|
39
|
+
brand: "AEG",
|
|
40
|
+
model: "R1",
|
|
41
|
+
ip: "http://192.168.1.100",
|
|
42
|
+
commands: aegPrinter.buildInvoiceCommands(order, {
|
|
43
|
+
paymentMethodId: "cash_nat",
|
|
44
|
+
storeName: "Mi Tienda",
|
|
45
|
+
}),
|
|
32
46
|
});
|
|
33
47
|
|
|
34
|
-
//
|
|
48
|
+
// DTP-80i (TCP; requiere client ya conectado)
|
|
49
|
+
const resultDtp = await sendPrinterCommands({
|
|
50
|
+
brand: "DTP",
|
|
51
|
+
model: "80i",
|
|
52
|
+
client: dtpClient, // DtpClient conectado
|
|
53
|
+
commands: dtpPrinter.buildInvoiceCommands(order, {
|
|
54
|
+
paymentMethodId: "cash_nat",
|
|
55
|
+
storeName: "Mi Tienda",
|
|
56
|
+
}),
|
|
57
|
+
});
|
|
35
58
|
```
|
|
36
59
|
|
|
37
|
-
|
|
60
|
+
## Ejemplos por entorno
|
|
61
|
+
|
|
62
|
+
### Web (AEG-R1)
|
|
63
|
+
|
|
64
|
+
En un proyecto web (Next.js, Vite, etc.), normalmente se usa AEG por HTTP:
|
|
38
65
|
|
|
39
66
|
```ts
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
67
|
+
import {
|
|
68
|
+
aegPrinter,
|
|
69
|
+
sendPrinterCommands,
|
|
70
|
+
type Order,
|
|
71
|
+
} from "@danielrebolledo/cafe-ipdh-lib";
|
|
72
|
+
|
|
73
|
+
async function imprimirFactura(order: Order, printerIp: string) {
|
|
74
|
+
const commands = aegPrinter.buildInvoiceCommands(order, {
|
|
75
|
+
paymentMethodId: "cash_nat",
|
|
76
|
+
storeName: "Mi Tienda",
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const result = await sendPrinterCommands({
|
|
80
|
+
brand: "AEG",
|
|
81
|
+
model: "R1",
|
|
82
|
+
ip: printerIp,
|
|
83
|
+
commands,
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const invoiceRef = Array.isArray(result)
|
|
87
|
+
? result.find((r) => r.cmd === "endFac")?.dataD ?? 0
|
|
88
|
+
: result.documentNumber ?? 0;
|
|
89
|
+
|
|
90
|
+
return { success: true, invoiceRef };
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### React Native (DTP-80i)
|
|
95
|
+
|
|
96
|
+
En React Native (Expo, etc.) se suele usar DTP vía TCP con `react-native-tcp-socket`:
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
npm install react-native-tcp-socket
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```ts
|
|
103
|
+
import TcpSocket from "react-native-tcp-socket";
|
|
104
|
+
import {
|
|
105
|
+
DtpClient,
|
|
106
|
+
dtpPrinter,
|
|
107
|
+
sendPrinterCommands,
|
|
108
|
+
type Order,
|
|
109
|
+
} from "@danielrebolledo/cafe-ipdh-lib";
|
|
110
|
+
|
|
111
|
+
const createConnection = (opts: { host: string; port: number }) =>
|
|
112
|
+
new Promise((resolve, reject) => {
|
|
113
|
+
const socket = TcpSocket.createConnection(opts, () => resolve(socket));
|
|
114
|
+
socket.once("error", reject);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
async function imprimirFactura(order: Order, host: string, port: number) {
|
|
118
|
+
const client = new DtpClient({
|
|
119
|
+
host,
|
|
120
|
+
port,
|
|
121
|
+
connectTimeoutMs: 15000,
|
|
122
|
+
createConnection: createConnection as any,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
try {
|
|
126
|
+
await client.connect();
|
|
127
|
+
|
|
128
|
+
const commands = dtpPrinter.buildInvoiceCommands(order, {
|
|
129
|
+
paymentMethodId: "cash_nat",
|
|
130
|
+
storeName: "Mi Tienda",
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const result = await sendPrinterCommands({
|
|
134
|
+
brand: "DTP",
|
|
135
|
+
model: "80i",
|
|
136
|
+
client,
|
|
137
|
+
commands,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
success: true,
|
|
142
|
+
invoiceRef: result.documentNumber ?? 0,
|
|
143
|
+
};
|
|
144
|
+
} finally {
|
|
145
|
+
client.close();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
46
148
|
```
|
|
47
149
|
|
|
48
150
|
## API
|
|
49
151
|
|
|
50
|
-
###
|
|
152
|
+
### Drivers
|
|
51
153
|
|
|
52
|
-
Driver
|
|
154
|
+
| Driver | Modelo | Métodos |
|
|
155
|
+
|--------|--------|---------|
|
|
156
|
+
| `aegPrinter` | AEG-R1 | `buildInvoiceCommands`, `buildReceiptCommands` |
|
|
157
|
+
| `dtpPrinter` | DTP-80i | `buildInvoiceCommands`, `buildReceiptCommands`, `buildCreditNoteCommands` |
|
|
53
158
|
|
|
54
|
-
|
|
55
|
-
|
|
159
|
+
### `sendPrinterCommands`
|
|
160
|
+
|
|
161
|
+
Función unificada para enviar comandos a cualquier impresora.
|
|
162
|
+
|
|
163
|
+
- **AEG**: `{ brand: "AEG", model: "R1", ip, commands }`
|
|
164
|
+
- **DTP**: `{ brand: "DTP", model: "80i", client, commands }`
|
|
165
|
+
|
|
166
|
+
Retorna:
|
|
167
|
+
- AEG: `PrinterCommandResponse[]`
|
|
168
|
+
- DTP: `{ documentNumber?: number; totalAmount?: number }`
|
|
169
|
+
|
|
170
|
+
### Node.js y DTP
|
|
171
|
+
|
|
172
|
+
Para usar DTP en Node.js (backend), importa `createNodeDtpConnection` del entry `node`:
|
|
173
|
+
|
|
174
|
+
```ts
|
|
175
|
+
import {
|
|
176
|
+
DtpClient,
|
|
177
|
+
dtpPrinter,
|
|
178
|
+
sendPrinterCommands,
|
|
179
|
+
} from "@danielrebolledo/cafe-ipdh-lib";
|
|
180
|
+
import {
|
|
181
|
+
createNodeDtpConnection,
|
|
182
|
+
} from "@danielrebolledo/cafe-ipdh-lib/node";
|
|
183
|
+
|
|
184
|
+
const client = new DtpClient({
|
|
185
|
+
host: "192.168.1.10",
|
|
186
|
+
port: 3010,
|
|
187
|
+
createConnection: createNodeDtpConnection,
|
|
188
|
+
});
|
|
189
|
+
await client.connect();
|
|
190
|
+
|
|
191
|
+
const result = await sendPrinterCommands({
|
|
192
|
+
brand: "DTP",
|
|
193
|
+
model: "80i",
|
|
194
|
+
client,
|
|
195
|
+
commands: dtpPrinter.buildInvoiceCommands(order, opts),
|
|
196
|
+
});
|
|
197
|
+
```
|
|
56
198
|
|
|
57
199
|
### Tipos exportados
|
|
58
200
|
|
|
59
201
|
- `Order`, `OrderItem`, `FiscalClient`, `OrderPayment`
|
|
60
|
-
- `AegPrinterCommand`
|
|
61
|
-
- `BuildInvoiceOptions`, `BuildReceiptOptions`
|
|
202
|
+
- `AegPrinterCommand`, `DtpPrinterCommand`
|
|
203
|
+
- `BuildInvoiceOptions`, `BuildReceiptOptions`, `BuildCreditNoteOptions`
|
|
204
|
+
- `SendPrinterCommandsArgs`, `SendPrinterCommandsResult`
|
|
62
205
|
- `PaymentMethodId`, `PrinterTaxValues`, `TaxValues`
|
|
63
206
|
|
|
64
207
|
## Scripts
|
|
65
208
|
|
|
66
209
|
```bash
|
|
67
|
-
npm run build # Compilar
|
|
68
|
-
npm run dev
|
|
69
|
-
npm run lint
|
|
70
|
-
npm run test
|
|
210
|
+
npm run build # Compilar
|
|
211
|
+
npm run dev # Watch mode
|
|
212
|
+
npm run lint # Biome
|
|
213
|
+
npm run test # Vitest
|
|
71
214
|
```
|
|
72
215
|
|
|
73
216
|
## Stack
|
|
74
217
|
|
|
75
218
|
- TypeScript
|
|
76
|
-
- tsup
|
|
77
|
-
- Biome
|
|
78
|
-
- Vitest
|
|
219
|
+
- tsup
|
|
220
|
+
- Biome
|
|
221
|
+
- Vitest
|
|
@@ -70,6 +70,19 @@ interface BuildInvoiceOptions {
|
|
|
70
70
|
paymentMethodId: "pos_credit" | "pos_debit" | "pos_debit_credit_int" | "cash_int" | "cash_nat";
|
|
71
71
|
storeName?: string;
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Opciones para construir comandos de nota de crédito.
|
|
75
|
+
*/
|
|
76
|
+
interface BuildCreditNoteOptions {
|
|
77
|
+
/** Número de la factura original que se está anulando. */
|
|
78
|
+
referenceInvoiceNumber: number;
|
|
79
|
+
/** Fecha de la factura original. */
|
|
80
|
+
referenceInvoiceDate: Date;
|
|
81
|
+
/** Serial fiscal de la factura original (opcional). */
|
|
82
|
+
referenceInvoiceSerial?: string;
|
|
83
|
+
paymentMethodId: "pos_credit" | "pos_debit" | "pos_debit_credit_int" | "cash_int" | "cash_nat";
|
|
84
|
+
storeName?: string;
|
|
85
|
+
}
|
|
73
86
|
/**
|
|
74
87
|
* Opciones para construir comandos de recibo de pago.
|
|
75
88
|
*/
|
|
@@ -95,6 +108,10 @@ interface PrinterDriver<TCmd = unknown> {
|
|
|
95
108
|
* Construye comandos para imprimir un recibo de pago (DNF).
|
|
96
109
|
*/
|
|
97
110
|
buildReceiptCommands(options: BuildReceiptOptions): TCmd[];
|
|
111
|
+
/**
|
|
112
|
+
* Construye comandos para imprimir una nota de crédito fiscal (opcional).
|
|
113
|
+
*/
|
|
114
|
+
buildCreditNoteCommands?(order: Order, options: BuildCreditNoteOptions): TCmd[];
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
/**
|
|
@@ -255,4 +272,4 @@ interface ExecuteDtpCommandsResult {
|
|
|
255
272
|
*/
|
|
256
273
|
declare function executeDtpCommands(client: DtpClient, commands: DtpPrinterCommand[]): Promise<ExecuteDtpCommandsResult>;
|
|
257
274
|
|
|
258
|
-
export { type
|
|
275
|
+
export { type BuildCreditNoteOptions as B, type CreateDtpConnection as C, DtpClient as D, type ExecuteDtpCommandsResult as E, type FiscalClient as F, type ItemTax as I, type Order as O, type PrinterDriver as P, type DtpPrinterCommand as a, type BuildInvoiceOptions as b, type BuildReceiptOptions as c, type DocumentType as d, type DtpOptions as e, type DtpSocketLike as f, type OrderItem as g, type OrderPayment as h, type PrinterCommandResponse as i, dtpPrinter as j, executeDtpCommands as k };
|
|
@@ -70,6 +70,19 @@ interface BuildInvoiceOptions {
|
|
|
70
70
|
paymentMethodId: "pos_credit" | "pos_debit" | "pos_debit_credit_int" | "cash_int" | "cash_nat";
|
|
71
71
|
storeName?: string;
|
|
72
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Opciones para construir comandos de nota de crédito.
|
|
75
|
+
*/
|
|
76
|
+
interface BuildCreditNoteOptions {
|
|
77
|
+
/** Número de la factura original que se está anulando. */
|
|
78
|
+
referenceInvoiceNumber: number;
|
|
79
|
+
/** Fecha de la factura original. */
|
|
80
|
+
referenceInvoiceDate: Date;
|
|
81
|
+
/** Serial fiscal de la factura original (opcional). */
|
|
82
|
+
referenceInvoiceSerial?: string;
|
|
83
|
+
paymentMethodId: "pos_credit" | "pos_debit" | "pos_debit_credit_int" | "cash_int" | "cash_nat";
|
|
84
|
+
storeName?: string;
|
|
85
|
+
}
|
|
73
86
|
/**
|
|
74
87
|
* Opciones para construir comandos de recibo de pago.
|
|
75
88
|
*/
|
|
@@ -95,6 +108,10 @@ interface PrinterDriver<TCmd = unknown> {
|
|
|
95
108
|
* Construye comandos para imprimir un recibo de pago (DNF).
|
|
96
109
|
*/
|
|
97
110
|
buildReceiptCommands(options: BuildReceiptOptions): TCmd[];
|
|
111
|
+
/**
|
|
112
|
+
* Construye comandos para imprimir una nota de crédito fiscal (opcional).
|
|
113
|
+
*/
|
|
114
|
+
buildCreditNoteCommands?(order: Order, options: BuildCreditNoteOptions): TCmd[];
|
|
98
115
|
}
|
|
99
116
|
|
|
100
117
|
/**
|
|
@@ -255,4 +272,4 @@ interface ExecuteDtpCommandsResult {
|
|
|
255
272
|
*/
|
|
256
273
|
declare function executeDtpCommands(client: DtpClient, commands: DtpPrinterCommand[]): Promise<ExecuteDtpCommandsResult>;
|
|
257
274
|
|
|
258
|
-
export { type
|
|
275
|
+
export { type BuildCreditNoteOptions as B, type CreateDtpConnection as C, DtpClient as D, type ExecuteDtpCommandsResult as E, type FiscalClient as F, type ItemTax as I, type Order as O, type PrinterDriver as P, type DtpPrinterCommand as a, type BuildInvoiceOptions as b, type BuildReceiptOptions as c, type DocumentType as d, type DtpOptions as e, type DtpSocketLike as f, type OrderItem as g, type OrderPayment as h, type PrinterCommandResponse as i, dtpPrinter as j, executeDtpCommands as k };
|
package/dist/index.cjs
CHANGED
|
@@ -666,6 +666,121 @@ var dtpPrinter = {
|
|
|
666
666
|
commands.push({ cmd: "F5", data: {} });
|
|
667
667
|
return commands;
|
|
668
668
|
},
|
|
669
|
+
buildCreditNoteCommands(order, options) {
|
|
670
|
+
const commands = [];
|
|
671
|
+
if (!order) {
|
|
672
|
+
throw new Error("Order es requerido");
|
|
673
|
+
}
|
|
674
|
+
if (!order.client) {
|
|
675
|
+
throw new Error("Order debe tener un cliente asociado");
|
|
676
|
+
}
|
|
677
|
+
if (!order.items || order.items.length === 0) {
|
|
678
|
+
throw new Error("Order debe tener al menos un item");
|
|
679
|
+
}
|
|
680
|
+
const {
|
|
681
|
+
referenceInvoiceNumber,
|
|
682
|
+
referenceInvoiceDate,
|
|
683
|
+
referenceInvoiceSerial = "",
|
|
684
|
+
paymentMethodId,
|
|
685
|
+
storeName = "N/A"
|
|
686
|
+
} = options;
|
|
687
|
+
const clientName = order.client.name || "";
|
|
688
|
+
const clientRif = order.client.id || "";
|
|
689
|
+
const storeLine = `Tienda: ${storeName}`;
|
|
690
|
+
commands.push({
|
|
691
|
+
cmd: "F0",
|
|
692
|
+
data: {
|
|
693
|
+
iTipo: 1,
|
|
694
|
+
sNombreCliente: truncateString2(clientName, 64),
|
|
695
|
+
sRifCliente: truncateString2(clientRif, 20),
|
|
696
|
+
iFacturaReferencia: referenceInvoiceNumber,
|
|
697
|
+
fechaReferencia: referenceInvoiceDate,
|
|
698
|
+
sSerialReferencia: truncateString2(referenceInvoiceSerial, 20),
|
|
699
|
+
bLogo: false,
|
|
700
|
+
sLineaAdicional: truncateString2(storeLine, 64)
|
|
701
|
+
}
|
|
702
|
+
});
|
|
703
|
+
let subtotalWithoutTaxes = 0;
|
|
704
|
+
for (const item of order.items) {
|
|
705
|
+
if (!item.name) continue;
|
|
706
|
+
const taxId = item.taxes && item.taxes.length > 0 ? item.taxes[0].id : null;
|
|
707
|
+
const iImpuesto = mapTaxIdToDtpCode(taxId);
|
|
708
|
+
const price = item.price ?? 0;
|
|
709
|
+
const lPrecio = Math.round(Math.max(price, 0) * 100);
|
|
710
|
+
const quantity = item.selectedQuantity ?? item.quantity ?? 1;
|
|
711
|
+
const lCantidad = -Math.round(Math.max(quantity, 1) * 1e3);
|
|
712
|
+
subtotalWithoutTaxes += price * Math.max(quantity, 1);
|
|
713
|
+
commands.push({
|
|
714
|
+
cmd: "F1",
|
|
715
|
+
data: {
|
|
716
|
+
iTipo: 1,
|
|
717
|
+
sDescripcion: truncateString2(item.name, 64),
|
|
718
|
+
sCodigo: truncateString2(item.sku ?? "N/A", 20),
|
|
719
|
+
lCantidad,
|
|
720
|
+
sUnidad: "UND",
|
|
721
|
+
lPrecio,
|
|
722
|
+
iImpuesto,
|
|
723
|
+
iDecPrecio: 2,
|
|
724
|
+
iDecCantidad: 3
|
|
725
|
+
}
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
const isForeignCurrency = paymentMethodId === "pos_debit_credit_int" || paymentMethodId === "cash_int";
|
|
729
|
+
if (isForeignCurrency && subtotalWithoutTaxes > 0) {
|
|
730
|
+
const roundedSubtotal = Math.round((subtotalWithoutTaxes + Number.EPSILON) * 100) / 100;
|
|
731
|
+
const igtfPercentage = 3 /* BI_IGTF */ / 100;
|
|
732
|
+
const igtfAmount = Math.round((roundedSubtotal * igtfPercentage + Number.EPSILON) * 100) / 100;
|
|
733
|
+
commands.push({
|
|
734
|
+
cmd: "F1",
|
|
735
|
+
data: {
|
|
736
|
+
iTipo: 1,
|
|
737
|
+
sDescripcion: "IGTF 3% pago en divisas",
|
|
738
|
+
sCodigo: "IGTF",
|
|
739
|
+
lCantidad: -1e3,
|
|
740
|
+
sUnidad: "UND",
|
|
741
|
+
lPrecio: Math.round(igtfAmount * 100),
|
|
742
|
+
iImpuesto: 4,
|
|
743
|
+
iDecPrecio: 2,
|
|
744
|
+
iDecCantidad: 3
|
|
745
|
+
}
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
commands.push({
|
|
749
|
+
cmd: "F2",
|
|
750
|
+
data: { mode: 1, foreignCurrencyAmount: 0 }
|
|
751
|
+
});
|
|
752
|
+
if (!order.payments?.length) {
|
|
753
|
+
throw new Error("Order debe tener al menos un pago exitoso");
|
|
754
|
+
}
|
|
755
|
+
for (const payment of order.payments) {
|
|
756
|
+
const tipo = mapPaymentMethod2(payment.paymentMethod);
|
|
757
|
+
const lMonto = Math.round(payment.amount * 100);
|
|
758
|
+
const isForeign = payment.paymentMethod === "pos_debit_credit_int" || payment.paymentMethod === "cash_int";
|
|
759
|
+
if (isForeign) {
|
|
760
|
+
commands.push({
|
|
761
|
+
cmd: "F11",
|
|
762
|
+
data: {
|
|
763
|
+
iFormaPago: tipo,
|
|
764
|
+
sDescripcion: paymentMethodLabel(tipo),
|
|
765
|
+
lMonto,
|
|
766
|
+
lTasaCambio: 1,
|
|
767
|
+
sSimbolo: "USD"
|
|
768
|
+
}
|
|
769
|
+
});
|
|
770
|
+
} else {
|
|
771
|
+
commands.push({
|
|
772
|
+
cmd: "F4",
|
|
773
|
+
data: {
|
|
774
|
+
iFormaPago: tipo,
|
|
775
|
+
sDescripcion: paymentMethodLabel(tipo),
|
|
776
|
+
lMonto
|
|
777
|
+
}
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
commands.push({ cmd: "F5", data: {} });
|
|
782
|
+
return commands;
|
|
783
|
+
},
|
|
669
784
|
buildReceiptCommands(options) {
|
|
670
785
|
const {
|
|
671
786
|
orderId,
|
|
@@ -803,9 +918,7 @@ async function sendPrinterCommands(args, options) {
|
|
|
803
918
|
`Modelo inv\xE1lido para DTP: "${model}". Solo se soporta "80i".`
|
|
804
919
|
);
|
|
805
920
|
}
|
|
806
|
-
|
|
807
|
-
"DTP-80i requiere el m\xF3dulo nativo ExpoDtpFiscalPrinter. Use la conexi\xF3n TCP directamente desde su aplicaci\xF3n."
|
|
808
|
-
);
|
|
921
|
+
return sendDtpCommands(args);
|
|
809
922
|
default: {
|
|
810
923
|
const _exhaustive = brand;
|
|
811
924
|
throw new Error(
|
|
@@ -814,6 +927,10 @@ async function sendPrinterCommands(args, options) {
|
|
|
814
927
|
}
|
|
815
928
|
}
|
|
816
929
|
}
|
|
930
|
+
async function sendDtpCommands(args) {
|
|
931
|
+
const { client, commands } = args;
|
|
932
|
+
return executeDtpCommands(client, commands);
|
|
933
|
+
}
|
|
817
934
|
async function sendAegCommands(args, options) {
|
|
818
935
|
const { ip, commands } = args;
|
|
819
936
|
const baseUrl = normalizeBaseUrl(ip);
|