@devlas/dte-sii 2.20.0 → 2.21.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.
Files changed (2) hide show
  1. package/CafSolicitor.js +30 -1
  2. package/package.json +1 -1
package/CafSolicitor.js CHANGED
@@ -241,6 +241,28 @@ class CafSolicitor {
241
241
  return /NO\s+(SE\s+)?AUTORIZA\s+TIMBRAJE/i.test(CafSolicitor.textoVisible(html, 4000));
242
242
  }
243
243
 
244
+ /**
245
+ * Aísla el motivo real que el SII escribe en la página de bloqueo de timbraje, en vez
246
+ * de descartarlo — hasta ahora `solicitar()` detectaba el bloqueo con `esBloqueoTimbraje`
247
+ * y siempre devolvía el mismo mensaje genérico, tirando a la basura el texto real de la
248
+ * página (que sí queda en el HTML, ya se guardaba en debug).
249
+ *
250
+ * Caso real (verificado 2026-09-03, RUT anonimizado en los tests): el SII no dice un
251
+ * error genérico, dice algo concreto y accionable — "de acuerdo a nuestros registros,
252
+ * usted tiene disponible una cantidad de folios suficiente para emitir documentos
253
+ * electronicos... debe emitir y enviar documentos electronicos al SII o anular folios".
254
+ * Ese texto es justo lo que el consumidor necesita para armar un aviso útil, en vez de
255
+ * mandar a alguien a "revisa el portal" sin decirle qué va a encontrar ahí.
256
+ *
257
+ * @returns {string|null} el motivo aislado, o null si no se pudo — el llamador cae al
258
+ * mensaje genérico en ese caso, nunca se vuelve fatal por esto.
259
+ */
260
+ static extraerMotivoBloqueoTimbraje(html) {
261
+ const t = CafSolicitor.textoVisible(html, 4000);
262
+ const m = t.match(/(NO\s+(?:SE\s+)?AUTORIZA\s+TIMBRAJE[\s\S]{0,600}?)(?:\s+Si necesita mas informacion|$)/i);
263
+ return m ? m[1].trim() : null;
264
+ }
265
+
244
266
  /**
245
267
  * Detecta el rechazo genérico "no está autorizado para ingresar a esta opción" en
246
268
  * palena (producción). A diferencia de maullin/certificación, donde el bloqueo por
@@ -596,7 +618,14 @@ class CafSolicitor {
596
618
  }
597
619
 
598
620
  if (response.body && CafSolicitor.esBloqueoTimbraje(response.body)) {
599
- return { success: false, errorCode: 'TIMBRAJE_BLOQUEADO', error: 'SII: No se autoriza timbraje. Folios acumulados excesivos o situaciones tributarias pendientes. Revisa el portal SII → Factura Electrónica → Solicitud de Timbraje.' };
621
+ const motivoSii = CafSolicitor.extraerMotivoBloqueoTimbraje(response.body);
622
+ return {
623
+ success: false,
624
+ errorCode: 'TIMBRAJE_BLOQUEADO',
625
+ error: motivoSii
626
+ ? `SII: ${motivoSii}`
627
+ : 'SII: No se autoriza timbraje. Folios acumulados excesivos o situaciones tributarias pendientes. Revisa el portal SII → Factura Electrónica → Solicitud de Timbraje.',
628
+ };
600
629
  }
601
630
 
602
631
  if (response.body && CafSolicitor.esRequiereTramitePresencial(response.body)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devlas/dte-sii",
3
- "version": "2.20.0",
3
+ "version": "2.21.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",