@devlas/dte-sii 2.12.14 → 2.12.16

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.
@@ -1425,7 +1425,11 @@ class SiiCertificacion {
1425
1425
  * @returns {Promise<Object>} { success, estados, timedOut }
1426
1426
  */
1427
1427
  async waitForApproval(setsAEsperar = [], options = {}) {
1428
- const { maxIntentos = 30, intervalo = 10000, onProgress } = options;
1428
+ // maxIntentos bajado de 30 a 5 (10s c/u = 50s tope, antes 5 min): evidencia real de hoy
1429
+ // (~10 corridas) muestra que esto SIEMPRE resuelve en el intento 1-3 (10-30s) — si tarda
1430
+ // más que eso, algo anda mal en vez de ser una demora normal del SII, y esperar 5 min
1431
+ // solo posterga descubrirlo.
1432
+ const { maxIntentos = 5, intervalo = 10000, onProgress } = options;
1429
1433
  const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
1430
1434
 
1431
1435
  for (let intento = 1; intento <= maxIntentos; intento++) {
@@ -1006,19 +1006,22 @@ class CertRunner {
1006
1006
  const _enviadorSoap = this._createLibroEnviador();
1007
1007
  const _rutEmisor = this.config.emisor.rut;
1008
1008
 
1009
- // Polling hasta 5 minutos (20 intentos × 15s). Si los libros no llegan a LOK
1010
- // en ese lapso se declara igual (ver más abajo "Declarando igual"). El SII de
1011
- // certificación (maullín) suele dejar los libros en LSO mucho tiempo sin avanzar,
1012
- // así que esperar 30 min (el valor anterior) solo agregaba demora sin cambiar el
1013
- // resultado. LSO y otros intermedios igual esperan hasta LOK o rechazo, pero acotado.
1014
- const _MAX_SOAP_POLLS = 20;
1009
+ // Polling corto (3 intentos × 15s = 45s). Se declara igual después sin importar cómo
1010
+ // termine este poll (ver más abajo "Declarando igual") — nunca bloquea. Evidencia real
1011
+ // de hoy: en NINGUNA corrida este poll llegó a ver LOK ni LNC antes de agotarse, ni con
1012
+ // 20 intentos (5 min) ni con 120 (30 min, el valor original) maullín deja los libros
1013
+ // en LSO mucho más tiempo del que tiene sentido esperar acá. El único caso que este poll
1014
+ // puede capturar a tiempo es un rechazo de schema INMEDIATO (rápido por naturaleza); el
1015
+ // LNC por período ocupado se detecta más tarde, en el retry de _reenviarLibros (poll
1016
+ // aparte, sin cambios). Se deja en 3 intentos en vez de 0 por si ese caso rápido ocurre.
1017
+ const _MAX_SOAP_POLLS = 3;
1015
1018
  const _SOAP_INTERVAL_MS = 15000;
1016
1019
  let _soapPendientes = new Set(_librosParaConsultar.map(l => l.key));
1017
1020
  const _soapFinalStates = {}; // key → resultado SOAP terminal (LOK/LNC/LRH/etc.)
1018
1021
  const _soapErrCount = {}; // key → contador de errores SOAP consecutivos (ok:false o throw)
1019
1022
  const _MAX_SOAP_ERR = 10; // reintentos antes de desistir por errores transitorios
1020
1023
 
1021
- console.log('\n[SOAP] Consultando estado de envíos (espera hasta 5 min)...');
1024
+ console.log('\n[SOAP] Consultando estado de envíos (espera hasta 45s)...');
1022
1025
  await sleep(15000); // espera inicial — SII tarda al menos 15s en validar schema
1023
1026
  for (let _pi = 0; _pi < _MAX_SOAP_POLLS && _soapPendientes.size > 0; _pi++) {
1024
1027
  for (const { key, nombre } of _librosParaConsultar) {
@@ -1065,7 +1068,7 @@ class CertRunner {
1065
1068
  }
1066
1069
  if (_soapPendientes.size > 0) {
1067
1070
  const _nombresTimeout = _librosParaConsultar.filter(l => _soapPendientes.has(l.key)).map(l => l.nombre);
1068
- console.log(` [SOAP] ${_nombresTimeout.join(', ')} siguen en proceso tras 5 min. Declarando igual — verifica correos del SII.`);
1071
+ console.log(` [SOAP] ${_nombresTimeout.join(', ')} siguen en proceso tras 45s. Declarando igual — verifica correos del SII.`);
1069
1072
  }
1070
1073
 
1071
1074
  // 4. Declarar + retry automático:
@@ -1244,6 +1247,11 @@ class CertRunner {
1244
1247
  console.log(`\n[!] Solo ${librosEnviados}/3 libros enviados. Errores: ${errores.join('; ')}`);
1245
1248
  }
1246
1249
 
1250
+ const _librosProcesados = Object.keys(resultados)
1251
+ .filter(k => k.startsWith('libro'))
1252
+ .map(k => k.slice('libro'.length).replace(/^./, c => c.toLowerCase()));
1253
+ emitProgress(STEPS.BOOKS_DONE, { libros: _librosProcesados, success: librosEnviados === 3 });
1254
+
1247
1255
  return {
1248
1256
  success: librosEnviados === 3,
1249
1257
  librosEnviados,
@@ -1806,7 +1814,10 @@ class CertRunner {
1806
1814
 
1807
1815
  if (todosAprobados) {
1808
1816
  console.log('\n ¡Todos los libros aprobados!');
1809
- return await this.avanzarSiguientePaso();
1817
+ const resultadoAvance = await this.avanzarSiguientePaso();
1818
+ const avanceActual = await this.consultarAvance().catch(() => null);
1819
+ emitProgress(STEPS.LIBROS_AVANZADOS, { etapaActual: avanceActual?.etapaActual ?? null });
1820
+ return resultadoAvance;
1810
1821
  }
1811
1822
 
1812
1823
  await sleep(intervalo);
@@ -2157,6 +2168,7 @@ class CertRunner {
2157
2168
  const intercambioDir = path.join(this.debugDir, 'intercambio');
2158
2169
  fs.mkdirSync(intercambioDir, { recursive: true });
2159
2170
 
2171
+ emitProgress(STEPS.INTERCAMBIO_START);
2160
2172
  console.log('\n' + '═'.repeat(60));
2161
2173
  console.log('FASE 7: INTERCAMBIO DE INFORMACIÓN');
2162
2174
  console.log('═'.repeat(60));
@@ -2198,6 +2210,8 @@ class CertRunner {
2198
2210
  }
2199
2211
  }
2200
2212
 
2213
+ emitProgress(STEPS.INTERCAMBIO_DESCARGADO);
2214
+
2201
2215
  // ── PASO 2: Generar XMLs de respuesta ─────────────────────
2202
2216
  console.log('\nGenerando respuestas firmadas...');
2203
2217
  const intercambioCert = new IntercambioCert({
@@ -2225,6 +2239,7 @@ class CertRunner {
2225
2239
  });
2226
2240
 
2227
2241
  if (uploadResult.success) {
2242
+ emitProgress(STEPS.INTERCAMBIO_DONE, { uploaded: true });
2228
2243
  console.log('\n' + '═'.repeat(60));
2229
2244
  console.log('[OK] INTERCAMBIO COMPLETADO');
2230
2245
  console.log('═'.repeat(60));
@@ -2799,7 +2814,10 @@ class CertRunner {
2799
2814
  console.log(`FASE 8: MUESTRAS IMPRESAS (${pdfPaths.length} PDFs)`);
2800
2815
  console.log('═'.repeat(60));
2801
2816
 
2802
- return this._subirMuestrasImpresasPortal({ pdfPaths, debugDir: pdfDir });
2817
+ emitProgress(STEPS.MUESTRAS_UPLOADING, { count: pdfPaths.length });
2818
+ const result = await this._subirMuestrasImpresasPortal({ pdfPaths, debugDir: pdfDir });
2819
+ emitProgress(STEPS.MUESTRAS_DONE, { success: result.success });
2820
+ return result;
2803
2821
  }
2804
2822
 
2805
2823
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devlas/dte-sii",
3
- "version": "2.12.14",
3
+ "version": "2.12.16",
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",
package/utils/progress.js CHANGED
@@ -34,8 +34,9 @@ const STEPS = {
34
34
  BOOK_SKIPPED: 'BOOK_SKIPPED', // data: { book }
35
35
  BOOK_ERROR: 'BOOK_ERROR', // data: { book, error }
36
36
  BOOKS_DECLARING: 'BOOKS_DECLARING',
37
- BOOKS_DONE: 'BOOKS_DONE',
37
+ BOOKS_DONE: 'BOOKS_DONE', // data: { libros, success } al terminar la fase completa
38
38
  BOOK_PERIOD_RETRY: 'BOOK_PERIOD_RETRY', // data: { periodo, intento }
39
+ LIBROS_AVANZADOS: 'LIBROS_AVANZADOS', // data: { etapaActual } — tras avanzarSiguientePaso() post-libros
39
40
  // Avance (Fase 5)
40
41
  ADVANCE_WAITING: 'ADVANCE_WAITING',
41
42
  ADVANCE_DONE: 'ADVANCE_DONE',
@@ -47,13 +48,14 @@ const STEPS = {
47
48
  SIM_POLLING: 'SIM_POLLING', // data: { intento, max }
48
49
  SIM_DONE: 'SIM_DONE',
49
50
  // Intercambio (Fase 7)
50
- INTERCAMBIO_START: 'INTERCAMBIO_START',
51
- INTERCAMBIO_DONE: 'INTERCAMBIO_DONE',
51
+ INTERCAMBIO_START: 'INTERCAMBIO_START',
52
+ INTERCAMBIO_DESCARGADO: 'INTERCAMBIO_DESCARGADO', // set de intercambio obtenido (leído de disco o descargado)
53
+ INTERCAMBIO_DONE: 'INTERCAMBIO_DONE', // data: { uploaded }
52
54
  // Muestras impresas (Fase 8)
53
55
  MUESTRAS_START: 'MUESTRAS_START',
54
56
  MUESTRAS_PDFS: 'MUESTRAS_PDFS',
55
- MUESTRAS_UPLOADING: 'MUESTRAS_UPLOADING',
56
- MUESTRAS_DONE: 'MUESTRAS_DONE',
57
+ MUESTRAS_UPLOADING: 'MUESTRAS_UPLOADING', // data: { count }
58
+ MUESTRAS_DONE: 'MUESTRAS_DONE', // data: { success }
57
59
  // Boleta electronica
58
60
  BOLETA_START: 'BOLETA_START',
59
61
  BOLETA_SET_DOWNLOAD: 'BOLETA_SET_DOWNLOAD',