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,175 +1,175 @@
1
- /**
2
- * Constantes e helpers — Reforma Tributária (NT 2025.002 / PL_010).
3
- * IBS + CBS. Injeção no builder NF-e/NFC-e quando item.reforma ou reformaTributaria.
4
- */
5
-
6
- export const REFORMA_LAYOUT = 'PL_010';
7
-
8
- export const CST_IBSCBS = {
9
- TRIBUTACAO_INTEGRAL: '000',
10
- ISENCAO: '100',
11
- DIFERIMENTO: '200',
12
- REDUCAO_BASE: '300',
13
- SUSPENSAO: '400',
14
- };
15
-
16
- /**
17
- * @typedef {Object} TributacaoRTC
18
- * @property {string} [cst]
19
- * @property {string} [cClassTrib]
20
- * @property {number} [vBC]
21
- * @property {number} [pIBSUF]
22
- * @property {number} [pIBSMun]
23
- * @property {number} [pCBS]
24
- * @property {number} [vIBSUF]
25
- * @property {number} [vIBSMun]
26
- * @property {number} [vCBS]
27
- */
28
-
29
- /**
30
- * @param {number} baseCalculo
31
- * @param {Omit<TributacaoRTC, 'vIBSUF'|'vIBSMun'|'vCBS'|'vBC'>} [aliquotas]
32
- * @returns {TributacaoRTC & { vBC: number }}
33
- */
34
- export function calcularIBSCBS(baseCalculo, aliquotas = {}) {
35
- const pIBSUF = aliquotas.pIBSUF ?? 0;
36
- const pIBSMun = aliquotas.pIBSMun ?? 0;
37
- const pCBS = aliquotas.pCBS ?? 0;
38
- const base = Number(baseCalculo) || 0;
39
-
40
- return {
41
- cst: aliquotas.cst ?? CST_IBSCBS.TRIBUTACAO_INTEGRAL,
42
- cClassTrib: aliquotas.cClassTrib,
43
- vBC: base,
44
- pIBSUF,
45
- pIBSMun,
46
- pCBS,
47
- vIBSUF: Number(((base * pIBSUF) / 100).toFixed(2)),
48
- vIBSMun: Number(((base * pIBSMun) / 100).toFixed(2)),
49
- vCBS: Number(((base * pCBS) / 100).toFixed(2)),
50
- };
51
- }
52
-
53
- /**
54
- * @param {TributacaoRTC} trib
55
- * @returns {string}
56
- */
57
- export function buildFragmentoIBSCBS(trib) {
58
- const dec = (v, d = 2) => Number(v ?? 0).toFixed(d);
59
- return `<IBSCBS>
60
- <CST>${trib.cst ?? CST_IBSCBS.TRIBUTACAO_INTEGRAL}</CST>
61
- ${trib.cClassTrib ? `<cClassTrib>${trib.cClassTrib}</cClassTrib>` : ''}
62
- <gIBSCBS>
63
- <vBC>${dec(trib.vBC ?? 0)}</vBC>
64
- <gIBSUF>
65
- <pIBSUF>${dec(trib.pIBSUF, 4)}</pIBSUF>
66
- <vIBSUF>${dec(trib.vIBSUF)}</vIBSUF>
67
- </gIBSUF>
68
- <gIBSMun>
69
- <pIBSMun>${dec(trib.pIBSMun, 4)}</pIBSMun>
70
- <vIBSMun>${dec(trib.vIBSMun)}</vIBSMun>
71
- </gIBSMun>
72
- <gCBS>
73
- <pCBS>${dec(trib.pCBS, 4)}</pCBS>
74
- <vCBS>${dec(trib.vCBS)}</vCBS>
75
- </gCBS>
76
- </gIBSCBS>
77
- </IBSCBS>`;
78
- }
79
-
80
- /**
81
- * Anexa grupo IBSCBS ao nó imposto (xmlbuilder2).
82
- * @param {import('xmlbuilder2').XMLBuilder} impostoNode
83
- * @param {TributacaoRTC} trib
84
- */
85
- export function appendIBSCBS(impostoNode, trib) {
86
- if (!trib) return;
87
- const dec = (v, d = 2) => Number(v ?? 0).toFixed(d);
88
- const ibs = impostoNode.ele('IBSCBS');
89
- ibs.ele('CST').txt(trib.cst ?? CST_IBSCBS.TRIBUTACAO_INTEGRAL).up();
90
- if (trib.cClassTrib) ibs.ele('cClassTrib').txt(trib.cClassTrib).up();
91
-
92
- const g = ibs.ele('gIBSCBS');
93
- g.ele('vBC').txt(dec(trib.vBC ?? 0)).up();
94
-
95
- const gUf = g.ele('gIBSUF');
96
- gUf.ele('pIBSUF').txt(dec(trib.pIBSUF, 4)).up();
97
- gUf.ele('vIBSUF').txt(dec(trib.vIBSUF)).up();
98
- gUf.up();
99
-
100
- const gMun = g.ele('gIBSMun');
101
- gMun.ele('pIBSMun').txt(dec(trib.pIBSMun, 4)).up();
102
- gMun.ele('vIBSMun').txt(dec(trib.vIBSMun)).up();
103
- gMun.up();
104
-
105
- const gCbs = g.ele('gCBS');
106
- gCbs.ele('pCBS').txt(dec(trib.pCBS, 4)).up();
107
- gCbs.ele('vCBS').txt(dec(trib.vCBS)).up();
108
- gCbs.up();
109
-
110
- g.up();
111
- ibs.up();
112
- }
113
-
114
- /**
115
- * Anexa totais IBS/CBS em &lt;total&gt; (irmão de ICMSTot).
116
- * @param {import('xmlbuilder2').XMLBuilder} totalParent
117
- * @param {{ vIBSUF: number, vIBSMun: number, vCBS: number }} totais
118
- */
119
- export function appendTotaisIBSCBS(totalParent, totais) {
120
- if (!totais) return;
121
- const dec = (v) => Number(v ?? 0).toFixed(2);
122
- const node = totalParent.ele('IBSCBSTot');
123
- node.ele('vIBS').txt(dec((totais.vIBSUF ?? 0) + (totais.vIBSMun ?? 0))).up();
124
- node.ele('vIBSUF').txt(dec(totais.vIBSUF)).up();
125
- node.ele('vIBSMun').txt(dec(totais.vIBSMun)).up();
126
- node.ele('vCBS').txt(dec(totais.vCBS)).up();
127
- node.up();
128
- }
129
-
130
- /**
131
- * @param {Array<{ reforma?: TributacaoRTC, valorTotal?: number }>} itens
132
- * @param {boolean} [autoCalcular]
133
- */
134
- export function normalizarItensReforma(itens = [], autoCalcular = false) {
135
- return itens.map((item) => {
136
- if (item.reforma) {
137
- if (item.reforma.vIBSUF == null && autoCalcular !== false) {
138
- return {
139
- ...item,
140
- reforma: calcularIBSCBS(item.reforma.vBC ?? item.valorTotal ?? 0, item.reforma),
141
- };
142
- }
143
- return item;
144
- }
145
- return item;
146
- });
147
- }
148
-
149
- /**
150
- * @param {Array<{ reforma?: TributacaoRTC }>} itens
151
- */
152
- export function somarTotaisReforma(itens = []) {
153
- return itens.reduce(
154
- (acc, item) => {
155
- const r = item.reforma;
156
- if (!r) return acc;
157
- acc.vIBSUF += r.vIBSUF ?? 0;
158
- acc.vIBSMun += r.vIBSMun ?? 0;
159
- acc.vCBS += r.vCBS ?? 0;
160
- return acc;
161
- },
162
- { vIBSUF: 0, vIBSMun: 0, vCBS: 0 }
163
- );
164
- }
165
-
166
- /**
167
- * @param {{ reformaTributaria?: boolean, itens?: Array<{ reforma?: unknown }> }} documentoOuOptions
168
- */
169
- export function reformaHabilitada(documentoOuOptions = {}) {
170
- if (documentoOuOptions.reformaTributaria) return true;
171
- if (Array.isArray(documentoOuOptions.itens)) {
172
- return documentoOuOptions.itens.some((i) => i.reforma);
173
- }
174
- return false;
175
- }
1
+ /**
2
+ * Constantes e helpers — Reforma Tributária (NT 2025.002 / PL_010).
3
+ * IBS + CBS. Injeção no builder NF-e/NFC-e quando item.reforma ou reformaTributaria.
4
+ */
5
+
6
+ export const REFORMA_LAYOUT = 'PL_010';
7
+
8
+ export const CST_IBSCBS = {
9
+ TRIBUTACAO_INTEGRAL: '000',
10
+ ISENCAO: '100',
11
+ DIFERIMENTO: '200',
12
+ REDUCAO_BASE: '300',
13
+ SUSPENSAO: '400',
14
+ };
15
+
16
+ /**
17
+ * @typedef {Object} TributacaoRTC
18
+ * @property {string} [cst]
19
+ * @property {string} [cClassTrib]
20
+ * @property {number} [vBC]
21
+ * @property {number} [pIBSUF]
22
+ * @property {number} [pIBSMun]
23
+ * @property {number} [pCBS]
24
+ * @property {number} [vIBSUF]
25
+ * @property {number} [vIBSMun]
26
+ * @property {number} [vCBS]
27
+ */
28
+
29
+ /**
30
+ * @param {number} baseCalculo
31
+ * @param {Omit<TributacaoRTC, 'vIBSUF'|'vIBSMun'|'vCBS'|'vBC'>} [aliquotas]
32
+ * @returns {TributacaoRTC & { vBC: number }}
33
+ */
34
+ export function calcularIBSCBS(baseCalculo, aliquotas = {}) {
35
+ const pIBSUF = aliquotas.pIBSUF ?? 0;
36
+ const pIBSMun = aliquotas.pIBSMun ?? 0;
37
+ const pCBS = aliquotas.pCBS ?? 0;
38
+ const base = Number(baseCalculo) || 0;
39
+
40
+ return {
41
+ cst: aliquotas.cst ?? CST_IBSCBS.TRIBUTACAO_INTEGRAL,
42
+ cClassTrib: aliquotas.cClassTrib,
43
+ vBC: base,
44
+ pIBSUF,
45
+ pIBSMun,
46
+ pCBS,
47
+ vIBSUF: Number(((base * pIBSUF) / 100).toFixed(2)),
48
+ vIBSMun: Number(((base * pIBSMun) / 100).toFixed(2)),
49
+ vCBS: Number(((base * pCBS) / 100).toFixed(2)),
50
+ };
51
+ }
52
+
53
+ /**
54
+ * @param {TributacaoRTC} trib
55
+ * @returns {string}
56
+ */
57
+ export function buildFragmentoIBSCBS(trib) {
58
+ const dec = (v, d = 2) => Number(v ?? 0).toFixed(d);
59
+ return `<IBSCBS>
60
+ <CST>${trib.cst ?? CST_IBSCBS.TRIBUTACAO_INTEGRAL}</CST>
61
+ ${trib.cClassTrib ? `<cClassTrib>${trib.cClassTrib}</cClassTrib>` : ''}
62
+ <gIBSCBS>
63
+ <vBC>${dec(trib.vBC ?? 0)}</vBC>
64
+ <gIBSUF>
65
+ <pIBSUF>${dec(trib.pIBSUF, 4)}</pIBSUF>
66
+ <vIBSUF>${dec(trib.vIBSUF)}</vIBSUF>
67
+ </gIBSUF>
68
+ <gIBSMun>
69
+ <pIBSMun>${dec(trib.pIBSMun, 4)}</pIBSMun>
70
+ <vIBSMun>${dec(trib.vIBSMun)}</vIBSMun>
71
+ </gIBSMun>
72
+ <gCBS>
73
+ <pCBS>${dec(trib.pCBS, 4)}</pCBS>
74
+ <vCBS>${dec(trib.vCBS)}</vCBS>
75
+ </gCBS>
76
+ </gIBSCBS>
77
+ </IBSCBS>`;
78
+ }
79
+
80
+ /**
81
+ * Anexa grupo IBSCBS ao nó imposto (xmlbuilder2).
82
+ * @param {import('xmlbuilder2').XMLBuilder} impostoNode
83
+ * @param {TributacaoRTC} trib
84
+ */
85
+ export function appendIBSCBS(impostoNode, trib) {
86
+ if (!trib) return;
87
+ const dec = (v, d = 2) => Number(v ?? 0).toFixed(d);
88
+ const ibs = impostoNode.ele('IBSCBS');
89
+ ibs.ele('CST').txt(trib.cst ?? CST_IBSCBS.TRIBUTACAO_INTEGRAL).up();
90
+ if (trib.cClassTrib) ibs.ele('cClassTrib').txt(trib.cClassTrib).up();
91
+
92
+ const g = ibs.ele('gIBSCBS');
93
+ g.ele('vBC').txt(dec(trib.vBC ?? 0)).up();
94
+
95
+ const gUf = g.ele('gIBSUF');
96
+ gUf.ele('pIBSUF').txt(dec(trib.pIBSUF, 4)).up();
97
+ gUf.ele('vIBSUF').txt(dec(trib.vIBSUF)).up();
98
+ gUf.up();
99
+
100
+ const gMun = g.ele('gIBSMun');
101
+ gMun.ele('pIBSMun').txt(dec(trib.pIBSMun, 4)).up();
102
+ gMun.ele('vIBSMun').txt(dec(trib.vIBSMun)).up();
103
+ gMun.up();
104
+
105
+ const gCbs = g.ele('gCBS');
106
+ gCbs.ele('pCBS').txt(dec(trib.pCBS, 4)).up();
107
+ gCbs.ele('vCBS').txt(dec(trib.vCBS)).up();
108
+ gCbs.up();
109
+
110
+ g.up();
111
+ ibs.up();
112
+ }
113
+
114
+ /**
115
+ * Anexa totais IBS/CBS em &lt;total&gt; (irmão de ICMSTot).
116
+ * @param {import('xmlbuilder2').XMLBuilder} totalParent
117
+ * @param {{ vIBSUF: number, vIBSMun: number, vCBS: number }} totais
118
+ */
119
+ export function appendTotaisIBSCBS(totalParent, totais) {
120
+ if (!totais) return;
121
+ const dec = (v) => Number(v ?? 0).toFixed(2);
122
+ const node = totalParent.ele('IBSCBSTot');
123
+ node.ele('vIBS').txt(dec((totais.vIBSUF ?? 0) + (totais.vIBSMun ?? 0))).up();
124
+ node.ele('vIBSUF').txt(dec(totais.vIBSUF)).up();
125
+ node.ele('vIBSMun').txt(dec(totais.vIBSMun)).up();
126
+ node.ele('vCBS').txt(dec(totais.vCBS)).up();
127
+ node.up();
128
+ }
129
+
130
+ /**
131
+ * @param {Array<{ reforma?: TributacaoRTC, valorTotal?: number }>} itens
132
+ * @param {boolean} [autoCalcular]
133
+ */
134
+ export function normalizarItensReforma(itens = [], autoCalcular = false) {
135
+ return itens.map((item) => {
136
+ if (item.reforma) {
137
+ if (item.reforma.vIBSUF == null && autoCalcular !== false) {
138
+ return {
139
+ ...item,
140
+ reforma: calcularIBSCBS(item.reforma.vBC ?? item.valorTotal ?? 0, item.reforma),
141
+ };
142
+ }
143
+ return item;
144
+ }
145
+ return item;
146
+ });
147
+ }
148
+
149
+ /**
150
+ * @param {Array<{ reforma?: TributacaoRTC }>} itens
151
+ */
152
+ export function somarTotaisReforma(itens = []) {
153
+ return itens.reduce(
154
+ (acc, item) => {
155
+ const r = item.reforma;
156
+ if (!r) return acc;
157
+ acc.vIBSUF += r.vIBSUF ?? 0;
158
+ acc.vIBSMun += r.vIBSMun ?? 0;
159
+ acc.vCBS += r.vCBS ?? 0;
160
+ return acc;
161
+ },
162
+ { vIBSUF: 0, vIBSMun: 0, vCBS: 0 }
163
+ );
164
+ }
165
+
166
+ /**
167
+ * @param {{ reformaTributaria?: boolean, itens?: Array<{ reforma?: unknown }> }} documentoOuOptions
168
+ */
169
+ export function reformaHabilitada(documentoOuOptions = {}) {
170
+ if (documentoOuOptions.reformaTributaria) return true;
171
+ if (Array.isArray(documentoOuOptions.itens)) {
172
+ return documentoOuOptions.itens.some((i) => i.reforma);
173
+ }
174
+ return false;
175
+ }
@@ -1,95 +1,95 @@
1
- import { UF_AUTORIZADOR, AUTORIZADOR_ENDPOINTS, SEFAZ_SERVICO } from './endpoints.registry.js';
2
- import { GhinfeError } from '../errors/GhinfeError.js';
3
-
4
- /**
5
- * Resolve endpoints SEFAZ por UF, ambiente e tipo de serviço.
6
- * Elimina necessidade de configurar URLs manualmente em produção.
7
- */
8
- export class SefazEndpointResolver {
9
- /**
10
- * @param {string} uf Sigla da UF (ex: "SP")
11
- * @returns {string} Código do autorizador (ex: "SVRS", "SP")
12
- */
13
- static obterAutorizador(uf) {
14
- const autorizador = UF_AUTORIZADOR[uf?.toUpperCase()];
15
- if (!autorizador) {
16
- throw new GhinfeError(`UF não mapeada para autorizador SEFAZ: ${uf}`, 'UF_AUTORIZADOR_NOT_FOUND');
17
- }
18
- return autorizador;
19
- }
20
-
21
- /**
22
- * @param {string} uf
23
- * @param {number} [ambiente] 1=Produção, 2=Homologação
24
- * @returns {Record<string, string>}
25
- */
26
- static obterEndpoints(uf, ambiente = 2) {
27
- const autorizador = this.obterAutorizador(uf);
28
- const endpoints = AUTORIZADOR_ENDPOINTS[autorizador]?.[ambiente];
29
-
30
- if (!endpoints) {
31
- throw new GhinfeError(
32
- `Endpoints não configurados para autorizador ${autorizador} ambiente ${ambiente}`,
33
- 'SEFAZ_ENDPOINTS_NOT_FOUND'
34
- );
35
- }
36
-
37
- return { autorizador, ambiente, endpoints };
38
- }
39
-
40
- /**
41
- * @param {{
42
- * uf: string,
43
- * ambiente?: number,
44
- * servico?: string,
45
- * modelo?: '55'|'65',
46
- * }} params
47
- * @returns {string}
48
- */
49
- static resolver(params) {
50
- const { endpoints } = this.obterEndpoints(params.uf, params.ambiente ?? 2);
51
- const servico = params.servico ?? SEFAZ_SERVICO.AUTORIZACAO;
52
- const url = endpoints[servico];
53
-
54
- if (!url) {
55
- throw new GhinfeError(
56
- `Serviço "${servico}" não disponível para UF ${params.uf} (autorizador ${this.obterAutorizador(params.uf)})`,
57
- 'SEFAZ_SERVICO_NOT_FOUND',
58
- { servico, uf: params.uf, modelo: params.modelo }
59
- );
60
- }
61
-
62
- return url;
63
- }
64
-
65
- /**
66
- * Configuração pronta para NFeSoapService.
67
- * @param {string} uf
68
- * @param {number} [ambiente]
69
- */
70
- static paraNFe(uf, ambiente = 2) {
71
- return {
72
- endpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.AUTORIZACAO, modelo: '55' }),
73
- eventoEndpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.EVENTO, modelo: '55' }),
74
- };
75
- }
76
-
77
- /**
78
- * NFC-e usa os mesmos webservices de autorização na maioria dos estados.
79
- * @param {string} uf
80
- * @param {number} [ambiente]
81
- */
82
- static paraNFCe(uf, ambiente = 2) {
83
- return {
84
- endpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.AUTORIZACAO, modelo: '65' }),
85
- eventoEndpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.EVENTO, modelo: '65' }),
86
- };
87
- }
88
-
89
- /** @returns {string[]} */
90
- static listarUFs() {
91
- return Object.keys(UF_AUTORIZADOR);
92
- }
93
- }
94
-
95
- export { SEFAZ_SERVICO };
1
+ import { UF_AUTORIZADOR, AUTORIZADOR_ENDPOINTS, SEFAZ_SERVICO } from './endpoints.registry.js';
2
+ import { GhinfeError } from '../errors/GhinfeError.js';
3
+
4
+ /**
5
+ * Resolve endpoints SEFAZ por UF, ambiente e tipo de serviço.
6
+ * Elimina necessidade de configurar URLs manualmente em produção.
7
+ */
8
+ export class SefazEndpointResolver {
9
+ /**
10
+ * @param {string} uf Sigla da UF (ex: "SP")
11
+ * @returns {string} Código do autorizador (ex: "SVRS", "SP")
12
+ */
13
+ static obterAutorizador(uf) {
14
+ const autorizador = UF_AUTORIZADOR[uf?.toUpperCase()];
15
+ if (!autorizador) {
16
+ throw new GhinfeError(`UF não mapeada para autorizador SEFAZ: ${uf}`, 'UF_AUTORIZADOR_NOT_FOUND');
17
+ }
18
+ return autorizador;
19
+ }
20
+
21
+ /**
22
+ * @param {string} uf
23
+ * @param {number} [ambiente] 1=Produção, 2=Homologação
24
+ * @returns {Record<string, string>}
25
+ */
26
+ static obterEndpoints(uf, ambiente = 2) {
27
+ const autorizador = this.obterAutorizador(uf);
28
+ const endpoints = AUTORIZADOR_ENDPOINTS[autorizador]?.[ambiente];
29
+
30
+ if (!endpoints) {
31
+ throw new GhinfeError(
32
+ `Endpoints não configurados para autorizador ${autorizador} ambiente ${ambiente}`,
33
+ 'SEFAZ_ENDPOINTS_NOT_FOUND'
34
+ );
35
+ }
36
+
37
+ return { autorizador, ambiente, endpoints };
38
+ }
39
+
40
+ /**
41
+ * @param {{
42
+ * uf: string,
43
+ * ambiente?: number,
44
+ * servico?: string,
45
+ * modelo?: '55'|'65',
46
+ * }} params
47
+ * @returns {string}
48
+ */
49
+ static resolver(params) {
50
+ const { endpoints } = this.obterEndpoints(params.uf, params.ambiente ?? 2);
51
+ const servico = params.servico ?? SEFAZ_SERVICO.AUTORIZACAO;
52
+ const url = endpoints[servico];
53
+
54
+ if (!url) {
55
+ throw new GhinfeError(
56
+ `Serviço "${servico}" não disponível para UF ${params.uf} (autorizador ${this.obterAutorizador(params.uf)})`,
57
+ 'SEFAZ_SERVICO_NOT_FOUND',
58
+ { servico, uf: params.uf, modelo: params.modelo }
59
+ );
60
+ }
61
+
62
+ return url;
63
+ }
64
+
65
+ /**
66
+ * Configuração pronta para NFeSoapService.
67
+ * @param {string} uf
68
+ * @param {number} [ambiente]
69
+ */
70
+ static paraNFe(uf, ambiente = 2) {
71
+ return {
72
+ endpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.AUTORIZACAO, modelo: '55' }),
73
+ eventoEndpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.EVENTO, modelo: '55' }),
74
+ };
75
+ }
76
+
77
+ /**
78
+ * NFC-e usa os mesmos webservices de autorização na maioria dos estados.
79
+ * @param {string} uf
80
+ * @param {number} [ambiente]
81
+ */
82
+ static paraNFCe(uf, ambiente = 2) {
83
+ return {
84
+ endpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.AUTORIZACAO, modelo: '65' }),
85
+ eventoEndpoint: this.resolver({ uf, ambiente, servico: SEFAZ_SERVICO.EVENTO, modelo: '65' }),
86
+ };
87
+ }
88
+
89
+ /** @returns {string[]} */
90
+ static listarUFs() {
91
+ return Object.keys(UF_AUTORIZADOR);
92
+ }
93
+ }
94
+
95
+ export { SEFAZ_SERVICO };
@@ -0,0 +1,38 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIGrDCCBJSgAwIBAgIJANLVi0S/gZNCMA0GCSqGSIb3DQEBDQUAMIGYMQswCQYD
3
+ VQQGEwJCUjETMBEGA1UECgwKSUNQLUJyYXNpbDE9MDsGA1UECww0SW5zdGl0dXRv
4
+ IE5hY2lvbmFsIGRlIFRlY25vbG9naWEgZGEgSW5mb3JtYWNhbyAtIElUSTE1MDMG
5
+ A1UEAwwsQXV0b3JpZGFkZSBDZXJ0aWZpY2Fkb3JhIFJhaXogQnJhc2lsZWlyYSB2
6
+ MTAwHhcNMTkwNzAxMTkxNTU5WhcNMzIwNzAxMTIwMDU5WjCBmDELMAkGA1UEBhMC
7
+ QlIxEzARBgNVBAoMCklDUC1CcmFzaWwxPTA7BgNVBAsMNEluc3RpdHV0byBOYWNp
8
+ b25hbCBkZSBUZWNub2xvZ2lhIGRhIEluZm9ybWFjYW8gLSBJVEkxNTAzBgNVBAMM
9
+ LEF1dG9yaWRhZGUgQ2VydGlmaWNhZG9yYSBSYWl6IEJyYXNpbGVpcmEgdjEwMIIC
10
+ IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAk3AxKl1ZtP0pNyjChqO7qNkn
11
+ +/sClZeqiV/Kd7KnnbkDbI2y3VWcUG7feCE/deIxot6GH6JXncRG794UZl+4doD0
12
+ D0/cEwBd4DvrDSZm0RT40xhmYYOTxZDJxv+coTHdmsT5aNmSkktfjzYX4HQHh/7M
13
+ em+kTOpT/3E4K6B7KVs9HkOT7nXx5yU1qYbVWqI0qpJM9mOTSFx8C9HiKcHvLCvt
14
+ 1ioXKPAmFuHPkayOcXP2MXeb+VRNjWKU4E+L2t5uZPKVx1M/9i1DztlLb4K8OfYg
15
+ GaPDUSF1sxnoGk5qZHLleO6KjCpmuQepmgsBvxi2YNO7X2YUwQQx1AXNSolgtkAR
16
+ 5gt+1WzxhbFUhItQqlhqxgWHefLmiT5T/Ctz/P2v+zSO4efkkIzsi1iwD+ypZvM2
17
+ lnIvB24RcSN6jzmCahLPX4CwjwIK6JsSoMVxIhpZHCguUP4LXqP8IWUZ6WgS/4zB
18
+ 7B9E0EICl2rM1PRy+6ulv+ZOW256e8a0pijUB+hXM1msUq9L92476FAAX8va3sP7
19
+ +Uut94+bGHmubcTLImWUPrxNT7QyrvE3FyHicfiHioeFL2oV4cXTLZrEq2wS8R4P
20
+ KPdSzNn5Z9e2uMEGYQaSNO+OwvVycpIhOBOqrm12wJ9ZhWKtM5UOo34/o37r5ZBI
21
+ TYXAGbhqQDB9mWXwH+0CAwEAAaOB9jCB8zBOBgNVHSAERzBFMEMGBWBMAQEAMDow
22
+ OAYIKwYBBQUHAgEWLGh0dHA6Ly9hY3JhaXouaWNwYnJhc2lsLmdvdi5ici9EUENh
23
+ Y3JhaXoucGRmMEAGA1UdHwQ5MDcwNaAzoDGGL2h0dHA6Ly9hY3JhaXouaWNwYnJh
24
+ c2lsLmdvdi5ici9MQ1JhY3JhaXp2MTAuY3JsMB8GA1UdIwQYMBaAFHTzfv/8n1N6
25
+ 8Xzrqz6kptoYukVjMB0GA1UdDgQWBBR0837//J9TevF866s+pKbaGLpFYzAPBgNV
26
+ HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQ0FAAOCAgEA
27
+ eCNhBSuy/Ih/T+1VOtAJju85SrtoE3vET1qXASpmjQllDHG/ph7VFNRAkC+gha+B
28
+ CbjoA5oJ/8wwl+Qdp1KGz6nXXFTLx3osU+kjm0srmBf9nyXHPqvFyvBeB0A7sYb7
29
+ TmII9GKD20oCxsdkccR/oE/JuTaNnGq0GYZ2aDb5v62uLi21Y6P9UBiTxZqQ4ojW
30
+ ET6kXNjlK238jpXv17FR8Sg3VusCvX7Q8eJkavvHHZDeWck2fSA+ycAc2JeL2Z0B
31
+ MSxGWpH32WM9J8+6XqCJUXHiWEV0zCE8wDYiYC+047pTxQI/gB/FcU7jvylh98DJ
32
+ kQPHd/Tp6Og3ynlDA9n9uBbxYHVRZs9vsZ/7xTFaxRe+zk8dhgKgZ/3RrcMFB570
33
+ 2t8LFbyuUE/kQVY6rZ0QJ9qMWQ7VPLRwRhiMeU3k8WDJb/tBbOXHBqldTbWyQ+mp
34
+ MEDWhbrzE/IED82wAuO23Tb05cYk2xC7+Izef8fSc3XdJDuPSbcDpWukzyCDtSEH
35
+ isLiGEtIbYRiPsF3czlQPsnIEVoTTCWxHCH1zYR6zScSv18Qh69qVe2J40K5jZoP
36
+ GEOhq/oKhVJQAdvAFW5Odp7mF3Tk9nivjjsctJSxY26LFiV5GRV+07SSse4ti0aO
37
+ jO5PLg5SWjfcOtBG2rz02EIvQAmLcb0kGBtfdj0lW/w=
38
+ -----END CERTIFICATE-----