@devlas/dte-sii 2.5.4 → 2.5.6
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/ConsumoFolio.js +3 -3
- package/EnviadorSII.js +51 -2
- package/Envio.js +7 -6
- package/SiiCertificacion.js +6 -3
- package/SiiPortalAuth.js +30 -22
- package/SiiSession.js +2 -2
- package/cert/ConfigLoader.js +11 -13
- package/package.json +1 -1
- package/utils/emisor.js +4 -2
package/ConsumoFolio.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
|
-
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
1
|
+
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
|
+
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
3
3
|
/**
|
|
4
4
|
* ConsumoFolio.js
|
|
5
5
|
*
|
|
@@ -224,7 +224,7 @@ class ConsumoFolio {
|
|
|
224
224
|
|
|
225
225
|
// Construir XML SIN indentación para C14N consistente
|
|
226
226
|
const schemaLoc = 'http://www.sii.cl/SiiDte ConsumoFolio_v10.xsd';
|
|
227
|
-
const xmlSinFirma = `<?xml version="1.0" encoding="
|
|
227
|
+
const xmlSinFirma = `<?xml version="1.0" encoding="UTF-8"?>
|
|
228
228
|
<ConsumoFolios xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="${schemaLoc}" version="1.0"><DocumentoConsumoFolios ID="${this.id}"><Caratula version="1.0"><RutEmisor>${this.caratula.RutEmisor}</RutEmisor><RutEnvia>${this.caratula.RutEnvia}</RutEnvia><FchResol>${this.caratula.FchResol}</FchResol><NroResol>${this.caratula.NroResol}</NroResol><FchInicio>${this.caratula.FchInicio}</FchInicio><FchFinal>${this.caratula.FchFinal}</FchFinal><SecEnvio>${this.caratula.SecEnvio}</SecEnvio><TmstFirmaEnv>${this.caratula.TmstFirmaEnv}</TmstFirmaEnv></Caratula>${resumenXml}</DocumentoConsumoFolios></ConsumoFolios>`;
|
|
229
229
|
|
|
230
230
|
// Firmar el documento
|
package/EnviadorSII.js
CHANGED
|
@@ -396,7 +396,7 @@ class EnviadorSII {
|
|
|
396
396
|
|
|
397
397
|
log.log('SignedInfo para firmar (length):', signedInfoParaFirmar.length);
|
|
398
398
|
|
|
399
|
-
const xmlFirmado = `<?xml version="1.0" encoding="
|
|
399
|
+
const xmlFirmado = `<?xml version="1.0" encoding="UTF-8"?>
|
|
400
400
|
<getToken><item><Semilla>${semilla}</Semilla></item><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#"><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/><DigestValue>${digestValue}</DigestValue></Reference></SignedInfo><SignatureValue>${signatureValue}</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>${modulus}</Modulus><Exponent>${exponent}</Exponent></RSAKeyValue></KeyValue><X509Data><X509Certificate>${cert}</X509Certificate></X509Data></KeyInfo></Signature></getToken>`;
|
|
401
401
|
|
|
402
402
|
log.log('DigestValue:', digestValue);
|
|
@@ -528,7 +528,7 @@ class EnviadorSII {
|
|
|
528
528
|
const url = this.urls[this.ambiente].envio;
|
|
529
529
|
|
|
530
530
|
if (!xml.startsWith('<?xml')) {
|
|
531
|
-
xml = '<?xml version="1.0" encoding="
|
|
531
|
+
xml = '<?xml version="1.0" encoding="UTF-8"?>\n' + xml;
|
|
532
532
|
}
|
|
533
533
|
|
|
534
534
|
const [rutSenderStr, dvSender] = rutEnvia.split('-');
|
|
@@ -873,6 +873,55 @@ class EnviadorSII {
|
|
|
873
873
|
mensaje = `❌ Rechazado: ${glosa || 'Error en documento'}`;
|
|
874
874
|
esRechazado = true;
|
|
875
875
|
break;
|
|
876
|
+
// Códigos numéricos del SII (QueryEstUp)
|
|
877
|
+
case '-11':
|
|
878
|
+
mensaje = `⏳ Pendiente de proceso - El sobre aún no ha sido revisado por el SII`;
|
|
879
|
+
esIntermedio = true;
|
|
880
|
+
break;
|
|
881
|
+
case '-10':
|
|
882
|
+
mensaje = `❌ Token inválido o no autorizado`;
|
|
883
|
+
esRechazado = true;
|
|
884
|
+
break;
|
|
885
|
+
case '-9':
|
|
886
|
+
mensaje = `❌ Firma del envío inválida - ${glosa || 'Verificar certificado'}`;
|
|
887
|
+
esRechazado = true;
|
|
888
|
+
break;
|
|
889
|
+
case '-8':
|
|
890
|
+
mensaje = `❌ El envío no pertenece al firmante`;
|
|
891
|
+
esRechazado = true;
|
|
892
|
+
break;
|
|
893
|
+
case '-7':
|
|
894
|
+
mensaje = `❌ Error en datos del receptor - ${glosa || 'Verificar RUT receptor'}`;
|
|
895
|
+
esRechazado = true;
|
|
896
|
+
break;
|
|
897
|
+
case '-6':
|
|
898
|
+
mensaje = `❌ Error en datos del emisor - ${glosa || 'Verificar RUT emisor'}`;
|
|
899
|
+
esRechazado = true;
|
|
900
|
+
break;
|
|
901
|
+
case '-5':
|
|
902
|
+
mensaje = `❌ Error de certificación - ${glosa || 'Verificar proceso de certificación'}`;
|
|
903
|
+
esRechazado = true;
|
|
904
|
+
break;
|
|
905
|
+
case '-4':
|
|
906
|
+
mensaje = `❌ Envío fuera de plazo - ${glosa || 'El plazo de envío ha vencido'}`;
|
|
907
|
+
esRechazado = true;
|
|
908
|
+
break;
|
|
909
|
+
case '-3':
|
|
910
|
+
mensaje = `❌ RUT emisor no coincide con el certificado`;
|
|
911
|
+
esRechazado = true;
|
|
912
|
+
break;
|
|
913
|
+
case '-2':
|
|
914
|
+
mensaje = `❌ Error de firma en el sobre - ${glosa || 'Verificar firma digital'}`;
|
|
915
|
+
esRechazado = true;
|
|
916
|
+
break;
|
|
917
|
+
case '-1':
|
|
918
|
+
mensaje = `❌ Error de schema XML - ${glosa || 'El XML no cumple el XSD del SII'}`;
|
|
919
|
+
esRechazado = true;
|
|
920
|
+
break;
|
|
921
|
+
case '0':
|
|
922
|
+
mensaje = `⏳ Enviado al SII, pendiente de validación`;
|
|
923
|
+
esIntermedio = true;
|
|
924
|
+
break;
|
|
876
925
|
default:
|
|
877
926
|
mensaje = `Estado: ${estado} - ${glosa || 'Sin descripción'}`;
|
|
878
927
|
}
|
package/Envio.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
|
-
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
1
|
+
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
|
+
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
3
3
|
/**
|
|
4
4
|
* Clases de Envío (EnvioBOLETA, EnvioDTE)
|
|
5
5
|
*
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const Signer = require('./Signer');
|
|
10
|
+
const { formatRutSii } = require('./utils/rut');
|
|
10
11
|
|
|
11
12
|
// ============================================
|
|
12
13
|
// CLASE BASE ENVIO
|
|
@@ -106,8 +107,8 @@ class EnvioBOLETA extends EnvioBase {
|
|
|
106
107
|
const timestamp = caratula.TmstFirmaEnv || this._generateTimestamp();
|
|
107
108
|
|
|
108
109
|
this.caratula = {
|
|
109
|
-
RutEmisor: caratula.RutEmisor,
|
|
110
|
-
RutEnvia: caratula.RutEnvia,
|
|
110
|
+
RutEmisor: formatRutSii(caratula.RutEmisor), // sin puntos, maxLength=10
|
|
111
|
+
RutEnvia: formatRutSii(caratula.RutEnvia), // sin puntos
|
|
111
112
|
RutReceptor: '60803000-K', // Siempre SII para boletas
|
|
112
113
|
FchResol: _normDateXsd(caratula.FchResol),
|
|
113
114
|
NroResol: caratula.NroResol,
|
|
@@ -126,7 +127,7 @@ class EnvioBOLETA extends EnvioBase {
|
|
|
126
127
|
.map(s => `<SubTotDTE><TpoDTE>${s.TpoDTE}</TpoDTE><NroDTE>${s.NroDTE}</NroDTE></SubTotDTE>`)
|
|
127
128
|
.join('');
|
|
128
129
|
|
|
129
|
-
const xmlBase = `<?xml version="1.0" encoding="
|
|
130
|
+
const xmlBase = `<?xml version="1.0" encoding="UTF-8"?>
|
|
130
131
|
<EnvioBOLETA xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioBOLETA_v11.xsd" version="1.0"><SetDTE ID="${this.setId}"><Caratula version="1.0"><RutEmisor>${this.caratula.RutEmisor}</RutEmisor><RutEnvia>${this.caratula.RutEnvia}</RutEnvia><RutReceptor>${this.caratula.RutReceptor}</RutReceptor><FchResol>${this.caratula.FchResol}</FchResol><NroResol>${this.caratula.NroResol}</NroResol><TmstFirmaEnv>${this.caratula.TmstFirmaEnv}</TmstFirmaEnv>${subTotDTEs}</Caratula><!-- DTES_PLACEHOLDER --></SetDTE></EnvioBOLETA>`;
|
|
131
132
|
|
|
132
133
|
const dtesXml = this._extractDTEsXml();
|
|
@@ -180,7 +181,7 @@ class EnvioDTE extends EnvioBase {
|
|
|
180
181
|
.map(s => `<SubTotDTE><TpoDTE>${s.TpoDTE}</TpoDTE><NroDTE>${s.NroDTE}</NroDTE></SubTotDTE>`)
|
|
181
182
|
.join('');
|
|
182
183
|
|
|
183
|
-
const xmlBase = `<?xml version="1.0" encoding="
|
|
184
|
+
const xmlBase = `<?xml version="1.0" encoding="UTF-8"?>
|
|
184
185
|
<EnvioDTE xmlns="http://www.sii.cl/SiiDte" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sii.cl/SiiDte EnvioDTE_v10.xsd" version="1.0"><SetDTE ID="${this.setId}"><Caratula version="1.0"><RutEmisor>${this.caratula.RutEmisor}</RutEmisor><RutEnvia>${this.caratula.RutEnvia}</RutEnvia><RutReceptor>${this.caratula.RutReceptor}</RutReceptor><FchResol>${this.caratula.FchResol}</FchResol><NroResol>${this.caratula.NroResol}</NroResol><TmstFirmaEnv>${this.caratula.TmstFirmaEnv}</TmstFirmaEnv>${subTotDTEs}</Caratula><!-- DTES_PLACEHOLDER --></SetDTE></EnvioDTE>`;
|
|
185
186
|
|
|
186
187
|
const dtesXml = this._extractDTEsXml();
|
package/SiiCertificacion.js
CHANGED
|
@@ -221,10 +221,13 @@ class SiiCertificacion {
|
|
|
221
221
|
TOTAL: totalMatch ? totalMatch[1] : '15',
|
|
222
222
|
};
|
|
223
223
|
|
|
224
|
-
// Marcar
|
|
225
|
-
//
|
|
224
|
+
// Marcar solo los sets opcionales configurados (DEFAULT_SETS_OPCIONALES)
|
|
225
|
+
// No marcar todos para evitar incluir Exportación, Liquidación, etc.
|
|
226
|
+
const requestedSets = options.setsOpcionales || {};
|
|
226
227
|
for (const set of setsOpcionales) {
|
|
227
|
-
|
|
228
|
+
if (requestedSets[set.id]) {
|
|
229
|
+
formData[set.id] = 'S';
|
|
230
|
+
}
|
|
228
231
|
}
|
|
229
232
|
// SET01 (básico) siempre incluido aunque no aparezca como checkbox opcional
|
|
230
233
|
formData.SET01 = 'S';
|
package/SiiPortalAuth.js
CHANGED
|
@@ -143,7 +143,9 @@ class SiiPortalAuth {
|
|
|
143
143
|
res.on('end', () => {
|
|
144
144
|
const buf = Buffer.concat(chunks);
|
|
145
145
|
const ct = res.headers['content-type'] || '';
|
|
146
|
-
|
|
146
|
+
// Todos los hosts *.sii.cl sirven páginas ISO-8859-1; a veces no incluyen charset en Content-Type.
|
|
147
|
+
const isSiiHost = url.hostname.endsWith('.sii.cl');
|
|
148
|
+
const encoding = (isSiiHost || /iso-8859|latin-1|windows-1252/i.test(ct)) ? 'latin1' : 'utf8';
|
|
147
149
|
resolve({ status: res.statusCode, headers: res.headers, body: buf.toString(encoding), cookieJar });
|
|
148
150
|
});
|
|
149
151
|
});
|
|
@@ -228,7 +230,10 @@ class SiiPortalAuth {
|
|
|
228
230
|
const loc = res.headers['location'] || '';
|
|
229
231
|
if (loc.includes('InicioAutenticacion') || loc.includes('IngresoRutClave')) return false;
|
|
230
232
|
// Si el body contiene formulario de empresa → válida
|
|
231
|
-
|
|
233
|
+
const valida = res.status === 200 && (res.body.includes('RUT_EMP') || res.body.includes('ad_empresa'));
|
|
234
|
+
// Refrescar timestamp del caché para extender TTL mientras la sesión se usa activamente
|
|
235
|
+
if (valida) SiiPortalAuth._guardarSesionCache(this._certHash, cookieJar);
|
|
236
|
+
return valida;
|
|
232
237
|
} catch {
|
|
233
238
|
return false;
|
|
234
239
|
}
|
|
@@ -240,8 +245,8 @@ class SiiPortalAuth {
|
|
|
240
245
|
if (!fs.existsSync(SESSION_CACHE_PATH)) return null;
|
|
241
246
|
const data = JSON.parse(fs.readFileSync(SESSION_CACHE_PATH, 'utf8'));
|
|
242
247
|
if (data.certHash !== certHash) return null;
|
|
243
|
-
// TTL:
|
|
244
|
-
if (Date.now() - data.ts >
|
|
248
|
+
// TTL: 90 minutos (SII permite ~2h de inactividad; se refresca en cada validación)
|
|
249
|
+
if (Date.now() - data.ts > 90 * 60 * 1000) return null;
|
|
245
250
|
return data.cookies;
|
|
246
251
|
} catch {
|
|
247
252
|
return null;
|
|
@@ -410,26 +415,29 @@ class SiiPortalAuth {
|
|
|
410
415
|
*/
|
|
411
416
|
static _parsearTablaEmpresa(html) {
|
|
412
417
|
const datos = {};
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
if (celdas.length
|
|
418
|
+
const decode = s => s
|
|
419
|
+
.replace(/<[^>]+>/g, '')
|
|
420
|
+
.replace(/ /gi, '')
|
|
421
|
+
.replace(/ó/g, 'ó')
|
|
422
|
+
.replace(/á/g, 'á')
|
|
423
|
+
.replace(/é/g, 'é')
|
|
424
|
+
.replace(/í/g, 'í')
|
|
425
|
+
.replace(/ú/g, 'ú')
|
|
426
|
+
.replace(/ñ/g, 'ñ')
|
|
427
|
+
.replace(/&/g, '&')
|
|
428
|
+
.trim();
|
|
429
|
+
|
|
430
|
+
// Dividir por apertura <TR> — HTML 4.01 no exige tags </TR> de cierre
|
|
431
|
+
for (const seg of html.split(/<tr[^>]*>/i)) {
|
|
432
|
+
const celdas = [...seg.matchAll(/<td[^>]*>([\s\S]*?)<\/td>/gi)].map(m => decode(m[1]));
|
|
433
|
+
if (celdas.length >= 2 && celdas[0]) datos[celdas[0]] = celdas[1];
|
|
429
434
|
}
|
|
430
435
|
|
|
431
|
-
|
|
432
|
-
const
|
|
436
|
+
// Buscar por regex para ser resiliente ante variaciones de encoding / tildes
|
|
437
|
+
const fechaKey = Object.keys(datos).find(k => /fecha.*resol/i.test(k)) || null;
|
|
438
|
+
const nroKey = Object.keys(datos).find(k => /^resoluci/i.test(k) && !/fecha/i.test(k)) || null;
|
|
439
|
+
const fechaResol = fechaKey ? datos[fechaKey] : null;
|
|
440
|
+
const nroResol = nroKey ? datos[nroKey] : null;
|
|
433
441
|
|
|
434
442
|
if (fechaResol === null && nroResol === null) {
|
|
435
443
|
// Loguear los campos encontrados para diagnóstico
|
package/SiiSession.js
CHANGED
|
@@ -355,7 +355,7 @@ class SiiSession {
|
|
|
355
355
|
cookieJar: this.cookieJar,
|
|
356
356
|
baseHost: this.baseHost,
|
|
357
357
|
savedAt: Date.now(),
|
|
358
|
-
expiresAt: Date.now() + (
|
|
358
|
+
expiresAt: Date.now() + (90 * 60 * 1000), // 90 minutos de validez
|
|
359
359
|
};
|
|
360
360
|
fs.writeFileSync(filePath, JSON.stringify(sessionData, null, 2), 'utf8');
|
|
361
361
|
}
|
|
@@ -375,7 +375,7 @@ class SiiSession {
|
|
|
375
375
|
|
|
376
376
|
// Verificar que la sesión no haya expirado
|
|
377
377
|
if (data.expiresAt && Date.now() > data.expiresAt) {
|
|
378
|
-
console.log('Sesión SII expirada, se requiere nuevo login');
|
|
378
|
+
console.log('Sesión SII (maullin) expirada, se requiere nuevo login');
|
|
379
379
|
return false;
|
|
380
380
|
}
|
|
381
381
|
|
package/cert/ConfigLoader.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
|
-
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
1
|
+
// Copyright (c) 2026 Devlas SpA — https://devlas.cl
|
|
2
|
+
// Licencia MIT. Ver archivo LICENSE para mas detalles.
|
|
3
3
|
/**
|
|
4
4
|
* ConfigLoader - Carga configuración de certificación desde .env
|
|
5
5
|
*
|
|
@@ -24,27 +24,25 @@ function loadConfig(options = {}) {
|
|
|
24
24
|
// Determinar baseDir
|
|
25
25
|
const baseDir = options.baseDir || path.resolve(__dirname, '..', '..', '..');
|
|
26
26
|
|
|
27
|
-
// Cargar .env
|
|
27
|
+
// Cargar .env (opcional — las vars pueden venir de process.env inyectadas por el proceso padre)
|
|
28
28
|
const envPath = options.envPath || path.join(baseDir, '.env');
|
|
29
29
|
|
|
30
|
-
if (
|
|
31
|
-
|
|
30
|
+
if (fs.existsSync(envPath)) {
|
|
31
|
+
require('dotenv').config({ path: envPath });
|
|
32
|
+
} else {
|
|
33
|
+
console.warn(`[ConfigLoader] .env no encontrado en ${envPath} — usando variables de entorno del proceso.`);
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
// Usar dotenv para cargar
|
|
35
|
-
require('dotenv').config({ path: envPath });
|
|
36
|
-
|
|
37
36
|
// Resolver rutas relativas
|
|
38
37
|
const resolvePath = (filePath) => {
|
|
39
38
|
if (!filePath) return null;
|
|
40
39
|
return path.isAbsolute(filePath) ? filePath : path.resolve(baseDir, filePath);
|
|
41
40
|
};
|
|
42
41
|
|
|
43
|
-
// Validar variables requeridas
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
throw new Error(`Variables de entorno faltantes: ${missing.join(', ')}`);
|
|
42
|
+
// Validar variables requeridas (solo CERT_PATH es estrictamente necesario;
|
|
43
|
+
// el resto puede no estar si los datos vienen del portal SII vía getEmisorFromPortal)
|
|
44
|
+
if (!process.env.CERT_PATH) {
|
|
45
|
+
throw new Error('Variable de entorno faltante: CERT_PATH');
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
// Construir objetos de configuración
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@devlas/dte-sii",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.6",
|
|
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/emisor.js
CHANGED
|
@@ -94,9 +94,11 @@ function buildEmisorBoleta(config) {
|
|
|
94
94
|
* @returns {Object} Emisor normalizado
|
|
95
95
|
*/
|
|
96
96
|
function normalizeEmisor(emisor, esBoleta = false) {
|
|
97
|
+
// El schema SII no permite puntos en RUTEmisor (maxLength=10). Siempre normalizar.
|
|
98
|
+
const rutNorm = formatRutSii(emisor.RUTEmisor || '');
|
|
97
99
|
if (esBoleta) {
|
|
98
100
|
return {
|
|
99
|
-
RUTEmisor:
|
|
101
|
+
RUTEmisor: rutNorm,
|
|
100
102
|
RznSocEmisor: sanitizeSiiText(emisor.RznSocEmisor || emisor.RznSoc),
|
|
101
103
|
GiroEmisor: sanitizeSiiText(emisor.GiroEmisor || emisor.GiroEmis),
|
|
102
104
|
DirOrigen: sanitizeSiiText(emisor.DirOrigen),
|
|
@@ -106,7 +108,7 @@ function normalizeEmisor(emisor, esBoleta = false) {
|
|
|
106
108
|
}
|
|
107
109
|
|
|
108
110
|
const result = {
|
|
109
|
-
RUTEmisor:
|
|
111
|
+
RUTEmisor: rutNorm,
|
|
110
112
|
RznSoc: sanitizeSiiText(emisor.RznSoc || emisor.RznSocEmisor),
|
|
111
113
|
GiroEmis: sanitizeSiiText(emisor.GiroEmis || emisor.GiroEmisor),
|
|
112
114
|
};
|