@devlas/dte-sii 2.5.12 → 2.5.14
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/BoletaService.js +1 -1
- package/CafSolicitor.js +11 -12
- package/Certificado.js +2 -2
- package/ConsumoFolio.js +3 -3
- package/EnviadorSII.js +72 -99
- package/FolioService.js +1 -1
- package/SiiCertificacion.js +159 -28
- package/SiiPortalAuth.js +33 -9
- package/SiiSession.js +4 -4
- package/cert/BoletaCert.js +44 -44
- package/cert/CertRunner.js +511 -219
- package/cert/ConfigLoader.js +1 -1
- package/cert/IntercambioCert.js +19 -19
- package/cert/LibroCompras.js +45 -5
- package/cert/MuestrasImpresas.js +18 -18
- package/cert/SetBase.js +16 -16
- package/cert/SetBasico.js +6 -6
- package/cert/SetCompra.js +6 -6
- package/cert/SetExenta.js +6 -6
- package/cert/SetGuia.js +2 -2
- package/cert/SetParser.js +96 -13
- package/cert/SetsProvider.js +16 -19
- package/cert/Simulacion.js +1 -1
- package/package.json +2 -1
- package/utils/progress.js +78 -0
- package/utils/xml.js +2 -2
package/cert/ConfigLoader.js
CHANGED
|
@@ -51,7 +51,7 @@ function loadConfig(options = {}) {
|
|
|
51
51
|
const fch_resol = process.env.FECHA_RESOLUCION || new Date().toISOString().slice(0, 10);
|
|
52
52
|
const nro_resol = parseInt(process.env.NRO_RESOLUCION || '0', 10);
|
|
53
53
|
|
|
54
|
-
console.log(`[ConfigLoader]
|
|
54
|
+
console.log(`[ConfigLoader] Resolución: NroResol=${nro_resol} FchResol=${fch_resol} (AMBIENTE=${AMBIENTE})`);
|
|
55
55
|
|
|
56
56
|
const EMISOR = {
|
|
57
57
|
rut: process.env.EMISOR_RUT,
|
package/cert/IntercambioCert.js
CHANGED
|
@@ -361,57 +361,57 @@ class IntercambioCert {
|
|
|
361
361
|
fs.mkdirSync(outDir, { recursive: true });
|
|
362
362
|
|
|
363
363
|
console.log('\n' + '═'.repeat(60));
|
|
364
|
-
console.log('
|
|
364
|
+
console.log('INTERCAMBIO DE INFORMACIÓN DTE');
|
|
365
365
|
console.log('═'.repeat(60));
|
|
366
366
|
|
|
367
367
|
// Parsear EnvioDTE
|
|
368
|
-
console.log('\
|
|
368
|
+
console.log('\nParseando EnvioDTE...');
|
|
369
369
|
const meta = this.parseEnvioDTE(envioDteXml);
|
|
370
370
|
|
|
371
371
|
if (!meta?.items?.length) {
|
|
372
372
|
throw new Error('No se encontraron DTEs en el EnvioDTE de entrada');
|
|
373
373
|
}
|
|
374
374
|
|
|
375
|
-
console.log(`
|
|
376
|
-
console.log(`
|
|
377
|
-
console.log(`
|
|
375
|
+
console.log(` ✓ ${meta.items.length} documentos encontrados`);
|
|
376
|
+
console.log(` ✓ Emisor: ${meta.rutEmisor}`);
|
|
377
|
+
console.log(` ✓ Receptor: ${meta.rutReceptor}`);
|
|
378
378
|
|
|
379
379
|
meta.items.forEach((item, idx) => {
|
|
380
|
-
console.log(`
|
|
380
|
+
console.log(` ${idx + 1}. Tipo ${item.tipoDTE} Folio ${item.folio} - $${item.mntTotal.toLocaleString('es-CL')}`);
|
|
381
381
|
});
|
|
382
382
|
|
|
383
383
|
// Generar respuestas
|
|
384
|
-
console.log('\
|
|
384
|
+
console.log('\nGenerando respuestas de intercambio...');
|
|
385
385
|
|
|
386
386
|
// 1. Respuesta Recepción de Envío
|
|
387
|
-
console.log('
|
|
387
|
+
console.log(' 1. Respuesta Recepción de Envío...');
|
|
388
388
|
const recepcionXml = this.generarRespuestaRecepcionEnvio(meta, options.envioNombre);
|
|
389
389
|
const recepcionPath = path.join(outDir, 'respuesta-recepcion-envio.xml');
|
|
390
390
|
fs.writeFileSync(recepcionPath, recepcionXml, 'utf8');
|
|
391
|
-
console.log(`
|
|
391
|
+
console.log(` ✓ ${recepcionPath}`);
|
|
392
392
|
|
|
393
393
|
// 2. Respuesta Aprobación Comercial
|
|
394
|
-
console.log('
|
|
394
|
+
console.log(' 2. Respuesta Aprobación Comercial...');
|
|
395
395
|
const aprobacionXml = this.generarRespuestaAprobacionComercial(meta);
|
|
396
396
|
const aprobacionPath = path.join(outDir, 'respuesta-aprobacion-comercial.xml');
|
|
397
397
|
fs.writeFileSync(aprobacionPath, aprobacionXml, 'utf8');
|
|
398
|
-
console.log(`
|
|
398
|
+
console.log(` ✓ ${aprobacionPath}`);
|
|
399
399
|
|
|
400
400
|
// 3. Envío de Recibos
|
|
401
|
-
console.log('
|
|
401
|
+
console.log(' 3. Envío de Recibos (Mercaderías)...');
|
|
402
402
|
const recibosXml = this.generarEnvioRecibos(meta);
|
|
403
403
|
const recibosPath = path.join(outDir, 'envio-recibos.xml');
|
|
404
404
|
fs.writeFileSync(recibosPath, recibosXml, 'utf8');
|
|
405
|
-
console.log(`
|
|
405
|
+
console.log(` ✓ ${recibosPath}`);
|
|
406
406
|
|
|
407
407
|
console.log('\n' + '═'.repeat(60));
|
|
408
|
-
console.log('
|
|
408
|
+
console.log('[OK] INTERCAMBIO GENERADO');
|
|
409
409
|
console.log('═'.repeat(60));
|
|
410
|
-
console.log(`
|
|
411
|
-
console.log('
|
|
412
|
-
console.log('
|
|
413
|
-
console.log('
|
|
414
|
-
console.log('
|
|
410
|
+
console.log(` Directorio: ${outDir}`);
|
|
411
|
+
console.log(' Archivos generados:');
|
|
412
|
+
console.log(' - respuesta-recepcion-envio.xml');
|
|
413
|
+
console.log(' - respuesta-aprobacion-comercial.xml');
|
|
414
|
+
console.log(' - envio-recibos.xml');
|
|
415
415
|
|
|
416
416
|
return {
|
|
417
417
|
success: true,
|
package/cert/LibroCompras.js
CHANGED
|
@@ -120,10 +120,32 @@ class LibroCompras {
|
|
|
120
120
|
else if (doc.IVANoRec) {
|
|
121
121
|
docAjustado.TasaImp = 0;
|
|
122
122
|
docAjustado.MntIVA = 0;
|
|
123
|
+
// SII requiere MntNeto presente (aunque sea 0) cuando hay IVANoRec — LBR-3 si falta
|
|
124
|
+
if (docAjustado.MntNeto === undefined || docAjustado.MntNeto === null) {
|
|
125
|
+
docAjustado.MntNeto = 0;
|
|
126
|
+
}
|
|
123
127
|
}
|
|
124
128
|
// Caso normal: Asegurar TasaImp sea número entero (19) no decimal (0.19)
|
|
129
|
+
// Si hay TasaImp pero no hay MntNeto, el SII igual exige TasaImp + MntNeto=0 + MntIVA=0 explícitos
|
|
125
130
|
else if (doc.TasaImp !== undefined) {
|
|
126
|
-
|
|
131
|
+
const tasaNum = doc.TasaImp < 1 ? Math.round(doc.TasaImp * 100) : doc.TasaImp;
|
|
132
|
+
const tieneMntNeto = doc.MntNeto !== undefined && Number(doc.MntNeto) > 0;
|
|
133
|
+
const tieneMntExe = doc.MntExe !== undefined && Number(doc.MntExe) > 0;
|
|
134
|
+
if (tasaNum > 0 && !tieneMntNeto && tieneMntExe) {
|
|
135
|
+
// Documento con TasaImp + MntExe pero sin MntNeto (p.ej. TipoDoc=30 folio exento)
|
|
136
|
+
// SII exige TasaImp + MntNeto + MntIVA presentes; con MntNeto=0 da LOK+LBR-2 (aceptado)
|
|
137
|
+
// Borrar los campos da LRH+LBR-3 (rechazado) — NO borrar
|
|
138
|
+
docAjustado.TasaImp = tasaNum;
|
|
139
|
+
docAjustado.MntNeto = 0;
|
|
140
|
+
docAjustado.MntIVA = 0;
|
|
141
|
+
} else if (tasaNum > 0 && !tieneMntNeto) {
|
|
142
|
+
// TasaImp presente pero sin MntNeto ni MntExe: SII exige ceros explícitos
|
|
143
|
+
docAjustado.TasaImp = tasaNum;
|
|
144
|
+
docAjustado.MntNeto = 0;
|
|
145
|
+
docAjustado.MntIVA = 0;
|
|
146
|
+
} else {
|
|
147
|
+
docAjustado.TasaImp = tasaNum;
|
|
148
|
+
}
|
|
127
149
|
}
|
|
128
150
|
|
|
129
151
|
return docAjustado;
|
|
@@ -262,6 +284,7 @@ class LibroCompras {
|
|
|
262
284
|
TotIVANoRec: {},
|
|
263
285
|
TotOtrosImp: {},
|
|
264
286
|
TotIVARetTotal: 0,
|
|
287
|
+
TotMntNoFact: 0,
|
|
265
288
|
});
|
|
266
289
|
}
|
|
267
290
|
|
|
@@ -271,6 +294,7 @@ class LibroCompras {
|
|
|
271
294
|
r.TotMntNeto += Number(doc.MntNeto || 0);
|
|
272
295
|
r.TotMntIVA += Number(doc.MntIVA || 0);
|
|
273
296
|
r.TotMntTotal += Number(doc.MntTotal || 0);
|
|
297
|
+
r.TotMntNoFact += Number(doc.MntNoFact || 0);
|
|
274
298
|
|
|
275
299
|
// IVA Uso Común
|
|
276
300
|
if (doc.IVAUsoComun) {
|
|
@@ -319,10 +343,26 @@ class LibroCompras {
|
|
|
319
343
|
TotDoc: r.TotDoc,
|
|
320
344
|
};
|
|
321
345
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
346
|
+
// TotMntExe siempre presente (incluso como 0)
|
|
347
|
+
// TotMntNeto y TotMntIVA solo se emiten cuando son > 0:
|
|
348
|
+
// - Para docs afectos: siempre > 0 → se emiten
|
|
349
|
+
// - Para docs puramente exentos (TpoDoc=30/34/etc sin IVA): son 0
|
|
350
|
+
// y emitir <TotMntNeto>0</TotMntNeto> causa 'El Monto Neto No Cuadra'
|
|
351
|
+
// porque el SII espera que esté AUSENTE, no cero
|
|
352
|
+
limpio.TotMntExe = r.TotMntExe;
|
|
353
|
+
// El XSD LibroCV requiere el orden estricto: TotMntNeto → TotMntIVA → TotIVANoRec/TotOtrosImp
|
|
354
|
+
// TotMntNeto y TotMntIVA son SIEMPRE requeridos por el XSD (incluso como 0)
|
|
355
|
+
const tieneIVANoRec = Object.keys(r.TotIVANoRec).length > 0;
|
|
356
|
+
const tieneOtrosImp = Object.keys(r.TotOtrosImp).length > 0;
|
|
357
|
+
const necesitaIVAFields = tieneIVANoRec || tieneOtrosImp;
|
|
358
|
+
limpio.TotMntNeto = r.TotMntNeto;
|
|
359
|
+
limpio.TotMntIVA = r.TotMntIVA;
|
|
360
|
+
limpio.TotMntTotal = r.TotMntTotal;
|
|
361
|
+
|
|
362
|
+
// MntNoFact (TpoDoc=32 Liquidación-Factura)
|
|
363
|
+
if (r.TotMntNoFact > 0) {
|
|
364
|
+
limpio.TotMntNoFact = r.TotMntNoFact;
|
|
365
|
+
}
|
|
326
366
|
|
|
327
367
|
// IVA Uso Común
|
|
328
368
|
if (r.TotOpIVAUsoComun > 0) {
|
package/cert/MuestrasImpresas.js
CHANGED
|
@@ -519,10 +519,10 @@ class MuestrasImpresas {
|
|
|
519
519
|
fs.mkdirSync(simulacionDir, { recursive: true });
|
|
520
520
|
|
|
521
521
|
console.log('\n' + '═'.repeat(60));
|
|
522
|
-
console.log('
|
|
522
|
+
console.log('GENERACIÓN DE MUESTRAS IMPRESAS');
|
|
523
523
|
console.log('═'.repeat(60));
|
|
524
|
-
console.log(`
|
|
525
|
-
console.log(`
|
|
524
|
+
console.log(` SET-PRUEBAS: ${pruebasDir}`);
|
|
525
|
+
console.log(` SET-SIMULACION: ${simulacionDir}`);
|
|
526
526
|
|
|
527
527
|
const browser = await puppeteer.launch({ headless: true });
|
|
528
528
|
const resultado = {
|
|
@@ -537,20 +537,20 @@ class MuestrasImpresas {
|
|
|
537
537
|
|
|
538
538
|
try {
|
|
539
539
|
for (const filePath of xmlFiles) {
|
|
540
|
-
console.log(`\n
|
|
540
|
+
console.log(`\n Procesando: ${path.basename(filePath)}`);
|
|
541
541
|
const xml = fs.readFileSync(filePath, 'utf8');
|
|
542
542
|
|
|
543
543
|
let documentos;
|
|
544
544
|
try {
|
|
545
545
|
documentos = this.parseEnvioDTE(xml);
|
|
546
546
|
} catch (e) {
|
|
547
|
-
console.log(`
|
|
547
|
+
console.log(` [!] Error parseando: ${e.message}`);
|
|
548
548
|
resultado.errores.push({ file: filePath, error: e.message });
|
|
549
549
|
continue;
|
|
550
550
|
}
|
|
551
551
|
|
|
552
552
|
if (!documentos.length) {
|
|
553
|
-
console.log('
|
|
553
|
+
console.log(' [!] Sin documentos');
|
|
554
554
|
continue;
|
|
555
555
|
}
|
|
556
556
|
|
|
@@ -559,7 +559,7 @@ class MuestrasImpresas {
|
|
|
559
559
|
const isPruebas = /envio-set-(basico|guia|exenta|compra)\.xml/i.test(sourceFile);
|
|
560
560
|
const targetDir = isPruebas ? pruebasDir : simulacionDir;
|
|
561
561
|
const categoria = isPruebas ? 'PRUEBAS' : 'SIMULACION';
|
|
562
|
-
console.log(`
|
|
562
|
+
console.log(` Categoria: SET-${categoria}`);
|
|
563
563
|
|
|
564
564
|
for (const doc of documentos) {
|
|
565
565
|
resultado.totalDocs++;
|
|
@@ -579,13 +579,13 @@ class MuestrasImpresas {
|
|
|
579
579
|
resultado.archivos.push(outputPath);
|
|
580
580
|
if (isPruebas) resultado.setPruebas++;
|
|
581
581
|
else resultado.setSimulacion++;
|
|
582
|
-
console.log(`
|
|
582
|
+
console.log(` ✓ ${outputName}`);
|
|
583
583
|
|
|
584
584
|
// Generar copia cedible si corresponde
|
|
585
585
|
if (generarCedible && CEDIBLE_TIPOS.has(doc.tipoDte)) {
|
|
586
586
|
// Guía de traslado interno no tiene cedible
|
|
587
587
|
if (doc.tipoDte === 52 && [5, 6].includes(doc.indTraslado)) {
|
|
588
|
-
console.log(
|
|
588
|
+
console.log(' Guia traslado interno - sin cedible');
|
|
589
589
|
continue;
|
|
590
590
|
}
|
|
591
591
|
|
|
@@ -598,11 +598,11 @@ class MuestrasImpresas {
|
|
|
598
598
|
resultado.archivos.push(outputPathCedible);
|
|
599
599
|
if (isPruebas) resultado.setPruebas++;
|
|
600
600
|
else resultado.setSimulacion++;
|
|
601
|
-
console.log(`
|
|
601
|
+
console.log(` ✓ ${outputNameCedible}`);
|
|
602
602
|
}
|
|
603
603
|
|
|
604
604
|
} catch (e) {
|
|
605
|
-
console.log(`
|
|
605
|
+
console.log(` [ERR] Error: ${e.message}`);
|
|
606
606
|
resultado.errores.push({ tipo: doc.tipoDte, folio: doc.folio, error: e.message });
|
|
607
607
|
}
|
|
608
608
|
}
|
|
@@ -613,17 +613,17 @@ class MuestrasImpresas {
|
|
|
613
613
|
|
|
614
614
|
// Resumen
|
|
615
615
|
console.log('\n' + '═'.repeat(60));
|
|
616
|
-
console.log('
|
|
616
|
+
console.log('[OK] MUESTRAS IMPRESAS GENERADAS');
|
|
617
617
|
console.log('═'.repeat(60));
|
|
618
|
-
console.log(`
|
|
619
|
-
console.log(`
|
|
620
|
-
console.log(`
|
|
621
|
-
console.log(`
|
|
622
|
-
console.log(`
|
|
618
|
+
console.log(` Documentos procesados: ${resultado.totalDocs}`);
|
|
619
|
+
console.log(` PDFs generados: ${resultado.totalPdfs}`);
|
|
620
|
+
console.log(` SET-PRUEBAS: ${resultado.setPruebas} PDFs`);
|
|
621
|
+
console.log(` SET-SIMULACION: ${resultado.setSimulacion} PDFs`);
|
|
622
|
+
console.log(` Directorio base: ${outDir}`);
|
|
623
623
|
|
|
624
624
|
if (resultado.errores.length > 0) {
|
|
625
625
|
resultado.success = false;
|
|
626
|
-
console.log(`
|
|
626
|
+
console.log(` [!] Errores: ${resultado.errores.length}`);
|
|
627
627
|
}
|
|
628
628
|
|
|
629
629
|
return resultado;
|
package/cert/SetBase.js
CHANGED
|
@@ -37,8 +37,8 @@ class SetBase {
|
|
|
37
37
|
this.logger = deps.logger || console;
|
|
38
38
|
|
|
39
39
|
// Subclases deben definir estos
|
|
40
|
-
this.key = '';
|
|
41
|
-
this.label = '';
|
|
40
|
+
this.key = ''; // 'basico', 'exenta', 'guia', 'compra'
|
|
41
|
+
this.label = ''; // 'Set Básico (Facturas)'
|
|
42
42
|
this.tiposDte = []; // [33, 56, 61]
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -82,7 +82,7 @@ class SetBase {
|
|
|
82
82
|
async ejecutar(casos, preloadedCafs = null) {
|
|
83
83
|
const startTime = Date.now();
|
|
84
84
|
this.logger.log(`\n${'═'.repeat(60)}`);
|
|
85
|
-
this.logger.log(
|
|
85
|
+
this.logger.log(`${this.label}`);
|
|
86
86
|
this.logger.log(`${'═'.repeat(60)}\n`);
|
|
87
87
|
|
|
88
88
|
try {
|
|
@@ -90,26 +90,26 @@ class SetBase {
|
|
|
90
90
|
this._validarCasos(casos);
|
|
91
91
|
|
|
92
92
|
// 2. Asegurar CAFs disponibles (usa pre-cargados si existen)
|
|
93
|
-
this.logger.log('
|
|
93
|
+
this.logger.log('Verificando folios (CAFs)...');
|
|
94
94
|
const cafs = preloadedCafs || await this.ensureCafs(casos);
|
|
95
95
|
|
|
96
96
|
if (preloadedCafs) {
|
|
97
97
|
for (const [tipoDte, cafPath] of Object.entries(preloadedCafs)) {
|
|
98
|
-
this.logger.log(`
|
|
98
|
+
this.logger.log(` ✓ CAF tipo ${tipoDte} (pre-cargado)`);
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// 3. Generar DTEs (subclases implementan)
|
|
103
|
-
this.logger.log('
|
|
103
|
+
this.logger.log('Generando DTEs...');
|
|
104
104
|
const dtes = await this.generarDtes(casos, cafs);
|
|
105
|
-
this.logger.log(`
|
|
105
|
+
this.logger.log(` ✓ ${dtes.length} DTEs generados`);
|
|
106
106
|
|
|
107
107
|
// 4. Crear envío firmado
|
|
108
|
-
this.logger.log('
|
|
108
|
+
this.logger.log('Firmando envío...');
|
|
109
109
|
const envio = await this.crearEnvio(dtes);
|
|
110
110
|
|
|
111
111
|
// 5. Enviar al SII
|
|
112
|
-
this.logger.log('
|
|
112
|
+
this.logger.log('Enviando al SII...');
|
|
113
113
|
const respuesta = await this.enviarSii(envio);
|
|
114
114
|
|
|
115
115
|
// 6. Construir resultado con documentos para libros
|
|
@@ -160,14 +160,14 @@ class SetBase {
|
|
|
160
160
|
duration: Date.now() - startTime,
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
-
this.logger.log(`\n
|
|
164
|
-
this.logger.log(`
|
|
165
|
-
this.logger.log(`
|
|
163
|
+
this.logger.log(`\n[OK] ${this.label} completado`);
|
|
164
|
+
this.logger.log(` Track ID: ${result.trackId}`);
|
|
165
|
+
this.logger.log(` Duración: ${result.duration}ms\n`);
|
|
166
166
|
|
|
167
167
|
return result;
|
|
168
168
|
|
|
169
169
|
} catch (error) {
|
|
170
|
-
this.logger.error(`\n
|
|
170
|
+
this.logger.error(`\n[ERR] Error en ${this.label}: ${error.message}\n`);
|
|
171
171
|
|
|
172
172
|
const result = SetResult.failure(error.message);
|
|
173
173
|
result.duration = Date.now() - startTime;
|
|
@@ -197,7 +197,7 @@ class SetBase {
|
|
|
197
197
|
|
|
198
198
|
for (const tipoDte of this.tiposDte) {
|
|
199
199
|
const cantidad = this._calcularCantidadFolios(casos, tipoDte);
|
|
200
|
-
this.logger.log(`
|
|
200
|
+
this.logger.log(` Tipo ${tipoDte}: ${cantidad} folios requeridos`);
|
|
201
201
|
|
|
202
202
|
const cafPath = await this.cafManager.ensureCaf({
|
|
203
203
|
tipoDte,
|
|
@@ -212,7 +212,7 @@ class SetBase {
|
|
|
212
212
|
}
|
|
213
213
|
|
|
214
214
|
cafs[tipoDte] = cafPath;
|
|
215
|
-
this.logger.log(`
|
|
215
|
+
this.logger.log(` ✓ CAF tipo ${tipoDte}: ${cafPath}`);
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
return cafs;
|
|
@@ -237,7 +237,7 @@ class SetBase {
|
|
|
237
237
|
/**
|
|
238
238
|
* Genera los DTEs del set
|
|
239
239
|
*
|
|
240
|
-
*
|
|
240
|
+
* [!] DEBE SER IMPLEMENTADO POR SUBCLASES
|
|
241
241
|
*
|
|
242
242
|
* @abstract
|
|
243
243
|
* @param {Object} casos - Casos parseados del SII
|
package/cert/SetBasico.js
CHANGED
|
@@ -72,21 +72,21 @@ class SetBasico extends SetBase {
|
|
|
72
72
|
const dtes = [];
|
|
73
73
|
|
|
74
74
|
// 1. Generar facturas primero (las NC/ND referencian facturas)
|
|
75
|
-
this.logger.log('
|
|
75
|
+
this.logger.log(' Generando facturas...');
|
|
76
76
|
for (const caso of casos.casosFactura || []) {
|
|
77
77
|
const dte = await this._generarFactura(caso, cafs[33]);
|
|
78
78
|
dtes.push(dte);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
// 2. Generar notas de crédito
|
|
82
|
-
this.logger.log('
|
|
82
|
+
this.logger.log(' Generando notas de crédito...');
|
|
83
83
|
for (const caso of casos.casosNC || []) {
|
|
84
84
|
const dte = await this._generarNotaCredito(caso, cafs[61]);
|
|
85
85
|
dtes.push(dte);
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
// 3. Generar notas de débito
|
|
89
|
-
this.logger.log('
|
|
89
|
+
this.logger.log(' Generando notas de débito...');
|
|
90
90
|
for (const caso of casos.casosND || []) {
|
|
91
91
|
const dte = await this._generarNotaDebito(caso, cafs[56]);
|
|
92
92
|
dtes.push(dte);
|
|
@@ -161,7 +161,7 @@ class SetBasico extends SetBase {
|
|
|
161
161
|
descuentoGlobalPct: caso.descuentoGlobalPct,
|
|
162
162
|
};
|
|
163
163
|
|
|
164
|
-
this.logger.log(`
|
|
164
|
+
this.logger.log(` ✓ Factura caso ${caso.id}: folio ${folio}`);
|
|
165
165
|
return dte;
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -248,7 +248,7 @@ class SetBasico extends SetBase {
|
|
|
248
248
|
items: itemsFinal,
|
|
249
249
|
};
|
|
250
250
|
|
|
251
|
-
this.logger.log(`
|
|
251
|
+
this.logger.log(` ✓ NC caso ${caso.id}: folio ${folio} (ref: caso ${caso.referenciaCaso})`);
|
|
252
252
|
return dte;
|
|
253
253
|
}
|
|
254
254
|
|
|
@@ -309,7 +309,7 @@ class SetBasico extends SetBase {
|
|
|
309
309
|
const dte = new DTE(dteDatos);
|
|
310
310
|
this._timbrarYFirmar(dte, caf);
|
|
311
311
|
|
|
312
|
-
this.logger.log(`
|
|
312
|
+
this.logger.log(` ✓ ND caso ${caso.id}: folio ${folio} (ref: caso ${caso.referenciaCaso})`);
|
|
313
313
|
return dte;
|
|
314
314
|
}
|
|
315
315
|
|
package/cert/SetCompra.js
CHANGED
|
@@ -66,20 +66,20 @@ class SetCompra extends SetBase {
|
|
|
66
66
|
const dtes = [];
|
|
67
67
|
|
|
68
68
|
// 1. Generar factura de compra
|
|
69
|
-
this.logger.log('
|
|
69
|
+
this.logger.log(' Generando factura de compra...');
|
|
70
70
|
const dteFactura = await this._generarFacturaCompra(casos.casoFactura, cafs[46]);
|
|
71
71
|
dtes.push(dteFactura);
|
|
72
72
|
|
|
73
73
|
// 2. Generar nota de crédito
|
|
74
74
|
if (casos.casoNC) {
|
|
75
|
-
this.logger.log('
|
|
75
|
+
this.logger.log(' Generando nota de crédito...');
|
|
76
76
|
const dteNc = await this._generarNotaCredito(casos.casoNC, cafs[61]);
|
|
77
77
|
dtes.push(dteNc);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
// 3. Generar nota de débito
|
|
81
81
|
if (casos.casoND) {
|
|
82
|
-
this.logger.log('
|
|
82
|
+
this.logger.log(' Generando nota de débito...');
|
|
83
83
|
const dteNd = await this._generarNotaDebito(casos.casoND, cafs[56]);
|
|
84
84
|
dtes.push(dteNd);
|
|
85
85
|
}
|
|
@@ -139,7 +139,7 @@ class SetCompra extends SetBase {
|
|
|
139
139
|
items,
|
|
140
140
|
};
|
|
141
141
|
|
|
142
|
-
this.logger.log(`
|
|
142
|
+
this.logger.log(` ✓ Factura Compra caso ${caso.id}: folio ${folio}`);
|
|
143
143
|
return dte;
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -207,7 +207,7 @@ class SetCompra extends SetBase {
|
|
|
207
207
|
items,
|
|
208
208
|
};
|
|
209
209
|
|
|
210
|
-
this.logger.log(`
|
|
210
|
+
this.logger.log(` ✓ NC Compra caso ${caso.id}: folio ${folio} (ref: ${caso.referenciaCaso})`);
|
|
211
211
|
return dte;
|
|
212
212
|
}
|
|
213
213
|
|
|
@@ -265,7 +265,7 @@ class SetCompra extends SetBase {
|
|
|
265
265
|
const dte = new DTE(dteDatos);
|
|
266
266
|
this._timbrarYFirmar(dte, caf);
|
|
267
267
|
|
|
268
|
-
this.logger.log(`
|
|
268
|
+
this.logger.log(` ✓ ND Compra caso ${caso.id}: folio ${folio} (ref: ${caso.referenciaCaso})`);
|
|
269
269
|
return dte;
|
|
270
270
|
}
|
|
271
271
|
|
package/cert/SetExenta.js
CHANGED
|
@@ -69,21 +69,21 @@ class SetExenta extends SetBase {
|
|
|
69
69
|
const dtes = [];
|
|
70
70
|
|
|
71
71
|
// 1. Generar facturas exentas primero
|
|
72
|
-
this.logger.log('
|
|
72
|
+
this.logger.log(' Generando facturas exentas...');
|
|
73
73
|
for (const caso of casos.casosFactura || []) {
|
|
74
74
|
const dte = await this._generarFacturaExenta(caso, cafs[34]);
|
|
75
75
|
dtes.push(dte);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// 2. Generar notas de crédito
|
|
79
|
-
this.logger.log('
|
|
79
|
+
this.logger.log(' Generando notas de crédito...');
|
|
80
80
|
for (const caso of casos.casosNC || []) {
|
|
81
81
|
const dte = await this._generarNotaCredito(caso, cafs[61]);
|
|
82
82
|
dtes.push(dte);
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
// 3. Generar notas de débito
|
|
86
|
-
this.logger.log('
|
|
86
|
+
this.logger.log(' Generando notas de débito...');
|
|
87
87
|
for (const caso of casos.casosND || []) {
|
|
88
88
|
const dte = await this._generarNotaDebito(caso, cafs[56]);
|
|
89
89
|
dtes.push(dte);
|
|
@@ -144,7 +144,7 @@ class SetExenta extends SetBase {
|
|
|
144
144
|
items,
|
|
145
145
|
};
|
|
146
146
|
|
|
147
|
-
this.logger.log(`
|
|
147
|
+
this.logger.log(` ✓ Factura Exenta caso ${caso.id}: folio ${folio}`);
|
|
148
148
|
return dte;
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -212,7 +212,7 @@ class SetExenta extends SetBase {
|
|
|
212
212
|
items,
|
|
213
213
|
};
|
|
214
214
|
|
|
215
|
-
this.logger.log(`
|
|
215
|
+
this.logger.log(` ✓ NC Exenta caso ${caso.id}: folio ${folio} (ref: ${caso.referenciaCaso})`);
|
|
216
216
|
return dte;
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -270,7 +270,7 @@ class SetExenta extends SetBase {
|
|
|
270
270
|
const dte = new DTE(dteDatos);
|
|
271
271
|
this._timbrarYFirmar(dte, caf);
|
|
272
272
|
|
|
273
|
-
this.logger.log(`
|
|
273
|
+
this.logger.log(` ✓ ND Exenta caso ${caso.id}: folio ${folio} (ref: ${caso.referenciaCaso})`);
|
|
274
274
|
return dte;
|
|
275
275
|
}
|
|
276
276
|
|
package/cert/SetGuia.js
CHANGED
|
@@ -64,7 +64,7 @@ class SetGuia extends SetBase {
|
|
|
64
64
|
async generarDtes(casos, cafs) {
|
|
65
65
|
const dtes = [];
|
|
66
66
|
|
|
67
|
-
this.logger.log('
|
|
67
|
+
this.logger.log(' Generando guías de despacho...');
|
|
68
68
|
for (const caso of casos.casos || []) {
|
|
69
69
|
const dte = await this._generarGuia(caso, cafs[52]);
|
|
70
70
|
dtes.push(dte);
|
|
@@ -138,7 +138,7 @@ class SetGuia extends SetBase {
|
|
|
138
138
|
const dte = new DTE(dteDatos);
|
|
139
139
|
this._timbrarYFirmar(dte, caf);
|
|
140
140
|
|
|
141
|
-
this.logger.log(`
|
|
141
|
+
this.logger.log(` ✓ Guía caso ${caso.id}: folio ${folio} (IndTraslado: ${idDoc.IndTraslado})`);
|
|
142
142
|
return dte;
|
|
143
143
|
}
|
|
144
144
|
|