consultame-sdk 1.1.2 → 1.2.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/README.md CHANGED
@@ -5,7 +5,8 @@ que se necesitan para interactuar con **SIFEN** (Sistema Integrado de Facturaci
5
5
  Nacional de Paraguay – SET).
6
6
 
7
7
  La librería **no** hace las peticiones HTTP al web service de SIFEN: su responsabilidad es
8
- **construir los sobres XML** (consulta de RUC, consulta de lote, consulta de documento),
8
+ **construir los sobres XML** (consulta de RUC, consulta de lote, consulta de documento y
9
+ evento de nominación de un documento ya emitido),
9
10
  **extraer el certificado y la llave privada** desde un archivo de firma digital `.p12`/`.pfx`,
10
11
  **firmar digitalmente (XMLDSig)** el Documento Electrónico generado y **generar el código QR**
11
12
  que se incrusta en el documento electrónico ya firmado.
@@ -25,6 +26,7 @@ Con esa salida, la aplicación consumidora envía los mensajes por su cuenta.
25
26
  - [`generateQr`](#generateqrgenerationqrdto)
26
27
  - [`generateDocument`](#generatedocumentgeneratedocumentoelectronicodto)
27
28
  - [`signedXml`](#signedxmlxml-tag-responsedigitalsign)
29
+ - [`nominationInvoice`](#nominationinvoicenominationinvoicedto)
28
30
  - [DTOs (contratos de entrada)](#dtos-contratos-de-entrada)
29
31
  - [Funciones utilitarias internas](#funciones-utilitarias-internas)
30
32
  - [Arquitectura del proyecto](#arquitectura-del-proyecto)
@@ -69,7 +71,7 @@ Todo el punto de entrada público es la clase **`SifenService`**. Se instancia s
69
71
  argumentos y ya arma internamente sus casos de uso y dependencias.
70
72
 
71
73
  ```ts
72
- import { SifenService } from "consultame-skd";
74
+ import { SifenService } from "consultame-sdk";
73
75
 
74
76
  const sifen = new SifenService();
75
77
 
@@ -170,6 +172,21 @@ const xmlConQr = await sifen.generateQr({
170
172
  idCsc: "0001",
171
173
  ambiente: "test", // "test" | "produccion"
172
174
  });
175
+
176
+ // 8) Nominar un documento ya emitido a un receptor (evento de nominación, sin firmar)
177
+ const xmlNominacion = sifen.nominationInvoice({
178
+ id: 4,
179
+ cdc: "01800123456001001000000012023052212345678901",
180
+ motivo: "Nominación solicitada por el cliente",
181
+ idTipoReceptor: 1, // 1 = contribuyente
182
+ idTipoOperacion: 1, // 1 = B2B
183
+ idPais: "PRY",
184
+ esContribuyente: true,
185
+ idTipoContribuyente: 2,
186
+ ruc: "80099999",
187
+ digitoVerificado: "1",
188
+ razonSocial: "Cliente Ejemplo S.R.L.",
189
+ });
173
190
  ```
174
191
 
175
192
  ---
@@ -342,7 +359,7 @@ Toma un documento electrónico (`rDE`) **ya firmado digitalmente**, calcula el e
342
359
  código QR exigido por SIFEN y devuelve el **mismo XML con el nodo `<gCamFuFD><dCarQR>`
343
360
  incrustado**.
344
361
 
345
- > ⚠️ Este es el único método **asíncrono** de la librería: devuelve `Promise<string>`.
362
+ > ⚠️ Método **asíncrono**: devuelve `Promise<string>`.
346
363
 
347
364
  | Parámetro | Tipo | Descripción |
348
365
  | ---------- | -------- | ---------------------------------------------------------------------- |
@@ -634,6 +651,131 @@ try {
634
651
 
635
652
  ---
636
653
 
654
+ ### `nominationInvoice(nominationInvoiceDto)`
655
+
656
+ Genera el sobre SOAP `rEnviEventoDe` con el **evento de nominación** (`rGEveNom`): asocia los
657
+ datos de un receptor a un documento electrónico ya emitido, identificado por su **CDC**.
658
+
659
+ > ⚠️ El XML devuelto **no está firmado**: la aplicación consumidora debe firmar el evento y
660
+ > enviarlo a SIFEN por su cuenta.
661
+
662
+ Método **síncrono** que valida el DTO antes de armar el XML.
663
+
664
+ | Parámetro | Tipo | Descripción |
665
+ | --------------------- | ------------------- | --------------------------------------------------------------------------------------------- |
666
+ | `id` | `number` | Identificador de la petición (`dId`); también se usa como `Id` del evento (`rEve`). |
667
+ | `cdc` | `string` | CDC de 44 dígitos del documento a nominar (`Id` de `rGEveNom`). |
668
+ | `motivo` | `string` | Motivo del evento (`mOtEve`), de 5 a 500 caracteres. |
669
+ | `idTipoReceptor` | `number` | `1` = contribuyente, `2` = no contribuyente (`iNatRec`). |
670
+ | `idTipoOperacion` | `number` | `1` = B2B, `2` = B2C, `4` = B2F (`iTiOpe`). |
671
+ | `idPais` | `string` | Código de país del receptor (ej. `"PRY"`); debe existir en `PAISES`. |
672
+ | `esContribuyente` | `boolean` | Si el receptor es contribuyente. |
673
+ | `razonSocial` | `string` | Nombre o razón social del receptor (`dNomRec`), de 4 a 255 caracteres. |
674
+ | `idTipoContribuyente` | `number?` | `1` = persona física, `2` = persona jurídica. Obligatorio si `esContribuyente`. |
675
+ | `ruc` | `string?` | RUC del receptor. Obligatorio si `esContribuyente`. |
676
+ | `digitoVerificado` | `string \| number?` | Dígito verificador del RUC. Obligatorio si `esContribuyente`. |
677
+ | `idTipoDocumento` | `number?` | Tipo de documento de identidad. Obligatorio si **no** es contribuyente. |
678
+ | `numeroDocumento` | `string?` | Número de documento. Obligatorio si **no** es contribuyente. |
679
+ | `otroTipoDocumento` | `string?` | Descripción del tipo de documento cuando `idTipoDocumento = 9` (Otro). |
680
+ | `nombreFantasia` | `string?` | Nombre de fantasía del receptor. |
681
+ | `direccion` | `string?` | Dirección del receptor. Obligatoria si `idTipoOperacion = 4` (B2F). |
682
+ | `numeroCasa` | `string?` | Obligatorio si se informa `direccion`. |
683
+ | `idDepartamento`, `idDistricto`, `idCiudad` | `number?` | Ubicación del receptor. **Se ignoran en B2F.** |
684
+ | `telefono`, `celular`, `email`, `codigoCliente` | `string?` | Datos de contacto opcionales. |
685
+
686
+ > El campo se llama `idDistricto` (con esa grafía) en el DTO.
687
+
688
+ **Retorna:** `string` — XML SOAP normalizado (una sola línea), con `dFecFirma` tomado de la
689
+ fecha/hora actual y `dVerFor` = `150`.
690
+
691
+ ```ts
692
+ const xml = sifen.nominationInvoice({
693
+ id: 4,
694
+ cdc: "01800123456001001000000012023052212345678901",
695
+ motivo: "Nominación solicitada por el cliente",
696
+ idTipoReceptor: 1,
697
+ idTipoOperacion: 1,
698
+ idPais: "PRY",
699
+ esContribuyente: true,
700
+ idTipoContribuyente: 2,
701
+ ruc: "80099999",
702
+ digitoVerificado: "1",
703
+ razonSocial: "Cliente Ejemplo S.R.L.",
704
+ });
705
+ ```
706
+
707
+ <details>
708
+ <summary>Ejemplo de salida (formateada para lectura)</summary>
709
+
710
+ ```xml
711
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
712
+ <env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope">
713
+ <env:Header/>
714
+ <env:Body>
715
+ <rEnviEventoDe xmlns="http://ekuatia.set.gov.py/sifen/xsd">
716
+ <dId>4</dId>
717
+ <dEvReg>
718
+ <gGroupGesEve xmlns="http://ekuatia.set.gov.py/sifen/xsd"
719
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
720
+ xsi:schemaLocation="http://ekuatia.set.gov.py/sifen/xsd siRecepEvento_v150.xsd">
721
+ <rGesEve xsi:schemaLocation="http://ekuatia.set.gov.py/sifen/xsd siRecepEvento_v150.xsd">
722
+ <rEve Id="4">
723
+ <dFecFirma>2026-10-14T16:43:03</dFecFirma>
724
+ <dVerFor>150</dVerFor>
725
+ <gGroupTiEvt>
726
+ <rGEveNom>
727
+ <Id>01800123456001001000000012023052212345678901</Id>
728
+ <mOtEve>Nominación solicitada por el cliente</mOtEve>
729
+ <iNatRec>1</iNatRec>
730
+ <iTiOpe>1</iTiOpe>
731
+ <cPaisRec>PRY</cPaisRec>
732
+ <dDesPaisRe>Paraguay</dDesPaisRe>
733
+ <iTiContRec>2</iTiContRec>
734
+ <dRucRec>80099999</dRucRec>
735
+ <dDVRec>1</dDVRec>
736
+ <dNomRec>Cliente Ejemplo S.R.L.</dNomRec>
737
+ </rGEveNom>
738
+ </gGroupTiEvt>
739
+ </rEve>
740
+ </rGesEve>
741
+ </gGroupGesEve>
742
+ </dEvReg>
743
+ </rEnviEventoDe>
744
+ </env:Body>
745
+ </env:Envelope>
746
+ ```
747
+
748
+ </details>
749
+
750
+ #### Reglas de validación
751
+
752
+ Antes de armar el XML se valida el DTO y se lanza un `Error` con un mensaje descriptivo si
753
+ algo no cumple:
754
+
755
+ - `cdc` debe tener exactamente 44 dígitos.
756
+ - `motivo` de 5 a 500 caracteres y `razonSocial` de 4 a 255 (ambos sin contar espacios en los extremos).
757
+ - `idTipoReceptor` debe ser coherente con `esContribuyente` (`1` ⇔ contribuyente).
758
+ - `idTipoOperacion` debe ser `1`, `2` o `4`; B2B (`1`) exige receptor contribuyente, y B2C (`2`) /
759
+ B2F (`4`) exigen no contribuyente.
760
+ - `idPais` debe ser `"PRY"`, salvo en B2F (`4`), donde debe ser **distinto** de `"PRY"`.
761
+ - Contribuyente: `idTipoContribuyente`, `ruc` y `digitoVerificado` son obligatorios.
762
+ - No contribuyente: `idTipoDocumento` y `numeroDocumento` son obligatorios.
763
+ - B2F: `direccion` es obligatoria; y si se informa `direccion`, también `numeroCasa`.
764
+
765
+ También lanza error si algún código (`idPais`, `idTipoDocumento`, `idDepartamento`, `idDistricto`,
766
+ `idCiudad`) no existe en los catálogos de
767
+ [`src/shared/utils/dictionary.utils.ts`](src/shared/utils/dictionary.utils.ts).
768
+
769
+ ```ts
770
+ try {
771
+ const xml = sifen.nominationInvoice({ ... });
772
+ } catch (error) {
773
+ // DTO inválido (ver reglas de validación) o código inexistente en el diccionario
774
+ }
775
+ ```
776
+
777
+ ---
778
+
637
779
  ## DTOs (contratos de entrada)
638
780
 
639
781
  Todos los DTOs de consulta extienden `GenerateIdDto`, que aporta el campo `id`.
@@ -666,6 +808,18 @@ interface GenerationQrDto {
666
808
  idCsc: string; // Identificador del CSC
667
809
  ambiente: string; // "test" | "produccion"
668
810
  }
811
+
812
+ // Campos completos y reglas en la sección `nominationInvoice`
813
+ interface NominationInvoiceDto extends GenerateIdDto {
814
+ cdc: string;
815
+ motivo: string;
816
+ idTipoReceptor: number;
817
+ idTipoOperacion: number;
818
+ idPais: string;
819
+ esContribuyente: boolean;
820
+ razonSocial: string;
821
+ // ...y los campos opcionales del receptor (ruc, direccion, idDistricto, email, etc.)
822
+ }
669
823
  ```
670
824
 
671
825
  Enums disponibles en [`src/shared/utils/dictionary.utils.ts`](src/shared/utils/dictionary.utils.ts):
@@ -725,6 +879,8 @@ No forman parte de la API pública, pero es útil conocerlas:
725
879
  | `generateConsultRucXml` | Arma el string XML de consulta de RUC. |
726
880
  | `generateConsultDocumentXml` | Arma el string XML de consulta de documento por CDC. |
727
881
  | `generateConsultBatchXml` | Arma el string XML de consulta de lote. |
882
+ | `generateNominationInvoiceXml` | Valida el `NominationInvoiceDto` y arma el sobre `rEnviEventoDe` del evento de nominación con `xml2js.Builder`, ya normalizado. |
883
+ | `convertToFormatDateSET` | Formatea una `Date` como fecha/hora SIFEN (usada para `dFecFirma` del evento). |
728
884
  | `normalizeXML` | Colapsa el XML a una sola línea: elimina saltos, tabulaciones y espacios entre etiquetas. |
729
885
  | `readDigitalSign` | Lee el `.p12` con `node-forge` y extrae certificado + llave privada en PEM, emparejando el certificado correcto por módulo RSA cuando hay varios. |
730
886
  | `signXml` | Firma un XML (XMLDSig) con `xml-crypto`: `enveloped-signature` + `exc-c14n`, digest SHA-256, firma RSA-SHA256. _(async)_ |
@@ -787,6 +943,11 @@ mantener estado intermedio (`jsonFactura`) mientras se arma cada sección del XM
787
943
  `SifenRepository` → `SifenPersistence.signedXml`), delegando en la función utilitaria `signXml`
788
944
  (`src/shared/functions/functions.utils.ts`), que envuelve `xml-crypto`.
789
945
 
946
+ `nominationInvoice` también sigue el mismo flujo (`SifenService.nominationInvoice` →
947
+ `NominationInvoiceUseCase` → `SifenRepository` → `SifenPersistence.nominationInvoice`),
948
+ delegando en `generateNominationInvoiceXml`, que valida el DTO y arma el evento con
949
+ `xml2js.Builder` (a diferencia de las consultas simples, que son strings de plantilla).
950
+
790
951
  **Por qué esta separación:**
791
952
 
792
953
  - **`domain`** no depende de nada externo: define _qué_ se hace (casos de uso) y el
@@ -830,6 +991,7 @@ consultame-sdk/
830
991
  │ │ │ ├── consultBatch.dto.ts
831
992
  │ │ │ ├── digitalSign.dto.ts
832
993
  │ │ │ ├── generationQr.dto.ts
994
+ │ │ │ ├── nominationInvoice.dto.ts
833
995
  │ │ │ ├── cancelDocument.dto.ts
834
996
  │ │ │ └── invalidationInvoice.dto.ts
835
997
  │ │ └── services/
@@ -846,6 +1008,7 @@ consultame-sdk/
846
1008
  │ │ ├── obtainDigitalSign.useCase.ts
847
1009
  │ │ ├── generateQr.useCase.ts
848
1010
  │ │ ├── generateDocument.useCase.ts
1011
+ │ │ ├── nominationInvoice.useCase.ts
849
1012
  │ │ └── signedXml.useCase.ts
850
1013
  │ │
851
1014
  │ └── infrastructure/ # Detalles concretos (ADAPTADORES)
@@ -886,6 +1049,7 @@ Funcionalidades **implementadas**:
886
1049
  - ✅ Generación del XML completo del Documento Electrónico — Factura, Autofactura, Nota de
887
1050
  Crédito/Débito y Remisión (`generateDocument`)
888
1051
  - ✅ Firma digital XMLDSig del Documento Electrónico (`signedXml`)
1052
+ - ✅ Evento de nominación de un documento emitido (`nominationInvoice`)
889
1053
 
890
1054
  Definidas pero **pendientes de implementación** (hoy lanzan `Method not implemented`
891
1055
  o aún no están expuestas en `SifenService`):
@@ -897,5 +1061,5 @@ o aún no están expuestas en `SifenService`):
897
1061
 
898
1062
  > **Nota:** esta librería genera insumos (XML, credenciales, firma XMLDSig y el QR) para SIFEN,
899
1063
  > pero no realiza el envío HTTP de los documentos — eso queda a cargo de la aplicación
900
- > consumidora. `generateQr` **requiere** que el XML ya venga firmado (con `signedXml` o por
1064
+ > consumidora. El evento que devuelve `nominationInvoice` tampoco viene firmado. `generateQr` **requiere** que el XML ya venga firmado (con `signedXml` o por
901
1065
  > cualquier otro medio), porque toma el `DigestValue` de la firma para calcular el hash del QR.
package/dist/index.js CHANGED
@@ -120,6 +120,18 @@ var SignedXmlUseCase = class {
120
120
  }
121
121
  };
122
122
 
123
+ // src/sifen/domain/useCases/nominationInvoice.useCase.ts
124
+ var NominationInvoiceUseCase = class {
125
+ constructor(sifenRepository) {
126
+ this.sifenRepository = sifenRepository;
127
+ }
128
+ sifenRepository;
129
+ execute(nominationInvoiceDto) {
130
+ const xml = this.sifenRepository.nominationInvoice(nominationInvoiceDto);
131
+ return xml;
132
+ }
133
+ };
134
+
123
135
  // src/shared/utils/dictionary.utils.ts
124
136
  var TIPOS_DOCUMENTOS = [
125
137
  {
@@ -8157,6 +8169,139 @@ var generateConsultBatchXml = (consultBatchDto) => {
8157
8169
  </env:Envelope>
8158
8170
  `;
8159
8171
  };
8172
+ var validateNominationInvoice = (dto) => {
8173
+ if (!/^\d{44}$/.test(dto.cdc)) {
8174
+ throw new Error("El CDC debe tener 44 d\xEDgitos");
8175
+ }
8176
+ if (dto.motivo.trim().length < 5 || dto.motivo.trim().length > 500) {
8177
+ throw new Error("El motivo debe tener entre 5 y 500 caracteres");
8178
+ }
8179
+ if (dto.razonSocial.trim().length < 4 || dto.razonSocial.trim().length > 255) {
8180
+ throw new Error("La raz\xF3n social debe tener entre 4 y 255 caracteres");
8181
+ }
8182
+ if (dto.esContribuyente !== (dto.idTipoReceptor === 1)) {
8183
+ throw new Error(
8184
+ "idTipoReceptor (1 = contribuyente, 2 = no contribuyente) no coincide con esContribuyente"
8185
+ );
8186
+ }
8187
+ if (![1, 2, 4].includes(dto.idTipoOperacion)) {
8188
+ throw new Error("idTipoOperacion debe ser 1 (B2B), 2 (B2C) o 4 (B2F)");
8189
+ }
8190
+ if (dto.esContribuyente !== (dto.idTipoOperacion === 1)) {
8191
+ throw new Error(
8192
+ "B2B exige receptor contribuyente; B2C y B2F exigen no contribuyente"
8193
+ );
8194
+ }
8195
+ if (dto.idTipoOperacion === 4 === (dto.idPais === "PRY")) {
8196
+ throw new Error(
8197
+ "idPais debe ser PRY, salvo en B2F donde debe ser distinto de PRY"
8198
+ );
8199
+ }
8200
+ if (dto.esContribuyente) {
8201
+ if (!dto.idTipoContribuyente || !dto.ruc || dto.digitoVerificado === void 0) {
8202
+ throw new Error(
8203
+ "Receptor contribuyente: idTipoContribuyente, ruc y digitoVerificado son obligatorios"
8204
+ );
8205
+ }
8206
+ } else if (!dto.idTipoDocumento || !dto.numeroDocumento) {
8207
+ throw new Error(
8208
+ "Receptor no contribuyente: idTipoDocumento y numeroDocumento son obligatorios"
8209
+ );
8210
+ }
8211
+ if (dto.idTipoOperacion === 4 && !dto.direccion) {
8212
+ throw new Error("B2F: la direcci\xF3n del receptor es obligatoria");
8213
+ }
8214
+ if (dto.direccion && !dto.numeroCasa) {
8215
+ throw new Error("numeroCasa es obligatorio si se informa la direcci\xF3n");
8216
+ }
8217
+ };
8218
+ var generateNominationInvoiceXml = (dto) => {
8219
+ validateNominationInvoice(dto);
8220
+ const pais = PAISES.find((item) => item.codigo === dto.idPais).descripcion;
8221
+ const rGEveNom = {
8222
+ Id: dto.cdc,
8223
+ mOtEve: dto.motivo.trim(),
8224
+ iNatRec: dto.idTipoReceptor,
8225
+ iTiOpe: dto.idTipoOperacion,
8226
+ cPaisRec: dto.idPais,
8227
+ dDesPaisRe: pais
8228
+ };
8229
+ if (dto.esContribuyente) {
8230
+ rGEveNom.iTiContRec = dto.idTipoContribuyente;
8231
+ rGEveNom.dRucRec = dto.ruc;
8232
+ rGEveNom.dDVRec = dto.digitoVerificado;
8233
+ } else {
8234
+ rGEveNom.iTipIDRec = dto.idTipoDocumento;
8235
+ rGEveNom.dDTipIDRec = dto.idTipoDocumento === 9 && dto.otroTipoDocumento ? dto.otroTipoDocumento : TIPOS_DOCUMENTOS.find((item) => item.codigo === dto.idTipoDocumento).descripcion;
8236
+ rGEveNom.dNumIDRec = dto.numeroDocumento.trim();
8237
+ }
8238
+ rGEveNom.dNomRec = dto.razonSocial.trim();
8239
+ if (dto.nombreFantasia) rGEveNom.dNomFanRec = dto.nombreFantasia.trim();
8240
+ if (dto.direccion) {
8241
+ rGEveNom.dDirRec = dto.direccion.trim();
8242
+ rGEveNom.dNumCasRec = dto.numeroCasa.trim();
8243
+ }
8244
+ if (dto.idTipoOperacion !== 4) {
8245
+ if (dto.idDepartamento) {
8246
+ rGEveNom.cDepRec = dto.idDepartamento;
8247
+ rGEveNom.dDesDepRec = DEPARTAMENTOS.find(
8248
+ (item) => item.codigo === dto.idDepartamento
8249
+ ).descripcion;
8250
+ }
8251
+ if (dto.idDistricto) {
8252
+ rGEveNom.cDisRec = dto.idDistricto;
8253
+ rGEveNom.dDesDisRec = DISTRICTOS.find(
8254
+ (item) => item.codigo === dto.idDistricto
8255
+ ).descripcion;
8256
+ }
8257
+ if (dto.idCiudad) {
8258
+ rGEveNom.cCiuRec = dto.idCiudad;
8259
+ rGEveNom.dDesCiuRec = CIUDADES.find(
8260
+ (item) => item.codigo === dto.idCiudad
8261
+ ).descripcion;
8262
+ }
8263
+ }
8264
+ if (dto.telefono) rGEveNom.dTelRec = dto.telefono.trim();
8265
+ if (dto.celular) rGEveNom.dCelRec = dto.celular.trim();
8266
+ if (dto.email) rGEveNom.dEmailRec = dto.email.trim();
8267
+ if (dto.codigoCliente) rGEveNom.dCodCliente = dto.codigoCliente.trim();
8268
+ const xsd = "http://ekuatia.set.gov.py/sifen/xsd";
8269
+ const schemaLocation = `${xsd} siRecepEvento_v150.xsd`;
8270
+ const envelope = {
8271
+ "env:Envelope": {
8272
+ $: { "xmlns:env": "http://www.w3.org/2003/05/soap-envelope" },
8273
+ "env:Header": {},
8274
+ "env:Body": {
8275
+ rEnviEventoDe: {
8276
+ $: { xmlns: xsd },
8277
+ dId: dto.id,
8278
+ dEvReg: {
8279
+ gGroupGesEve: {
8280
+ $: {
8281
+ xmlns: xsd,
8282
+ "xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
8283
+ "xsi:schemaLocation": schemaLocation
8284
+ },
8285
+ rGesEve: {
8286
+ $: { "xsi:schemaLocation": schemaLocation },
8287
+ rEve: {
8288
+ $: { Id: dto.id },
8289
+ dFecFirma: convertToFormatDateSET(/* @__PURE__ */ new Date()),
8290
+ dVerFor: 150,
8291
+ gGroupTiEvt: { rGEveNom }
8292
+ }
8293
+ }
8294
+ }
8295
+ }
8296
+ }
8297
+ }
8298
+ }
8299
+ };
8300
+ const builder = new xml2js__namespace.Builder({
8301
+ xmldec: { version: "1.0", encoding: "UTF-8", standalone: false }
8302
+ });
8303
+ return normalizeXML(builder.buildObject(envelope));
8304
+ };
8160
8305
  var OIDS_KEYS = [forge__default.default.pki.oids.pkcs8ShroudedKeyBag, forge__default.default.pki.oids.keyBag];
8161
8306
  var obtainBags = (almacen) => almacen.safeContents.flatMap((contenido) => contenido.safeBags);
8162
8307
  var readDigitalSign = (digitalSignDto) => {
@@ -9976,6 +10121,14 @@ var SifenPersistence = class {
9976
10121
  throw error;
9977
10122
  }
9978
10123
  }
10124
+ nominationInvoice(nominationInvoiceDto) {
10125
+ try {
10126
+ return generateNominationInvoiceXml(nominationInvoiceDto);
10127
+ } catch (error) {
10128
+ console.log(error);
10129
+ throw error;
10130
+ }
10131
+ }
9979
10132
  obtainDigitalSign(digitalSignDto) {
9980
10133
  try {
9981
10134
  const digitalSign = readDigitalSign(digitalSignDto);
@@ -10026,6 +10179,7 @@ var SifenService = class {
10026
10179
  generateQrUseCase;
10027
10180
  generateDocumentUseCase;
10028
10181
  signedXmlUseCase;
10182
+ nominationInvoiceUseCase;
10029
10183
  sifenRepository;
10030
10184
  constructor() {
10031
10185
  this.sifenRepository = new SifenPersistence();
@@ -10042,6 +10196,9 @@ var SifenService = class {
10042
10196
  );
10043
10197
  this.signedXmlUseCase = new SignedXmlUseCase(this.sifenRepository);
10044
10198
  this.generateQrUseCase = new GenerateQrUseCase(this.sifenRepository);
10199
+ this.nominationInvoiceUseCase = new NominationInvoiceUseCase(
10200
+ this.sifenRepository
10201
+ );
10045
10202
  }
10046
10203
  consultRuc(consultRucDto) {
10047
10204
  const ruc = this.consultRucUseCase.execute(consultRucDto);
@@ -10055,6 +10212,10 @@ var SifenService = class {
10055
10212
  const invoice = this.consultDocumentUseCase.execute(consultDocumentDto);
10056
10213
  return invoice;
10057
10214
  }
10215
+ nominationInvoice(nominationInvoiceDto) {
10216
+ const xml = this.nominationInvoiceUseCase.execute(nominationInvoiceDto);
10217
+ return xml;
10218
+ }
10058
10219
  obtainDigitalSign(digitalSignDto) {
10059
10220
  const digitalSign = this.obtainDigitalSignUseCase.execute(digitalSignDto);
10060
10221
  return digitalSign;