@albertomarturelo/sii-core 0.3.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/CHANGELOG.md +114 -0
- package/LICENSE +21 -0
- package/README.md +108 -0
- package/dist/adapters/fake/index.d.ts +98 -0
- package/dist/adapters/fake/index.d.ts.map +1 -0
- package/dist/adapters/fake/index.js +131 -0
- package/dist/adapters/fake/index.js.map +1 -0
- package/dist/adapters/node/index.d.ts +22 -0
- package/dist/adapters/node/index.d.ts.map +1 -0
- package/dist/adapters/node/index.js +65 -0
- package/dist/adapters/node/index.js.map +1 -0
- package/dist/adapters/node/portal.d.ts +8 -0
- package/dist/adapters/node/portal.d.ts.map +1 -0
- package/dist/adapters/node/portal.js +222 -0
- package/dist/adapters/node/portal.js.map +1 -0
- package/dist/adapters/node/response.d.ts +21 -0
- package/dist/adapters/node/response.d.ts.map +1 -0
- package/dist/adapters/node/response.js +48 -0
- package/dist/adapters/node/response.js.map +1 -0
- package/dist/audit/audit.d.ts +8 -0
- package/dist/audit/audit.d.ts.map +1 -0
- package/dist/audit/audit.js +15 -0
- package/dist/audit/audit.js.map +1 -0
- package/dist/audit/index.d.ts +2 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +2 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/auth/auth.d.ts +43 -0
- package/dist/auth/auth.d.ts.map +1 -0
- package/dist/auth/auth.js +219 -0
- package/dist/auth/auth.js.map +1 -0
- package/dist/auth/index.d.ts +3 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +3 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/login-error.d.ts +8 -0
- package/dist/auth/login-error.d.ts.map +1 -0
- package/dist/auth/login-error.js +18 -0
- package/dist/auth/login-error.js.map +1 -0
- package/dist/auth/session.d.ts +31 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +52 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +6 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/config.d.ts +38 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +40 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/errors/errors.d.ts +56 -0
- package/dist/errors/errors.d.ts.map +1 -0
- package/dist/errors/errors.js +62 -0
- package/dist/errors/errors.js.map +1 -0
- package/dist/errors/index.d.ts +2 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +2 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/format/format.d.ts +5 -0
- package/dist/format/format.d.ts.map +1 -0
- package/dist/format/format.js +14 -0
- package/dist/format/format.js.map +1 -0
- package/dist/format/index.d.ts +2 -0
- package/dist/format/index.d.ts.map +1 -0
- package/dist/format/index.js +2 -0
- package/dist/format/index.js.map +1 -0
- package/dist/identity/identity.d.ts +56 -0
- package/dist/identity/identity.d.ts.map +1 -0
- package/dist/identity/identity.js +93 -0
- package/dist/identity/identity.js.map +1 -0
- package/dist/identity/index.d.ts +2 -0
- package/dist/identity/index.d.ts.map +1 -0
- package/dist/identity/index.js +2 -0
- package/dist/identity/index.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +9 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +22 -0
- package/dist/node.js.map +1 -0
- package/dist/periodo/anio.d.ts +15 -0
- package/dist/periodo/anio.d.ts.map +1 -0
- package/dist/periodo/anio.js +42 -0
- package/dist/periodo/anio.js.map +1 -0
- package/dist/periodo/index.d.ts +3 -0
- package/dist/periodo/index.d.ts.map +1 -0
- package/dist/periodo/index.js +3 -0
- package/dist/periodo/index.js.map +1 -0
- package/dist/periodo/periodo.d.ts +19 -0
- package/dist/periodo/periodo.d.ts.map +1 -0
- package/dist/periodo/periodo.js +55 -0
- package/dist/periodo/periodo.js.map +1 -0
- package/dist/portal/bte-comunas.d.ts +9 -0
- package/dist/portal/bte-comunas.d.ts.map +1 -0
- package/dist/portal/bte-comunas.js +400 -0
- package/dist/portal/bte-comunas.js.map +1 -0
- package/dist/portal/bte-emit.d.ts +70 -0
- package/dist/portal/bte-emit.d.ts.map +1 -0
- package/dist/portal/bte-emit.js +266 -0
- package/dist/portal/bte-emit.js.map +1 -0
- package/dist/portal/bte.d.ts +55 -0
- package/dist/portal/bte.d.ts.map +1 -0
- package/dist/portal/bte.js +215 -0
- package/dist/portal/bte.js.map +1 -0
- package/dist/portal/dte-public.d.ts +36 -0
- package/dist/portal/dte-public.d.ts.map +1 -0
- package/dist/portal/dte-public.js +192 -0
- package/dist/portal/dte-public.js.map +1 -0
- package/dist/portal/f22/declaraciones.d.ts +37 -0
- package/dist/portal/f22/declaraciones.d.ts.map +1 -0
- package/dist/portal/f22/declaraciones.js +86 -0
- package/dist/portal/f22/declaraciones.js.map +1 -0
- package/dist/portal/f22/grid.d.ts +14 -0
- package/dist/portal/f22/grid.d.ts.map +1 -0
- package/dist/portal/f22/grid.js +51 -0
- package/dist/portal/f22/grid.js.map +1 -0
- package/dist/portal/f22/historial.d.ts +34 -0
- package/dist/portal/f22/historial.d.ts.map +1 -0
- package/dist/portal/f22/historial.js +66 -0
- package/dist/portal/f22/historial.js.map +1 -0
- package/dist/portal/f22/index.d.ts +7 -0
- package/dist/portal/f22/index.d.ts.map +1 -0
- package/dist/portal/f22/index.js +11 -0
- package/dist/portal/f22/index.js.map +1 -0
- package/dist/portal/f22/observaciones.d.ts +20 -0
- package/dist/portal/f22/observaciones.d.ts.map +1 -0
- package/dist/portal/f22/observaciones.js +38 -0
- package/dist/portal/f22/observaciones.js.map +1 -0
- package/dist/portal/f22/shared.d.ts +32 -0
- package/dist/portal/f22/shared.d.ts.map +1 -0
- package/dist/portal/f22/shared.js +130 -0
- package/dist/portal/f22/shared.js.map +1 -0
- package/dist/portal/f22-codigos.d.ts +28 -0
- package/dist/portal/f22-codigos.d.ts.map +1 -0
- package/dist/portal/f22-codigos.js +141 -0
- package/dist/portal/f22-codigos.js.map +1 -0
- package/dist/portal/f29-codigos.d.ts +15 -0
- package/dist/portal/f29-codigos.d.ts.map +1 -0
- package/dist/portal/f29-codigos.js +552 -0
- package/dist/portal/f29-codigos.js.map +1 -0
- package/dist/portal/f29.d.ts +62 -0
- package/dist/portal/f29.d.ts.map +1 -0
- package/dist/portal/f29.js +244 -0
- package/dist/portal/f29.js.map +1 -0
- package/dist/portal/rcv.d.ts +62 -0
- package/dist/portal/rcv.d.ts.map +1 -0
- package/dist/portal/rcv.js +252 -0
- package/dist/portal/rcv.js.map +1 -0
- package/dist/portal/representacion.d.ts +24 -0
- package/dist/portal/representacion.d.ts.map +1 -0
- package/dist/portal/representacion.js +153 -0
- package/dist/portal/representacion.js.map +1 -0
- package/dist/rut/index.d.ts +2 -0
- package/dist/rut/index.d.ts.map +1 -0
- package/dist/rut/index.js +2 -0
- package/dist/rut/index.js.map +1 -0
- package/dist/rut/rut.d.ts +16 -0
- package/dist/rut/rut.d.ts.map +1 -0
- package/dist/rut/rut.js +70 -0
- package/dist/rut/rut.js.map +1 -0
- package/dist/seams/index.d.ts +126 -0
- package/dist/seams/index.d.ts.map +1 -0
- package/dist/seams/index.js +6 -0
- package/dist/seams/index.js.map +1 -0
- package/dist/tasks/auth.d.ts +16 -0
- package/dist/tasks/auth.d.ts.map +1 -0
- package/dist/tasks/auth.js +22 -0
- package/dist/tasks/auth.js.map +1 -0
- package/dist/tasks/bte.d.ts +52 -0
- package/dist/tasks/bte.d.ts.map +1 -0
- package/dist/tasks/bte.js +169 -0
- package/dist/tasks/bte.js.map +1 -0
- package/dist/tasks/dte.d.ts +9 -0
- package/dist/tasks/dte.d.ts.map +1 -0
- package/dist/tasks/dte.js +30 -0
- package/dist/tasks/dte.js.map +1 -0
- package/dist/tasks/f22.d.ts +69 -0
- package/dist/tasks/f22.d.ts.map +1 -0
- package/dist/tasks/f22.js +189 -0
- package/dist/tasks/f22.js.map +1 -0
- package/dist/tasks/f29.d.ts +67 -0
- package/dist/tasks/f29.d.ts.map +1 -0
- package/dist/tasks/f29.js +213 -0
- package/dist/tasks/f29.js.map +1 -0
- package/dist/tasks/operate.d.ts +22 -0
- package/dist/tasks/operate.d.ts.map +1 -0
- package/dist/tasks/operate.js +34 -0
- package/dist/tasks/operate.js.map +1 -0
- package/dist/tasks/rcv.d.ts +17 -0
- package/dist/tasks/rcv.d.ts.map +1 -0
- package/dist/tasks/rcv.js +76 -0
- package/dist/tasks/rcv.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
// BHE EMISSION (write) — the `TMBECN_*` form-POST flow on loa.sii.cl (ADR-017). Wire contract
|
|
2
|
+
// captured live 2026-07-02 (own session, a real boleta issued end-to-end); see
|
|
3
|
+
// docs/sii-contract/bte.md § Emisión. NOT a third-party library (ADR-004): every field/endpoint
|
|
4
|
+
// below is first-hand-observed and cited.
|
|
5
|
+
//
|
|
6
|
+
// DISTINCT from the read facade (portal/bte.ts, which reads inline JS maps via goto/evaluate):
|
|
7
|
+
// emission is a sequence of AUTHENTICATED FORM POSTS returning HTML, so it goes through the
|
|
8
|
+
// `PortalSession.requestForm` seam and parses each response's inline `xml_values` from the HTML
|
|
9
|
+
// text (single-quoted `xml_values['k'] = 'v';`, observed). SESSION-KEYED (ADR-005): the emisor is
|
|
10
|
+
// the session principal (`rut_arrastre` = `rut_autentificado`); the task rejects a representing
|
|
11
|
+
// pointer up front.
|
|
12
|
+
//
|
|
13
|
+
// Flow (state machine `presionaBoton()` in loa.sii.cl/IMT/js/TMBECN_Emision.js):
|
|
14
|
+
// 1. GET TMBECN_ValidaTimbrajeContrib.cgi?modo=1 — validate authorized to emit
|
|
15
|
+
// 2. POST TMBECN_PresentaDatosBoleta.cgi — the emisor form (source of emisor context)
|
|
16
|
+
// 3. POST TMBECN_ConfirmaTimbrajeContrib.cgi (33) — PREVIEW: server computes retención/líquido
|
|
17
|
+
// 4. POST TMBECN_BoletaHonorariosElectronica.cgi(24)— ISSUE: assigns cód. de barras (folio)
|
|
18
|
+
// `previewBteEmision` runs 1–3 (never issues); `emitBteEmision` runs 1–4.
|
|
19
|
+
import { HOSTS } from '../config/index.js';
|
|
20
|
+
import { BteError } from '../errors/index.js';
|
|
21
|
+
import { comunaInRegion, comunaName, isRegion } from './bte-comunas.js';
|
|
22
|
+
const CGI = HOSTS.bheCgi;
|
|
23
|
+
const VALIDA_URL = `${CGI}/TMBECN_ValidaTimbrajeContrib.cgi?modo=1`;
|
|
24
|
+
const PRESENTA_URL = `${CGI}/TMBECN_PresentaDatosBoleta.cgi`;
|
|
25
|
+
const CONFIRMA_URL = `${CGI}/TMBECN_ConfirmaTimbrajeContrib.cgi`;
|
|
26
|
+
const EMITE_URL = `${CGI}/TMBECN_BoletaHonorariosElectronica.cgi`;
|
|
27
|
+
/** The PDF is fetched by código de barras (observed). */
|
|
28
|
+
export const pdfUrl = (codBarras) => `${CGI}/TMBCOT_ConsultaBoletaPdf.cgi?txt_codigobarras=${codBarras}`;
|
|
29
|
+
const OPT_RETENCION = {
|
|
30
|
+
RECEPTOR: 'RETRECEPTOR',
|
|
31
|
+
EMISOR: 'RETCONTRIBUYENTE',
|
|
32
|
+
};
|
|
33
|
+
// --- HTML parsing (in-house, no third-party lib — ADR-004) ------------------------
|
|
34
|
+
// The TMBECN_* responses embed state as `xml_values['key'] = 'value';` (single quotes,
|
|
35
|
+
// variable whitespace — observed 2026-07-02). Amounts on the confirm page are wrapped in
|
|
36
|
+
// `formatMiles("<n>", ".")` — we read the raw integer argument.
|
|
37
|
+
/** Read a single `xml_values['key'] = '...'` (or `"..."`) value from the response HTML, or null.
|
|
38
|
+
* SII mixes single- and double-quoted values (e.g. `PorcentajeRetencion` / `iddir1` are double),
|
|
39
|
+
* so accept either; the closing quote must match the opening one. */
|
|
40
|
+
function xmlValue(html, key) {
|
|
41
|
+
const re = new RegExp(`xml_values\\['${key}'\\]\\s*=\\s*(?:'([^']*)'|"([^"]*)")`);
|
|
42
|
+
const m = re.exec(html);
|
|
43
|
+
return m ? (m[1] ?? m[2] ?? null) : null;
|
|
44
|
+
}
|
|
45
|
+
/** Read a `xml_values['key'] = formatMiles("<n>", ...)` integer amount from the confirm page. */
|
|
46
|
+
function xmlMonto(html, key) {
|
|
47
|
+
const re = new RegExp(`xml_values\\['${key}'\\]\\s*=\\s*formatMiles\\("(-?\\d+)"`);
|
|
48
|
+
const m = re.exec(html)?.[1];
|
|
49
|
+
return m === undefined ? null : Number(m);
|
|
50
|
+
}
|
|
51
|
+
/** The emisor's registered domicilio id (`cbo_domicilio` value). The address `<select>` is
|
|
52
|
+
* built client-side by JS from an `arr_direcciones` map, so it is NOT a static `<option>` in the
|
|
53
|
+
* HTML — the ids live in `iddir<n>` entries (observed 2026-07-2: `['iddir1'] = "092726950"`,
|
|
54
|
+
* double-quoted). `iddir1` is the first/default address (the selected one for a single-address
|
|
55
|
+
* emisor; `CantidadDirecciones` counts them). Returns it, or null. */
|
|
56
|
+
function firstDomicilioId(html) {
|
|
57
|
+
return /\['iddir1'\]\s*=\s*["']([^"']+)["']/.exec(html)?.[1] ?? null;
|
|
58
|
+
}
|
|
59
|
+
/** Assert the response is a real emisor/confirm page, not a SII rejection. NOTE: the valid form is
|
|
60
|
+
* full of `alert('…')` VALIDATION calls in its JS, so a generic alert-scan would false-positive —
|
|
61
|
+
* we only detect the explicit AUTHORIZATION-rejection text ("no está autorizado a emitir …") and
|
|
62
|
+
* surface it VERBATIM (ADR-004; the login-wall case is already `SessionExpiredError` from the
|
|
63
|
+
* seam). Otherwise, a page with no emisor form at all (no `xml_values` AND no `formulario`) is a
|
|
64
|
+
* generic hard failure. */
|
|
65
|
+
function assertEmisorForm(html, step) {
|
|
66
|
+
const rejection = /(no (?:est[aá]|se encuentra) autorizad[oa](?: a emitir)?[^<.]{0,120})/i.exec(html)?.[1];
|
|
67
|
+
if (rejection)
|
|
68
|
+
throw new BteError(rejection.replace(/\s+/g, ' ').trim());
|
|
69
|
+
if (!html.includes('xml_values[') && !html.includes('formulario')) {
|
|
70
|
+
throw new BteError(`El SII no entregó el formulario de emisión de BHE (paso: ${step}). ` +
|
|
71
|
+
'Verifica que estés autorizado a emitir boletas de honorarios y que la sesión esté viva.');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const two = (n) => String(n).padStart(2, '0');
|
|
75
|
+
/** Steps 1–2: validate authorization, then POST for the emisor form and read the emisor context
|
|
76
|
+
* (own domicilio / comuna / actividad / server date). `rut` is the session principal.
|
|
77
|
+
* `optRetencion` is the who-withholds choice — the from-scratch flow (modo=1) POSTs it to get
|
|
78
|
+
* the form (observed 2026-07-02: body `{rut_arrastre, dv_arrastre, sin_destinatario, OptTipoRetencion}`;
|
|
79
|
+
* the `prellenar/ult_boleta/boleta` body is the modo=2 prefill path, NOT used here). */
|
|
80
|
+
async function loadEmisorForm(session, rut, optRetencion) {
|
|
81
|
+
// 1. Validate the contribuyente is authorized to emit (liveness + auth). The seam turns a dead
|
|
82
|
+
// session into SessionExpiredError; a non-form body here is a "not authorized" failure.
|
|
83
|
+
await session.requestForm(VALIDA_URL, { method: 'GET' });
|
|
84
|
+
// 2. Request the blank emisor form (from scratch) with the retención choice.
|
|
85
|
+
const res = await session.requestForm(PRESENTA_URL, {
|
|
86
|
+
form: {
|
|
87
|
+
rut_arrastre: String(rut.body),
|
|
88
|
+
dv_arrastre: rut.dv,
|
|
89
|
+
sin_destinatario: 'NO',
|
|
90
|
+
OptTipoRetencion: optRetencion,
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
const html = res.body;
|
|
94
|
+
assertEmisorForm(html, 'presentaDatos');
|
|
95
|
+
const now = new Date(); // fallback only; the form's server date wins when present
|
|
96
|
+
const ctx = {
|
|
97
|
+
diaActual: xmlValue(html, 'dia_actual') ?? two(now.getDate()),
|
|
98
|
+
mesActual: xmlValue(html, 'mes_actual') ?? two(now.getMonth() + 1),
|
|
99
|
+
anioActual: xmlValue(html, 'anio_actual') ?? String(now.getFullYear()),
|
|
100
|
+
cboDomicilio: firstDomicilioId(html) ?? '',
|
|
101
|
+
comuna: xmlValue(html, 'comuna_ctr') ?? '',
|
|
102
|
+
telefono: xmlValue(html, 'fono_ctr') ?? '',
|
|
103
|
+
glosaActividad: xmlValue(html, 'glosa_actividad') ?? '',
|
|
104
|
+
};
|
|
105
|
+
return { html, ctx };
|
|
106
|
+
}
|
|
107
|
+
/** Build the 33-field confirm payload (step 3) from the emisor context + the caller's boleta.
|
|
108
|
+
* Field names + shape observed 2026-07-02. Only the used prestación lines carry values;
|
|
109
|
+
* `cantidad_filas_ingreso` is the form capacity (4). */
|
|
110
|
+
function buildConfirmForm(rut, ctx, input) {
|
|
111
|
+
const mostrar = input.mostrarDetalle !== false;
|
|
112
|
+
const form = {
|
|
113
|
+
dia_actual: ctx.diaActual,
|
|
114
|
+
mes_actual: ctx.mesActual,
|
|
115
|
+
anio_actual: ctx.anioActual,
|
|
116
|
+
rut_arrastre: String(rut.body),
|
|
117
|
+
dv_arrastre: rut.dv,
|
|
118
|
+
sin_destinatario: 'NO',
|
|
119
|
+
OptTipoRetencion: OPT_RETENCION[input.retiene],
|
|
120
|
+
hdn_muestra_glosa: mostrar ? 'si' : 'no',
|
|
121
|
+
hdn_glosa_actividad: ctx.glosaActividad,
|
|
122
|
+
cantidad_filas_ingreso: '4',
|
|
123
|
+
rdb_glosa: mostrar ? 'si' : 'no',
|
|
124
|
+
cbo_domicilio: ctx.cboDomicilio,
|
|
125
|
+
txt_comuna: ctx.comuna,
|
|
126
|
+
txt_telefono: ctx.telefono,
|
|
127
|
+
txt_fax: '',
|
|
128
|
+
cbo_dia_boleta: two(input.fecha.dia),
|
|
129
|
+
cbo_mes_boleta: two(input.fecha.mes),
|
|
130
|
+
cbo_anio_boleta: String(input.fecha.anio),
|
|
131
|
+
txt_rut_destinatario: String(input.receptor.body),
|
|
132
|
+
txt_dv_destinatario: input.receptor.dv,
|
|
133
|
+
txt_nombres_destinatario: input.receptorNombre,
|
|
134
|
+
txt_domicilio_destinatario: input.receptorDomicilio,
|
|
135
|
+
cod_region: String(input.region),
|
|
136
|
+
cbo_comuna: String(input.comuna),
|
|
137
|
+
txt_comuna_destinatario: comunaName(input.region, input.comuna) ?? '',
|
|
138
|
+
};
|
|
139
|
+
for (let i = 1; i <= 4; i++) {
|
|
140
|
+
const linea = input.lineas[i - 1];
|
|
141
|
+
form[`desc_prestacion_${i}`] = linea ? linea.glosa : '';
|
|
142
|
+
form[`valor_prestacion_${i}`] = linea ? String(linea.monto) : '';
|
|
143
|
+
}
|
|
144
|
+
return form;
|
|
145
|
+
}
|
|
146
|
+
/** Parse the preview (confirm page) computed amounts. */
|
|
147
|
+
function parsePreview(html, retiene) {
|
|
148
|
+
return {
|
|
149
|
+
totalHonorarios: xmlMonto(html, 'Monto_Boleta'),
|
|
150
|
+
retencion: xmlMonto(html, 'Monto_Retencion'),
|
|
151
|
+
liquido: xmlMonto(html, 'Monto_Liquido'),
|
|
152
|
+
porcentajeRetencion: xmlValue(html, 'PorcentajeRetencion'),
|
|
153
|
+
retiene,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
/** Steps 1–3: run to the PREVIEW and return the server-computed boleta WITHOUT issuing.
|
|
157
|
+
* Returns the parsed preview + the confirm HTML + the confirm form (so `emitBteEmision` can build
|
|
158
|
+
* the issue payload from the same server state). `session` must be a live PortalSession. */
|
|
159
|
+
async function runToPreview(session, rut, input) {
|
|
160
|
+
const { ctx } = await loadEmisorForm(session, rut, OPT_RETENCION[input.retiene]);
|
|
161
|
+
const confirmForm = buildConfirmForm(rut, ctx, input);
|
|
162
|
+
const res = await session.requestForm(CONFIRMA_URL, { form: confirmForm });
|
|
163
|
+
assertEmisorForm(res.body, 'confirmaTimbraje');
|
|
164
|
+
return { preview: parsePreview(res.body, input.retiene), confirmHtml: res.body, confirmForm };
|
|
165
|
+
}
|
|
166
|
+
/** PREVIEW an emission: run steps 1–3, return the server-computed retención/líquido. NEVER issues.
|
|
167
|
+
* Local validation of the input happens in the task BEFORE any session (fail fast). */
|
|
168
|
+
export async function previewBteEmision(session, rut, input) {
|
|
169
|
+
const { preview } = await runToPreview(session, rut, input);
|
|
170
|
+
return preview;
|
|
171
|
+
}
|
|
172
|
+
/** Build the 24-field issue payload (step 4) from the confirm form + the confirm page's state.
|
|
173
|
+
* Drops the emisor-only + empty-line fields the confirm carried and adds `origen`, the emisor
|
|
174
|
+
* email, and the recomputed `CantidadFilas` (= number of used lines). (observed 2026-07-02) */
|
|
175
|
+
function buildEmitForm(confirmForm, confirmHtml, input) {
|
|
176
|
+
const nLineas = String(input.lineas.length);
|
|
177
|
+
const emit = {
|
|
178
|
+
dia_actual: confirmForm['dia_actual'],
|
|
179
|
+
cantidad_filas_ingreso: nLineas,
|
|
180
|
+
mes_actual: confirmForm['mes_actual'],
|
|
181
|
+
anio_actual: confirmForm['anio_actual'],
|
|
182
|
+
rut_arrastre: confirmForm['rut_arrastre'],
|
|
183
|
+
dv_arrastre: confirmForm['dv_arrastre'],
|
|
184
|
+
OptTipoRetencion: confirmForm['OptTipoRetencion'],
|
|
185
|
+
cbo_domicilio: confirmForm['cbo_domicilio'],
|
|
186
|
+
cbo_dia_boleta: confirmForm['cbo_dia_boleta'],
|
|
187
|
+
cbo_mes_boleta: confirmForm['cbo_mes_boleta'],
|
|
188
|
+
cbo_anio_boleta: confirmForm['cbo_anio_boleta'],
|
|
189
|
+
txt_rut_destinatario: confirmForm['txt_rut_destinatario'],
|
|
190
|
+
txt_dv_destinatario: confirmForm['txt_dv_destinatario'],
|
|
191
|
+
txt_domicilio_destinatario: confirmForm['txt_domicilio_destinatario'],
|
|
192
|
+
txt_comuna_destinatario: confirmForm['txt_comuna_destinatario'],
|
|
193
|
+
hdn_muestra_glosa: confirmForm['hdn_muestra_glosa'],
|
|
194
|
+
hdn_glosa_actividad: confirmForm['hdn_glosa_actividad'],
|
|
195
|
+
sin_destinatario: confirmForm['sin_destinatario'],
|
|
196
|
+
// The emisor's email for the copy — the confirm page carries it; empty if absent.
|
|
197
|
+
txt_email_contribuyente: xmlValue(confirmHtml, 'email_contribuyente') ?? '',
|
|
198
|
+
// `origen=SEPTIMO` marks the "confirmar" (issue) step in SII's flow (observed).
|
|
199
|
+
origen: 'SEPTIMO',
|
|
200
|
+
txt_nombres_destinatario: confirmForm['txt_nombres_destinatario'],
|
|
201
|
+
CantidadFilas: nLineas,
|
|
202
|
+
};
|
|
203
|
+
for (let i = 1; i <= input.lineas.length; i++) {
|
|
204
|
+
emit[`desc_prestacion_${i}`] = confirmForm[`desc_prestacion_${i}`];
|
|
205
|
+
emit[`valor_prestacion_${i}`] = confirmForm[`valor_prestacion_${i}`];
|
|
206
|
+
}
|
|
207
|
+
return emit;
|
|
208
|
+
}
|
|
209
|
+
/** ISSUE the boleta: run steps 1–4. Returns the código de barras (the boleta id) + its PDF URL +
|
|
210
|
+
* the computed amounts. ⚠️ This CREATES a legally-binding document; the task gates it behind an
|
|
211
|
+
* explicit confirmation and NEVER retries. */
|
|
212
|
+
export async function emitBteEmision(session, rut, input) {
|
|
213
|
+
const { preview, confirmHtml, confirmForm } = await runToPreview(session, rut, input);
|
|
214
|
+
const emitForm = buildEmitForm(confirmForm, confirmHtml, input);
|
|
215
|
+
const res = await session.requestForm(EMITE_URL, { form: emitForm });
|
|
216
|
+
const codBarras = xmlValue(res.body, 'cod_barras');
|
|
217
|
+
if (codBarras === null) {
|
|
218
|
+
// No código de barras on the result page → the issue did not complete. Surface it, no retry.
|
|
219
|
+
throw new BteError('El SII no confirmó la emisión de la boleta (no se recibió el código de barras). ' +
|
|
220
|
+
'Revisa en el portal si la boleta quedó emitida antes de reintentar.');
|
|
221
|
+
}
|
|
222
|
+
return { ...preview, codBarras, pdfUrl: pdfUrl(codBarras) };
|
|
223
|
+
}
|
|
224
|
+
// --- Envío por email (optional, post-issue) ---------------------------------------
|
|
225
|
+
const PRESENTA_ENVIO_URL = `${CGI}/TMBECN_PresentaDatosEnvio.cgi`;
|
|
226
|
+
const ENVIAR_URL = `${CGI}/TMBECN_EnviarBoleta.cgi`;
|
|
227
|
+
/** Email the issued boleta's PDF to the receptor (optional, post-issue). Reuses the código de
|
|
228
|
+
* barras. OBSERVATION STATUS (ADR-004): the two POST REQUEST shapes are observed 2026-07-02 —
|
|
229
|
+
* `PresentaDatosEnvio` sends `{origen:'SEPTIMO', txt_codigo_barra}` (event 12), `EnviarBoleta`
|
|
230
|
+
* sends the field NAMES below with `origen:'NOVENO'` (event 14). NOT yet verified: the
|
|
231
|
+
* envío-prep RESPONSE's `xml_values` keys that source `txt_rut_destinatario`/`…dv`/`txt_cod_39`
|
|
232
|
+
* /`txt_descr_comuna`/`txt_nombre_receptor` — that response body was not captured, so those
|
|
233
|
+
* reads are INFERRED and live-validated with the issue path in #62. Until then the email send is
|
|
234
|
+
* best-effort. */
|
|
235
|
+
export async function enviarBteEmision(session, envio) {
|
|
236
|
+
const prep = await session.requestForm(PRESENTA_ENVIO_URL, {
|
|
237
|
+
// origen SEPTIMO observed 2026-07-02 (event 12) — NOT a guess.
|
|
238
|
+
form: { origen: 'SEPTIMO', txt_codigo_barra: envio.codBarras },
|
|
239
|
+
});
|
|
240
|
+
const html = prep.body;
|
|
241
|
+
// The request field names are observed (event 14); the xml_values sources are INFERRED (#62).
|
|
242
|
+
const form = {
|
|
243
|
+
txt_rut_destinatario: xmlValue(html, 'rut_destinatario') ?? '',
|
|
244
|
+
txt_dv_destinatario: xmlValue(html, 'dv_destinatario') ?? '',
|
|
245
|
+
txt_cod_39: xmlValue(html, 'codigo_inferior') ?? '',
|
|
246
|
+
txt_codigo_barra: envio.codBarras,
|
|
247
|
+
txt_descr_comuna: xmlValue(html, 'desc_comuna') ?? '',
|
|
248
|
+
origen: 'NOVENO', // observed 2026-07-02 (event 14)
|
|
249
|
+
txt_nombre_receptor: xmlValue(html, 'nombres_destinatario') ?? '',
|
|
250
|
+
txt_email: envio.email,
|
|
251
|
+
OptMandaEmailOrigen: envio.copiaEmisor === false ? 'NO' : 'SI',
|
|
252
|
+
};
|
|
253
|
+
const res = await session.requestForm(ENVIAR_URL, { form });
|
|
254
|
+
return { enviado: /enviado|exitosamente/i.test(res.body) };
|
|
255
|
+
}
|
|
256
|
+
// --- Local input validation (before any SII call) ---------------------------------
|
|
257
|
+
/** Validate a region/comuna pair against the ported SII table. */
|
|
258
|
+
export function assertRegionComuna(region, comuna) {
|
|
259
|
+
if (!isRegion(region)) {
|
|
260
|
+
throw new BteError(`Región inválida: ${region} (esperado 1–16, código interno del SII).`);
|
|
261
|
+
}
|
|
262
|
+
if (!comunaInRegion(region, comuna)) {
|
|
263
|
+
throw new BteError(`La comuna ${comuna} no pertenece a la región ${region} (usa el código de comuna del SII).`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=bte-emit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bte-emit.js","sourceRoot":"","sources":["../../src/portal/bte-emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { Rut } from '../rut/index.js';
|
|
2
|
+
import type { Periodo } from '../periodo/index.js';
|
|
3
|
+
import type { PortalSession } from '../seams/index.js';
|
|
4
|
+
export type BteSide = 'EMITIDAS' | 'RECIBIDAS';
|
|
5
|
+
/** One boleta de honorarios — curated, **no `raw`** (live BUG-1, 2026-06-30). The per-boleta
|
|
6
|
+
* ROW mixes counterparty data with the taxpayer's OWN identity on BOTH sides (EMITIDAS:
|
|
7
|
+
* `usuemisor` = the emitter = self; RECIBIDAS: a self receptor-name field), plus a counterparty
|
|
8
|
+
* email — and the full own-identity field set is not provably enumerable. So, like F22/F29, BTE
|
|
9
|
+
* exposes NO `raw`: the curated fields below ARE the tax detail a contador reads; the dropped
|
|
10
|
+
* fields are own-identity PII / counterparty email / low-value metadata (barcode, comuna). The
|
|
11
|
+
* report META's `nombre_contribuyente`/`rut_arrastre` are likewise never read. Montos are parsed
|
|
12
|
+
* from SII's es-CL dot-formatted strings. (CONVENTIONS: drop `raw` when non-curated data is PII.) */
|
|
13
|
+
export interface BteBoleta {
|
|
14
|
+
readonly folio: number | null;
|
|
15
|
+
/** Emisión/boleta date, `DD/MM/YYYY` verbatim (ADR-004). */
|
|
16
|
+
readonly fecha: string | null;
|
|
17
|
+
/** Counterparty: receptor (emitidas) or emisor (recibidas), canonical RUT. */
|
|
18
|
+
readonly contraparteRut: string | null;
|
|
19
|
+
readonly contraparteNombre: string | null;
|
|
20
|
+
readonly totalHonorarios: number | null;
|
|
21
|
+
readonly honorariosLiquidos: number | null;
|
|
22
|
+
readonly retencionEmisor: number | null;
|
|
23
|
+
readonly retencionReceptor: number | null;
|
|
24
|
+
/** `N` → `VIG` (vigente) / `S` → `ANUL` (anulada). */
|
|
25
|
+
readonly estado: 'VIG' | 'ANUL' | null;
|
|
26
|
+
readonly fechaAnulacion: string | null;
|
|
27
|
+
readonly socProfesional: boolean | null;
|
|
28
|
+
}
|
|
29
|
+
/** Per-month aggregates from the report META (`xml_values`). */
|
|
30
|
+
export interface BteTotales {
|
|
31
|
+
readonly honorarios: number | null;
|
|
32
|
+
readonly retencionEmisor: number | null;
|
|
33
|
+
readonly retencionReceptor: number | null;
|
|
34
|
+
readonly liquido: number | null;
|
|
35
|
+
}
|
|
36
|
+
export interface BteMensual {
|
|
37
|
+
/** Session-principal RUT these boletas belong to (canonical). */
|
|
38
|
+
readonly rut: string;
|
|
39
|
+
readonly periodo: string;
|
|
40
|
+
readonly side: BteSide;
|
|
41
|
+
readonly totalBoletas: number | null;
|
|
42
|
+
readonly totales: BteTotales;
|
|
43
|
+
readonly boletas: readonly BteBoleta[];
|
|
44
|
+
}
|
|
45
|
+
/** Monthly BHE detail for one (período, side), session-keyed. Walks `pagina_solicitada` from 0,
|
|
46
|
+
* paced via `pace` (ADR-004), de-duping by folio+counterparty; stops at `total_boletas`, a
|
|
47
|
+
* no-new-rows page, or `MAX_PAGINAS`. An empty month is a clean 0-boleta result, NOT an error;
|
|
48
|
+
* a non-report / cross-RUT page (no `xml_values`) on page 0 is a `BteError`. `session` must be a
|
|
49
|
+
* live PortalSession acquired via `withSession`. */
|
|
50
|
+
export declare function fetchBteMensual(session: PortalSession, params: {
|
|
51
|
+
rut: Rut;
|
|
52
|
+
periodo: Periodo;
|
|
53
|
+
side: BteSide;
|
|
54
|
+
}, pace: () => Promise<void>): Promise<BteMensual>;
|
|
55
|
+
//# sourceMappingURL=bte.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bte.d.ts","sourceRoot":"","sources":["../../src/portal/bte.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC;AAa/C;;;;;;;sGAOsG;AACtG,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;CACzC;AAED,gEAAgE;AAChE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,CAAC;CACxC;AAgJD;;;;qDAIqD;AACrD,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE;IAAE,GAAG,EAAE,GAAG,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,EACrD,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACxB,OAAO,CAAC,UAAU,CAAC,CAmDrB"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
// BTE/BHE — Boletas de Honorarios Electrónicas. Typed facade over the inline JS maps the
|
|
2
|
+
// legacy `loa.sii.cl/cgi_IMT/` CGIs fill client-side. Ported from the proven Python sii-cli
|
|
3
|
+
// (portal/bte.py, live-captured #62) and TS-live-validated 2026-06-30 (#20); the wire
|
|
4
|
+
// contract is first-hand-observed, NOT a third-party library (ADR-004). See
|
|
5
|
+
// docs/sii-contract/bte.md.
|
|
6
|
+
//
|
|
7
|
+
// DISTINCT from the SDI-JSON facades (RCV/F22/F29): these CGIs serve an HTML skeleton and
|
|
8
|
+
// fill their tables from global JS maps, so we read those maps through the browser
|
|
9
|
+
// primitives — `PortalSession.goto` (the .sii.cl session cookie SSO-carries to loa.sii.cl —
|
|
10
|
+
// observed 2026-06-30) + `PortalSession.evaluate` — NOT `requestJson`. Do NOT scrape the DOM:
|
|
11
|
+
// after domcontentloaded the cells still hold the filling JS (CONVENTIONS: prefer inline data).
|
|
12
|
+
//
|
|
13
|
+
// SESSION-KEYED (ADR-005): `rut_arrastre` is keyed to the session PRINCIPAL — a represented
|
|
14
|
+
// RUT does NOT reach the empresa's data (confirmed live #62). The task reads self only.
|
|
15
|
+
import { HOSTS, LOGIN_HOST } from '../config/index.js';
|
|
16
|
+
import { BteError, SessionExpiredError } from '../errors/index.js';
|
|
17
|
+
import { Rut } from '../rut/index.js';
|
|
18
|
+
// Monthly-detail CGIs (observed 2026-06-30). Emitidas (emisor) = `…Bhe`; recibidas
|
|
19
|
+
// (receptor) = `…BheRec`. All reads are GET; the RUT travels split in the query string.
|
|
20
|
+
const MENSUAL_CGI = {
|
|
21
|
+
EMITIDAS: 'TMBCOC_InformeMensualBhe.cgi',
|
|
22
|
+
RECIBIDAS: 'TMBCOC_InformeMensualBheRec.cgi',
|
|
23
|
+
};
|
|
24
|
+
// A non-advancing-loop backstop. The total_boletas target + the no-new-rows guard end
|
|
25
|
+
// pagination first in practice; this only caps a pathological page sequence (ADR-004).
|
|
26
|
+
const MAX_PAGINAS = 100;
|
|
27
|
+
// --- Alias-tolerant row fields (observed name first; emitidas / recibidas differ) --------
|
|
28
|
+
const ALIASES = {
|
|
29
|
+
folio: ['nroboleta'],
|
|
30
|
+
fecha: ['fechaemision', 'fecha_boleta'], // emitidas: fechaemision; recibidas: fecha_boleta
|
|
31
|
+
rutDigits: ['rutreceptor', 'rutemisor'],
|
|
32
|
+
dv: ['dvreceptor', 'dvemisor'],
|
|
33
|
+
nombre: ['nombrereceptor', 'nombre_emisor'],
|
|
34
|
+
totalHonorarios: ['totalhonorarios'],
|
|
35
|
+
honorariosLiquidos: ['honorariosliquidos'],
|
|
36
|
+
retencionEmisor: ['retencion_emisor'],
|
|
37
|
+
retencionReceptor: ['retencion_receptor'],
|
|
38
|
+
estado: ['estado'],
|
|
39
|
+
fechaAnulacion: ['fechaanulacion'],
|
|
40
|
+
socProfesional: ['es_soc_profesional'],
|
|
41
|
+
};
|
|
42
|
+
const aliasGet = (row, aliases) => {
|
|
43
|
+
for (const key of aliases) {
|
|
44
|
+
const v = row[key];
|
|
45
|
+
if (v !== undefined && v !== null)
|
|
46
|
+
return v;
|
|
47
|
+
}
|
|
48
|
+
return undefined;
|
|
49
|
+
};
|
|
50
|
+
const asStr = (v) => {
|
|
51
|
+
if (v === null || v === undefined)
|
|
52
|
+
return null;
|
|
53
|
+
const s = String(v).trim();
|
|
54
|
+
return s === '' ? null : s;
|
|
55
|
+
};
|
|
56
|
+
/** Parse a Chilean integer monto: row montos are dot-formatted (`"1.300.000"`), meta sums are
|
|
57
|
+
* plain (`"1300000"`) — strip thousands separators either way; non-numeric → null. */
|
|
58
|
+
const asMonto = (v) => {
|
|
59
|
+
const s = asStr(v);
|
|
60
|
+
if (s === null)
|
|
61
|
+
return null;
|
|
62
|
+
const digits = s.replace(/[.\s]/g, '').replace(/,/g, '');
|
|
63
|
+
if (!/^-?\d+$/.test(digits))
|
|
64
|
+
return null;
|
|
65
|
+
return Number(digits);
|
|
66
|
+
};
|
|
67
|
+
const estadoLabel = (v) => {
|
|
68
|
+
const s = asStr(v)?.toUpperCase();
|
|
69
|
+
if (s === 'N')
|
|
70
|
+
return 'VIG';
|
|
71
|
+
if (s === 'S')
|
|
72
|
+
return 'ANUL';
|
|
73
|
+
return null;
|
|
74
|
+
};
|
|
75
|
+
const boolSiNo = (v) => {
|
|
76
|
+
const s = asStr(v)?.toUpperCase();
|
|
77
|
+
if (s === 'SI' || s === 'S')
|
|
78
|
+
return true;
|
|
79
|
+
if (s === 'NO' || s === 'N')
|
|
80
|
+
return false;
|
|
81
|
+
return null;
|
|
82
|
+
};
|
|
83
|
+
const canonicalRut = (digits, dv) => {
|
|
84
|
+
if (digits === undefined || digits === null || dv === undefined || dv === null)
|
|
85
|
+
return null;
|
|
86
|
+
return Rut.tryParse(`${String(digits)}-${String(dv).trim()}`)?.canonical ?? null;
|
|
87
|
+
};
|
|
88
|
+
// Read an inline global JS map. The maps are JS Arrays with STRING keys, which a bare
|
|
89
|
+
// `evaluate("xml_values")` / JSON.stringify would drop — `Object.fromEntries(Object.entries())`
|
|
90
|
+
// preserves them (observed 2026-06-30). An undefined var (non-report page) → null.
|
|
91
|
+
const evalExpr = (v) => `(function(){ return typeof ${v} !== 'undefined' && ${v} !== null ` +
|
|
92
|
+
`? Object.fromEntries(Object.entries(${v})) : null; })()`;
|
|
93
|
+
function monthlyUrl(side, rut, periodo, pagina) {
|
|
94
|
+
const anio = String(periodo.year).padStart(4, '0');
|
|
95
|
+
const mes = String(periodo.month).padStart(2, '0');
|
|
96
|
+
return (`${HOSTS.bheCgi}/${MENSUAL_CGI[side]}?cbanoinformemensual=${anio}` +
|
|
97
|
+
`&cbmesinformemensual=${mes}&rut_arrastre=${String(rut.body)}&dv_arrastre=${rut.dv}` +
|
|
98
|
+
`&pagina_solicitada=${pagina}`);
|
|
99
|
+
}
|
|
100
|
+
/** Split a flat `arr_informe_mensual` map (`<campo>_<i>`) into per-row records keyed by the
|
|
101
|
+
* 1-based row index, ascending. Each record is `{ <campo>: value }` — the input to
|
|
102
|
+
* `projectBoleta` (NOT surfaced; BTE exposes no `raw`). */
|
|
103
|
+
function rowsByIndex(arr) {
|
|
104
|
+
const byIndex = new Map();
|
|
105
|
+
for (const [key, value] of Object.entries(arr)) {
|
|
106
|
+
const m = /^(.+)_(\d+)$/.exec(key);
|
|
107
|
+
if (!m)
|
|
108
|
+
continue;
|
|
109
|
+
const field = m[1];
|
|
110
|
+
const i = Number(m[2]);
|
|
111
|
+
let row = byIndex.get(i);
|
|
112
|
+
if (!row) {
|
|
113
|
+
row = {};
|
|
114
|
+
byIndex.set(i, row);
|
|
115
|
+
}
|
|
116
|
+
row[field] = value;
|
|
117
|
+
}
|
|
118
|
+
return [...byIndex.entries()].sort((a, b) => a[0] - b[0]).map(([, row]) => row);
|
|
119
|
+
}
|
|
120
|
+
// Curate ONLY the named tax fields — no `raw` (BUG-1): the row mixes own-identity PII
|
|
121
|
+
// (EMITIDAS `usuemisor`, RECIBIDAS self receptor-name) with counterparty data, so we read the
|
|
122
|
+
// known tax fields by alias and surface NOTHING else (cf. F22's no-raw posture).
|
|
123
|
+
function projectBoleta(row) {
|
|
124
|
+
return {
|
|
125
|
+
folio: asMonto(aliasGet(row, ALIASES.folio)),
|
|
126
|
+
fecha: asStr(aliasGet(row, ALIASES.fecha)),
|
|
127
|
+
contraparteRut: canonicalRut(aliasGet(row, ALIASES.rutDigits), aliasGet(row, ALIASES.dv)),
|
|
128
|
+
contraparteNombre: asStr(aliasGet(row, ALIASES.nombre)),
|
|
129
|
+
totalHonorarios: asMonto(aliasGet(row, ALIASES.totalHonorarios)),
|
|
130
|
+
honorariosLiquidos: asMonto(aliasGet(row, ALIASES.honorariosLiquidos)),
|
|
131
|
+
retencionEmisor: asMonto(aliasGet(row, ALIASES.retencionEmisor)),
|
|
132
|
+
retencionReceptor: asMonto(aliasGet(row, ALIASES.retencionReceptor)),
|
|
133
|
+
estado: estadoLabel(aliasGet(row, ALIASES.estado)),
|
|
134
|
+
fechaAnulacion: asStr(aliasGet(row, ALIASES.fechaAnulacion)),
|
|
135
|
+
socProfesional: boolSiNo(aliasGet(row, ALIASES.socProfesional)),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function parseTotales(meta) {
|
|
139
|
+
return {
|
|
140
|
+
honorarios: asMonto(meta['suma_honorarios']),
|
|
141
|
+
retencionEmisor: asMonto(meta['suma_retencion_emisor']),
|
|
142
|
+
retencionReceptor: asMonto(meta['suma_retencion_receptor']),
|
|
143
|
+
liquido: asMonto(meta['suma_liquido']),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/** Navigate to a report CGI and read its inline maps. A GET that lands back on the login host
|
|
147
|
+
* means the cookies-only session is dead → `SessionExpiredError` (actionable, like the SDI
|
|
148
|
+
* seam); this first `goto` IS the liveness test (withSession does not pre-probe). */
|
|
149
|
+
async function fetchPage(session, url) {
|
|
150
|
+
const landed = await session.goto(url);
|
|
151
|
+
if (new URL(landed).hostname === LOGIN_HOST) {
|
|
152
|
+
throw new SessionExpiredError('La sesión expiró. Ejecuta `sii auth login`.');
|
|
153
|
+
}
|
|
154
|
+
const meta = await session.evaluate(evalExpr('xml_values'));
|
|
155
|
+
const rows = await session.evaluate(evalExpr('arr_informe_mensual'));
|
|
156
|
+
return { meta, rows };
|
|
157
|
+
}
|
|
158
|
+
/** Monthly BHE detail for one (período, side), session-keyed. Walks `pagina_solicitada` from 0,
|
|
159
|
+
* paced via `pace` (ADR-004), de-duping by folio+counterparty; stops at `total_boletas`, a
|
|
160
|
+
* no-new-rows page, or `MAX_PAGINAS`. An empty month is a clean 0-boleta result, NOT an error;
|
|
161
|
+
* a non-report / cross-RUT page (no `xml_values`) on page 0 is a `BteError`. `session` must be a
|
|
162
|
+
* live PortalSession acquired via `withSession`. */
|
|
163
|
+
export async function fetchBteMensual(session, params, pace) {
|
|
164
|
+
const { rut, periodo, side } = params;
|
|
165
|
+
const boletas = [];
|
|
166
|
+
const seen = new Set();
|
|
167
|
+
let totalBoletas = null;
|
|
168
|
+
let totales = {
|
|
169
|
+
honorarios: null,
|
|
170
|
+
retencionEmisor: null,
|
|
171
|
+
retencionReceptor: null,
|
|
172
|
+
liquido: null,
|
|
173
|
+
};
|
|
174
|
+
for (let pagina = 0; pagina < MAX_PAGINAS; pagina++) {
|
|
175
|
+
if (pagina > 0)
|
|
176
|
+
await pace(); // pace each extra page (ADR-004); the task binds the rps
|
|
177
|
+
const { meta, rows } = await fetchPage(session, monthlyUrl(side, rut, periodo, pagina));
|
|
178
|
+
if (meta === null) {
|
|
179
|
+
// No report on this page. On page 0 the (RUT, período) has no informe — a non-report /
|
|
180
|
+
// cross-RUT page (BteError, ADR-004). On a later page it just means we walked past the end.
|
|
181
|
+
if (pagina === 0) {
|
|
182
|
+
throw new BteError(`El SII no entregó el informe de boletas de honorarios para ${periodo.formatted} ` +
|
|
183
|
+
`(${side.toLowerCase()}). Verifica la sesión y el período.`);
|
|
184
|
+
}
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
if (pagina === 0) {
|
|
188
|
+
totalBoletas = asMonto(meta['total_boletas']);
|
|
189
|
+
totales = parseTotales(meta);
|
|
190
|
+
}
|
|
191
|
+
let added = 0;
|
|
192
|
+
for (const row of rows === null ? [] : rowsByIndex(rows)) {
|
|
193
|
+
const boleta = projectBoleta(row);
|
|
194
|
+
const key = `${boleta.folio ?? '?'}|${boleta.contraparteRut ?? '?'}`;
|
|
195
|
+
if (seen.has(key))
|
|
196
|
+
continue;
|
|
197
|
+
seen.add(key);
|
|
198
|
+
boletas.push(boleta);
|
|
199
|
+
added++;
|
|
200
|
+
}
|
|
201
|
+
if (totalBoletas !== null && boletas.length >= totalBoletas)
|
|
202
|
+
break;
|
|
203
|
+
if (added === 0)
|
|
204
|
+
break; // no new rows → end (also the empty-month exit)
|
|
205
|
+
}
|
|
206
|
+
return {
|
|
207
|
+
rut: rut.canonical,
|
|
208
|
+
periodo: periodo.formatted,
|
|
209
|
+
side,
|
|
210
|
+
totalBoletas,
|
|
211
|
+
totales,
|
|
212
|
+
boletas,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=bte.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bte.js","sourceRoot":"","sources":["../../src/portal/bte.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Rut } from '../rut/index.js';
|
|
2
|
+
import type { PortalDriver } from '../seams/index.js';
|
|
3
|
+
/** One authorized DTE type row. `fecha*` keep SII's `DD-MM-YYYY` string verbatim
|
|
4
|
+
* (ADR-004 — pass SII's data through unchanged); `fechaDesautorizacion` is null while
|
|
5
|
+
* the type is currently authorized (empty cell). */
|
|
6
|
+
export interface DteAutorizado {
|
|
7
|
+
readonly codigo: number;
|
|
8
|
+
readonly descripcion: string | null;
|
|
9
|
+
readonly fechaAutorizacion: string | null;
|
|
10
|
+
readonly fechaDesautorizacion: string | null;
|
|
11
|
+
}
|
|
12
|
+
/** Authorized-DTE-emitter report for one subject RUT (public consulta). `autorizado` is
|
|
13
|
+
* true when the RUT is a registered DTE emisor (header + docs grid present); false when
|
|
14
|
+
* SII answered with the "no corresponde" message — then `mensaje` holds that verbatim
|
|
15
|
+
* sentence and `documentos` is empty. No `raw`: the HTML carries exactly these fields
|
|
16
|
+
* (ADR-004 curated+raw is for fat JSON rows, not this table). */
|
|
17
|
+
export interface DteAutorizados {
|
|
18
|
+
/** Subject RUT queried (canonical, e.g. "20000042-0"). */
|
|
19
|
+
readonly rut: string;
|
|
20
|
+
readonly autorizado: boolean;
|
|
21
|
+
readonly razonSocial: string | null;
|
|
22
|
+
readonly nResolucion: string | null;
|
|
23
|
+
readonly fechaResolucion: string | null;
|
|
24
|
+
readonly direccionRegional: string | null;
|
|
25
|
+
readonly documentos: readonly DteAutorizado[];
|
|
26
|
+
/** SII's verbatim "no autorizado" sentence; null on the authorized path. */
|
|
27
|
+
readonly mensaje: string | null;
|
|
28
|
+
}
|
|
29
|
+
/** List the DTE types a contribuyente is authorized to emit (public, login-free).
|
|
30
|
+
* Hits the palena consulta CGI with no session, for ANY RUT incl. counterparties
|
|
31
|
+
* (ADR-014). Returns the resolution header + authorized-document grid, or a clean
|
|
32
|
+
* negative (`autorizado: false` + SII's verbatim `mensaje`) when the RUT is not a
|
|
33
|
+
* registered DTE emisor. Throws `DteError` on a network/CGI failure, a non-200, or an
|
|
34
|
+
* unrecognizable body. `driver` is the seam — NO `PortalSession` (it is session-less). */
|
|
35
|
+
export declare function fetchDteAutorizados(driver: PortalDriver, rut: Rut): Promise<DteAutorizados>;
|
|
36
|
+
//# sourceMappingURL=dte-public.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dte-public.d.ts","sourceRoot":"","sources":["../../src/portal/dte-public.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,mBAAmB,CAAC;AAmBtE;;qDAEqD;AACrD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9C;AAED;;;;kEAIkE;AAClE,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IAC9C,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAkJD;;;;;2FAK2F;AAC3F,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,cAAc,CAAC,CAmBjG"}
|