@devlas/dte-sii 2.11.0 → 2.12.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/CafSolicitor.js +33 -5
- package/LICENSE +27 -27
- package/SiiSession.js +56 -17
- package/WsReclamo.js +434 -434
- package/cert/comunaOficina.js +458 -458
- package/cert/index.js +122 -122
- package/cert/types.js +328 -328
- package/package.json +1 -1
- package/test-qdetestlibro.js +174 -174
- package/test-muestras.js +0 -180
package/cert/types.js
CHANGED
|
@@ -1,330 +1,330 @@
|
|
|
1
1
|
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
2
|
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
3
|
-
/**
|
|
4
|
-
* Tipos e interfaces para módulo de Certificación SII
|
|
5
|
-
*
|
|
6
|
-
* Define las estructuras de datos comunes usadas por:
|
|
7
|
-
* - Sets de prueba (SetBasico, SetExenta, SetGuia, SetCompra)
|
|
8
|
-
* - Libros (Ventas, Compras, Guías)
|
|
9
|
-
* - Runner de certificación
|
|
10
|
-
*
|
|
11
|
-
* @module dte-sii/cert/types
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
// ═══════════════════════════════════════════════════════════════
|
|
15
|
-
// CONSTANTES
|
|
16
|
-
// ═══════════════════════════════════════════════════════════════
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Tipos de DTE por set de certificación
|
|
20
|
-
*/
|
|
21
|
-
const SETS_DTE = {
|
|
22
|
-
basico: [33, 56, 61], // Factura, ND, NC
|
|
23
|
-
exenta: [34], // Factura Exenta
|
|
24
|
-
guia: [52], // Guía de Despacho
|
|
25
|
-
compra: [46], // Factura de Compra
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Labels para cada set
|
|
30
|
-
*/
|
|
31
|
-
const SET_LABELS = {
|
|
32
|
-
basico: 'Set Básico (Facturas)',
|
|
33
|
-
exenta: 'Set Factura Exenta',
|
|
34
|
-
guia: 'Set Guía Despacho',
|
|
35
|
-
compra: 'Set Factura Compra',
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Orden de ejecución de sets (crítico para SII)
|
|
40
|
-
*/
|
|
41
|
-
const SET_ORDER = ['basico', 'guia', 'exenta', 'compra'];
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Tipos de libro
|
|
45
|
-
*/
|
|
46
|
-
const LIBRO_TYPES = {
|
|
47
|
-
ventas: 'VENTAS',
|
|
48
|
-
compras: 'COMPRAS',
|
|
49
|
-
guias: 'GUIAS',
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// ═══════════════════════════════════════════════════════════════
|
|
53
|
-
// ESTRUCTURAS DE CONFIGURACIÓN
|
|
54
|
-
// ═══════════════════════════════════════════════════════════════
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* @typedef {Object} EmisorConfig
|
|
58
|
-
* @property {string} rut - RUT completo con DV (ej: "76123456-7")
|
|
59
|
-
* @property {string} razonSocial - Razón social
|
|
60
|
-
* @property {string} giro - Giro comercial
|
|
61
|
-
* @property {string} acteco - Código de actividad económica
|
|
62
|
-
* @property {string} direccion - Dirección
|
|
63
|
-
* @property {string} comuna - Comuna
|
|
64
|
-
* @property {string} [ciudad] - Ciudad (opcional)
|
|
65
|
-
*/
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* @typedef {Object} ReceptorConfig
|
|
69
|
-
* @property {string} rut - RUT completo con DV
|
|
70
|
-
* @property {string} razonSocial - Razón social
|
|
71
|
-
* @property {string} giro - Giro comercial
|
|
72
|
-
* @property {string} direccion - Dirección
|
|
73
|
-
* @property {string} comuna - Comuna
|
|
74
|
-
*/
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* @typedef {Object} ResolucionConfig
|
|
78
|
-
* @property {number} numero - Número de resolución (0 para certificación)
|
|
79
|
-
* @property {string} fecha - Fecha resolución (YYYY-MM-DD)
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* @typedef {Object} CertificadoConfig
|
|
84
|
-
* @property {string} path - Ruta al archivo .pfx
|
|
85
|
-
* @property {string} password - Contraseña del certificado
|
|
86
|
-
*/
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Configuración completa para certificación
|
|
90
|
-
* @typedef {Object} CertConfig
|
|
91
|
-
* @property {EmisorConfig} emisor
|
|
92
|
-
* @property {ReceptorConfig} receptor
|
|
93
|
-
* @property {CertificadoConfig} certificado
|
|
94
|
-
* @property {ResolucionConfig} resolucion
|
|
95
|
-
* @property {string} ambiente - 'certificacion' | 'produccion'
|
|
96
|
-
* @property {string} debugDir - Directorio para XMLs de debug
|
|
97
|
-
*/
|
|
98
|
-
|
|
99
|
-
// ═══════════════════════════════════════════════════════════════
|
|
100
|
-
// ESTRUCTURAS DE RESULTADO
|
|
101
|
-
// ═══════════════════════════════════════════════════════════════
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Resultado de un DTE individual generado
|
|
105
|
-
* @typedef {Object} DteResult
|
|
106
|
-
* @property {number} tipo - Tipo de DTE (33, 34, etc.)
|
|
107
|
-
* @property {number} folio - Folio asignado
|
|
108
|
-
* @property {string} id - ID del documento (ej: "T33F123")
|
|
109
|
-
* @property {number} montoTotal - Monto total del DTE
|
|
110
|
-
*/
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Resultado de ejecución de un Set
|
|
114
|
-
*/
|
|
115
|
-
class SetResult {
|
|
116
|
-
constructor() {
|
|
117
|
-
/** @type {boolean} */
|
|
118
|
-
this.success = false;
|
|
119
|
-
|
|
120
|
-
/** @type {string|null} - Track ID del SII */
|
|
121
|
-
this.trackId = null;
|
|
122
|
-
|
|
123
|
-
/** @type {DteResult[]} - DTEs generados */
|
|
124
|
-
this.dtes = [];
|
|
125
|
-
|
|
126
|
-
/** @type {Object[]} - Documentos con totales para libros */
|
|
127
|
-
this.documentos = [];
|
|
128
|
-
|
|
129
|
-
/** @type {string[]} - Errores encontrados */
|
|
130
|
-
this.errors = [];
|
|
131
|
-
|
|
132
|
-
/** @type {string|null} - Path al XML enviado */
|
|
133
|
-
this.xmlPath = null;
|
|
134
|
-
|
|
135
|
-
/** @type {string|null} - Path al XML de respuesta */
|
|
136
|
-
this.responsePath = null;
|
|
137
|
-
|
|
138
|
-
/** @type {number} - Duración en ms */
|
|
139
|
-
this.duration = 0;
|
|
140
|
-
|
|
141
|
-
/** @type {string} - Timestamp de ejecución */
|
|
142
|
-
this.timestamp = new Date().toISOString();
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Crea un resultado exitoso
|
|
147
|
-
* @param {Object} data
|
|
148
|
-
* @returns {SetResult}
|
|
149
|
-
*/
|
|
150
|
-
static success(data = {}) {
|
|
151
|
-
const result = new SetResult();
|
|
152
|
-
result.success = true;
|
|
153
|
-
result.trackId = data.trackId || null;
|
|
154
|
-
result.dtes = data.dtes || [];
|
|
155
|
-
result.documentos = data.documentos || []; // Para libros
|
|
156
|
-
result.xmlPath = data.xmlPath || null;
|
|
157
|
-
result.responsePath = data.responsePath || null;
|
|
158
|
-
result.duration = data.duration || 0;
|
|
159
|
-
return result;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* Crea un resultado fallido
|
|
164
|
-
* @param {string|string[]} errors
|
|
165
|
-
* @returns {SetResult}
|
|
166
|
-
*/
|
|
167
|
-
static failure(errors) {
|
|
168
|
-
const result = new SetResult();
|
|
169
|
-
result.success = false;
|
|
170
|
-
result.errors = Array.isArray(errors) ? errors : [errors];
|
|
171
|
-
return result;
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Agrega un DTE al resultado
|
|
176
|
-
* @param {DteResult} dte
|
|
177
|
-
*/
|
|
178
|
-
addDte(dte) {
|
|
179
|
-
this.dtes.push(dte);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Agrega un error
|
|
184
|
-
* @param {string} error
|
|
185
|
-
*/
|
|
186
|
-
addError(error) {
|
|
187
|
-
this.errors.push(error);
|
|
188
|
-
this.success = false;
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Resultado de ejecución de un Libro
|
|
194
|
-
*/
|
|
195
|
-
class LibroResult {
|
|
196
|
-
constructor() {
|
|
197
|
-
/** @type {boolean} */
|
|
198
|
-
this.success = false;
|
|
199
|
-
|
|
200
|
-
/** @type {string|null} - Track ID del SII */
|
|
201
|
-
this.trackId = null;
|
|
202
|
-
|
|
203
|
-
/** @type {string} - Tipo: VENTAS, COMPRAS, GUIAS */
|
|
204
|
-
this.tipo = '';
|
|
205
|
-
|
|
206
|
-
/** @type {string} - Período YYYYMM */
|
|
207
|
-
this.periodo = '';
|
|
208
|
-
|
|
209
|
-
/** @type {number} - Total de documentos en el libro */
|
|
210
|
-
this.totalDocumentos = 0;
|
|
211
|
-
|
|
212
|
-
/** @type {string[]} */
|
|
213
|
-
this.errors = [];
|
|
214
|
-
|
|
215
|
-
/** @type {string|null} */
|
|
216
|
-
this.xmlPath = null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
static success(data = {}) {
|
|
220
|
-
const result = new LibroResult();
|
|
221
|
-
result.success = true;
|
|
222
|
-
Object.assign(result, data);
|
|
223
|
-
return result;
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
static failure(errors) {
|
|
227
|
-
const result = new LibroResult();
|
|
228
|
-
result.success = false;
|
|
229
|
-
result.errors = Array.isArray(errors) ? errors : [errors];
|
|
230
|
-
return result;
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Resultado completo del runner de certificación
|
|
236
|
-
*/
|
|
237
|
-
class CertRunnerResult {
|
|
238
|
-
constructor() {
|
|
239
|
-
/** @type {boolean} */
|
|
240
|
-
this.success = false;
|
|
241
|
-
|
|
242
|
-
/** @type {string} - Timestamp de inicio */
|
|
243
|
-
this.started = new Date().toISOString();
|
|
244
|
-
|
|
245
|
-
/** @type {string|null} - Timestamp de fin */
|
|
246
|
-
this.finished = null;
|
|
247
|
-
|
|
248
|
-
/** @type {Object.<string, SetResult>} - Resultados por set */
|
|
249
|
-
this.sets = {};
|
|
250
|
-
|
|
251
|
-
/** @type {Object.<string, LibroResult>} - Resultados por libro */
|
|
252
|
-
this.libros = {};
|
|
253
|
-
|
|
254
|
-
/** @type {SetResult|null} - Resultado de simulación */
|
|
255
|
-
this.simulacion = null;
|
|
256
|
-
|
|
257
|
-
/** @type {Object|null} - Estado de avance del SII */
|
|
258
|
-
this.avance = null;
|
|
259
|
-
|
|
260
|
-
/** @type {string[]} */
|
|
261
|
-
this.errors = [];
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* Calcula el resumen de la ejecución
|
|
266
|
-
* @returns {Object}
|
|
267
|
-
*/
|
|
268
|
-
getSummary() {
|
|
269
|
-
const setKeys = Object.keys(this.sets);
|
|
270
|
-
const libroKeys = Object.keys(this.libros);
|
|
271
|
-
|
|
272
|
-
return {
|
|
273
|
-
setsTotal: setKeys.length,
|
|
274
|
-
setsOk: setKeys.filter(k => this.sets[k].success).length,
|
|
275
|
-
librosTotal: libroKeys.length,
|
|
276
|
-
librosOk: libroKeys.filter(k => this.libros[k].success).length,
|
|
277
|
-
simulacionOk: this.simulacion?.success || false,
|
|
278
|
-
duracion: this.finished
|
|
279
|
-
? new Date(this.finished) - new Date(this.started)
|
|
280
|
-
: null,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
// ═══════════════════════════════════════════════════════════════
|
|
286
|
-
// ESTRUCTURAS DE CASOS (del SII)
|
|
287
|
-
// ═══════════════════════════════════════════════════════════════
|
|
288
|
-
|
|
289
|
-
/**
|
|
290
|
-
* Item de un caso de prueba
|
|
291
|
-
* @typedef {Object} CasoItem
|
|
292
|
-
* @property {string} nombre - Nombre del item
|
|
293
|
-
* @property {number} cantidad - Cantidad
|
|
294
|
-
* @property {number} precio - Precio unitario (neto)
|
|
295
|
-
* @property {number} [descuentoPct] - Descuento porcentual
|
|
296
|
-
*/
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Caso de prueba del SII
|
|
300
|
-
* @typedef {Object} CasoPrueba
|
|
301
|
-
* @property {string} id - ID del caso (ej: "4668070-1")
|
|
302
|
-
* @property {number} tipoDte - Tipo de DTE
|
|
303
|
-
* @property {CasoItem[]} items - Items del documento
|
|
304
|
-
* @property {number} [descuentoGlobalPct] - Descuento global %
|
|
305
|
-
* @property {Object} [referencia] - Referencia a otro documento
|
|
306
|
-
*/
|
|
307
|
-
|
|
308
|
-
/**
|
|
309
|
-
* Estructura de un set de pruebas parseado del SII
|
|
310
|
-
* @typedef {Object} SetEstructura
|
|
311
|
-
* @property {Object} cafRequired - { 33: 5, 56: 2, 61: 3 }
|
|
312
|
-
* @property {CasoPrueba[]} casos - Lista de casos
|
|
313
|
-
*/
|
|
314
|
-
|
|
315
|
-
// ═══════════════════════════════════════════════════════════════
|
|
316
|
-
// EXPORTS
|
|
317
|
-
// ═══════════════════════════════════════════════════════════════
|
|
318
|
-
|
|
319
|
-
module.exports = {
|
|
320
|
-
// Constantes
|
|
321
|
-
SETS_DTE,
|
|
322
|
-
SET_LABELS,
|
|
323
|
-
SET_ORDER,
|
|
324
|
-
LIBRO_TYPES,
|
|
325
|
-
|
|
326
|
-
// Clases de resultado
|
|
327
|
-
SetResult,
|
|
328
|
-
LibroResult,
|
|
329
|
-
CertRunnerResult,
|
|
330
|
-
};
|
|
3
|
+
/**
|
|
4
|
+
* Tipos e interfaces para módulo de Certificación SII
|
|
5
|
+
*
|
|
6
|
+
* Define las estructuras de datos comunes usadas por:
|
|
7
|
+
* - Sets de prueba (SetBasico, SetExenta, SetGuia, SetCompra)
|
|
8
|
+
* - Libros (Ventas, Compras, Guías)
|
|
9
|
+
* - Runner de certificación
|
|
10
|
+
*
|
|
11
|
+
* @module dte-sii/cert/types
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
// ═══════════════════════════════════════════════════════════════
|
|
15
|
+
// CONSTANTES
|
|
16
|
+
// ═══════════════════════════════════════════════════════════════
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Tipos de DTE por set de certificación
|
|
20
|
+
*/
|
|
21
|
+
const SETS_DTE = {
|
|
22
|
+
basico: [33, 56, 61], // Factura, ND, NC
|
|
23
|
+
exenta: [34], // Factura Exenta
|
|
24
|
+
guia: [52], // Guía de Despacho
|
|
25
|
+
compra: [46], // Factura de Compra
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Labels para cada set
|
|
30
|
+
*/
|
|
31
|
+
const SET_LABELS = {
|
|
32
|
+
basico: 'Set Básico (Facturas)',
|
|
33
|
+
exenta: 'Set Factura Exenta',
|
|
34
|
+
guia: 'Set Guía Despacho',
|
|
35
|
+
compra: 'Set Factura Compra',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Orden de ejecución de sets (crítico para SII)
|
|
40
|
+
*/
|
|
41
|
+
const SET_ORDER = ['basico', 'guia', 'exenta', 'compra'];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Tipos de libro
|
|
45
|
+
*/
|
|
46
|
+
const LIBRO_TYPES = {
|
|
47
|
+
ventas: 'VENTAS',
|
|
48
|
+
compras: 'COMPRAS',
|
|
49
|
+
guias: 'GUIAS',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// ═══════════════════════════════════════════════════════════════
|
|
53
|
+
// ESTRUCTURAS DE CONFIGURACIÓN
|
|
54
|
+
// ═══════════════════════════════════════════════════════════════
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @typedef {Object} EmisorConfig
|
|
58
|
+
* @property {string} rut - RUT completo con DV (ej: "76123456-7")
|
|
59
|
+
* @property {string} razonSocial - Razón social
|
|
60
|
+
* @property {string} giro - Giro comercial
|
|
61
|
+
* @property {string} acteco - Código de actividad económica
|
|
62
|
+
* @property {string} direccion - Dirección
|
|
63
|
+
* @property {string} comuna - Comuna
|
|
64
|
+
* @property {string} [ciudad] - Ciudad (opcional)
|
|
65
|
+
*/
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @typedef {Object} ReceptorConfig
|
|
69
|
+
* @property {string} rut - RUT completo con DV
|
|
70
|
+
* @property {string} razonSocial - Razón social
|
|
71
|
+
* @property {string} giro - Giro comercial
|
|
72
|
+
* @property {string} direccion - Dirección
|
|
73
|
+
* @property {string} comuna - Comuna
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @typedef {Object} ResolucionConfig
|
|
78
|
+
* @property {number} numero - Número de resolución (0 para certificación)
|
|
79
|
+
* @property {string} fecha - Fecha resolución (YYYY-MM-DD)
|
|
80
|
+
*/
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @typedef {Object} CertificadoConfig
|
|
84
|
+
* @property {string} path - Ruta al archivo .pfx
|
|
85
|
+
* @property {string} password - Contraseña del certificado
|
|
86
|
+
*/
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Configuración completa para certificación
|
|
90
|
+
* @typedef {Object} CertConfig
|
|
91
|
+
* @property {EmisorConfig} emisor
|
|
92
|
+
* @property {ReceptorConfig} receptor
|
|
93
|
+
* @property {CertificadoConfig} certificado
|
|
94
|
+
* @property {ResolucionConfig} resolucion
|
|
95
|
+
* @property {string} ambiente - 'certificacion' | 'produccion'
|
|
96
|
+
* @property {string} debugDir - Directorio para XMLs de debug
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
// ═══════════════════════════════════════════════════════════════
|
|
100
|
+
// ESTRUCTURAS DE RESULTADO
|
|
101
|
+
// ═══════════════════════════════════════════════════════════════
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Resultado de un DTE individual generado
|
|
105
|
+
* @typedef {Object} DteResult
|
|
106
|
+
* @property {number} tipo - Tipo de DTE (33, 34, etc.)
|
|
107
|
+
* @property {number} folio - Folio asignado
|
|
108
|
+
* @property {string} id - ID del documento (ej: "T33F123")
|
|
109
|
+
* @property {number} montoTotal - Monto total del DTE
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Resultado de ejecución de un Set
|
|
114
|
+
*/
|
|
115
|
+
class SetResult {
|
|
116
|
+
constructor() {
|
|
117
|
+
/** @type {boolean} */
|
|
118
|
+
this.success = false;
|
|
119
|
+
|
|
120
|
+
/** @type {string|null} - Track ID del SII */
|
|
121
|
+
this.trackId = null;
|
|
122
|
+
|
|
123
|
+
/** @type {DteResult[]} - DTEs generados */
|
|
124
|
+
this.dtes = [];
|
|
125
|
+
|
|
126
|
+
/** @type {Object[]} - Documentos con totales para libros */
|
|
127
|
+
this.documentos = [];
|
|
128
|
+
|
|
129
|
+
/** @type {string[]} - Errores encontrados */
|
|
130
|
+
this.errors = [];
|
|
131
|
+
|
|
132
|
+
/** @type {string|null} - Path al XML enviado */
|
|
133
|
+
this.xmlPath = null;
|
|
134
|
+
|
|
135
|
+
/** @type {string|null} - Path al XML de respuesta */
|
|
136
|
+
this.responsePath = null;
|
|
137
|
+
|
|
138
|
+
/** @type {number} - Duración en ms */
|
|
139
|
+
this.duration = 0;
|
|
140
|
+
|
|
141
|
+
/** @type {string} - Timestamp de ejecución */
|
|
142
|
+
this.timestamp = new Date().toISOString();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Crea un resultado exitoso
|
|
147
|
+
* @param {Object} data
|
|
148
|
+
* @returns {SetResult}
|
|
149
|
+
*/
|
|
150
|
+
static success(data = {}) {
|
|
151
|
+
const result = new SetResult();
|
|
152
|
+
result.success = true;
|
|
153
|
+
result.trackId = data.trackId || null;
|
|
154
|
+
result.dtes = data.dtes || [];
|
|
155
|
+
result.documentos = data.documentos || []; // Para libros
|
|
156
|
+
result.xmlPath = data.xmlPath || null;
|
|
157
|
+
result.responsePath = data.responsePath || null;
|
|
158
|
+
result.duration = data.duration || 0;
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Crea un resultado fallido
|
|
164
|
+
* @param {string|string[]} errors
|
|
165
|
+
* @returns {SetResult}
|
|
166
|
+
*/
|
|
167
|
+
static failure(errors) {
|
|
168
|
+
const result = new SetResult();
|
|
169
|
+
result.success = false;
|
|
170
|
+
result.errors = Array.isArray(errors) ? errors : [errors];
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Agrega un DTE al resultado
|
|
176
|
+
* @param {DteResult} dte
|
|
177
|
+
*/
|
|
178
|
+
addDte(dte) {
|
|
179
|
+
this.dtes.push(dte);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Agrega un error
|
|
184
|
+
* @param {string} error
|
|
185
|
+
*/
|
|
186
|
+
addError(error) {
|
|
187
|
+
this.errors.push(error);
|
|
188
|
+
this.success = false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Resultado de ejecución de un Libro
|
|
194
|
+
*/
|
|
195
|
+
class LibroResult {
|
|
196
|
+
constructor() {
|
|
197
|
+
/** @type {boolean} */
|
|
198
|
+
this.success = false;
|
|
199
|
+
|
|
200
|
+
/** @type {string|null} - Track ID del SII */
|
|
201
|
+
this.trackId = null;
|
|
202
|
+
|
|
203
|
+
/** @type {string} - Tipo: VENTAS, COMPRAS, GUIAS */
|
|
204
|
+
this.tipo = '';
|
|
205
|
+
|
|
206
|
+
/** @type {string} - Período YYYYMM */
|
|
207
|
+
this.periodo = '';
|
|
208
|
+
|
|
209
|
+
/** @type {number} - Total de documentos en el libro */
|
|
210
|
+
this.totalDocumentos = 0;
|
|
211
|
+
|
|
212
|
+
/** @type {string[]} */
|
|
213
|
+
this.errors = [];
|
|
214
|
+
|
|
215
|
+
/** @type {string|null} */
|
|
216
|
+
this.xmlPath = null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
static success(data = {}) {
|
|
220
|
+
const result = new LibroResult();
|
|
221
|
+
result.success = true;
|
|
222
|
+
Object.assign(result, data);
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
static failure(errors) {
|
|
227
|
+
const result = new LibroResult();
|
|
228
|
+
result.success = false;
|
|
229
|
+
result.errors = Array.isArray(errors) ? errors : [errors];
|
|
230
|
+
return result;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Resultado completo del runner de certificación
|
|
236
|
+
*/
|
|
237
|
+
class CertRunnerResult {
|
|
238
|
+
constructor() {
|
|
239
|
+
/** @type {boolean} */
|
|
240
|
+
this.success = false;
|
|
241
|
+
|
|
242
|
+
/** @type {string} - Timestamp de inicio */
|
|
243
|
+
this.started = new Date().toISOString();
|
|
244
|
+
|
|
245
|
+
/** @type {string|null} - Timestamp de fin */
|
|
246
|
+
this.finished = null;
|
|
247
|
+
|
|
248
|
+
/** @type {Object.<string, SetResult>} - Resultados por set */
|
|
249
|
+
this.sets = {};
|
|
250
|
+
|
|
251
|
+
/** @type {Object.<string, LibroResult>} - Resultados por libro */
|
|
252
|
+
this.libros = {};
|
|
253
|
+
|
|
254
|
+
/** @type {SetResult|null} - Resultado de simulación */
|
|
255
|
+
this.simulacion = null;
|
|
256
|
+
|
|
257
|
+
/** @type {Object|null} - Estado de avance del SII */
|
|
258
|
+
this.avance = null;
|
|
259
|
+
|
|
260
|
+
/** @type {string[]} */
|
|
261
|
+
this.errors = [];
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Calcula el resumen de la ejecución
|
|
266
|
+
* @returns {Object}
|
|
267
|
+
*/
|
|
268
|
+
getSummary() {
|
|
269
|
+
const setKeys = Object.keys(this.sets);
|
|
270
|
+
const libroKeys = Object.keys(this.libros);
|
|
271
|
+
|
|
272
|
+
return {
|
|
273
|
+
setsTotal: setKeys.length,
|
|
274
|
+
setsOk: setKeys.filter(k => this.sets[k].success).length,
|
|
275
|
+
librosTotal: libroKeys.length,
|
|
276
|
+
librosOk: libroKeys.filter(k => this.libros[k].success).length,
|
|
277
|
+
simulacionOk: this.simulacion?.success || false,
|
|
278
|
+
duracion: this.finished
|
|
279
|
+
? new Date(this.finished) - new Date(this.started)
|
|
280
|
+
: null,
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ═══════════════════════════════════════════════════════════════
|
|
286
|
+
// ESTRUCTURAS DE CASOS (del SII)
|
|
287
|
+
// ═══════════════════════════════════════════════════════════════
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* Item de un caso de prueba
|
|
291
|
+
* @typedef {Object} CasoItem
|
|
292
|
+
* @property {string} nombre - Nombre del item
|
|
293
|
+
* @property {number} cantidad - Cantidad
|
|
294
|
+
* @property {number} precio - Precio unitario (neto)
|
|
295
|
+
* @property {number} [descuentoPct] - Descuento porcentual
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Caso de prueba del SII
|
|
300
|
+
* @typedef {Object} CasoPrueba
|
|
301
|
+
* @property {string} id - ID del caso (ej: "4668070-1")
|
|
302
|
+
* @property {number} tipoDte - Tipo de DTE
|
|
303
|
+
* @property {CasoItem[]} items - Items del documento
|
|
304
|
+
* @property {number} [descuentoGlobalPct] - Descuento global %
|
|
305
|
+
* @property {Object} [referencia] - Referencia a otro documento
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Estructura de un set de pruebas parseado del SII
|
|
310
|
+
* @typedef {Object} SetEstructura
|
|
311
|
+
* @property {Object} cafRequired - { 33: 5, 56: 2, 61: 3 }
|
|
312
|
+
* @property {CasoPrueba[]} casos - Lista de casos
|
|
313
|
+
*/
|
|
314
|
+
|
|
315
|
+
// ═══════════════════════════════════════════════════════════════
|
|
316
|
+
// EXPORTS
|
|
317
|
+
// ═══════════════════════════════════════════════════════════════
|
|
318
|
+
|
|
319
|
+
module.exports = {
|
|
320
|
+
// Constantes
|
|
321
|
+
SETS_DTE,
|
|
322
|
+
SET_LABELS,
|
|
323
|
+
SET_ORDER,
|
|
324
|
+
LIBRO_TYPES,
|
|
325
|
+
|
|
326
|
+
// Clases de resultado
|
|
327
|
+
SetResult,
|
|
328
|
+
LibroResult,
|
|
329
|
+
CertRunnerResult,
|
|
330
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devlas/dte-sii",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.12.0",
|
|
4
4
|
"description": "Facturación y boletas electrónicas para el SII de Chile. Genera, timbra, firma y envía DTEs, libros electrónicos y automatiza la certificación.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "dte-sii.d.ts",
|