ghinfe 0.6.0 → 0.6.2

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 (110) hide show
  1. package/.env.example +24 -15
  2. package/LICENSE +21 -21
  3. package/README.md +491 -413
  4. package/docs/developer-guide.html +421 -421
  5. package/docs/openapi.yaml +428 -428
  6. package/examples/dce-homologacao.js +141 -0
  7. package/examples/emitir-nfce.js +51 -51
  8. package/examples/emitir-nfe.js +83 -83
  9. package/examples/emitir-nfse.js +46 -46
  10. package/examples/endpoints-sefaz.js +14 -14
  11. package/examples/eventos-nfe.js +49 -49
  12. package/examples/gerar-chave.js +25 -25
  13. package/examples/gerar-dace.js +59 -0
  14. package/examples/gerar-danfe.js +75 -75
  15. package/examples/gerar-dce.js +58 -0
  16. package/examples/layouts-nfse.js +51 -51
  17. package/examples/mock-sefaz.js +52 -52
  18. package/examples/nfse-eventos.js +57 -57
  19. package/examples/reforma-ibscbs.js +27 -27
  20. package/examples/reforma-nfe-xml.js +52 -52
  21. package/examples/status-sefaz.js +12 -12
  22. package/examples/validar-xsd.js +48 -48
  23. package/package.json +59 -68
  24. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/consSitDCeTiposBasico_v1.00.xsd +123 -0
  25. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/consSitDCe_v1.00.xsd +10 -0
  26. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/consStatServDCeTiposBasico_v1.00.xsd +110 -0
  27. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/consStatServDCe_v1.00.xsd +10 -0
  28. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/dceTiposBasico_v1.00.xsd +1388 -0
  29. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/retConsSitDCe_v1.00.xsd +10 -0
  30. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/retConsStatServDCe_v1.00.xsd +10 -0
  31. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/tiposGeralDCe_v1.00.xsd +712 -0
  32. package/schemas/dce/PL_DCe_100a_NT2024.001/consulta/xmldsig-core-schema_v1.01.xsd +98 -0
  33. package/schemas/dce/PL_DCe_100a_NT2024.001/dceTiposBasico_v1.00.xsd +1410 -0
  34. package/schemas/dce/PL_DCe_100a_NT2024.001/dce_v1.00.xsd +10 -0
  35. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/evCancDCe_v1.00.xsd +36 -0
  36. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/eventoDCeTiposBasico_v1.00.xsd +283 -0
  37. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/eventoDCe_v1.00.xsd +9 -0
  38. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/procEventoDCe_v1.00.xsd +10 -0
  39. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/retEventoDCe_v1.00.xsd +9 -0
  40. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/tiposGeralDCe_v1.00.xsd +712 -0
  41. package/schemas/dce/PL_DCe_100a_NT2024.001/evento/xmldsig-core-schema_v1.01.xsd +98 -0
  42. package/schemas/dce/PL_DCe_100a_NT2024.001/procDCe_v1.00.xsd +37 -0
  43. package/schemas/dce/PL_DCe_100a_NT2024.001/retDCe_v1.00.xsd +9 -0
  44. package/schemas/dce/PL_DCe_100a_NT2024.001/tiposGeralDCe_v1.00.xsd +712 -0
  45. package/schemas/dce/PL_DCe_100a_NT2024.001/xmldsig-core-schema_v1.01.xsd +98 -0
  46. package/schemas/nfe/PL_009_V4/enviNFe_v3.10.xsd +8 -8
  47. package/schemas/nfe/PL_009_V4/xmldsig-core-schema_v1.01.xsd +97 -97
  48. package/scripts/download-schemas.js +39 -39
  49. package/scripts/test-xsd.js +34 -34
  50. package/src/api/server.js +316 -316
  51. package/src/constants/sefaz.js +69 -69
  52. package/src/danfe/DanfeService.js +205 -205
  53. package/src/danfe/xml-extract.js +69 -69
  54. package/src/dce/builders/DCeEventoXmlBuilder.js +86 -0
  55. package/src/dce/builders/DCeXmlBuilder.js +345 -0
  56. package/src/dce/constants/dce.js +87 -0
  57. package/src/dce/dace/DaceService.js +356 -0
  58. package/src/dce/dace/dace-extract.js +114 -0
  59. package/src/dce/services/DCeService.js +263 -0
  60. package/src/dce/services/DCeSoapService.js +235 -0
  61. package/src/dce/services/DCeXmlService.js +67 -0
  62. package/src/dce/types/DCeDocument.js +106 -0
  63. package/src/dce/utils/qrcode.utils.js +59 -0
  64. package/src/errors/GhinfeError.js +13 -13
  65. package/src/errors/SefazError.js +25 -25
  66. package/src/errors/XsdValidationError.js +15 -15
  67. package/src/index.js +84 -60
  68. package/src/nfce/builders/NFCeXmlBuilder.js +178 -178
  69. package/src/nfce/constants/qrcode.js +26 -26
  70. package/src/nfce/services/NFCeService.js +188 -188
  71. package/src/nfce/services/NFCeXmlService.js +38 -38
  72. package/src/nfce/types/NFCeDocument.js +42 -42
  73. package/src/nfce/utils/qrcode.utils.js +92 -92
  74. package/src/nfe/builders/NFeEventoXmlBuilder.js +110 -110
  75. package/src/nfe/builders/NFeXmlBuilder.js +215 -215
  76. package/src/nfe/mocks/sefaz-responses.js +195 -195
  77. package/src/nfe/services/NFeEventoService.js +95 -95
  78. package/src/nfe/services/NFeService.js +196 -196
  79. package/src/nfe/services/NFeSignService.js +127 -111
  80. package/src/nfe/services/NFeSoapService.js +437 -437
  81. package/src/nfe/services/NFeXmlService.js +41 -41
  82. package/src/nfe/services/NFeXsdService.js +56 -56
  83. package/src/nfe/types/NFeDocument.js +92 -92
  84. package/src/nfe/types/NFeEvento.js +44 -44
  85. package/src/nfse/NFSeMunicipioResolver.js +42 -42
  86. package/src/nfse/builders/NFSeEventoXmlBuilder.js +92 -92
  87. package/src/nfse/builders/NFSeXmlBuilder.js +16 -16
  88. package/src/nfse/constants/municipios.js +82 -82
  89. package/src/nfse/layouts/adapters.js +202 -202
  90. package/src/nfse/mocks/nfse-responses.js +142 -142
  91. package/src/nfse/services/NFSeService.js +191 -191
  92. package/src/nfse/services/NFSeSoapService.js +232 -232
  93. package/src/nfse/services/NFSeXmlService.js +12 -12
  94. package/src/nfse/types/NFSeDocument.js +54 -54
  95. package/src/queue/NFCeQueue.js +63 -63
  96. package/src/queue/NFSeQueue.js +59 -59
  97. package/src/queue/NFeQueue.js +76 -76
  98. package/src/reforma/ibscbs.js +175 -175
  99. package/src/sefaz/SefazEndpointResolver.js +95 -95
  100. package/src/sefaz/ca/icp-brasil-raiz-v10.pem +38 -0
  101. package/src/sefaz/endpoints.registry.js +205 -205
  102. package/src/sefaz/httpsAgent.js +33 -0
  103. package/src/shared/fiscal.helpers.js +53 -53
  104. package/src/utils/certificate.utils.js +69 -47
  105. package/src/utils/chave.utils.js +205 -117
  106. package/src/utils/code128.utils.js +67 -0
  107. package/src/utils/date.utils.js +26 -26
  108. package/src/utils/xml.utils.js +44 -44
  109. package/src/validation/XsdValidator.js +133 -114
  110. package/src/validation/schemas.js +18 -14
@@ -1,195 +1,195 @@
1
- import { SEFAZ_STATUS } from '../../constants/sefaz.js';
2
-
3
- /**
4
- * Respostas simuladas da SEFAZ para desenvolvimento e testes.
5
- * Baseadas nos cStat reais do Manual de Orientação do Contribuinte.
6
- */
7
- export const SEFAZ_MOCK_RESPONSES = {
8
- autorizado: {
9
- cStat: SEFAZ_STATUS.AUTORIZADO,
10
- xMotivo: 'Autorizado o uso da NF-e',
11
- nProt: '135260000000001',
12
- dhRecbto: new Date().toISOString(),
13
- },
14
- loteRecebido: {
15
- cStat: SEFAZ_STATUS.LOTE_RECEBIDO,
16
- xMotivo: 'Lote recebido com sucesso',
17
- nRec: '135260000000001',
18
- tMed: '1',
19
- },
20
- rejeicaoDuplicidade: {
21
- cStat: SEFAZ_STATUS.REJEICAO_DUPLICIDADE,
22
- xMotivo: 'Rejeição: Duplicidade de NF-e',
23
- },
24
- rejeicaoSchema: {
25
- cStat: SEFAZ_STATUS.REJEICAO_SCHEMA,
26
- xMotivo: 'Rejeição: Falha no Schema XML da NFe',
27
- },
28
- rejeicaoCertificado: {
29
- cStat: SEFAZ_STATUS.REJEICAO_CERTIFICADO,
30
- xMotivo: 'Rejeição: Certificado Transmissor inválido',
31
- },
32
- servicoParalisado: {
33
- cStat: SEFAZ_STATUS.SERVICO_PARALISADO,
34
- xMotivo: 'Serviço Paralisado momentaneamente (curto prazo)',
35
- },
36
- eventoRegistrado: {
37
- cStat: SEFAZ_STATUS.EVENTO_REGISTRADO,
38
- xMotivo: 'Evento registrado e vinculado a NF-e',
39
- nProt: '135260000000002',
40
- },
41
- eventoRejeitado: {
42
- cStat: SEFAZ_STATUS.EVENTO_REJEICAO,
43
- xMotivo: 'Rejeição: Chave de Acesso inexistente',
44
- },
45
- statusOk: {
46
- cStat: '107',
47
- xMotivo: 'Serviço em Operação',
48
- tMed: '1',
49
- },
50
- statusParalisado: {
51
- cStat: SEFAZ_STATUS.SERVICO_PARALISADO,
52
- xMotivo: 'Serviço Paralisado momentaneamente (curto prazo)',
53
- tMed: '5',
54
- },
55
- };
56
-
57
- /**
58
- * Gera XML de retorno de autorização simulado (protNFe).
59
- * @param {string} chaveAcesso
60
- * @param {{ cStat: string, xMotivo: string, nProt?: string }} resultado
61
- * @returns {string}
62
- */
63
- export function buildMockProtNFeXml(chaveAcesso, resultado) {
64
- const nProt = resultado.nProt ?? '';
65
- const dhRecbto = new Date().toISOString().replace('Z', '-03:00');
66
-
67
- return `<?xml version="1.0" encoding="UTF-8"?>
68
- <retEnviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">
69
- <tpAmb>2</tpAmb>
70
- <verAplic>MOCK_GHINFE_1.0</verAplic>
71
- <cStat>${resultado.cStat}</cStat>
72
- <xMotivo>${resultado.xMotivo}</xMotivo>
73
- <cUF>35</cUF>
74
- <dhRecbto>${dhRecbto}</dhRecbto>
75
- ${
76
- resultado.cStat === SEFAZ_STATUS.AUTORIZADO
77
- ? `<protNFe versao="4.00">
78
- <infProt>
79
- <tpAmb>2</tpAmb>
80
- <verAplic>MOCK_GHINFE_1.0</verAplic>
81
- <chNFe>${chaveAcesso}</chNFe>
82
- <dhRecbto>${dhRecbto}</dhRecbto>
83
- <nProt>${nProt}</nProt>
84
- <digVal>mock-digest-value</digVal>
85
- <cStat>${resultado.cStat}</cStat>
86
- <xMotivo>${resultado.xMotivo}</xMotivo>
87
- </infProt>
88
- </protNFe>`
89
- : ''
90
- }
91
- </retEnviNFe>`;
92
- }
93
-
94
- /**
95
- * Gera envelope SOAP de retorno simulado.
96
- * @param {string} innerXml
97
- * @returns {string}
98
- */
99
- export function wrapSoapResponse(innerXml) {
100
- return `<?xml version="1.0" encoding="utf-8"?>
101
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
102
- <soap:Body>
103
- <nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeAutorizacao4">
104
- ${innerXml}
105
- </nfeResultMsg>
106
- </soap:Body>
107
- </soap:Envelope>`;
108
- }
109
-
110
- /**
111
- * Gera XML de retorno de evento simulado (retEnvEvento).
112
- * @param {string} chaveAcesso
113
- * @param {string} tpEvento
114
- * @param {{ cStat: string, xMotivo: string, nProt?: string }} resultado
115
- * @returns {string}
116
- */
117
- export function buildMockRetEnvEventoXml(chaveAcesso, tpEvento, resultado) {
118
- const dhReg = new Date().toISOString().replace('Z', '-03:00');
119
- const loteOk = resultado.cStat === SEFAZ_STATUS.EVENTO_REGISTRADO;
120
-
121
- return `<?xml version="1.0" encoding="UTF-8"?>
122
- <retEnvEvento xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.00">
123
- <idLote>1</idLote>
124
- <tpAmb>2</tpAmb>
125
- <verAplic>MOCK_GHINFE_1.0</verAplic>
126
- <cStat>${loteOk ? SEFAZ_STATUS.EVENTO_LOTE_PROCESSADO : '104'}</cStat>
127
- <xMotivo>${loteOk ? 'Lote de evento processado' : resultado.xMotivo}</xMotivo>
128
- ${
129
- loteOk
130
- ? `<retEvento versao="1.00">
131
- <infEvento>
132
- <tpAmb>2</tpAmb>
133
- <verAplic>MOCK_GHINFE_1.0</verAplic>
134
- <cOrgao>35</cOrgao>
135
- <cStat>${resultado.cStat}</cStat>
136
- <xMotivo>${resultado.xMotivo}</xMotivo>
137
- <chNFe>${chaveAcesso}</chNFe>
138
- <tpEvento>${tpEvento}</tpEvento>
139
- <nSeqEvento>1</nSeqEvento>
140
- <dhRegEvento>${dhReg}</dhRegEvento>
141
- <nProt>${resultado.nProt ?? '135260000000002'}</nProt>
142
- </infEvento>
143
- </retEvento>`
144
- : ''
145
- }
146
- </retEnvEvento>`;
147
- }
148
-
149
- /**
150
- * @param {string} innerXml
151
- * @returns {string}
152
- */
153
- export function wrapSoapEventoResponse(innerXml) {
154
- return `<?xml version="1.0" encoding="utf-8"?>
155
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
156
- <soap:Body>
157
- <nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeRecepcaoEvento4">
158
- ${innerXml}
159
- </nfeResultMsg>
160
- </soap:Body>
161
- </soap:Envelope>`;
162
- }
163
-
164
- /**
165
- * XML de retorno de status do serviço (retConsStatServ).
166
- * @param {{ cStat: string, xMotivo: string, tMed?: string }} resultado
167
- * @param {string} [cUF]
168
- */
169
- export function buildMockRetConsStatServXml(resultado, cUF = '35') {
170
- const dh = new Date().toISOString().replace('Z', '-03:00');
171
- return `<?xml version="1.0" encoding="UTF-8"?>
172
- <retConsStatServ xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">
173
- <tpAmb>2</tpAmb>
174
- <verAplic>MOCK_GHINFE_1.0</verAplic>
175
- <cStat>${resultado.cStat}</cStat>
176
- <xMotivo>${resultado.xMotivo}</xMotivo>
177
- <cUF>${cUF}</cUF>
178
- <dhRecbto>${dh}</dhRecbto>
179
- <tMed>${resultado.tMed ?? '1'}</tMed>
180
- </retConsStatServ>`;
181
- }
182
-
183
- /**
184
- * @param {string} innerXml
185
- */
186
- export function wrapSoapStatusResponse(innerXml) {
187
- return `<?xml version="1.0" encoding="utf-8"?>
188
- <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
189
- <soap:Body>
190
- <nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4">
191
- ${innerXml}
192
- </nfeResultMsg>
193
- </soap:Body>
194
- </soap:Envelope>`;
195
- }
1
+ import { SEFAZ_STATUS } from '../../constants/sefaz.js';
2
+
3
+ /**
4
+ * Respostas simuladas da SEFAZ para desenvolvimento e testes.
5
+ * Baseadas nos cStat reais do Manual de Orientação do Contribuinte.
6
+ */
7
+ export const SEFAZ_MOCK_RESPONSES = {
8
+ autorizado: {
9
+ cStat: SEFAZ_STATUS.AUTORIZADO,
10
+ xMotivo: 'Autorizado o uso da NF-e',
11
+ nProt: '135260000000001',
12
+ dhRecbto: new Date().toISOString(),
13
+ },
14
+ loteRecebido: {
15
+ cStat: SEFAZ_STATUS.LOTE_RECEBIDO,
16
+ xMotivo: 'Lote recebido com sucesso',
17
+ nRec: '135260000000001',
18
+ tMed: '1',
19
+ },
20
+ rejeicaoDuplicidade: {
21
+ cStat: SEFAZ_STATUS.REJEICAO_DUPLICIDADE,
22
+ xMotivo: 'Rejeição: Duplicidade de NF-e',
23
+ },
24
+ rejeicaoSchema: {
25
+ cStat: SEFAZ_STATUS.REJEICAO_SCHEMA,
26
+ xMotivo: 'Rejeição: Falha no Schema XML da NFe',
27
+ },
28
+ rejeicaoCertificado: {
29
+ cStat: SEFAZ_STATUS.REJEICAO_CERTIFICADO,
30
+ xMotivo: 'Rejeição: Certificado Transmissor inválido',
31
+ },
32
+ servicoParalisado: {
33
+ cStat: SEFAZ_STATUS.SERVICO_PARALISADO,
34
+ xMotivo: 'Serviço Paralisado momentaneamente (curto prazo)',
35
+ },
36
+ eventoRegistrado: {
37
+ cStat: SEFAZ_STATUS.EVENTO_REGISTRADO,
38
+ xMotivo: 'Evento registrado e vinculado a NF-e',
39
+ nProt: '135260000000002',
40
+ },
41
+ eventoRejeitado: {
42
+ cStat: SEFAZ_STATUS.EVENTO_REJEICAO,
43
+ xMotivo: 'Rejeição: Chave de Acesso inexistente',
44
+ },
45
+ statusOk: {
46
+ cStat: '107',
47
+ xMotivo: 'Serviço em Operação',
48
+ tMed: '1',
49
+ },
50
+ statusParalisado: {
51
+ cStat: SEFAZ_STATUS.SERVICO_PARALISADO,
52
+ xMotivo: 'Serviço Paralisado momentaneamente (curto prazo)',
53
+ tMed: '5',
54
+ },
55
+ };
56
+
57
+ /**
58
+ * Gera XML de retorno de autorização simulado (protNFe).
59
+ * @param {string} chaveAcesso
60
+ * @param {{ cStat: string, xMotivo: string, nProt?: string }} resultado
61
+ * @returns {string}
62
+ */
63
+ export function buildMockProtNFeXml(chaveAcesso, resultado) {
64
+ const nProt = resultado.nProt ?? '';
65
+ const dhRecbto = new Date().toISOString().replace('Z', '-03:00');
66
+
67
+ return `<?xml version="1.0" encoding="UTF-8"?>
68
+ <retEnviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">
69
+ <tpAmb>2</tpAmb>
70
+ <verAplic>MOCK_GHINFE_1.0</verAplic>
71
+ <cStat>${resultado.cStat}</cStat>
72
+ <xMotivo>${resultado.xMotivo}</xMotivo>
73
+ <cUF>35</cUF>
74
+ <dhRecbto>${dhRecbto}</dhRecbto>
75
+ ${
76
+ resultado.cStat === SEFAZ_STATUS.AUTORIZADO
77
+ ? `<protNFe versao="4.00">
78
+ <infProt>
79
+ <tpAmb>2</tpAmb>
80
+ <verAplic>MOCK_GHINFE_1.0</verAplic>
81
+ <chNFe>${chaveAcesso}</chNFe>
82
+ <dhRecbto>${dhRecbto}</dhRecbto>
83
+ <nProt>${nProt}</nProt>
84
+ <digVal>mock-digest-value</digVal>
85
+ <cStat>${resultado.cStat}</cStat>
86
+ <xMotivo>${resultado.xMotivo}</xMotivo>
87
+ </infProt>
88
+ </protNFe>`
89
+ : ''
90
+ }
91
+ </retEnviNFe>`;
92
+ }
93
+
94
+ /**
95
+ * Gera envelope SOAP de retorno simulado.
96
+ * @param {string} innerXml
97
+ * @returns {string}
98
+ */
99
+ export function wrapSoapResponse(innerXml) {
100
+ return `<?xml version="1.0" encoding="utf-8"?>
101
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
102
+ <soap:Body>
103
+ <nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeAutorizacao4">
104
+ ${innerXml}
105
+ </nfeResultMsg>
106
+ </soap:Body>
107
+ </soap:Envelope>`;
108
+ }
109
+
110
+ /**
111
+ * Gera XML de retorno de evento simulado (retEnvEvento).
112
+ * @param {string} chaveAcesso
113
+ * @param {string} tpEvento
114
+ * @param {{ cStat: string, xMotivo: string, nProt?: string }} resultado
115
+ * @returns {string}
116
+ */
117
+ export function buildMockRetEnvEventoXml(chaveAcesso, tpEvento, resultado) {
118
+ const dhReg = new Date().toISOString().replace('Z', '-03:00');
119
+ const loteOk = resultado.cStat === SEFAZ_STATUS.EVENTO_REGISTRADO;
120
+
121
+ return `<?xml version="1.0" encoding="UTF-8"?>
122
+ <retEnvEvento xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.00">
123
+ <idLote>1</idLote>
124
+ <tpAmb>2</tpAmb>
125
+ <verAplic>MOCK_GHINFE_1.0</verAplic>
126
+ <cStat>${loteOk ? SEFAZ_STATUS.EVENTO_LOTE_PROCESSADO : '104'}</cStat>
127
+ <xMotivo>${loteOk ? 'Lote de evento processado' : resultado.xMotivo}</xMotivo>
128
+ ${
129
+ loteOk
130
+ ? `<retEvento versao="1.00">
131
+ <infEvento>
132
+ <tpAmb>2</tpAmb>
133
+ <verAplic>MOCK_GHINFE_1.0</verAplic>
134
+ <cOrgao>35</cOrgao>
135
+ <cStat>${resultado.cStat}</cStat>
136
+ <xMotivo>${resultado.xMotivo}</xMotivo>
137
+ <chNFe>${chaveAcesso}</chNFe>
138
+ <tpEvento>${tpEvento}</tpEvento>
139
+ <nSeqEvento>1</nSeqEvento>
140
+ <dhRegEvento>${dhReg}</dhRegEvento>
141
+ <nProt>${resultado.nProt ?? '135260000000002'}</nProt>
142
+ </infEvento>
143
+ </retEvento>`
144
+ : ''
145
+ }
146
+ </retEnvEvento>`;
147
+ }
148
+
149
+ /**
150
+ * @param {string} innerXml
151
+ * @returns {string}
152
+ */
153
+ export function wrapSoapEventoResponse(innerXml) {
154
+ return `<?xml version="1.0" encoding="utf-8"?>
155
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
156
+ <soap:Body>
157
+ <nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeRecepcaoEvento4">
158
+ ${innerXml}
159
+ </nfeResultMsg>
160
+ </soap:Body>
161
+ </soap:Envelope>`;
162
+ }
163
+
164
+ /**
165
+ * XML de retorno de status do serviço (retConsStatServ).
166
+ * @param {{ cStat: string, xMotivo: string, tMed?: string }} resultado
167
+ * @param {string} [cUF]
168
+ */
169
+ export function buildMockRetConsStatServXml(resultado, cUF = '35') {
170
+ const dh = new Date().toISOString().replace('Z', '-03:00');
171
+ return `<?xml version="1.0" encoding="UTF-8"?>
172
+ <retConsStatServ xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">
173
+ <tpAmb>2</tpAmb>
174
+ <verAplic>MOCK_GHINFE_1.0</verAplic>
175
+ <cStat>${resultado.cStat}</cStat>
176
+ <xMotivo>${resultado.xMotivo}</xMotivo>
177
+ <cUF>${cUF}</cUF>
178
+ <dhRecbto>${dh}</dhRecbto>
179
+ <tMed>${resultado.tMed ?? '1'}</tMed>
180
+ </retConsStatServ>`;
181
+ }
182
+
183
+ /**
184
+ * @param {string} innerXml
185
+ */
186
+ export function wrapSoapStatusResponse(innerXml) {
187
+ return `<?xml version="1.0" encoding="utf-8"?>
188
+ <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
189
+ <soap:Body>
190
+ <nfeResultMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4">
191
+ ${innerXml}
192
+ </nfeResultMsg>
193
+ </soap:Body>
194
+ </soap:Envelope>`;
195
+ }
@@ -1,95 +1,95 @@
1
- import { NFeEventoXmlBuilder } from '../builders/NFeEventoXmlBuilder.js';
2
- import { NFeSignService } from './NFeSignService.js';
3
- import { NFeSoapService } from './NFeSoapService.js';
4
- import { NFE_EVENTOS } from '../types/NFeEvento.js';
5
-
6
- /**
7
- * Serviço de eventos NF-e: cancelamento, carta de correção, etc.
8
- */
9
- export class NFeEventoService {
10
- /**
11
- * @param {ConstructorParameters<typeof NFeSoapService>[0]} [soapOptions]
12
- */
13
- constructor(soapOptions = {}) {
14
- this.builder = new NFeEventoXmlBuilder();
15
- this.signService = new NFeSignService();
16
- this.soapService = new NFeSoapService(soapOptions);
17
- }
18
-
19
- /**
20
- * @param {import('../types/NFeEvento.js').NFeCancelamento} dados
21
- */
22
- gerarXmlCancelamento(dados) {
23
- return this.builder.buildCancelamento(dados);
24
- }
25
-
26
- /**
27
- * @param {import('../types/NFeEvento.js').NFeCartaCorrecao} dados
28
- */
29
- gerarXmlCartaCorrecao(dados) {
30
- return this.builder.buildCartaCorrecao(dados);
31
- }
32
-
33
- /**
34
- * Cancela NF-e autorizada (evento 110111).
35
- * @param {import('../types/NFeEvento.js').NFeCancelamento} dados
36
- * @param {{ pfx: Buffer|string, senha: string }} certificado
37
- */
38
- async cancelar(dados, certificado) {
39
- const xml = this.gerarXmlCancelamento(dados);
40
- const xmlAssinado = this.signService.assinarEvento(xml, certificado.pfx, certificado.senha);
41
- const retorno = await this.soapService.enviarEvento(
42
- xmlAssinado,
43
- dados.chaveAcesso,
44
- NFE_EVENTOS.CANCELAMENTO,
45
- dados.idLote
46
- );
47
-
48
- return { tipo: 'cancelamento', xmlGerado: xml, xmlAssinado, retorno };
49
- }
50
-
51
- /**
52
- * Registra Carta de Correção Eletrônica (evento 110110).
53
- * @param {import('../types/NFeEvento.js').NFeCartaCorrecao} dados
54
- * @param {{ pfx: Buffer|string, senha: string }} certificado
55
- */
56
- async cartaCorrecao(dados, certificado) {
57
- const xml = this.gerarXmlCartaCorrecao(dados);
58
- const xmlAssinado = this.signService.assinarEvento(xml, certificado.pfx, certificado.senha);
59
- const retorno = await this.soapService.enviarEvento(
60
- xmlAssinado,
61
- dados.chaveAcesso,
62
- NFE_EVENTOS.CARTA_CORRECAO,
63
- dados.idLote
64
- );
65
-
66
- return { tipo: 'carta_correcao', xmlGerado: xml, xmlAssinado, retorno };
67
- }
68
-
69
- /**
70
- * Envia evento já assinado (mock ou produção).
71
- * @param {string} xmlAssinado
72
- * @param {string} chaveAcesso
73
- * @param {string} tpEvento
74
- */
75
- async enviar(xmlAssinado, chaveAcesso, tpEvento) {
76
- return this.soapService.enviarEvento(xmlAssinado, chaveAcesso, tpEvento);
77
- }
78
-
79
- /**
80
- * Payload para persistência de evento no banco.
81
- * @param {Awaited<ReturnType<NFeEventoService['cancelar']>>} resultado
82
- */
83
- toPersistencePayload(resultado) {
84
- return {
85
- chave_acesso: resultado.retorno.chaveAcesso ?? null,
86
- tipo_evento: resultado.tipo,
87
- xml_evento: resultado.xmlAssinado,
88
- xml_retorno: resultado.retorno.xmlRetorno,
89
- protocolo: resultado.retorno.protocolo,
90
- status: resultado.retorno.cStat,
91
- motivo: resultado.retorno.xMotivo,
92
- registrado_em: new Date(),
93
- };
94
- }
95
- }
1
+ import { NFeEventoXmlBuilder } from '../builders/NFeEventoXmlBuilder.js';
2
+ import { NFeSignService } from './NFeSignService.js';
3
+ import { NFeSoapService } from './NFeSoapService.js';
4
+ import { NFE_EVENTOS } from '../types/NFeEvento.js';
5
+
6
+ /**
7
+ * Serviço de eventos NF-e: cancelamento, carta de correção, etc.
8
+ */
9
+ export class NFeEventoService {
10
+ /**
11
+ * @param {ConstructorParameters<typeof NFeSoapService>[0]} [soapOptions]
12
+ */
13
+ constructor(soapOptions = {}) {
14
+ this.builder = new NFeEventoXmlBuilder();
15
+ this.signService = new NFeSignService();
16
+ this.soapService = new NFeSoapService(soapOptions);
17
+ }
18
+
19
+ /**
20
+ * @param {import('../types/NFeEvento.js').NFeCancelamento} dados
21
+ */
22
+ gerarXmlCancelamento(dados) {
23
+ return this.builder.buildCancelamento(dados);
24
+ }
25
+
26
+ /**
27
+ * @param {import('../types/NFeEvento.js').NFeCartaCorrecao} dados
28
+ */
29
+ gerarXmlCartaCorrecao(dados) {
30
+ return this.builder.buildCartaCorrecao(dados);
31
+ }
32
+
33
+ /**
34
+ * Cancela NF-e autorizada (evento 110111).
35
+ * @param {import('../types/NFeEvento.js').NFeCancelamento} dados
36
+ * @param {{ pfx: Buffer|string, senha: string }} certificado
37
+ */
38
+ async cancelar(dados, certificado) {
39
+ const xml = this.gerarXmlCancelamento(dados);
40
+ const xmlAssinado = this.signService.assinarEvento(xml, certificado.pfx, certificado.senha);
41
+ const retorno = await this.soapService.enviarEvento(
42
+ xmlAssinado,
43
+ dados.chaveAcesso,
44
+ NFE_EVENTOS.CANCELAMENTO,
45
+ dados.idLote
46
+ );
47
+
48
+ return { tipo: 'cancelamento', xmlGerado: xml, xmlAssinado, retorno };
49
+ }
50
+
51
+ /**
52
+ * Registra Carta de Correção Eletrônica (evento 110110).
53
+ * @param {import('../types/NFeEvento.js').NFeCartaCorrecao} dados
54
+ * @param {{ pfx: Buffer|string, senha: string }} certificado
55
+ */
56
+ async cartaCorrecao(dados, certificado) {
57
+ const xml = this.gerarXmlCartaCorrecao(dados);
58
+ const xmlAssinado = this.signService.assinarEvento(xml, certificado.pfx, certificado.senha);
59
+ const retorno = await this.soapService.enviarEvento(
60
+ xmlAssinado,
61
+ dados.chaveAcesso,
62
+ NFE_EVENTOS.CARTA_CORRECAO,
63
+ dados.idLote
64
+ );
65
+
66
+ return { tipo: 'carta_correcao', xmlGerado: xml, xmlAssinado, retorno };
67
+ }
68
+
69
+ /**
70
+ * Envia evento já assinado (mock ou produção).
71
+ * @param {string} xmlAssinado
72
+ * @param {string} chaveAcesso
73
+ * @param {string} tpEvento
74
+ */
75
+ async enviar(xmlAssinado, chaveAcesso, tpEvento) {
76
+ return this.soapService.enviarEvento(xmlAssinado, chaveAcesso, tpEvento);
77
+ }
78
+
79
+ /**
80
+ * Payload para persistência de evento no banco.
81
+ * @param {Awaited<ReturnType<NFeEventoService['cancelar']>>} resultado
82
+ */
83
+ toPersistencePayload(resultado) {
84
+ return {
85
+ chave_acesso: resultado.retorno.chaveAcesso ?? null,
86
+ tipo_evento: resultado.tipo,
87
+ xml_evento: resultado.xmlAssinado,
88
+ xml_retorno: resultado.retorno.xmlRetorno,
89
+ protocolo: resultado.retorno.protocolo,
90
+ status: resultado.retorno.cStat,
91
+ motivo: resultado.retorno.xMotivo,
92
+ registrado_em: new Date(),
93
+ };
94
+ }
95
+ }