@sinete/nfe 0.0.0 → 0.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/LICENSE +202 -0
- package/NOTICE +11 -0
- package/README.md +148 -1
- package/dist/build/build.d.ts +127 -0
- package/dist/build/build.d.ts.map +1 -0
- package/dist/build/destinatario.d.ts +19 -0
- package/dist/build/destinatario.d.ts.map +1 -0
- package/dist/build/ibscbs.d.ts +27 -0
- package/dist/build/ibscbs.d.ts.map +1 -0
- package/dist/build/icms.d.ts +42 -0
- package/dist/build/icms.d.ts.map +1 -0
- package/dist/build/nfce.d.ts +122 -0
- package/dist/build/nfce.d.ts.map +1 -0
- package/dist/build/pl.d.ts +19 -0
- package/dist/build/pl.d.ts.map +1 -0
- package/dist/build/rejeicoes.d.ts +52 -0
- package/dist/build/rejeicoes.d.ts.map +1 -0
- package/dist/build/tributos.d.ts +45 -0
- package/dist/build/tributos.d.ts.map +1 -0
- package/dist/build/values.d.ts +48 -0
- package/dist/build/values.d.ts.map +1 -0
- package/dist/decimal.d.ts +66 -0
- package/dist/decimal.d.ts.map +1 -0
- package/dist/format.d.ts +48 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/ibs-cbs.d.ts +14 -0
- package/dist/ibs-cbs.d.ts.map +1 -0
- package/dist/ibs-cbs.js +43 -0
- package/dist/ibs-cbs.js.map +10 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4399 -0
- package/dist/index.js.map +33 -0
- package/dist/issues.d.ts +24 -0
- package/dist/issues.d.ts.map +1 -0
- package/dist/model.d.ts +861 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/ports.d.ts +109 -0
- package/dist/ports.d.ts.map +1 -0
- package/dist/rotulo.d.ts +12 -0
- package/dist/rotulo.d.ts.map +1 -0
- package/dist/rtc.d.ts +65 -0
- package/dist/rtc.d.ts.map +1 -0
- package/dist/services/client.d.ts +277 -0
- package/dist/services/client.d.ts.map +1 -0
- package/dist/services/gzip.d.ts +7 -0
- package/dist/services/gzip.d.ts.map +1 -0
- package/dist/services/index.d.ts +14 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/outcome.d.ts +15 -0
- package/dist/services/outcome.d.ts.map +1 -0
- package/dist/services/proc.d.ts +41 -0
- package/dist/services/proc.d.ts.map +1 -0
- package/dist/services/recuperar.d.ts +28 -0
- package/dist/services/recuperar.d.ts.map +1 -0
- package/dist/services/resolver.d.ts +88 -0
- package/dist/services/resolver.d.ts.map +1 -0
- package/dist/services/soap.d.ts +43 -0
- package/dist/services/soap.d.ts.map +1 -0
- package/dist/time.d.ts +12 -0
- package/dist/time.d.ts.map +1 -0
- package/dist/versao-gerada.d.ts +3 -0
- package/dist/versao-gerada.d.ts.map +1 -0
- package/package.json +58 -3
- package/src/build/build.ts +1503 -0
- package/src/build/destinatario.ts +212 -0
- package/src/build/ibscbs.ts +135 -0
- package/src/build/icms.ts +645 -0
- package/src/build/nfce.ts +425 -0
- package/src/build/pl.ts +73 -0
- package/src/build/rejeicoes.ts +142 -0
- package/src/build/tributos.ts +217 -0
- package/src/build/values.ts +126 -0
- package/src/data/arredondamento.json +30 -0
- package/src/data/cstat.json +36 -0
- package/src/data/fusos.json +17 -0
- package/src/data/nfce-urls.json +170 -0
- package/src/data/produtor-rural.json +17 -0
- package/src/data/reforma.json +6 -0
- package/src/data/resp-tec.json +13 -0
- package/src/data/servicos.json +44 -0
- package/src/data/suframa.json +7 -0
- package/src/decimal.ts +232 -0
- package/src/format.ts +65 -0
- package/src/ibs-cbs.ts +89 -0
- package/src/index.ts +155 -0
- package/src/issues.ts +80 -0
- package/src/model.ts +1033 -0
- package/src/ports.ts +96 -0
- package/src/rotulo.ts +137 -0
- package/src/rtc.ts +305 -0
- package/src/services/client.ts +1116 -0
- package/src/services/gzip.ts +26 -0
- package/src/services/index.ts +45 -0
- package/src/services/outcome.ts +50 -0
- package/src/services/proc.ts +165 -0
- package/src/services/recuperar.ts +93 -0
- package/src/services/resolver.ts +127 -0
- package/src/services/soap.ts +133 -0
- package/src/time.ts +23 -0
- package/src/versao-gerada.ts +3 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,4399 @@
|
|
|
1
|
+
// packages/nfe/src/build/build.ts
|
|
2
|
+
import {
|
|
3
|
+
ErroDeConfiguracao as ErroDeConfiguracao2,
|
|
4
|
+
ErroDeValidacao,
|
|
5
|
+
ehUf as ehUf2,
|
|
6
|
+
formatarVerProc,
|
|
7
|
+
relogioFixo as relogioFixo2,
|
|
8
|
+
tpAmbDoAmbiente as tpAmbDoAmbiente2,
|
|
9
|
+
ufPorSigla as ufPorSigla2
|
|
10
|
+
} from "@sinete/core";
|
|
11
|
+
import { assinarXml, codificarBase64 as codificarBase642, lerXml as lerXml3, primeiroFilho as primeiroFilho3 } from "@sinete/core/xml";
|
|
12
|
+
import { ErroSerializacao, serializar as serializar2, validar as validar3 } from "@sinete/schemas";
|
|
13
|
+
import { TIS as TISCt, TNFe_infNFeSupl, TTribNFe as TTribNFeCt } from "@sinete/schemas/nfe/PL_010f";
|
|
14
|
+
import { lerChaveAcesso, lerCnpj as lerCnpj3, lerCpf, lerIe, montarChaveAcesso } from "@sinete/validators";
|
|
15
|
+
// packages/nfe/src/data/arredondamento.json
|
|
16
|
+
var arredondamento_default = {
|
|
17
|
+
descricao: "Modo de arredondamento dos valores calculados pelo builder, por família de campo. HALF_UP é o arredondamento comercial; HALF_EVEN é o bancário (NBR 5891). Quem emite pode sobrepor por família em MontarNfeOpcoes.arredondamento.",
|
|
18
|
+
atualizadoEm: "2026-09-26",
|
|
19
|
+
familias: {
|
|
20
|
+
produto: {
|
|
21
|
+
modo: "HALF_UP",
|
|
22
|
+
fonte: "MOC 7.0 Anexo I, nota (*4): o produto de multiplicações arredonda em 2 casas, com tolerância de R$ 0,01; o modo não é fixado. vProd = qCom x vUnCom (I11)."
|
|
23
|
+
},
|
|
24
|
+
icms: {
|
|
25
|
+
modo: "HALF_UP",
|
|
26
|
+
fonte: "MOC 7.0 Anexo I, nota (*4) das regras N17, N16a, N16c, N23d: 2 casas, tolerância de R$ 0,01, modo não fixado."
|
|
27
|
+
},
|
|
28
|
+
ipi: {
|
|
29
|
+
modo: "HALF_UP",
|
|
30
|
+
fonte: "MOC 7.0 Anexo I, nota (*4): 2 casas, tolerância de R$ 0,01."
|
|
31
|
+
},
|
|
32
|
+
pisCofins: {
|
|
33
|
+
modo: "HALF_UP",
|
|
34
|
+
fonte: "MOC 7.0 Anexo I, nota (*4): 2 casas, tolerância de R$ 0,01."
|
|
35
|
+
},
|
|
36
|
+
issqn: {
|
|
37
|
+
modo: "HALF_UP",
|
|
38
|
+
fonte: "MOC 7.0 Anexo I, nota (*4): 2 casas, tolerância de R$ 0,01."
|
|
39
|
+
},
|
|
40
|
+
ibsCbs: {
|
|
41
|
+
modo: "HALF_EVEN",
|
|
42
|
+
fonte: "NT 2025.002 v1.51, RV UB35-10 e seguintes (tolerância de 0,01) e ADR 0007 (a Calculadora da RFB arredonda em HALF_EVEN)."
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
// packages/nfe/src/data/produtor-rural.json
|
|
47
|
+
var produtor_rural_default = {
|
|
48
|
+
descricao: "Regras do produtor rural que variam no tempo ou por UF. refNFP: a nota fiscal de produtor em papel (modelo 04) foi extinta; uma NF-e ainda pode referenciar uma nota modelo 04 emitida antes do fim da vigência na UF da nota referenciada. vedadaDesde é o primeiro AAMM em que a UF não aceita mais nota modelo 04 emitida; a referência a nota com AAMM igual ou posterior é recusada pelo builder. series: faixas de série por tipo de emitente na emissão pelo contribuinte (procEmi 0, a única que o montarNfe monta).",
|
|
49
|
+
atualizadoEm: "2026-09-28",
|
|
50
|
+
refNFP: {
|
|
51
|
+
modelo04: {
|
|
52
|
+
vedadaDesde: "2601",
|
|
53
|
+
fonte: "Ajuste SINIEF 10/2022 (extinção da nota fiscal de produtor modelo 4, com prazos prorrogados até 05/01/2026) e avisos das SEFAZ (RS e SP: fim do talão em 05/01/2026)."
|
|
54
|
+
},
|
|
55
|
+
ufs: {}
|
|
56
|
+
},
|
|
57
|
+
series: {
|
|
58
|
+
cpf: [920, 969],
|
|
59
|
+
fonte: "MOC 7.0 Anexo I, RV B07 e BA02-30: séries 920 a 969 reservadas à NF-e emitida por pessoa física (CPF).",
|
|
60
|
+
cnpj: [0, 889],
|
|
61
|
+
fonteCnpj: "MOC 7.0 Anexo I, RV C02-30 (emitente CNPJ: séries 0 a 909, rejeição 503) e B26-10 (emissão pelo contribuinte, procEmi 0: séries 0 a 889 ou 920 a 969, rejeição 244): as duas juntas deixam 0 a 889. A NT 2026.001 v1.02b (PAA, produção em 05/10/2026) abre 980 a 989 na C02-30 e mantém a B26-10, então a faixa continua 0 a 889."
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
// packages/nfe/src/data/reforma.json
|
|
65
|
+
var reforma_default = {
|
|
66
|
+
descricao: "Parâmetros da reforma tributária no total do item e da nota. vItemSomaTributosDesde: a partir desta data do fato gerador (Brasília), vItem soma vIBS, vCBS, vIS e os totais monofásicos; antes dela, não soma (exceção de 2025 e 2026).",
|
|
67
|
+
atualizadoEm: "2026-09-26",
|
|
68
|
+
vItemSomaTributosDesde: "2027-01-01",
|
|
69
|
+
fonte: "NT 2025.002 v1.51, RV VB01-10 e VB01-20, Exceção 1: em 2025 e 2026 não somar vIBS, vCBS, vIS, vTotIBSMonoItem e vTotCBSMonoItem."
|
|
70
|
+
};
|
|
71
|
+
// packages/nfe/src/data/resp-tec.json
|
|
72
|
+
var resp_tec_default = {
|
|
73
|
+
descricao: "Exigência do grupo infRespTec e do CSRT por UF do emitente, com vigência por ambiente. infRespTec: 'obrigatorio' faz o builder recusar a nota sem responsável técnico; 'opcional' só o inclui quando informado. csrt: 'obrigatorio' exige idCSRT e hashCSRT (rejeição 975). Datas no formato AAAA-MM-DD, a partir de 00:00 de Brasília. UF ausente usa o padrão. A adesão é de cada UF (NT 2018.005); quem emite pode sobrepor em MontarNfeOpcoes.",
|
|
74
|
+
atualizadoEm: "2026-09-26",
|
|
75
|
+
fonte: "NT 2018.005 v1.50 (responsável técnico e CSRT, adesão a critério da UF)",
|
|
76
|
+
padrao: { infRespTec: "opcional", csrt: "opcional" },
|
|
77
|
+
ufs: {
|
|
78
|
+
PR: {
|
|
79
|
+
csrt: { homologacao: "2025-03-02", producao: "2025-09-15" },
|
|
80
|
+
infRespTec: { homologacao: "2025-03-02", producao: "2025-09-15" },
|
|
81
|
+
fonte: "SEFAZ-PR, NT 2018.005 v1.50: CSRT obrigatório na NF-e em homologação desde 02/03/2025 e em produção desde 15/09/2025 (aviso da SEFAZ-PR, reproduzido em https://inventti.com.br/nf-e-nfc-e-nt-2018-005-versao-1-50-prorroga-regras-de-validacao-para-uf-do-parana/)."
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
// packages/nfe/src/decimal.ts
|
|
87
|
+
import { ErroDeConfiguracao } from "@sinete/core";
|
|
88
|
+
var DECIMAL_TEXT = /^([+-])?(\d+)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$|^([+-])?\.(\d+)(?:[eE]([+-]?\d+))?$/;
|
|
89
|
+
var MAX_SCALE = 64;
|
|
90
|
+
function pow10(n) {
|
|
91
|
+
return 10n ** BigInt(n);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
class Decimal {
|
|
95
|
+
coef;
|
|
96
|
+
scale;
|
|
97
|
+
constructor(coef, scale) {
|
|
98
|
+
this.coef = coef;
|
|
99
|
+
this.scale = scale;
|
|
100
|
+
}
|
|
101
|
+
static ZERO = new Decimal(0n, 0);
|
|
102
|
+
static ONE = new Decimal(1n, 0);
|
|
103
|
+
static HUNDRED = new Decimal(100n, 0);
|
|
104
|
+
static fromParts(coef, scale) {
|
|
105
|
+
if (!Number.isInteger(scale) || scale < 0 || scale > MAX_SCALE)
|
|
106
|
+
throw new ErroDeConfiguracao(`escala inválida: ${scale}`);
|
|
107
|
+
return new Decimal(coef, scale);
|
|
108
|
+
}
|
|
109
|
+
static of(input) {
|
|
110
|
+
const d = Decimal.tryOf(input);
|
|
111
|
+
if (d === undefined)
|
|
112
|
+
throw new ErroDeConfiguracao(`número decimal inválido: ${JSON.stringify(String(input))}`);
|
|
113
|
+
return d;
|
|
114
|
+
}
|
|
115
|
+
static tryOf(input) {
|
|
116
|
+
if (input instanceof Decimal)
|
|
117
|
+
return input;
|
|
118
|
+
if (typeof input === "bigint")
|
|
119
|
+
return new Decimal(input, 0);
|
|
120
|
+
if (typeof input === "number") {
|
|
121
|
+
if (!Number.isFinite(input))
|
|
122
|
+
return;
|
|
123
|
+
return Decimal.tryOf(String(input));
|
|
124
|
+
}
|
|
125
|
+
if (typeof input !== "string")
|
|
126
|
+
return;
|
|
127
|
+
const m = DECIMAL_TEXT.exec(input);
|
|
128
|
+
if (!m)
|
|
129
|
+
return;
|
|
130
|
+
const sign = (m[1] ?? m[5]) === "-" ? -1n : 1n;
|
|
131
|
+
const intPart = m[2] ?? "";
|
|
132
|
+
const frac = m[3] ?? m[6] ?? "";
|
|
133
|
+
const exp = Number(m[4] ?? m[7] ?? "0");
|
|
134
|
+
if (!Number.isSafeInteger(exp) || Math.abs(exp) > MAX_SCALE)
|
|
135
|
+
return;
|
|
136
|
+
let coef = BigInt(`${intPart}${frac}` || "0") * sign;
|
|
137
|
+
let scale = frac.length - exp;
|
|
138
|
+
if (scale < 0) {
|
|
139
|
+
coef *= pow10(-scale);
|
|
140
|
+
scale = 0;
|
|
141
|
+
}
|
|
142
|
+
if (scale > MAX_SCALE)
|
|
143
|
+
return;
|
|
144
|
+
return new Decimal(coef, scale);
|
|
145
|
+
}
|
|
146
|
+
aligned(other) {
|
|
147
|
+
if (this.scale === other.scale)
|
|
148
|
+
return [this.coef, other.coef, this.scale];
|
|
149
|
+
if (this.scale > other.scale)
|
|
150
|
+
return [this.coef, other.coef * pow10(this.scale - other.scale), this.scale];
|
|
151
|
+
return [this.coef * pow10(other.scale - this.scale), other.coef, other.scale];
|
|
152
|
+
}
|
|
153
|
+
plus(other) {
|
|
154
|
+
const [a, b, s] = this.aligned(Decimal.of(other));
|
|
155
|
+
return new Decimal(a + b, s);
|
|
156
|
+
}
|
|
157
|
+
minus(other) {
|
|
158
|
+
const [a, b, s] = this.aligned(Decimal.of(other));
|
|
159
|
+
return new Decimal(a - b, s);
|
|
160
|
+
}
|
|
161
|
+
times(other) {
|
|
162
|
+
const o = Decimal.of(other);
|
|
163
|
+
const scale = this.scale + o.scale;
|
|
164
|
+
if (scale > MAX_SCALE) {
|
|
165
|
+
return new Decimal(this.coef * o.coef, scale).round(MAX_SCALE, "HALF_EVEN");
|
|
166
|
+
}
|
|
167
|
+
return new Decimal(this.coef * o.coef, scale);
|
|
168
|
+
}
|
|
169
|
+
dividedBy(other, scale, mode) {
|
|
170
|
+
const o = Decimal.of(other);
|
|
171
|
+
if (o.coef === 0n)
|
|
172
|
+
throw new ErroDeConfiguracao("divisão por zero");
|
|
173
|
+
const shift = o.scale + scale + 1 - this.scale;
|
|
174
|
+
const num = shift >= 0 ? this.coef * pow10(shift) : this.coef;
|
|
175
|
+
const den = shift >= 0 ? o.coef : o.coef * pow10(-shift);
|
|
176
|
+
const q = num / den;
|
|
177
|
+
const exact = q * den === num;
|
|
178
|
+
return roundCoef(q, scale + 1, scale, mode, !exact);
|
|
179
|
+
}
|
|
180
|
+
percent(rate) {
|
|
181
|
+
const product = this.times(rate);
|
|
182
|
+
return new Decimal(product.coef, product.scale + 2);
|
|
183
|
+
}
|
|
184
|
+
negate() {
|
|
185
|
+
return new Decimal(-this.coef, this.scale);
|
|
186
|
+
}
|
|
187
|
+
abs() {
|
|
188
|
+
return this.coef < 0n ? this.negate() : this;
|
|
189
|
+
}
|
|
190
|
+
round(scale, mode) {
|
|
191
|
+
if (!Number.isInteger(scale) || scale < 0)
|
|
192
|
+
throw new ErroDeConfiguracao(`casas decimais inválidas: ${scale}`);
|
|
193
|
+
if (scale >= this.scale)
|
|
194
|
+
return new Decimal(this.coef * pow10(scale - this.scale), scale);
|
|
195
|
+
return roundCoef(this.coef, this.scale, scale, mode, false);
|
|
196
|
+
}
|
|
197
|
+
compare(other) {
|
|
198
|
+
const [a, b] = this.aligned(Decimal.of(other));
|
|
199
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
200
|
+
}
|
|
201
|
+
eq(other) {
|
|
202
|
+
return this.compare(other) === 0;
|
|
203
|
+
}
|
|
204
|
+
lt(other) {
|
|
205
|
+
return this.compare(other) < 0;
|
|
206
|
+
}
|
|
207
|
+
gt(other) {
|
|
208
|
+
return this.compare(other) > 0;
|
|
209
|
+
}
|
|
210
|
+
isZero() {
|
|
211
|
+
return this.coef === 0n;
|
|
212
|
+
}
|
|
213
|
+
isNegative() {
|
|
214
|
+
return this.coef < 0n;
|
|
215
|
+
}
|
|
216
|
+
significantScale() {
|
|
217
|
+
if (this.coef === 0n)
|
|
218
|
+
return 0;
|
|
219
|
+
let c = this.coef;
|
|
220
|
+
let s = this.scale;
|
|
221
|
+
while (s > 0 && c % 10n === 0n) {
|
|
222
|
+
c /= 10n;
|
|
223
|
+
s--;
|
|
224
|
+
}
|
|
225
|
+
return s;
|
|
226
|
+
}
|
|
227
|
+
toFixed(scale, mode = "HALF_UP") {
|
|
228
|
+
const r = this.round(scale, mode);
|
|
229
|
+
const neg = r.coef < 0n;
|
|
230
|
+
const digits = (neg ? -r.coef : r.coef).toString().padStart(scale + 1, "0");
|
|
231
|
+
const int = digits.slice(0, digits.length - scale);
|
|
232
|
+
const frac = digits.slice(digits.length - scale);
|
|
233
|
+
return `${neg ? "-" : ""}${int}${scale > 0 ? `.${frac}` : ""}`;
|
|
234
|
+
}
|
|
235
|
+
toString() {
|
|
236
|
+
return this.toFixed(this.significantScale());
|
|
237
|
+
}
|
|
238
|
+
toJSON() {
|
|
239
|
+
return this.toString();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
function roundCoef(coef, from, to, mode, sticky) {
|
|
243
|
+
const div = pow10(from - to);
|
|
244
|
+
const neg = coef < 0n;
|
|
245
|
+
const abs = neg ? -coef : coef;
|
|
246
|
+
let q = abs / div;
|
|
247
|
+
const r = abs % div;
|
|
248
|
+
if (mode !== "DOWN" && (r !== 0n || sticky)) {
|
|
249
|
+
const twice = r * 2n;
|
|
250
|
+
const above = twice > div || twice === div && sticky;
|
|
251
|
+
const tie = twice === div && !sticky;
|
|
252
|
+
if (above || tie && (mode === "HALF_UP" || mode === "HALF_EVEN" && q % 2n === 1n))
|
|
253
|
+
q += 1n;
|
|
254
|
+
}
|
|
255
|
+
return Decimal.fromParts(neg ? -q : q, to);
|
|
256
|
+
}
|
|
257
|
+
function dec(valor) {
|
|
258
|
+
return Decimal.of(valor);
|
|
259
|
+
}
|
|
260
|
+
function sum(valores) {
|
|
261
|
+
let acc = Decimal.ZERO;
|
|
262
|
+
for (const v of valores)
|
|
263
|
+
acc = acc.plus(v);
|
|
264
|
+
return acc;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// packages/nfe/src/format.ts
|
|
268
|
+
var D1302 = { nome: "TDec_1302", min: 2, max: 2, digitosInteiros: 13 };
|
|
269
|
+
var D1302_OPC = { nome: "TDec_1302Opc", min: 2, max: 2, digitosInteiros: 13, naoNulo: true };
|
|
270
|
+
var D0302A04 = { nome: "TDec_0302a04", min: 2, max: 4, digitosInteiros: 3 };
|
|
271
|
+
var D0302A04_OPC = { nome: "TDec_0302a04Opc", min: 2, max: 4, digitosInteiros: 3 };
|
|
272
|
+
var D0302 = { nome: "TDec_0302Max100", min: 2, max: 2, digitosInteiros: 3 };
|
|
273
|
+
var D1104V = { nome: "TDec_1104v", min: 0, max: 4, digitosInteiros: 11 };
|
|
274
|
+
var D1104 = { nome: "TDec_1104", min: 4, max: 4, digitosInteiros: 11 };
|
|
275
|
+
var D1110V = { nome: "TDec_1110v", min: 0, max: 10, digitosInteiros: 11 };
|
|
276
|
+
var D1204V = { nome: "TDec_1204v", min: 0, max: 4, digitosInteiros: 12 };
|
|
277
|
+
var D1204 = { nome: "TDec_1204", min: 4, max: 4, digitosInteiros: 12 };
|
|
278
|
+
var D1203 = { nome: "TDec_1203", min: 3, max: 3, digitosInteiros: 12 };
|
|
279
|
+
function formatarDecimal(valor, formato, modo = "HALF_UP") {
|
|
280
|
+
const r = valor.round(formato.max, modo);
|
|
281
|
+
let places = Math.max(formato.min, Math.min(formato.max, r.significantScale()));
|
|
282
|
+
if (formato.minimoAbaixoDeUm !== undefined && !r.isZero() && r.abs().lt(1))
|
|
283
|
+
places = Math.max(places, formato.minimoAbaixoDeUm);
|
|
284
|
+
return r.toFixed(places, modo);
|
|
285
|
+
}
|
|
286
|
+
function problemaDeFormato(valor, formato) {
|
|
287
|
+
if (valor.isNegative())
|
|
288
|
+
return "valor negativo";
|
|
289
|
+
if (formato.naoNulo && valor.isZero())
|
|
290
|
+
return "valor zero não é aceito neste campo";
|
|
291
|
+
if (valor.significantScale() > formato.max)
|
|
292
|
+
return `mais de ${formato.max} casas decimais`;
|
|
293
|
+
const intDigits = valor.round(0, "DOWN").abs().toString().replace(/^0$/, "").length;
|
|
294
|
+
if (intDigits > formato.digitosInteiros)
|
|
295
|
+
return `mais de ${formato.digitosInteiros} dígitos inteiros`;
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// packages/nfe/src/issues.ts
|
|
300
|
+
var CODIGOS_OCORRENCIA_NFE = [
|
|
301
|
+
"campo_obrigatorio",
|
|
302
|
+
"campo_invalido",
|
|
303
|
+
"campo_fora_do_pl",
|
|
304
|
+
"decimal_invalido",
|
|
305
|
+
"valor_divergente",
|
|
306
|
+
"combinacao_invalida",
|
|
307
|
+
"modelo_nao_suportado",
|
|
308
|
+
"serie_invalida",
|
|
309
|
+
"documento_invalido",
|
|
310
|
+
"ie_invalida",
|
|
311
|
+
"chave_invalida",
|
|
312
|
+
"referencia_vedada",
|
|
313
|
+
"resp_tec_obrigatorio",
|
|
314
|
+
"csrt_obrigatorio",
|
|
315
|
+
"ibscbs_calculo",
|
|
316
|
+
"ibscbs_base_ausente",
|
|
317
|
+
"ibscbs_nao_suportado",
|
|
318
|
+
"ibscbs_redutor_divergente",
|
|
319
|
+
"ibscbs_regra_nt",
|
|
320
|
+
"totais_divergentes",
|
|
321
|
+
"itens_limite",
|
|
322
|
+
"contingencia_invalida",
|
|
323
|
+
"pagamento_igual_total",
|
|
324
|
+
"emitente_difere_do_certificado",
|
|
325
|
+
"grupo_vedado",
|
|
326
|
+
"pagamento_invalido",
|
|
327
|
+
"qrcode_invalido",
|
|
328
|
+
"schema"
|
|
329
|
+
];
|
|
330
|
+
|
|
331
|
+
class Issues {
|
|
332
|
+
list;
|
|
333
|
+
constructor() {
|
|
334
|
+
this.list = [];
|
|
335
|
+
}
|
|
336
|
+
add(path, code, message, origem = "entrada") {
|
|
337
|
+
this.list.push({ caminho: path, code, mensagem: message, origem });
|
|
338
|
+
}
|
|
339
|
+
montagem(path, code, message) {
|
|
340
|
+
this.add(path, code, message, "montagem");
|
|
341
|
+
}
|
|
342
|
+
get classificadas() {
|
|
343
|
+
return this.list.map((i) => i.origem === undefined ? { ...i, origem: "entrada" } : i);
|
|
344
|
+
}
|
|
345
|
+
addAll(issues, origem = "entrada") {
|
|
346
|
+
this.list.push(...issues.map((i) => i.origem === undefined ? { ...i, origem } : i));
|
|
347
|
+
}
|
|
348
|
+
reclassificarDesde(inicio, origem) {
|
|
349
|
+
for (let k = inicio;k < this.list.length; k++) {
|
|
350
|
+
const i = this.list[k];
|
|
351
|
+
if (i !== undefined)
|
|
352
|
+
this.list[k] = { ...i, origem };
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
get empty() {
|
|
356
|
+
return this.list.length === 0;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// packages/nfe/src/rtc.ts
|
|
361
|
+
import { contextoDeTempo, ehUf, relogioFixo, ufPorCUf } from "@sinete/core";
|
|
362
|
+
import { aliquotasOficiais, ErroAliquotaDesconhecida } from "@sinete/ibs-cbs/aliquotas";
|
|
363
|
+
import { calcular, ErroClassificacao, ErroRegimeNaoSuportado } from "@sinete/ibs-cbs/calcular";
|
|
364
|
+
import { documentoDoRoc, validar } from "@sinete/ibs-cbs/validar";
|
|
365
|
+
var BASE = /^\d{1,13}(\.\d{1,2})?$/;
|
|
366
|
+
function normalizado(v) {
|
|
367
|
+
const [int = "0", frac = ""] = v.split(".");
|
|
368
|
+
const f = frac.replace(/0+$/, "");
|
|
369
|
+
const i = int.replace(/^0+(?=\d)/, "");
|
|
370
|
+
return f === "" ? i : `${i}.${f}`;
|
|
371
|
+
}
|
|
372
|
+
var caminho = (nItem) => `itens[${nItem - 1}].impostos.ibsCbs`;
|
|
373
|
+
function ufDoMunicipio(cMun) {
|
|
374
|
+
return ufPorCUf(cMun.slice(0, 2))?.sigla;
|
|
375
|
+
}
|
|
376
|
+
function localDaOperacao(nota) {
|
|
377
|
+
if (nota.cMunFGIBS !== undefined) {
|
|
378
|
+
const uf = ufDoMunicipio(nota.cMunFGIBS);
|
|
379
|
+
if (uf !== undefined)
|
|
380
|
+
return { uf, cMun: nota.cMunFGIBS };
|
|
381
|
+
}
|
|
382
|
+
const d = nota.destino;
|
|
383
|
+
if (d !== undefined && d.UF !== "EX" && ehUf(d.UF))
|
|
384
|
+
return { uf: d.UF, cMun: d.cMun };
|
|
385
|
+
return { uf: nota.emitente.UF, cMun: nota.emitente.cMun };
|
|
386
|
+
}
|
|
387
|
+
function grupoDoLeiaute(g, indDoacao) {
|
|
388
|
+
const { gCredPresOper, gCredPresIBSZFM, ...resto } = g;
|
|
389
|
+
return {
|
|
390
|
+
...resto,
|
|
391
|
+
...indDoacao === undefined ? {} : { indDoacao },
|
|
392
|
+
...gCredPresOper === undefined ? {} : { gCredPresOper: { ...gCredPresOper, cCredPres: String(gCredPresOper.cCredPres).padStart(2, "0") } },
|
|
393
|
+
...gCredPresIBSZFM === undefined ? {} : {
|
|
394
|
+
gCredPresIBSZFM: {
|
|
395
|
+
...gCredPresIBSZFM,
|
|
396
|
+
tpCredPresIBSZFM: String(gCredPresIBSZFM.tpCredPresIBSZFM)
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function ocorrenciaDoMotor(e, itens) {
|
|
402
|
+
if (e instanceof ErroClassificacao || e instanceof ErroRegimeNaoSuportado) {
|
|
403
|
+
const path = e.item !== undefined ? caminho(e.item) : caminho(itens[0]?.nItem ?? 1);
|
|
404
|
+
return { caminho: path, code: e.code, mensagem: e.message, origem: "entrada" };
|
|
405
|
+
}
|
|
406
|
+
if (e instanceof ErroAliquotaDesconhecida)
|
|
407
|
+
return { caminho: "impostos.ibsCbs", code: e.code, mensagem: e.message, origem: "montagem" };
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
var embarcado;
|
|
411
|
+
function carregarDatasetEmbarcado() {
|
|
412
|
+
embarcado ??= import("@sinete/ibs-cbs-dados/embarcado").then((m) => m.datasetEmbarcado(), (e) => {
|
|
413
|
+
embarcado = undefined;
|
|
414
|
+
throw e;
|
|
415
|
+
});
|
|
416
|
+
return embarcado;
|
|
417
|
+
}
|
|
418
|
+
function calculadoraIbsCbs(opcoes = {}) {
|
|
419
|
+
const rates = opcoes.aliquotas ?? aliquotasOficiais();
|
|
420
|
+
const dataset = opcoes.dataset;
|
|
421
|
+
return {
|
|
422
|
+
calcular(request) {
|
|
423
|
+
if (dataset !== undefined)
|
|
424
|
+
return calcularCom(dataset, rates, opcoes, request);
|
|
425
|
+
return carregarDatasetEmbarcado().then((ds) => calcularCom(ds, rates, opcoes, request));
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
function calcularCom(dataset, rates, options, {
|
|
430
|
+
nota,
|
|
431
|
+
itens
|
|
432
|
+
}) {
|
|
433
|
+
const issues = [];
|
|
434
|
+
const classificados = [];
|
|
435
|
+
for (const it of itens) {
|
|
436
|
+
if (it.cCredPres !== undefined) {
|
|
437
|
+
issues.push({
|
|
438
|
+
caminho: caminho(it.nItem),
|
|
439
|
+
code: "ibscbs_nao_suportado",
|
|
440
|
+
mensagem: "crédito presumido (cCredPres) precisa do grupo gCredPresOper pronto (ibsCbs.grupo)",
|
|
441
|
+
origem: "entrada"
|
|
442
|
+
});
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
const base = it.vBC !== undefined ? it.vBC.toFixed(2) : options.base?.(it, nota);
|
|
446
|
+
if (base === undefined) {
|
|
447
|
+
issues.push({
|
|
448
|
+
caminho: `${caminho(it.nItem)}.classificacao.vBC`,
|
|
449
|
+
code: "ibscbs_base_ausente",
|
|
450
|
+
mensagem: "informe vBC do IBS/CBS ou CalculadoraIbsCbsOpcoes.base: a composição da base (UB16-10) ainda não tem regra publicada",
|
|
451
|
+
origem: "entrada"
|
|
452
|
+
});
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (!BASE.test(base)) {
|
|
456
|
+
issues.push({
|
|
457
|
+
caminho: `${caminho(it.nItem)}.classificacao.vBC`,
|
|
458
|
+
code: "decimal_invalido",
|
|
459
|
+
mensagem: base,
|
|
460
|
+
origem: it.vBC !== undefined ? "entrada" : "montagem"
|
|
461
|
+
});
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
classificados.push({
|
|
465
|
+
n: it.nItem,
|
|
466
|
+
cst: it.CST,
|
|
467
|
+
cClassTrib: it.cClassTrib,
|
|
468
|
+
base,
|
|
469
|
+
quantidade: it.qTrib.toString(),
|
|
470
|
+
unidade: it.uTrib,
|
|
471
|
+
...it.gTribRegular === undefined ? {} : { regular: { cst: it.gTribRegular.CSTReg, cClassTrib: it.gTribRegular.cClassTribReg } }
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
if (issues.length > 0)
|
|
475
|
+
return { itens: [], ocorrencias: issues };
|
|
476
|
+
const op = {
|
|
477
|
+
modelo: Number(nota.mod),
|
|
478
|
+
local: localDaOperacao(nota),
|
|
479
|
+
...nota.compraGov === undefined ? {} : {
|
|
480
|
+
compraGovernamental: {
|
|
481
|
+
tpEnteGov: Number(nota.compraGov.tpEnteGov),
|
|
482
|
+
...nota.compraGov.tpOperGov === "1" || nota.compraGov.tpOperGov === "2" ? { tpOperGov: Number(nota.compraGov.tpOperGov) } : {}
|
|
483
|
+
}
|
|
484
|
+
},
|
|
485
|
+
itens: classificados
|
|
486
|
+
};
|
|
487
|
+
const time = contextoDeTempo({ emissao: relogioFixo(nota.emissao), fatoGerador: relogioFixo(nota.fatoGerador) });
|
|
488
|
+
let roc;
|
|
489
|
+
try {
|
|
490
|
+
roc = calcular(op, {
|
|
491
|
+
dataset,
|
|
492
|
+
aliquotas: rates,
|
|
493
|
+
tempo: time,
|
|
494
|
+
...options.deslocamentoMin === undefined ? {} : { deslocamentoMin: options.deslocamentoMin }
|
|
495
|
+
});
|
|
496
|
+
} catch (e) {
|
|
497
|
+
const issue = ocorrenciaDoMotor(e, itens);
|
|
498
|
+
if (issue === undefined)
|
|
499
|
+
throw e;
|
|
500
|
+
return { itens: [], ocorrencias: [issue] };
|
|
501
|
+
}
|
|
502
|
+
const redutor = roc.oper?.gCompraGov.pRedutor;
|
|
503
|
+
if (nota.compraGov !== undefined && redutor !== undefined && normalizado(nota.compraGov.pRedutor.toString()) !== normalizado(redutor)) {
|
|
504
|
+
issues.push({
|
|
505
|
+
caminho: "gCompraGov.pRedutor",
|
|
506
|
+
code: "ibscbs_redutor_divergente",
|
|
507
|
+
mensagem: `pRedutor informado (${nota.compraGov.pRedutor.toString()}) difere do vigente no fato gerador (${redutor})`,
|
|
508
|
+
origem: "entrada"
|
|
509
|
+
});
|
|
510
|
+
}
|
|
511
|
+
if (options.regras !== false) {
|
|
512
|
+
const doc = documentoDoRoc(roc, {
|
|
513
|
+
modelo: op.modelo,
|
|
514
|
+
crt: Number(nota.emitente.CRT),
|
|
515
|
+
finNFe: Number(nota.finNFe),
|
|
516
|
+
...nota.tpNFDebito === undefined ? {} : { tpNFDebito: nota.tpNFDebito },
|
|
517
|
+
...nota.tpNFCredito === undefined ? {} : { tpNFCredito: nota.tpNFCredito },
|
|
518
|
+
munEmitente: nota.emitente.cMun,
|
|
519
|
+
...nota.destino === undefined ? {} : { munDestinatario: nota.destino.cMun },
|
|
520
|
+
itens: itens.map((it) => ({ nItem: it.nItem, ncm: it.NCM, vProd: it.vProd.toFixed(2) }))
|
|
521
|
+
});
|
|
522
|
+
const report = validar(doc, {
|
|
523
|
+
dataset,
|
|
524
|
+
tempo: time,
|
|
525
|
+
ambiente: nota.ambiente,
|
|
526
|
+
aliquotas: rates,
|
|
527
|
+
...options.deslocamentoMin === undefined ? {} : { deslocamentoMin: options.deslocamentoMin },
|
|
528
|
+
...options.regras?.regras === undefined ? {} : { regras: options.regras.regras },
|
|
529
|
+
...options.regras?.ignorarAtivacao === undefined ? {} : { ignorarAtivacao: options.regras.ignorarAtivacao }
|
|
530
|
+
});
|
|
531
|
+
for (const v of report.violacoes) {
|
|
532
|
+
issues.push({
|
|
533
|
+
caminho: v.item === undefined ? "total.IBSCBSTot" : caminho(v.item),
|
|
534
|
+
code: "ibscbs_regra_nt",
|
|
535
|
+
mensagem: `${v.regra} (rejeição ${v.cStat}): ${v.message} [${v.fonte}]`,
|
|
536
|
+
origem: "montagem"
|
|
537
|
+
});
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
const porItem = new Map(itens.map((it) => [it.nItem, it]));
|
|
541
|
+
return {
|
|
542
|
+
itens: roc.itens.map((r) => ({
|
|
543
|
+
nItem: r.nItem,
|
|
544
|
+
IBSCBS: grupoDoLeiaute(r.IBSCBS, porItem.get(r.nItem)?.indDoacao)
|
|
545
|
+
})),
|
|
546
|
+
...issues.length === 0 ? {} : { ocorrencias: issues }
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// packages/nfe/src/time.ts
|
|
551
|
+
import { formatarDataHoraComFuso } from "@sinete/core";
|
|
552
|
+
// packages/nfe/src/data/fusos.json
|
|
553
|
+
var fusos_default = {
|
|
554
|
+
descricao: "Deslocamento do horário legal de cada UF em relação a UTC, em minutos, usado para formatar dhEmi, dhSaiEnt, dhCont e dhEvento quando quem emite não informa o fuso. Sem horário de verão desde 2019. UFs com mais de um fuso usam o da capital; o emitente de outro fuso informa deslocamentoMin.",
|
|
555
|
+
atualizadoEm: "2026-09-26",
|
|
556
|
+
fontes: [
|
|
557
|
+
"Lei 11.662/2008 e Lei 12.876/2013 (fusos horários do Brasil; Acre em UTC-5)",
|
|
558
|
+
"Decreto 9.772/2019 (fim do horário de verão)"
|
|
559
|
+
],
|
|
560
|
+
padrao: -180,
|
|
561
|
+
ufs: {
|
|
562
|
+
AC: -300,
|
|
563
|
+
AM: -240,
|
|
564
|
+
MS: -240,
|
|
565
|
+
MT: -240,
|
|
566
|
+
RO: -240,
|
|
567
|
+
RR: -240
|
|
568
|
+
}
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
// packages/nfe/src/time.ts
|
|
572
|
+
var UF_OFFSETS = fusos_default.ufs;
|
|
573
|
+
function deslocamentoDaUf(uf) {
|
|
574
|
+
return Object.hasOwn(UF_OFFSETS, uf) ? UF_OFFSETS[uf] : fusos_default.padrao;
|
|
575
|
+
}
|
|
576
|
+
function formatarDh(data, deslocamentoMin) {
|
|
577
|
+
return formatarDataHoraComFuso(data, deslocamentoMin);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// packages/nfe/src/versao-gerada.ts
|
|
581
|
+
var VERSAO_PACOTE = "0.2.0";
|
|
582
|
+
|
|
583
|
+
// packages/nfe/src/build/destinatario.ts
|
|
584
|
+
import { ufPorSigla } from "@sinete/core";
|
|
585
|
+
import { lerCnpj } from "@sinete/validators";
|
|
586
|
+
// packages/nfe/src/data/suframa.json
|
|
587
|
+
var suframa_default = {
|
|
588
|
+
descricao: "Onde a inscrição na Suframa do destinatário (ISUF) é aceita na NF-e: UFs inteiras e, no Amapá, só os municípios listados. Fora delas, rejeição 251.",
|
|
589
|
+
atualizadoEm: "2026-09-28",
|
|
590
|
+
fonte: "MOC 7.0 Anexo I, RV E18-30 (rejeição 251, modelo 55, obrigatória)",
|
|
591
|
+
ufs: ["AC", "AM", "RO", "RR"],
|
|
592
|
+
municipios: { AP: ["1600303", "1600600"] }
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
// packages/nfe/src/build/destinatario.ts
|
|
596
|
+
var ID_ESTRANGEIRO = /^[0-9A-Za-z:.+\-/()]*$/;
|
|
597
|
+
var digitos = (s) => s.replace(/\D/g, "");
|
|
598
|
+
function conferirDestinatario(input, ide, issues) {
|
|
599
|
+
const d = input.destinatario;
|
|
600
|
+
if (d === undefined)
|
|
601
|
+
return;
|
|
602
|
+
const nfe = ide.mod === "55";
|
|
603
|
+
const emitUf = input.emitente.endereco.UF;
|
|
604
|
+
const end = d.endereco;
|
|
605
|
+
const exterior = end !== undefined && "exterior" in end && end.exterior === true;
|
|
606
|
+
const destUf = end === undefined ? undefined : exterior ? "EX" : end.UF;
|
|
607
|
+
const idEstrangeiro = "idEstrangeiro" in d ? d.idEstrangeiro : undefined;
|
|
608
|
+
if (nfe && ide.idDest === "3" && idEstrangeiro === undefined) {
|
|
609
|
+
issues.add("destinatario", "campo_obrigatorio", "na operação com o exterior (idDest 3) o destinatário é identificado por idEstrangeiro, mesmo vazio (E03a-10, rejeição 720)");
|
|
610
|
+
}
|
|
611
|
+
if (nfe && idEstrangeiro !== undefined && ide.idDest !== "3" && ide.indFinal !== "1") {
|
|
612
|
+
issues.add("destinatario.idEstrangeiro", "combinacao_invalida", "idEstrangeiro fora da operação com o exterior só com consumidor final, indFinal 1 (E03a-20, rejeição 721)");
|
|
613
|
+
}
|
|
614
|
+
if (idEstrangeiro !== undefined && d.IE !== undefined) {
|
|
615
|
+
issues.add("destinatario.IE", "combinacao_invalida", "destinatário estrangeiro (idEstrangeiro) não informa IE (E03a-30, rejeição 925)");
|
|
616
|
+
}
|
|
617
|
+
if (idEstrangeiro !== undefined && !ID_ESTRANGEIRO.test(idEstrangeiro)) {
|
|
618
|
+
issues.add("destinatario.idEstrangeiro", "campo_invalido", "idEstrangeiro só com algarismos, letras e os caracteres : . + - / ( ) (E03a-60, rejeição 372)");
|
|
619
|
+
}
|
|
620
|
+
if (nfe && ide.producao && (d.xNome === undefined || d.xNome.trim() === "")) {
|
|
621
|
+
issues.add("destinatario.xNome", "campo_obrigatorio", "a NF-e informa o nome do destinatário (E04-10, rejeição 724)");
|
|
622
|
+
}
|
|
623
|
+
if (nfe && end === undefined) {
|
|
624
|
+
issues.add("destinatario.endereco", "campo_obrigatorio", "a NF-e informa o endereço do destinatário (E05-10, rejeição 726)");
|
|
625
|
+
}
|
|
626
|
+
if (end !== undefined && !exterior) {
|
|
627
|
+
const e = end;
|
|
628
|
+
const cUF = ufPorSigla(e.UF)?.cUF;
|
|
629
|
+
if (cUF !== undefined && digitos(e.cMun).slice(0, 2) !== cUF) {
|
|
630
|
+
issues.add("destinatario.endereco.cMun", "combinacao_invalida", `município ${e.cMun} não é da UF ${e.UF} do destinatário (E10-20, rejeição 275)`);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
if (nfe && destUf !== undefined && destUf !== "EX") {
|
|
634
|
+
const caminho = ide.idDestInformado ? "idDest" : "destinatario.endereco.UF";
|
|
635
|
+
const ufsCons = input.itens.flatMap((it) => {
|
|
636
|
+
const esp = it.produto.especifico;
|
|
637
|
+
return esp !== undefined && "comb" in esp ? [String(esp.comb.UFCons)] : [];
|
|
638
|
+
});
|
|
639
|
+
const entrega = input.entrega?.UF;
|
|
640
|
+
const retirada = input.retirada?.UF;
|
|
641
|
+
const saida = ide.tpNF === "1";
|
|
642
|
+
const [ufEntrega, ufRetirada] = saida ? [emitUf, destUf] : [destUf, emitUf];
|
|
643
|
+
if (ide.idDest === "2" && destUf === emitUf) {
|
|
644
|
+
const cnpj = (v) => {
|
|
645
|
+
if (v === undefined)
|
|
646
|
+
return;
|
|
647
|
+
const r = lerCnpj(v);
|
|
648
|
+
return r.ok ? r.valor : undefined;
|
|
649
|
+
};
|
|
650
|
+
const cnpjDest = "CNPJ" in d ? cnpj(d.CNPJ) : undefined;
|
|
651
|
+
const mesmoCnpj = cnpjDest !== undefined && cnpjDest === cnpj(input.emitente.CNPJ);
|
|
652
|
+
const excecao = ufsCons.some((u) => u !== emitUf) || entrega !== undefined && retirada === undefined && entrega !== ufEntrega || retirada !== undefined && entrega === undefined && retirada !== ufRetirada || entrega !== undefined && retirada !== undefined && entrega !== retirada;
|
|
653
|
+
if (!mesmoCnpj && !excecao) {
|
|
654
|
+
issues.add(caminho, "combinacao_invalida", `operação interestadual (idDest 2) com o destinatário na UF do emitente (${emitUf}) (${saida ? "E12-30" : "E12-50"}, rejeição 772)`);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
if (ide.idDest === "1" && destUf !== emitUf && ide.indFinal !== "1") {
|
|
658
|
+
const excecao = ufsCons.some((u) => u === emitUf) || entrega !== undefined && retirada === undefined && entrega === ufEntrega || retirada !== undefined && entrega === undefined && retirada === ufRetirada || entrega !== undefined && retirada !== undefined && entrega === retirada;
|
|
659
|
+
if (!excecao) {
|
|
660
|
+
issues.add(caminho, "combinacao_invalida", `operação interna (idDest 1) com o destinatário em ${destUf}, fora da UF do emitente (${emitUf}) (${saida ? "E12-40" : "E12-60"}, rejeição 773)`);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
if (exterior && Number(digitos(end.cPais)) === 1058) {
|
|
665
|
+
issues.add("destinatario.endereco.cPais", "campo_invalido", "destinatário no exterior com o país Brasil, 1058 (E14-30, rejeição 926)");
|
|
666
|
+
}
|
|
667
|
+
if (!nfe)
|
|
668
|
+
return;
|
|
669
|
+
if (ide.idDest === "3" && d.indIEDest !== "9") {
|
|
670
|
+
issues.add("destinatario.indIEDest", "combinacao_invalida", "na operação com o exterior o destinatário é não contribuinte, indIEDest 9 (E16a-20, rejeição 790)");
|
|
671
|
+
}
|
|
672
|
+
if (d.indIEDest === "9" && ide.indFinal !== "1" && ide.tpNF === "1" && ide.idDest !== "3") {
|
|
673
|
+
issues.add("indFinal", "combinacao_invalida", "saída para não contribuinte (indIEDest 9) é operação com consumidor final, indFinal 1 (E16a-40, rejeição 696)");
|
|
674
|
+
}
|
|
675
|
+
if (d.indIEDest === "1" && d.IE === undefined) {
|
|
676
|
+
issues.add("destinatario.IE", "campo_obrigatorio", "destinatário contribuinte (indIEDest 1) informa a IE (E17-20, rejeição 728)");
|
|
677
|
+
}
|
|
678
|
+
if (d.indIEDest === "2" && d.IE !== undefined) {
|
|
679
|
+
issues.add("destinatario.IE", "combinacao_invalida", "destinatário contribuinte isento (indIEDest 2) não informa a IE (E17-30, rejeição 791)");
|
|
680
|
+
}
|
|
681
|
+
if (exterior && d.IE !== undefined) {
|
|
682
|
+
issues.add("destinatario.IE", "combinacao_invalida", "destinatário no exterior não informa a IE (E17-40, rejeição 792)");
|
|
683
|
+
}
|
|
684
|
+
if (d.ISUF !== undefined && destUf !== undefined) {
|
|
685
|
+
const cMun = exterior ? "" : digitos(end.cMun);
|
|
686
|
+
const municipios = suframa_default.municipios[destUf];
|
|
687
|
+
const aceita = suframa_default.ufs.includes(destUf) || (municipios?.includes(cMun) ?? false);
|
|
688
|
+
if (!aceita) {
|
|
689
|
+
const onde = exterior ? "no exterior" : `${destUf}, município ${end.cMun}`;
|
|
690
|
+
issues.add("destinatario.ISUF", "combinacao_invalida", `inscrição na Suframa com o destinatário fora da área incentivada (${onde}) (E18-30, rejeição 251)`);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
// packages/nfe/src/build/ibscbs.ts
|
|
696
|
+
import { lerXml, primeiroFilho } from "@sinete/core/xml";
|
|
697
|
+
import { serializar, validar as validar2 } from "@sinete/schemas";
|
|
698
|
+
var NFE_NS = "http://www.portalfiscal.inf.br/nfe";
|
|
699
|
+
function grupoInvalido(ct, nome, value, path, issues) {
|
|
700
|
+
if (value === undefined)
|
|
701
|
+
return false;
|
|
702
|
+
try {
|
|
703
|
+
const doc = lerXml(`<w xmlns="${NFE_NS}">${serializar(ct, nome, value, NFE_NS)}</w>`);
|
|
704
|
+
const el = primeiroFilho(doc.raiz, nome, NFE_NS);
|
|
705
|
+
const erros = el === undefined ? [{ caminho: "", code: "modelo_de_conteudo", mensagem: "grupo vazio" }] : validar2(ct, el);
|
|
706
|
+
for (const e of erros)
|
|
707
|
+
issues.add(`${path}${e.caminho.replace(/^\/[^/]+/, "").replace(/\//g, ".")}`, "schema", `${e.code}: ${e.mensagem}`);
|
|
708
|
+
return erros.length > 0;
|
|
709
|
+
} catch (e) {
|
|
710
|
+
issues.add(path, "schema", `grupo malformado: ${e.message}`);
|
|
711
|
+
return true;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
var NUMERICO = /^(v|p|q|adRem)[A-Z]/;
|
|
715
|
+
function decimaisInvalidos(value, path, issues) {
|
|
716
|
+
if (typeof value !== "object" || value === null)
|
|
717
|
+
return;
|
|
718
|
+
for (const [k, v] of Object.entries(value)) {
|
|
719
|
+
const p = `${path}.${k}`;
|
|
720
|
+
if (typeof v === "string" && NUMERICO.test(k) && Decimal.tryOf(v) === undefined) {
|
|
721
|
+
issues.add(p, "decimal_invalido", "número decimal inválido");
|
|
722
|
+
} else if (typeof v === "object")
|
|
723
|
+
decimaisInvalidos(v, p, issues);
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
function somaCampo(value, name) {
|
|
727
|
+
if (typeof value !== "object" || value === null)
|
|
728
|
+
return Decimal.ZERO;
|
|
729
|
+
let acc = Decimal.ZERO;
|
|
730
|
+
for (const [k, v] of Object.entries(value)) {
|
|
731
|
+
if (k === name && typeof v === "string")
|
|
732
|
+
acc = acc.plus(Decimal.of(v));
|
|
733
|
+
else if (typeof v === "object")
|
|
734
|
+
acc = acc.plus(somaCampo(v, name));
|
|
735
|
+
}
|
|
736
|
+
return acc;
|
|
737
|
+
}
|
|
738
|
+
function ibsCbsDoItem(g) {
|
|
739
|
+
const s = (x) => x === undefined ? Decimal.ZERO : Decimal.of(x);
|
|
740
|
+
return {
|
|
741
|
+
vIBS: s(g.gIBSCBS?.vIBS),
|
|
742
|
+
vCBS: s(g.gIBSCBS?.gCBS.vCBS),
|
|
743
|
+
vTotIBSMonoItem: s(g.gIBSCBSMono?.vTotIBSMonoItem),
|
|
744
|
+
vTotCBSMonoItem: s(g.gIBSCBSMono?.vTotCBSMonoItem)
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
function totalIbsCbs(grupos) {
|
|
748
|
+
const f = (d) => d.toFixed(2);
|
|
749
|
+
const sum = (pick, name) => grupos.reduce((acc, g) => acc.plus(somaCampo(pick(g), name)), Decimal.ZERO);
|
|
750
|
+
const regulares = grupos.filter((g) => g.gIBSCBS !== undefined || g.gCredPresOper !== undefined);
|
|
751
|
+
const total = {
|
|
752
|
+
vBCIBSCBS: f(sum((g) => g.gIBSCBS && { vBC: g.gIBSCBS.vBC }, "vBC"))
|
|
753
|
+
};
|
|
754
|
+
if (regulares.length > 0) {
|
|
755
|
+
const credIbs = (g) => g.gCredPresOper?.gIBSCredPres;
|
|
756
|
+
const credCbs = (g) => g.gCredPresOper?.gCBSCredPres;
|
|
757
|
+
total.gIBS = {
|
|
758
|
+
gIBSUF: {
|
|
759
|
+
vDif: f(sum((g) => g.gIBSCBS?.gIBSUF.gDif, "vDif")),
|
|
760
|
+
vDevTrib: f(sum((g) => g.gIBSCBS?.gIBSUF.gDevTrib, "vDevTrib")),
|
|
761
|
+
vIBSUF: f(sum((g) => g.gIBSCBS && { v: g.gIBSCBS.gIBSUF.vIBSUF }, "v"))
|
|
762
|
+
},
|
|
763
|
+
gIBSMun: {
|
|
764
|
+
vDif: f(sum((g) => g.gIBSCBS?.gIBSMun.gDif, "vDif")),
|
|
765
|
+
vDevTrib: f(sum((g) => g.gIBSCBS?.gIBSMun.gDevTrib, "vDevTrib")),
|
|
766
|
+
vIBSMun: f(sum((g) => g.gIBSCBS && { v: g.gIBSCBS.gIBSMun.vIBSMun }, "v"))
|
|
767
|
+
},
|
|
768
|
+
vIBS: f(sum((g) => g.gIBSCBS && { v: g.gIBSCBS.vIBS }, "v")),
|
|
769
|
+
vCredPres: f(sum(credIbs, "vCredPres")),
|
|
770
|
+
vCredPresCondSus: f(sum(credIbs, "vCredPresCondSus"))
|
|
771
|
+
};
|
|
772
|
+
total.gCBS = {
|
|
773
|
+
vDif: f(sum((g) => g.gIBSCBS?.gCBS.gDif, "vDif")),
|
|
774
|
+
vDevTrib: f(sum((g) => g.gIBSCBS?.gCBS.gDevTrib, "vDevTrib")),
|
|
775
|
+
vCBS: f(sum((g) => g.gIBSCBS && { v: g.gIBSCBS.gCBS.vCBS }, "v")),
|
|
776
|
+
vCredPres: f(sum(credCbs, "vCredPres")),
|
|
777
|
+
vCredPresCondSus: f(sum(credCbs, "vCredPresCondSus"))
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
if (grupos.some((g) => g.gIBSCBSMono !== undefined)) {
|
|
781
|
+
const mono = (n) => f(sum((g) => g.gIBSCBSMono, n));
|
|
782
|
+
total.gMono = {
|
|
783
|
+
vIBSMono: mono("vIBSMono"),
|
|
784
|
+
vCBSMono: mono("vCBSMono"),
|
|
785
|
+
vIBSMonoReten: mono("vIBSMonoReten"),
|
|
786
|
+
vCBSMonoReten: mono("vCBSMonoReten"),
|
|
787
|
+
vIBSMonoRet: mono("vIBSMonoRet"),
|
|
788
|
+
vCBSMonoRet: mono("vCBSMonoRet")
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (grupos.some((g) => g.gEstornoCred !== undefined)) {
|
|
792
|
+
total.gEstornoCred = {
|
|
793
|
+
vIBSEstCred: f(sum((g) => g.gEstornoCred, "vIBSEstCred")),
|
|
794
|
+
vCBSEstCred: f(sum((g) => g.gEstornoCred, "vCBSEstCred"))
|
|
795
|
+
};
|
|
796
|
+
}
|
|
797
|
+
return total;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// packages/nfe/src/build/values.ts
|
|
801
|
+
var TOLERANCIA = Decimal.of("0.01");
|
|
802
|
+
|
|
803
|
+
class Ctx {
|
|
804
|
+
issues;
|
|
805
|
+
modes;
|
|
806
|
+
conferir;
|
|
807
|
+
constructor(issues, modes, conferir = true) {
|
|
808
|
+
this.issues = issues;
|
|
809
|
+
this.modes = modes;
|
|
810
|
+
this.conferir = conferir;
|
|
811
|
+
}
|
|
812
|
+
opt(value, path, format) {
|
|
813
|
+
if (value === undefined)
|
|
814
|
+
return;
|
|
815
|
+
const d = Decimal.tryOf(value);
|
|
816
|
+
if (d === undefined) {
|
|
817
|
+
this.issues.add(path, "decimal_invalido", "número decimal inválido (use ponto como separador, sem milhar)");
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
const problem = problemaDeFormato(d, format);
|
|
821
|
+
if (problem !== undefined) {
|
|
822
|
+
this.issues.add(path, "decimal_invalido", `${problem} (${format.nome})`);
|
|
823
|
+
return;
|
|
824
|
+
}
|
|
825
|
+
return d;
|
|
826
|
+
}
|
|
827
|
+
req(value, path, format) {
|
|
828
|
+
if (value === undefined) {
|
|
829
|
+
this.issues.add(path, "campo_obrigatorio", "campo obrigatório");
|
|
830
|
+
return Decimal.ZERO;
|
|
831
|
+
}
|
|
832
|
+
return this.opt(value, path, format) ?? Decimal.ZERO;
|
|
833
|
+
}
|
|
834
|
+
round(value, format, familia) {
|
|
835
|
+
return value.round(format.max, this.modes[familia]);
|
|
836
|
+
}
|
|
837
|
+
base(given, padrao, path, format, familia) {
|
|
838
|
+
return this.opt(given, path, format) ?? this.round(padrao, format, familia);
|
|
839
|
+
}
|
|
840
|
+
calc(given, computed, path, format, familia) {
|
|
841
|
+
const r = this.round(computed, format, familia);
|
|
842
|
+
if (given === undefined)
|
|
843
|
+
return r;
|
|
844
|
+
const g = this.opt(given, path, format);
|
|
845
|
+
if (g === undefined)
|
|
846
|
+
return r;
|
|
847
|
+
if (this.conferir && g.minus(r).abs().gt(TOLERANCIA)) {
|
|
848
|
+
this.issues.add(path, "valor_divergente", `valor informado difere do calculado (${r.toFixed(format.max)}) em mais de ${TOLERANCIA.toString()}`);
|
|
849
|
+
}
|
|
850
|
+
return g;
|
|
851
|
+
}
|
|
852
|
+
s(value, format) {
|
|
853
|
+
return formatarDecimal(value, format);
|
|
854
|
+
}
|
|
855
|
+
so(value, format) {
|
|
856
|
+
if (value === undefined)
|
|
857
|
+
return;
|
|
858
|
+
if (format.naoNulo && value.isZero())
|
|
859
|
+
return;
|
|
860
|
+
return formatarDecimal(value, format);
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
function clean(o) {
|
|
864
|
+
const out = {};
|
|
865
|
+
for (const [k, v] of Object.entries(o))
|
|
866
|
+
if (v !== undefined)
|
|
867
|
+
out[k] = v;
|
|
868
|
+
return out;
|
|
869
|
+
}
|
|
870
|
+
function digits(s) {
|
|
871
|
+
return s.replace(/\D/g, "");
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
// packages/nfe/src/build/icms.ts
|
|
875
|
+
function zeroIcmsTotais() {
|
|
876
|
+
const z = Decimal.ZERO;
|
|
877
|
+
return {
|
|
878
|
+
vBC: z,
|
|
879
|
+
vICMS: z,
|
|
880
|
+
vICMSDeson: z,
|
|
881
|
+
vICMSDesonDeduz: z,
|
|
882
|
+
vFCP: z,
|
|
883
|
+
vBCST: z,
|
|
884
|
+
vST: z,
|
|
885
|
+
vFCPST: z,
|
|
886
|
+
vFCPSTRet: z,
|
|
887
|
+
qBCMono: z,
|
|
888
|
+
vICMSMono: z,
|
|
889
|
+
qBCMonoReten: z,
|
|
890
|
+
vICMSMonoReten: z,
|
|
891
|
+
qBCMonoRet: z,
|
|
892
|
+
vICMSMonoRet: z,
|
|
893
|
+
mono: false
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
var M = D1302;
|
|
897
|
+
var P = D0302A04;
|
|
898
|
+
var PO = D0302A04_OPC;
|
|
899
|
+
function nonNeg(d) {
|
|
900
|
+
return d.isNegative() ? Decimal.ZERO : d;
|
|
901
|
+
}
|
|
902
|
+
function buildIcms(ctx, input, base, path) {
|
|
903
|
+
const t = zeroIcmsTotais();
|
|
904
|
+
const S = (d) => ctx.s(d, M);
|
|
905
|
+
const proprio = (i, pRedBC, required) => {
|
|
906
|
+
const pICMS = required ? ctx.req(i.pICMS, `${path}.pICMS`, P) : ctx.opt(i.pICMS, `${path}.pICMS`, P);
|
|
907
|
+
if (pICMS === undefined && i.vBC === undefined && i.vICMS === undefined)
|
|
908
|
+
return;
|
|
909
|
+
const reduzida = pRedBC === undefined ? base.vOp : base.vOp.times(Decimal.HUNDRED.minus(pRedBC)).dividedBy(100, 10, "HALF_EVEN");
|
|
910
|
+
const vBC = ctx.base(i.vBC, reduzida, `${path}.vBC`, M, "icms");
|
|
911
|
+
const aliq = pICMS ?? Decimal.ZERO;
|
|
912
|
+
const vICMS = ctx.calc(i.vICMS, vBC.percent(aliq), `${path}.vICMS`, M, "icms");
|
|
913
|
+
t.vBC = t.vBC.plus(vBC);
|
|
914
|
+
t.vICMS = t.vICMS.plus(vICMS);
|
|
915
|
+
return {
|
|
916
|
+
out: { modBC: i.modBC ?? "3", vBC: S(vBC), pICMS: ctx.s(aliq, P), vICMS: S(vICMS) },
|
|
917
|
+
vBC,
|
|
918
|
+
vICMS
|
|
919
|
+
};
|
|
920
|
+
};
|
|
921
|
+
const orfao = (valor, presente, campo, exige, base = path) => {
|
|
922
|
+
if (valor !== undefined && !presente) {
|
|
923
|
+
ctx.issues.add(`${base}.${exige}`, "campo_obrigatorio", `${campo} informado exige ${exige}`);
|
|
924
|
+
}
|
|
925
|
+
};
|
|
926
|
+
const fcp = (i, vBC, withBase) => {
|
|
927
|
+
const pFCP = ctx.opt(i.pFCP, `${path}.pFCP`, PO);
|
|
928
|
+
orfao(i.vBCFCP, i.pFCP !== undefined || i.vFCP !== undefined, "vBCFCP", "pFCP");
|
|
929
|
+
if (pFCP === undefined && i.vFCP === undefined)
|
|
930
|
+
return {};
|
|
931
|
+
const vBCFCP = ctx.base(i.vBCFCP, vBC, `${path}.vBCFCP`, M, "icms");
|
|
932
|
+
const vFCP = ctx.calc(i.vFCP, vBCFCP.percent(pFCP ?? Decimal.ZERO), `${path}.vFCP`, M, "icms");
|
|
933
|
+
t.vFCP = t.vFCP.plus(vFCP);
|
|
934
|
+
return { ...withBase ? { vBCFCP: S(vBCFCP) } : {}, pFCP: ctx.so(pFCP, PO), vFCP: S(vFCP) };
|
|
935
|
+
};
|
|
936
|
+
const st = (i, vICMSProprio, vFCPProprio) => {
|
|
937
|
+
const sp = `${path}.st`;
|
|
938
|
+
const pMVAST = ctx.opt(i.pMVAST, `${sp}.pMVAST`, PO);
|
|
939
|
+
const pRedBCST = ctx.opt(i.pRedBCST, `${sp}.pRedBCST`, PO);
|
|
940
|
+
const pICMSST = ctx.req(i.pICMSST, `${sp}.pICMSST`, P);
|
|
941
|
+
if (i.modBCST === "4" && pMVAST === undefined) {
|
|
942
|
+
ctx.issues.add(`${sp}.pMVAST`, "campo_obrigatorio", "modBCST 4 (MVA) exige pMVAST");
|
|
943
|
+
}
|
|
944
|
+
if (i.modBCST !== "4" && pMVAST !== undefined) {
|
|
945
|
+
ctx.issues.add(`${sp}.pMVAST`, "combinacao_invalida", "pMVAST só pode ser informado com modBCST 4 (MVA)");
|
|
946
|
+
}
|
|
947
|
+
let vBCST;
|
|
948
|
+
if (i.vBCST === undefined && i.modBCST === "4") {
|
|
949
|
+
const bruta = base.vOp.plus(base.vIPI).times(Decimal.HUNDRED.plus(pMVAST ?? Decimal.ZERO)).dividedBy(100, 12, "HALF_EVEN");
|
|
950
|
+
const reduzida = pRedBCST === undefined ? bruta : bruta.times(Decimal.HUNDRED.minus(pRedBCST)).dividedBy(100, 12, "HALF_EVEN");
|
|
951
|
+
vBCST = ctx.round(reduzida, M, "icms");
|
|
952
|
+
} else {
|
|
953
|
+
vBCST = ctx.req(i.vBCST, `${sp}.vBCST`, M);
|
|
954
|
+
}
|
|
955
|
+
const deducao = ctx.opt(i.vICMSDeducaoST, `${sp}.vICMSDeducaoST`, M) ?? vICMSProprio;
|
|
956
|
+
const vICMSST = ctx.calc(i.vICMSST, nonNeg(ctx.round(vBCST.percent(pICMSST), M, "icms").minus(deducao)), `${sp}.vICMSST`, M, "icms");
|
|
957
|
+
t.vBCST = t.vBCST.plus(vBCST);
|
|
958
|
+
t.vST = t.vST.plus(vICMSST);
|
|
959
|
+
const out = {
|
|
960
|
+
modBCST: i.modBCST,
|
|
961
|
+
pMVAST: ctx.so(pMVAST, PO),
|
|
962
|
+
pRedBCST: ctx.so(pRedBCST, PO),
|
|
963
|
+
vBCST: S(vBCST),
|
|
964
|
+
pICMSST: ctx.s(pICMSST, P),
|
|
965
|
+
vICMSST: S(vICMSST)
|
|
966
|
+
};
|
|
967
|
+
const pFCPST = ctx.opt(i.pFCPST, `${sp}.pFCPST`, PO);
|
|
968
|
+
orfao(i.vBCFCPST, i.pFCPST !== undefined || i.vFCPST !== undefined, "vBCFCPST", "pFCPST", sp);
|
|
969
|
+
if (pFCPST !== undefined || i.vFCPST !== undefined) {
|
|
970
|
+
const vBCFCPST = ctx.base(i.vBCFCPST, vBCST, `${sp}.vBCFCPST`, M, "icms");
|
|
971
|
+
const vFCPST = ctx.calc(i.vFCPST, nonNeg(ctx.round(vBCFCPST.percent(pFCPST ?? Decimal.ZERO), M, "icms").minus(vFCPProprio)), `${sp}.vFCPST`, M, "icms");
|
|
972
|
+
t.vFCPST = t.vFCPST.plus(vFCPST);
|
|
973
|
+
Object.assign(out, { vBCFCPST: S(vBCFCPST), pFCPST: ctx.so(pFCPST, PO), vFCPST: S(vFCPST) });
|
|
974
|
+
}
|
|
975
|
+
return out;
|
|
976
|
+
};
|
|
977
|
+
const deson = (d) => {
|
|
978
|
+
if (d === undefined)
|
|
979
|
+
return {};
|
|
980
|
+
const v = ctx.req(d.vICMSDeson, `${path}.desoneracao.vICMSDeson`, M);
|
|
981
|
+
t.vICMSDeson = t.vICMSDeson.plus(v);
|
|
982
|
+
if (d.indDeduzDeson === "1")
|
|
983
|
+
t.vICMSDesonDeduz = t.vICMSDesonDeduz.plus(v);
|
|
984
|
+
return { vICMSDeson: S(v), motDesICMS: d.motDesICMS, indDeduzDeson: d.indDeduzDeson };
|
|
985
|
+
};
|
|
986
|
+
const desonSt = (d) => {
|
|
987
|
+
if (d === undefined)
|
|
988
|
+
return {};
|
|
989
|
+
const v = ctx.req(d.vICMSSTDeson, `${path}.desoneracaoSt.vICMSSTDeson`, M);
|
|
990
|
+
return { vICMSSTDeson: S(v), motDesICMSST: d.motDesICMSST };
|
|
991
|
+
};
|
|
992
|
+
const retido = (i) => {
|
|
993
|
+
const o = (k, f) => ctx.so(ctx.opt(i[k], `${path}.${k}`, f), f);
|
|
994
|
+
const vFCPSTRet = ctx.opt(i.vFCPSTRet, `${path}.vFCPSTRet`, M);
|
|
995
|
+
if (vFCPSTRet !== undefined)
|
|
996
|
+
t.vFCPSTRet = t.vFCPSTRet.plus(vFCPSTRet);
|
|
997
|
+
return {
|
|
998
|
+
vBCSTRet: o("vBCSTRet", M),
|
|
999
|
+
pST: o("pST", PO),
|
|
1000
|
+
vICMSSubstituto: o("vICMSSubstituto", M),
|
|
1001
|
+
vICMSSTRet: o("vICMSSTRet", M),
|
|
1002
|
+
vBCFCPSTRet: o("vBCFCPSTRet", M),
|
|
1003
|
+
pFCPSTRet: o("pFCPSTRet", PO),
|
|
1004
|
+
vFCPSTRet: ctx.so(vFCPSTRet, M),
|
|
1005
|
+
pRedBCEfet: o("pRedBCEfet", PO),
|
|
1006
|
+
vBCEfet: o("vBCEfet", M),
|
|
1007
|
+
pICMSEfet: o("pICMSEfet", PO),
|
|
1008
|
+
vICMSEfet: o("vICMSEfet", M)
|
|
1009
|
+
};
|
|
1010
|
+
};
|
|
1011
|
+
const diferimento = (i, redFormat, triade) => {
|
|
1012
|
+
const pRedBC = ctx.opt(i.pRedBC, `${path}.pRedBC`, redFormat);
|
|
1013
|
+
const pICMS = ctx.opt(i.pICMS, `${path}.pICMS`, P);
|
|
1014
|
+
const out = {};
|
|
1015
|
+
let vBC;
|
|
1016
|
+
if (pICMS !== undefined || i.vBC !== undefined) {
|
|
1017
|
+
const reduzida = pRedBC === undefined ? base.vOp : base.vOp.times(Decimal.HUNDRED.minus(pRedBC)).dividedBy(100, 10, "HALF_EVEN");
|
|
1018
|
+
vBC = ctx.base(i.vBC, reduzida, `${path}.vBC`, M, "icms");
|
|
1019
|
+
out.modBC = i.modBC ?? "3";
|
|
1020
|
+
out.vBC = S(vBC);
|
|
1021
|
+
}
|
|
1022
|
+
out.pRedBC = ctx.so(pRedBC, redFormat);
|
|
1023
|
+
out.cBenefRBC = i.cBenefRBC;
|
|
1024
|
+
if (pICMS !== undefined && vBC !== undefined) {
|
|
1025
|
+
out.pICMS = ctx.s(pICMS, P);
|
|
1026
|
+
const vICMSOp = ctx.calc(i.vICMSOp, vBC.percent(pICMS), `${path}.vICMSOp`, M, "icms");
|
|
1027
|
+
const pDif = ctx.opt(i.pDif, `${path}.pDif`, P);
|
|
1028
|
+
const vICMSDif = ctx.calc(i.vICMSDif, vICMSOp.percent(pDif ?? Decimal.ZERO), `${path}.vICMSDif`, M, "icms");
|
|
1029
|
+
const vICMS = ctx.calc(i.vICMS, vICMSOp.minus(vICMSDif), `${path}.vICMS`, M, "icms");
|
|
1030
|
+
const temDif = pDif !== undefined || i.vICMSDif !== undefined || i.vICMSOp !== undefined;
|
|
1031
|
+
if (triade) {
|
|
1032
|
+
if (temDif)
|
|
1033
|
+
Object.assign(out, { vICMSOp: S(vICMSOp), pDif: ctx.s(pDif ?? Decimal.ZERO, P), vICMSDif: S(vICMSDif) });
|
|
1034
|
+
} else {
|
|
1035
|
+
Object.assign(out, {
|
|
1036
|
+
vICMSOp: S(vICMSOp),
|
|
1037
|
+
pDif: ctx.so(pDif, P),
|
|
1038
|
+
vICMSDif: pDif === undefined && i.vICMSDif === undefined ? undefined : S(vICMSDif)
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
1041
|
+
Object.assign(out, {
|
|
1042
|
+
vICMS: S(vICMS)
|
|
1043
|
+
});
|
|
1044
|
+
t.vBC = t.vBC.plus(vBC);
|
|
1045
|
+
t.vICMS = t.vICMS.plus(vICMS);
|
|
1046
|
+
} else {
|
|
1047
|
+
const informados = [i.vBC, i.vICMS, i.vICMSOp, i.pDif, i.vICMSDif, i.pRedBC].some((x) => x !== undefined);
|
|
1048
|
+
if (triade && informados) {
|
|
1049
|
+
ctx.issues.add(`${path}.pICMS`, "campo_obrigatorio", "o ICMS próprio do CST 90 (vBC, vICMS, diferimento) exige pICMS");
|
|
1050
|
+
}
|
|
1051
|
+
if (!triade) {
|
|
1052
|
+
Object.assign(out, {
|
|
1053
|
+
modBC: out.modBC ?? i.modBC,
|
|
1054
|
+
vICMSOp: ctx.so(ctx.opt(i.vICMSOp, `${path}.vICMSOp`, M), M),
|
|
1055
|
+
pDif: ctx.so(ctx.opt(i.pDif, `${path}.pDif`, P), P),
|
|
1056
|
+
vICMSDif: ctx.so(ctx.opt(i.vICMSDif, `${path}.vICMSDif`, M), M)
|
|
1057
|
+
});
|
|
1058
|
+
}
|
|
1059
|
+
const vICMS = ctx.opt(i.vICMS, `${path}.vICMS`, M);
|
|
1060
|
+
if (vICMS !== undefined) {
|
|
1061
|
+
out.vICMS = S(vICMS);
|
|
1062
|
+
t.vICMS = t.vICMS.plus(vICMS);
|
|
1063
|
+
}
|
|
1064
|
+
if (vBC !== undefined)
|
|
1065
|
+
t.vBC = t.vBC.plus(vBC);
|
|
1066
|
+
}
|
|
1067
|
+
const pFCP = ctx.opt(i.pFCP, `${path}.pFCP`, PO);
|
|
1068
|
+
const temFcp = i.pFCP !== undefined || i.vFCP !== undefined;
|
|
1069
|
+
for (const k of ["vBCFCP", "pFCPDif", "vFCPDif", "vFCPEfet"])
|
|
1070
|
+
orfao(i[k], temFcp, k, "pFCP");
|
|
1071
|
+
orfao(i.vFCPEfet, !temFcp || i.pFCPDif !== undefined || i.vFCPDif !== undefined, "vFCPEfet", "pFCPDif");
|
|
1072
|
+
if (pFCP !== undefined || i.vFCP !== undefined) {
|
|
1073
|
+
const vBCFCP = ctx.base(i.vBCFCP, vBC ?? Decimal.ZERO, `${path}.vBCFCP`, M, "icms");
|
|
1074
|
+
const vFCP = ctx.calc(i.vFCP, vBCFCP.percent(pFCP ?? Decimal.ZERO), `${path}.vFCP`, M, "icms");
|
|
1075
|
+
const pFCPDif = ctx.opt(i.pFCPDif, `${path}.pFCPDif`, PO);
|
|
1076
|
+
const vFCPDif = ctx.calc(i.vFCPDif, vFCP.percent(pFCPDif ?? Decimal.ZERO), `${path}.vFCPDif`, M, "icms");
|
|
1077
|
+
const vFCPEfet = ctx.calc(i.vFCPEfet, vFCP.minus(vFCPDif), `${path}.vFCPEfet`, M, "icms");
|
|
1078
|
+
t.vFCP = t.vFCP.plus(vFCP);
|
|
1079
|
+
const temDif = pFCPDif !== undefined || i.vFCPDif !== undefined;
|
|
1080
|
+
Object.assign(out, {
|
|
1081
|
+
vBCFCP: S(vBCFCP),
|
|
1082
|
+
pFCP: ctx.so(pFCP, PO),
|
|
1083
|
+
vFCP: S(vFCP),
|
|
1084
|
+
pFCPDif: ctx.so(pFCPDif, PO),
|
|
1085
|
+
vFCPDif: temDif ? S(vFCPDif) : undefined,
|
|
1086
|
+
vFCPEfet: temDif ? S(vFCPEfet) : undefined
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
return out;
|
|
1090
|
+
};
|
|
1091
|
+
const q = (v, k) => ctx.opt(v, `${path}.${k}`, D1104V);
|
|
1092
|
+
const mono = (qtd, adRem, given, k) => ctx.base(given, (qtd ?? Decimal.ZERO).times(adRem ?? Decimal.ZERO), `${path}.${k}`, M, "icms");
|
|
1093
|
+
let grupo;
|
|
1094
|
+
if ("CSOSN" in input) {
|
|
1095
|
+
const orig = input.orig;
|
|
1096
|
+
switch (input.CSOSN) {
|
|
1097
|
+
case "101": {
|
|
1098
|
+
const pCredSN = ctx.req(input.pCredSN, `${path}.pCredSN`, P);
|
|
1099
|
+
const v = ctx.calc(input.vCredICMSSN, base.vOp.percent(pCredSN), `${path}.vCredICMSSN`, M, "icms");
|
|
1100
|
+
grupo = { ICMSSN101: { orig, CSOSN: "101", pCredSN: ctx.s(pCredSN, P), vCredICMSSN: S(v) } };
|
|
1101
|
+
break;
|
|
1102
|
+
}
|
|
1103
|
+
case "102":
|
|
1104
|
+
case "103":
|
|
1105
|
+
case "300":
|
|
1106
|
+
case "400":
|
|
1107
|
+
grupo = { ICMSSN102: { orig, CSOSN: input.CSOSN } };
|
|
1108
|
+
break;
|
|
1109
|
+
case "201": {
|
|
1110
|
+
const stOut = st(input.st, Decimal.ZERO, Decimal.ZERO);
|
|
1111
|
+
const pCredSN = ctx.req(input.pCredSN, `${path}.pCredSN`, P);
|
|
1112
|
+
const v = ctx.calc(input.vCredICMSSN, base.vOp.percent(pCredSN), `${path}.vCredICMSSN`, M, "icms");
|
|
1113
|
+
grupo = { ICMSSN201: { orig, CSOSN: "201", ...stOut, pCredSN: ctx.s(pCredSN, P), vCredICMSSN: S(v) } };
|
|
1114
|
+
break;
|
|
1115
|
+
}
|
|
1116
|
+
case "202":
|
|
1117
|
+
case "203":
|
|
1118
|
+
grupo = { ICMSSN202: { orig, CSOSN: input.CSOSN, ...st(input.st, Decimal.ZERO, Decimal.ZERO) } };
|
|
1119
|
+
break;
|
|
1120
|
+
case "500":
|
|
1121
|
+
grupo = { ICMSSN500: { orig, CSOSN: "500", ...retido(input) } };
|
|
1122
|
+
break;
|
|
1123
|
+
case "900": {
|
|
1124
|
+
const pRedBC = ctx.opt(input.pRedBC, `${path}.pRedBC`, PO);
|
|
1125
|
+
const p = proprio(input, pRedBC, false);
|
|
1126
|
+
const out = { orig, CSOSN: "900" };
|
|
1127
|
+
if (p)
|
|
1128
|
+
Object.assign(out, {
|
|
1129
|
+
modBC: p.out.modBC,
|
|
1130
|
+
vBC: p.out.vBC,
|
|
1131
|
+
pRedBC: ctx.so(pRedBC, PO),
|
|
1132
|
+
pICMS: p.out.pICMS,
|
|
1133
|
+
vICMS: p.out.vICMS
|
|
1134
|
+
});
|
|
1135
|
+
if (input.st)
|
|
1136
|
+
Object.assign(out, st(input.st, p?.vICMS ?? Decimal.ZERO, Decimal.ZERO));
|
|
1137
|
+
const pCredSN = ctx.opt(input.pCredSN, `${path}.pCredSN`, P);
|
|
1138
|
+
orfao(input.vCredICMSSN, input.pCredSN !== undefined, "vCredICMSSN", "pCredSN");
|
|
1139
|
+
if (pCredSN !== undefined) {
|
|
1140
|
+
const v = ctx.calc(input.vCredICMSSN, base.vOp.percent(pCredSN), `${path}.vCredICMSSN`, M, "icms");
|
|
1141
|
+
Object.assign(out, { pCredSN: ctx.s(pCredSN, P), vCredICMSSN: S(v) });
|
|
1142
|
+
}
|
|
1143
|
+
grupo = { ICMSSN900: out };
|
|
1144
|
+
break;
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
} else if (input.grupo === "Part") {
|
|
1148
|
+
const pRedBC = ctx.opt(input.pRedBC, `${path}.pRedBC`, PO);
|
|
1149
|
+
const p = proprio(input, pRedBC, true);
|
|
1150
|
+
const pBCOp = ctx.req(input.pBCOp, `${path}.pBCOp`, PO);
|
|
1151
|
+
grupo = {
|
|
1152
|
+
ICMSPart: {
|
|
1153
|
+
orig: input.orig,
|
|
1154
|
+
CST: input.CST,
|
|
1155
|
+
modBC: input.modBC,
|
|
1156
|
+
vBC: p.out.vBC,
|
|
1157
|
+
pRedBC: ctx.so(pRedBC, PO),
|
|
1158
|
+
pICMS: p.out.pICMS,
|
|
1159
|
+
vICMS: p.out.vICMS,
|
|
1160
|
+
...st(input.st, p.vICMS, Decimal.ZERO),
|
|
1161
|
+
pBCOp: ctx.s(pBCOp, PO),
|
|
1162
|
+
UFST: input.UFST,
|
|
1163
|
+
...deson(input.desoneracao)
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
} else if (input.grupo === "ST") {
|
|
1167
|
+
grupo = {
|
|
1168
|
+
ICMSST: {
|
|
1169
|
+
orig: input.orig,
|
|
1170
|
+
CST: input.CST,
|
|
1171
|
+
...retido(input),
|
|
1172
|
+
vBCSTRet: S(ctx.req(input.vBCSTRet, `${path}.vBCSTRet`, M)),
|
|
1173
|
+
vICMSSTRet: S(ctx.req(input.vICMSSTRet, `${path}.vICMSSTRet`, M)),
|
|
1174
|
+
vBCSTDest: S(ctx.req(input.vBCSTDest, `${path}.vBCSTDest`, M)),
|
|
1175
|
+
vICMSSTDest: S(ctx.req(input.vICMSSTDest, `${path}.vICMSSTDest`, M))
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
} else {
|
|
1179
|
+
const orig = input.orig;
|
|
1180
|
+
switch (input.CST) {
|
|
1181
|
+
case "00": {
|
|
1182
|
+
const p = proprio(input, undefined, true);
|
|
1183
|
+
grupo = { ICMS00: { orig, CST: "00", ...p.out, ...fcp(input, p.vBC, false) } };
|
|
1184
|
+
break;
|
|
1185
|
+
}
|
|
1186
|
+
case "02": {
|
|
1187
|
+
const qBCMono = q(input.qBCMono, "qBCMono");
|
|
1188
|
+
const adRem = ctx.req(input.adRemICMS, `${path}.adRemICMS`, P);
|
|
1189
|
+
const v = mono(qBCMono, adRem, input.vICMSMono, "vICMSMono");
|
|
1190
|
+
t.mono = true;
|
|
1191
|
+
t.qBCMono = t.qBCMono.plus(qBCMono ?? Decimal.ZERO);
|
|
1192
|
+
t.vICMSMono = t.vICMSMono.plus(v);
|
|
1193
|
+
grupo = {
|
|
1194
|
+
ICMS02: {
|
|
1195
|
+
orig,
|
|
1196
|
+
CST: "02",
|
|
1197
|
+
qBCMono: ctx.so(qBCMono, D1104V),
|
|
1198
|
+
adRemICMS: ctx.s(adRem, P),
|
|
1199
|
+
vICMSMono: S(v)
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
break;
|
|
1203
|
+
}
|
|
1204
|
+
case "10": {
|
|
1205
|
+
const p = proprio(input, undefined, true);
|
|
1206
|
+
const f = fcp(input, p.vBC, true);
|
|
1207
|
+
const vFCP = f.vFCP === undefined ? Decimal.ZERO : Decimal.of(f.vFCP);
|
|
1208
|
+
grupo = {
|
|
1209
|
+
ICMS10: { orig, CST: "10", ...p.out, ...f, ...st(input.st, p.vICMS, vFCP), ...desonSt(input.desoneracaoSt) }
|
|
1210
|
+
};
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
case "15": {
|
|
1214
|
+
const qBCMono = q(input.qBCMono, "qBCMono");
|
|
1215
|
+
const adRem = ctx.req(input.adRemICMS, `${path}.adRemICMS`, P);
|
|
1216
|
+
const v = mono(qBCMono, adRem, input.vICMSMono, "vICMSMono");
|
|
1217
|
+
const qReten = q(input.qBCMonoReten, "qBCMonoReten");
|
|
1218
|
+
const adRemReten = ctx.req(input.adRemICMSReten, `${path}.adRemICMSReten`, P);
|
|
1219
|
+
if (input.pRedAdRem !== undefined) {
|
|
1220
|
+
if (input.vICMSMono === undefined)
|
|
1221
|
+
ctx.issues.add(`${path}.vICMSMono`, "campo_obrigatorio", "com pRedAdRem, informe vICMSMono");
|
|
1222
|
+
if (input.vICMSMonoReten === undefined) {
|
|
1223
|
+
ctx.issues.add(`${path}.vICMSMonoReten`, "campo_obrigatorio", "com pRedAdRem, informe vICMSMonoReten");
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
const vReten = mono(qReten, adRemReten, input.vICMSMonoReten, "vICMSMonoReten");
|
|
1227
|
+
t.mono = true;
|
|
1228
|
+
t.qBCMono = t.qBCMono.plus(qBCMono ?? Decimal.ZERO);
|
|
1229
|
+
t.vICMSMono = t.vICMSMono.plus(v);
|
|
1230
|
+
t.qBCMonoReten = t.qBCMonoReten.plus(qReten ?? Decimal.ZERO);
|
|
1231
|
+
t.vICMSMonoReten = t.vICMSMonoReten.plus(vReten);
|
|
1232
|
+
grupo = {
|
|
1233
|
+
ICMS15: {
|
|
1234
|
+
orig,
|
|
1235
|
+
CST: "15",
|
|
1236
|
+
qBCMono: ctx.so(qBCMono, D1104V),
|
|
1237
|
+
adRemICMS: ctx.s(adRem, P),
|
|
1238
|
+
vICMSMono: S(v),
|
|
1239
|
+
qBCMonoReten: ctx.so(qReten, D1104V),
|
|
1240
|
+
adRemICMSReten: ctx.s(adRemReten, P),
|
|
1241
|
+
vICMSMonoReten: S(vReten),
|
|
1242
|
+
pRedAdRem: ctx.so(ctx.opt(input.pRedAdRem, `${path}.pRedAdRem`, D0302A04), D0302A04),
|
|
1243
|
+
motRedAdRem: input.motRedAdRem
|
|
1244
|
+
}
|
|
1245
|
+
};
|
|
1246
|
+
break;
|
|
1247
|
+
}
|
|
1248
|
+
case "20": {
|
|
1249
|
+
const pRedBC = ctx.req(input.pRedBC, `${path}.pRedBC`, P);
|
|
1250
|
+
const p = proprio(input, pRedBC, true);
|
|
1251
|
+
grupo = {
|
|
1252
|
+
ICMS20: {
|
|
1253
|
+
orig,
|
|
1254
|
+
CST: "20",
|
|
1255
|
+
modBC: p.out.modBC,
|
|
1256
|
+
pRedBC: ctx.s(pRedBC, P),
|
|
1257
|
+
vBC: p.out.vBC,
|
|
1258
|
+
pICMS: p.out.pICMS,
|
|
1259
|
+
vICMS: p.out.vICMS,
|
|
1260
|
+
...fcp(input, p.vBC, true),
|
|
1261
|
+
...deson(input.desoneracao)
|
|
1262
|
+
}
|
|
1263
|
+
};
|
|
1264
|
+
break;
|
|
1265
|
+
}
|
|
1266
|
+
case "30":
|
|
1267
|
+
grupo = {
|
|
1268
|
+
ICMS30: { orig, CST: "30", ...st(input.st, Decimal.ZERO, Decimal.ZERO), ...deson(input.desoneracao) }
|
|
1269
|
+
};
|
|
1270
|
+
break;
|
|
1271
|
+
case "40":
|
|
1272
|
+
case "41":
|
|
1273
|
+
case "50":
|
|
1274
|
+
grupo = { ICMS40: { orig, CST: input.CST, ...deson(input.desoneracao) } };
|
|
1275
|
+
break;
|
|
1276
|
+
case "51":
|
|
1277
|
+
grupo = { ICMS51: { orig, CST: "51", ...diferimento(input, P, false) } };
|
|
1278
|
+
break;
|
|
1279
|
+
case "53": {
|
|
1280
|
+
const qBCMono = q(input.qBCMono, "qBCMono");
|
|
1281
|
+
const adRem = ctx.opt(input.adRemICMS, `${path}.adRemICMS`, P);
|
|
1282
|
+
const vOp = mono(qBCMono, adRem, input.vICMSMonoOp, "vICMSMonoOp");
|
|
1283
|
+
const pDif = ctx.opt(input.pDif, `${path}.pDif`, P);
|
|
1284
|
+
const vDif = ctx.calc(input.vICMSMonoDif, vOp.percent(pDif ?? Decimal.ZERO), `${path}.vICMSMonoDif`, M, "icms");
|
|
1285
|
+
const v = ctx.calc(input.vICMSMono, vOp.minus(vDif), `${path}.vICMSMono`, M, "icms");
|
|
1286
|
+
const qDif = q(input.qBCMonoDif, "qBCMonoDif");
|
|
1287
|
+
const adRemDif = ctx.opt(input.adRemICMSDif, `${path}.adRemICMSDif`, P);
|
|
1288
|
+
t.mono = true;
|
|
1289
|
+
t.qBCMono = t.qBCMono.plus(qBCMono ?? Decimal.ZERO);
|
|
1290
|
+
t.vICMSMono = t.vICMSMono.plus(v);
|
|
1291
|
+
grupo = {
|
|
1292
|
+
ICMS53: {
|
|
1293
|
+
orig,
|
|
1294
|
+
CST: "53",
|
|
1295
|
+
qBCMono: ctx.so(qBCMono, D1104V),
|
|
1296
|
+
adRemICMS: ctx.so(adRem, P),
|
|
1297
|
+
vICMSMonoOp: adRem === undefined && input.vICMSMonoOp === undefined ? undefined : S(vOp),
|
|
1298
|
+
pDif: ctx.so(pDif, P),
|
|
1299
|
+
vICMSMonoDif: pDif === undefined && input.vICMSMonoDif === undefined ? undefined : S(vDif),
|
|
1300
|
+
vICMSMono: adRem === undefined && input.vICMSMono === undefined ? undefined : S(v),
|
|
1301
|
+
qBCMonoDif: ctx.so(qDif, D1104V),
|
|
1302
|
+
adRemICMSDif: ctx.so(adRemDif, P)
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
break;
|
|
1306
|
+
}
|
|
1307
|
+
case "60":
|
|
1308
|
+
grupo = { ICMS60: { orig, CST: "60", ...retido(input) } };
|
|
1309
|
+
break;
|
|
1310
|
+
case "61": {
|
|
1311
|
+
const qRet = q(input.qBCMonoRet, "qBCMonoRet");
|
|
1312
|
+
const adRem = ctx.req(input.adRemICMSRet, `${path}.adRemICMSRet`, P);
|
|
1313
|
+
const v = mono(qRet, adRem, input.vICMSMonoRet, "vICMSMonoRet");
|
|
1314
|
+
t.mono = true;
|
|
1315
|
+
t.qBCMonoRet = t.qBCMonoRet.plus(qRet ?? Decimal.ZERO);
|
|
1316
|
+
t.vICMSMonoRet = t.vICMSMonoRet.plus(v);
|
|
1317
|
+
grupo = {
|
|
1318
|
+
ICMS61: {
|
|
1319
|
+
orig,
|
|
1320
|
+
CST: "61",
|
|
1321
|
+
qBCMonoRet: ctx.so(qRet, D1104V),
|
|
1322
|
+
adRemICMSRet: ctx.s(adRem, P),
|
|
1323
|
+
vICMSMonoRet: S(v)
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
break;
|
|
1327
|
+
}
|
|
1328
|
+
case "70": {
|
|
1329
|
+
const pRedBC = ctx.req(input.pRedBC, `${path}.pRedBC`, P);
|
|
1330
|
+
const p = proprio(input, pRedBC, true);
|
|
1331
|
+
const f = fcp(input, p.vBC, true);
|
|
1332
|
+
const vFCP = f.vFCP === undefined ? Decimal.ZERO : Decimal.of(f.vFCP);
|
|
1333
|
+
grupo = {
|
|
1334
|
+
ICMS70: {
|
|
1335
|
+
orig,
|
|
1336
|
+
CST: "70",
|
|
1337
|
+
modBC: p.out.modBC,
|
|
1338
|
+
pRedBC: ctx.s(pRedBC, P),
|
|
1339
|
+
vBC: p.out.vBC,
|
|
1340
|
+
pICMS: p.out.pICMS,
|
|
1341
|
+
vICMS: p.out.vICMS,
|
|
1342
|
+
...f,
|
|
1343
|
+
...st(input.st, p.vICMS, vFCP),
|
|
1344
|
+
...deson(input.desoneracao),
|
|
1345
|
+
...desonSt(input.desoneracaoSt)
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
break;
|
|
1349
|
+
}
|
|
1350
|
+
case "90": {
|
|
1351
|
+
const d = diferimento(input, PO, true);
|
|
1352
|
+
const vICMS = d.vICMS === undefined ? Decimal.ZERO : Decimal.of(d.vICMS);
|
|
1353
|
+
const vFCP = d.vFCP;
|
|
1354
|
+
grupo = {
|
|
1355
|
+
ICMS90: {
|
|
1356
|
+
orig,
|
|
1357
|
+
CST: "90",
|
|
1358
|
+
...d,
|
|
1359
|
+
...input.st ? st(input.st, vICMS, vFCP === undefined ? Decimal.ZERO : Decimal.of(vFCP)) : {},
|
|
1360
|
+
...deson(input.desoneracao),
|
|
1361
|
+
...desonSt(input.desoneracaoSt)
|
|
1362
|
+
}
|
|
1363
|
+
};
|
|
1364
|
+
break;
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
}
|
|
1368
|
+
const [name, body] = Object.entries(grupo)[0];
|
|
1369
|
+
return { grupo: { [name]: clean(body) }, totais: t };
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
// packages/nfe/src/build/nfce.ts
|
|
1373
|
+
import { tpAmbDoAmbiente } from "@sinete/core";
|
|
1374
|
+
import { c14n, codificarBase64, lerXml as lerXml2, PREFIXO_DIGEST_INFO_SHA1, primeiroFilho as primeiroFilho2 } from "@sinete/core/xml";
|
|
1375
|
+
import { lerCnpj as lerCnpj2 } from "@sinete/validators";
|
|
1376
|
+
// packages/nfe/src/data/nfce-urls.json
|
|
1377
|
+
var nfce_urls_default = {
|
|
1378
|
+
descricao: "Endereços da NFC-e (modelo 65) por UF e ambiente: a consulta via QR Code (1ª parte da URL do infNFeSupl/qrCode, sem o '?p=' que o builder acrescenta) e a consulta por chave de acesso (infNFeSupl/urlChave, impressa no DANFC-e). Cada UF tem uma lista de endereços com a data de início ('desde', AAAA-MM-DD, 00:00 de Brasília); vale o mais recente cujo início não passou da data de emissão. As tabelas do ENCAT foram transcritas como publicadas, com três ajustes: o '?' final e o exemplo de parâmetros (AM: '?chNFe=1315....') foram retirados, porque o builder monta a query; o espaço dentro do endereço de homologação do MA ('homolog acao') foi juntado; e o endereço de MG por chave de acesso vem da página de web services da própria SEFAZ-MG, mais nova que a do ENCAT. Onde a tabela não dá o protocolo ('http://' ou 'https://'), a URL do QR Code fica null: o schema exige o protocolo e não há fonte para escolher um; informe MontarNfeOpcoes.urlQrCode. A regra ZX02-20 (rejeição 395) compara o endereço sem diferenciar maiúsculas e minúsculas; ZX03-20 (rejeição 878) é opcional por UF.",
|
|
1379
|
+
atualizadoEm: "2026-09-26",
|
|
1380
|
+
fontes: [
|
|
1381
|
+
"Portal Nacional da NFC-e (ENCAT), URL por UF utilizada QR code: https://nfce.encat.org/desenvolvedor/qrcode/ (coletada em 26/09/2026)",
|
|
1382
|
+
"Portal Nacional da NFC-e (ENCAT), URL por UF utilizada para consulta chave, QR Code versão 2.0: https://nfce.encat.org/desenvolvedor/httpnfce-encat-orgconsulte-sua-nota-qr-code-versao-2-0/ (coletada em 26/09/2026)",
|
|
1383
|
+
"SEFAZ-MG, web services da NFC-e: https://portalsped.fazenda.mg.gov.br/spedmg/nfce/web-services/ (a mesma fonte do urlsConsultaNfce do @sinete/transport) (coletada em 26/09/2026)",
|
|
1384
|
+
"MOC 7.0 Anexo I, regras ZX02-20 e ZX03-20; NT 2025.001 v1.03, grupo ZX (campos ZX02 qrCode e ZX03 urlChave)"
|
|
1385
|
+
],
|
|
1386
|
+
qrCode: {
|
|
1387
|
+
producao: {
|
|
1388
|
+
AC: [{ url: "http://www.sefaznet.ac.gov.br/nfce/qrcode" }],
|
|
1389
|
+
AL: [{ url: "http://nfce.sefaz.al.gov.br/QRCode/consultarNFCe.jsp" }],
|
|
1390
|
+
AP: [{ url: "https://www.sefaz.ap.gov.br/nfce/nfcep.php" }],
|
|
1391
|
+
AM: [
|
|
1392
|
+
{ url: null, nota: "tabela do ENCAT sem protocolo: sistemas.sefaz.am.gov.br/nfceweb/consultarNFCe.jsp" }
|
|
1393
|
+
],
|
|
1394
|
+
BA: [{ url: "http://nfe.sefaz.ba.gov.br/servicos/nfce/qrcode.aspx" }],
|
|
1395
|
+
CE: [{ url: "http://nfce.sefaz.ce.gov.br/pages/ShowNFCe.html" }],
|
|
1396
|
+
DF: [{ url: "http://www.fazenda.df.gov.br/nfce/qrcode" }],
|
|
1397
|
+
ES: [{ url: "http://app.sefaz.es.gov.br/ConsultaNFCe/" }],
|
|
1398
|
+
GO: [
|
|
1399
|
+
{ url: "http://nfe.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe" },
|
|
1400
|
+
{ url: "https://nfeweb.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe", desde: "2025-06-16" }
|
|
1401
|
+
],
|
|
1402
|
+
MA: [{ url: null, nota: "tabela do ENCAT sem protocolo: nfce.sefaz.ma.gov.br/portal/consultarNFCe.jsp" }],
|
|
1403
|
+
MT: [{ url: "http://www.sefaz.mt.gov.br/nfce/consultanfce" }],
|
|
1404
|
+
MS: [{ url: "http://www.dfe.ms.gov.br/nfce/qrcode" }],
|
|
1405
|
+
MG: [
|
|
1406
|
+
{ url: "https://nfce.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml" },
|
|
1407
|
+
{ url: "https://portalsped.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml", desde: "2022-03-21" }
|
|
1408
|
+
],
|
|
1409
|
+
PA: [{ url: "https://appnfc.sefa.pa.gov.br/portal/view/consultas/nfce/nfceForm.seam" }],
|
|
1410
|
+
PB: [{ url: "http://www.sefaz.pb.gov.br/nfce" }],
|
|
1411
|
+
PR: [{ url: "http://www.fazenda.pr.gov.br/nfce/qrcode" }],
|
|
1412
|
+
PE: [{ url: "http://nfce.sefaz.pe.gov.br/nfce/consulta" }],
|
|
1413
|
+
PI: [{ url: "http://www.sefaz.pi.gov.br/nfce/qrcode" }],
|
|
1414
|
+
RJ: [
|
|
1415
|
+
{ url: "http://www4.fazenda.rj.gov.br/consultaNFCe/QRCode" },
|
|
1416
|
+
{ url: "https://consultadfe.fazenda.rj.gov.br/consultaNFCe/QRCode", desde: "2023-12-19" }
|
|
1417
|
+
],
|
|
1418
|
+
RN: [
|
|
1419
|
+
{ url: "http://nfce.set.rn.gov.br/consultarNFCe.aspx" },
|
|
1420
|
+
{ url: "https://nfce.sefaz.rn.gov.br/consultarNFCe.aspx", desde: "2026-05-25" }
|
|
1421
|
+
],
|
|
1422
|
+
RS: [{ url: "https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx" }],
|
|
1423
|
+
RO: [{ url: "http://www.nfce.sefin.ro.gov.br/consultanfce/consulta.jsp" }],
|
|
1424
|
+
RR: [{ url: "https://www.sefaz.rr.gov.br/nfce/servlet/qrcode" }],
|
|
1425
|
+
SC: [{ url: "https://sat.sef.sc.gov.br/nfce/consulta" }],
|
|
1426
|
+
SP: [
|
|
1427
|
+
{
|
|
1428
|
+
url: "https://www.nfce.fazenda.sp.gov.br/NFCeConsultaPublica/Paginas/ConsultaQRCode.aspx",
|
|
1429
|
+
nota: "a tabela do ENCAT lista também https://www.nfce.fazenda.sp.gov.br/qrcode"
|
|
1430
|
+
}
|
|
1431
|
+
],
|
|
1432
|
+
SE: [{ url: "http://www.nfce.se.gov.br/nfce/qrcode" }],
|
|
1433
|
+
TO: [{ url: "http://www.sefaz.to.gov.br/nfce/qrcode" }]
|
|
1434
|
+
},
|
|
1435
|
+
homologacao: {
|
|
1436
|
+
AC: [{ url: "http://www.hml.sefaznet.ac.gov.br/nfce/qrcode" }],
|
|
1437
|
+
AL: [{ url: "http://nfce.sefaz.al.gov.br/QRCode/consultarNFCe.jsp" }],
|
|
1438
|
+
AP: [{ url: "https://www.sefaz.ap.gov.br/nfcehml/nfce.php" }],
|
|
1439
|
+
AM: [
|
|
1440
|
+
{ url: null, nota: "tabela do ENCAT sem protocolo: homnfce.sefaz.am.gov.br/nfceweb/consultarNFCe.jsp" }
|
|
1441
|
+
],
|
|
1442
|
+
BA: [{ url: "http://hnfe.sefaz.ba.gov.br/servicos/nfce/qrcode.aspx" }],
|
|
1443
|
+
CE: [{ url: "http://nfceh.sefaz.ce.gov.br/pages/ShowNFCe.html" }],
|
|
1444
|
+
DF: [{ url: "http://www.fazenda.df.gov.br/nfce/qrcode" }],
|
|
1445
|
+
ES: [{ url: "http://homologacao.sefaz.es.gov.br/ConsultaNFCe/" }],
|
|
1446
|
+
GO: [
|
|
1447
|
+
{ url: "http://homolog.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe" },
|
|
1448
|
+
{ url: "https://nfewebhomolog.sefaz.go.gov.br/nfeweb/sites/nfce/danfeNFCe", desde: "2025-06-16" }
|
|
1449
|
+
],
|
|
1450
|
+
MA: [
|
|
1451
|
+
{ url: null, nota: "tabela do ENCAT sem protocolo: homologacao.sefaz.ma.gov.br/portal/consultarNFCe.jsp" }
|
|
1452
|
+
],
|
|
1453
|
+
MT: [{ url: "http://homologacao.sefaz.mt.gov.br/nfce/consultanfce" }],
|
|
1454
|
+
MS: [{ url: "http://www.dfe.ms.gov.br/nfce/qrcode" }],
|
|
1455
|
+
MG: [
|
|
1456
|
+
{ url: "https://nfce.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml" },
|
|
1457
|
+
{ url: "https://portalsped.fazenda.mg.gov.br/portalnfce/sistema/qrcode.xhtml", desde: "2022-03-21" }
|
|
1458
|
+
],
|
|
1459
|
+
PA: [{ url: "https://appnfc.sefa.pa.gov.br/portal-homologacao/view/consultas/nfce/nfceForm.seam" }],
|
|
1460
|
+
PB: [{ url: "http://www.sefaz.pb.gov.br/nfcehom" }],
|
|
1461
|
+
PR: [{ url: "http://www.fazenda.pr.gov.br/nfce/qrcode" }],
|
|
1462
|
+
PE: [{ url: "http://nfcehomolog.sefaz.pe.gov.br/nfce/consulta" }],
|
|
1463
|
+
PI: [{ url: "http://www.sefaz.pi.gov.br/nfce/qrcode" }],
|
|
1464
|
+
RJ: [
|
|
1465
|
+
{ url: "http://www4.fazenda.rj.gov.br/consultaNFCe/QRCode" },
|
|
1466
|
+
{ url: "https://consultadfe.fazenda.rj.gov.br/consultaNFCe/QRCode", desde: "2023-12-19" }
|
|
1467
|
+
],
|
|
1468
|
+
RN: [
|
|
1469
|
+
{ url: "http://hom.nfce.set.rn.gov.br/consultarNFCe.aspx" },
|
|
1470
|
+
{ url: "https://hom.nfce.sefaz.rn.gov.br/consultarNFCe.aspx", desde: "2026-05-25" }
|
|
1471
|
+
],
|
|
1472
|
+
RS: [{ url: "https://www.sefaz.rs.gov.br/NFCE/NFCE-COM.aspx" }],
|
|
1473
|
+
RO: [{ url: "http://www.nfce.sefin.ro.gov.br/consultanfce/consulta.jsp" }],
|
|
1474
|
+
RR: [{ url: "http://200.174.88.103:8080/nfce/servlet/qrcode" }],
|
|
1475
|
+
SC: [{ url: "https://hom.sat.sef.sc.gov.br/nfce/consulta" }],
|
|
1476
|
+
SP: [
|
|
1477
|
+
{
|
|
1478
|
+
url: "https://www.homologacao.nfce.fazenda.sp.gov.br/NFCeConsultaPublica/Paginas/ConsultaQRCode.aspx",
|
|
1479
|
+
nota: "a tabela do ENCAT lista também https://www.homologacao.nfce.fazenda.sp.gov.br/qrcode"
|
|
1480
|
+
}
|
|
1481
|
+
],
|
|
1482
|
+
SE: [{ url: "http://www.hom.nfe.se.gov.br/nfce/qrcode" }],
|
|
1483
|
+
TO: [{ url: "http://homologacao.sefaz.to.gov.br/nfce/qrcode" }]
|
|
1484
|
+
}
|
|
1485
|
+
},
|
|
1486
|
+
urlChave: {
|
|
1487
|
+
producao: {
|
|
1488
|
+
AC: [{ url: "www.sefaznet.ac.gov.br/nfce/consulta" }],
|
|
1489
|
+
AL: [{ url: "www.sefaz.al.gov.br/nfce/consulta" }],
|
|
1490
|
+
AP: [{ url: "www.sefaz.ap.gov.br/nfce/consulta" }],
|
|
1491
|
+
AM: [{ url: "www.sefaz.am.gov.br/nfce/consulta" }],
|
|
1492
|
+
BA: [{ url: "www.sefaz.ba.gov.br/nfce/consulta" }],
|
|
1493
|
+
CE: [{ url: "www.sefaz.ce.gov.br/nfce/consulta" }],
|
|
1494
|
+
DF: [{ url: "www.fazenda.df.gov.br/nfce/consulta" }],
|
|
1495
|
+
ES: [{ url: "www.sefaz.es.gov.br/nfce/consulta" }],
|
|
1496
|
+
GO: [{ url: "www.sefaz.go.gov.br/nfce/consulta" }],
|
|
1497
|
+
MA: [{ url: "www.sefaz.ma.gov.br/nfce/consulta" }],
|
|
1498
|
+
MT: [{ url: "http://www.sefaz.mt.gov.br/nfce/consultanfce" }],
|
|
1499
|
+
MS: [{ url: "www.dfe.ms.gov.br/nfce/consulta" }],
|
|
1500
|
+
MG: [{ url: "https://portalsped.fazenda.mg.gov.br/portalnfce" }],
|
|
1501
|
+
PA: [{ url: "www.sefa.pa.gov.br/nfce/consulta" }],
|
|
1502
|
+
PB: [{ url: "www.receita.pb.gov.br/nfce/consulta" }],
|
|
1503
|
+
PR: [{ url: "http://www.fazenda.pr.gov.br/nfce/consulta" }],
|
|
1504
|
+
PE: [{ url: "nfce.sefaz.pe.gov.br/nfce/consulta" }],
|
|
1505
|
+
PI: [{ url: "www.sefaz.pi.gov.br/nfce/consulta" }],
|
|
1506
|
+
RJ: [{ url: "www.fazenda.rj.gov.br/nfce/consulta" }],
|
|
1507
|
+
RN: [{ url: "www.set.rn.gov.br/nfce/consulta" }],
|
|
1508
|
+
RS: [{ url: "www.sefaz.rs.gov.br/nfce/consulta" }],
|
|
1509
|
+
RO: [{ url: "www.sefin.ro.gov.br/nfce/consulta" }],
|
|
1510
|
+
RR: [{ url: "www.sefaz.rr.gov.br/nfce/consulta" }],
|
|
1511
|
+
SC: [{ url: "https://sat.sef.sc.gov.br/nfce/consulta" }],
|
|
1512
|
+
SP: [{ url: "https://www.nfce.fazenda.sp.gov.br/consulta" }],
|
|
1513
|
+
SE: [{ url: "http://www.nfce.se.gov.br/nfce/consulta" }],
|
|
1514
|
+
TO: [{ url: "www.sefaz.to.gov.br/nfce/consulta" }]
|
|
1515
|
+
},
|
|
1516
|
+
homologacao: {
|
|
1517
|
+
AC: [{ url: "www.sefaznet.ac.gov.br/nfce/consulta" }],
|
|
1518
|
+
AL: [{ url: "www.sefaz.al.gov.br/nfce/consulta" }],
|
|
1519
|
+
AP: [{ url: "www.sefaz.ap.gov.br/nfce/consulta" }],
|
|
1520
|
+
AM: [{ url: "www.sefaz.am.gov.br/nfce/consulta" }],
|
|
1521
|
+
BA: [{ url: "http://hinternet.sefaz.ba.gov.br/nfce/consulta" }],
|
|
1522
|
+
CE: [{ url: "www.sefaz.ce.gov.br/nfce/consulta" }],
|
|
1523
|
+
DF: [{ url: "www.fazenda.df.gov.br/nfce/consulta" }],
|
|
1524
|
+
ES: [{ url: "www.sefaz.es.gov.br/nfce/consulta" }],
|
|
1525
|
+
GO: [{ url: "www.sefaz.go.gov.br/nfce/consulta" }],
|
|
1526
|
+
MA: [{ url: "www.sefaz.ma.gov.br/nfce/consulta" }],
|
|
1527
|
+
MT: [{ url: "http://homologacao.sefaz.mt.gov.br/nfce/consultanfce" }],
|
|
1528
|
+
MS: [{ url: "www.dfe.ms.gov.br/nfce/consulta" }],
|
|
1529
|
+
MG: [{ url: "https://hportalsped.fazenda.mg.gov.br/portalnfce" }],
|
|
1530
|
+
PA: [{ url: "www.sefa.pa.gov.br/nfce/consulta" }],
|
|
1531
|
+
PB: [{ url: "www.receita.pb.gov.br/nfcehom" }],
|
|
1532
|
+
PR: [{ url: "http://www.fazenda.pr.gov.br/nfce/consulta" }],
|
|
1533
|
+
PE: [{ url: "nfce.sefaz.pe.gov.br/nfce/consulta" }],
|
|
1534
|
+
PI: [{ url: "www.sefaz.pi.gov.br/nfce/consulta" }],
|
|
1535
|
+
RJ: [{ url: "www.fazenda.rj.gov.br/nfce/consulta" }],
|
|
1536
|
+
RN: [{ url: "www.set.rn.gov.br/nfce/consulta" }],
|
|
1537
|
+
RS: [{ url: "www.sefaz.rs.gov.br/nfce/consulta" }],
|
|
1538
|
+
RO: [{ url: "www.sefin.ro.gov.br/nfce/consulta" }],
|
|
1539
|
+
RR: [{ url: "www.sefaz.rr.gov.br/nfce/consulta" }],
|
|
1540
|
+
SC: [{ url: "https://hom.sat.sef.sc.gov.br/nfce/consulta" }],
|
|
1541
|
+
SP: [{ url: "https://www.homologacao.nfce.fazenda.sp.gov.br/consulta" }],
|
|
1542
|
+
SE: [{ url: "http://www.hom.nfe.se.gov.br/nfce/consulta" }],
|
|
1543
|
+
TO: [{ url: "http://homologacao.sefaz.to.gov.br/nfce/consulta.jsf" }]
|
|
1544
|
+
}
|
|
1545
|
+
}
|
|
1546
|
+
};
|
|
1547
|
+
|
|
1548
|
+
// packages/nfe/src/build/nfce.ts
|
|
1549
|
+
function vigente(lista, dia) {
|
|
1550
|
+
let achado;
|
|
1551
|
+
for (const e of lista ?? []) {
|
|
1552
|
+
if ((e.desde ?? "") <= dia && (achado === undefined || (e.desde ?? "") >= (achado.desde ?? "")))
|
|
1553
|
+
achado = e;
|
|
1554
|
+
}
|
|
1555
|
+
return achado;
|
|
1556
|
+
}
|
|
1557
|
+
function urlsNfce(uf, ambiente, dia) {
|
|
1558
|
+
const q = vigente(nfce_urls_default.qrCode[ambiente][uf], dia);
|
|
1559
|
+
const c = vigente(nfce_urls_default.urlChave[ambiente][uf], dia);
|
|
1560
|
+
return { qrCode: q?.url ?? undefined, urlChave: c?.url ?? undefined };
|
|
1561
|
+
}
|
|
1562
|
+
var te = new TextEncoder;
|
|
1563
|
+
var NFE_NS2 = "http://www.portalfiscal.inf.br/nfe";
|
|
1564
|
+
async function sha1(bytes) {
|
|
1565
|
+
return new Uint8Array(await globalThis.crypto.subtle.digest("SHA-1", bytes));
|
|
1566
|
+
}
|
|
1567
|
+
var hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
|
1568
|
+
async function digValHex(xml) {
|
|
1569
|
+
const doc = lerXml2(xml);
|
|
1570
|
+
const inf = primeiroFilho2(doc.raiz, "infNFe", NFE_NS2);
|
|
1571
|
+
if (inf === undefined)
|
|
1572
|
+
throw new Error("NF-e montada sem infNFe");
|
|
1573
|
+
return hexDoDigestValue(codificarBase64(await sha1(te.encode(c14n(inf)))));
|
|
1574
|
+
}
|
|
1575
|
+
function hexDoDigestValue(digestValue) {
|
|
1576
|
+
return hex(te.encode(digestValue));
|
|
1577
|
+
}
|
|
1578
|
+
async function hashQrCodeV2(parametros, csc) {
|
|
1579
|
+
return hex(await sha1(te.encode(parametros + csc))).toUpperCase();
|
|
1580
|
+
}
|
|
1581
|
+
async function parametrosQrCode(d, qr) {
|
|
1582
|
+
const tpAmb = tpAmbDoAmbiente(d.ambiente);
|
|
1583
|
+
const offline = d.tpEmis === "9";
|
|
1584
|
+
const dia = d.dhEmi.slice(8, 10);
|
|
1585
|
+
if (qr.versao === "3") {
|
|
1586
|
+
if (!offline)
|
|
1587
|
+
return { parametros: `${d.chave}|3|${tpAmb}`, assinar: false };
|
|
1588
|
+
const dest = d.dest;
|
|
1589
|
+
const [tp, id] = dest?.CNPJ !== undefined ? ["1", dest.CNPJ] : dest?.CPF !== undefined ? ["2", dest.CPF] : dest?.idEstrangeiro !== undefined ? ["3", ""] : ["", ""];
|
|
1590
|
+
return { parametros: `${d.chave}|3|${tpAmb}|${dia}|${d.vNF}|${tp}|${id}`, assinar: true };
|
|
1591
|
+
}
|
|
1592
|
+
const idCSC = String(Number(qr.idCSC));
|
|
1593
|
+
const antes = offline ? `${d.chave}|2|${tpAmb}|${dia}|${d.vNF}|${await digValHex(d.xml)}|${idCSC}` : `${d.chave}|2|${tpAmb}|${idCSC}`;
|
|
1594
|
+
return { parametros: `${antes}|${await hashQrCodeV2(antes, qr.CSC)}`, assinar: false };
|
|
1595
|
+
}
|
|
1596
|
+
async function assinarParametros(parametros, signer) {
|
|
1597
|
+
const bytes = te.encode(parametros);
|
|
1598
|
+
if (signer.tipo === "dados")
|
|
1599
|
+
return codificarBase64(await signer.assinar(bytes, "SHA-1"));
|
|
1600
|
+
const h = await sha1(bytes);
|
|
1601
|
+
const di = new Uint8Array(PREFIXO_DIGEST_INFO_SHA1.length + h.length);
|
|
1602
|
+
di.set(PREFIXO_DIGEST_INFO_SHA1);
|
|
1603
|
+
di.set(h, PREFIXO_DIGEST_INFO_SHA1.length);
|
|
1604
|
+
return codificarBase64(await signer.assinarDigestInfo(di));
|
|
1605
|
+
}
|
|
1606
|
+
var CFOP_ISSQN = "5933";
|
|
1607
|
+
var NFCE_LIMITE_SEM_DESTINATARIO = "10000.00";
|
|
1608
|
+
var TPAG_VEDADOS = {
|
|
1609
|
+
"14": "duplicata mercantil não é meio de pagamento da NFC-e (YA02-10, rejeição 857)",
|
|
1610
|
+
"90": "a NFC-e sempre tem pagamento: tPag 90 (sem pagamento) é recusado (YA02-40, rejeição 899)",
|
|
1611
|
+
"99": "tPag 99 (outros) não é aceito na NFC-e (YA02-50, rejeição 436, NT 2020.006)"
|
|
1612
|
+
};
|
|
1613
|
+
function conferirNfce(input, ide, issues) {
|
|
1614
|
+
const vedado = (path, msg) => issues.add(path, "grupo_vedado", `NFC-e ${msg}`);
|
|
1615
|
+
const invalido = (path, msg) => issues.add(path, "campo_invalido", `NFC-e ${msg}`);
|
|
1616
|
+
if (input.dhSaiEnt !== undefined)
|
|
1617
|
+
vedado("dhSaiEnt", "sem data de entrada ou saída (B10-10, rejeição 705)");
|
|
1618
|
+
if (input.dPrevEntrega !== undefined) {
|
|
1619
|
+
vedado("dPrevEntrega", "sem data de previsão de entrega (NT 2025.002, B10a-10, rejeição 1153)");
|
|
1620
|
+
}
|
|
1621
|
+
if (ide.tpNF !== "1")
|
|
1622
|
+
invalido("tpNF", "só de saída, tpNF 1 (B11-10, rejeição 706)");
|
|
1623
|
+
if (ide.idDest !== "1") {
|
|
1624
|
+
invalido("idDest", "só em operação interna, idDest 1 (B11a-10, rejeição 707)");
|
|
1625
|
+
}
|
|
1626
|
+
if (ide.tpImp !== "4" && ide.tpImp !== "5") {
|
|
1627
|
+
invalido("tpImp", "com DANFC-e: tpImp 4 (impresso) ou 5 (mensagem eletrônica) (B21-10, rejeição 709)");
|
|
1628
|
+
}
|
|
1629
|
+
if (ide.finNFe !== "1")
|
|
1630
|
+
invalido("finNFe", "só com finalidade normal, finNFe 1 (B25-20, rejeição 715)");
|
|
1631
|
+
if (ide.indFinal !== "1")
|
|
1632
|
+
invalido("indFinal", "só com consumidor final, indFinal 1 (B25a-10, rejeição 716)");
|
|
1633
|
+
if (!["1", "4", "5"].includes(ide.indPres)) {
|
|
1634
|
+
invalido("indPres", "só presencial: indPres 1, 4 (entrega a domicílio) ou 5 (NT 2025.002, B25b-20, rejeição 717)");
|
|
1635
|
+
}
|
|
1636
|
+
if (input.cMunFGIBS !== undefined && ide.indPres !== "5") {
|
|
1637
|
+
invalido("cMunFGIBS", "com cMunFGIBS só em operação presencial fora do estabelecimento, indPres 5 (NT 2025.002, B25b-60, rejeição 1000)");
|
|
1638
|
+
}
|
|
1639
|
+
if (input.cMunFGIBS === undefined && ide.indPres === "5") {
|
|
1640
|
+
issues.add("cMunFGIBS", "campo_obrigatorio", "NFC-e presencial fora do estabelecimento (indPres 5) informa cMunFGIBS (NT 2025.002, B25b-70, rejeição 1005)");
|
|
1641
|
+
}
|
|
1642
|
+
if (input.referenciadas !== undefined && input.referenciadas.length > 0) {
|
|
1643
|
+
vedado("referenciadas", "não referencia documento fiscal (BA01-10, rejeição 708)");
|
|
1644
|
+
}
|
|
1645
|
+
if (input.gCompraGov !== undefined)
|
|
1646
|
+
vedado("gCompraGov", "sem compra governamental (NT 2025.002, BB01-10, rejeição 1006)");
|
|
1647
|
+
if (input.emitente.IEST !== undefined)
|
|
1648
|
+
vedado("emitente.IEST", "sem IE de substituto tributário (C18-10, rejeição 718)");
|
|
1649
|
+
const d = input.destinatario;
|
|
1650
|
+
if (ide.indPres === "4" && d === undefined) {
|
|
1651
|
+
issues.add("destinatario", "campo_obrigatorio", "NFC-e com entrega a domicílio identifica o destinatário (E01-20, rejeição 787)");
|
|
1652
|
+
}
|
|
1653
|
+
if (ide.indPres === "4" && d !== undefined && d.endereco === undefined) {
|
|
1654
|
+
issues.add("destinatario.endereco", "campo_obrigatorio", "NFC-e com entrega a domicílio informa o endereço do destinatário (E05-20, rejeição 788)");
|
|
1655
|
+
}
|
|
1656
|
+
if (d !== undefined) {
|
|
1657
|
+
if (d.CNPJ !== undefined && input.emitente.CNPJ !== undefined && digitos2(d.CNPJ) === digitos2(input.emitente.CNPJ)) {
|
|
1658
|
+
invalido("destinatario.CNPJ", "com destinatário igual ao emitente (E02-20, rejeição 220)");
|
|
1659
|
+
}
|
|
1660
|
+
if (d.indIEDest !== "9") {
|
|
1661
|
+
invalido("destinatario.indIEDest", "só para não contribuinte, indIEDest 9 (E16a-10, rejeição 789)");
|
|
1662
|
+
}
|
|
1663
|
+
if (d.ISUF !== undefined)
|
|
1664
|
+
vedado("destinatario.ISUF", "sem inscrição na Suframa (E18-10, rejeição 730)");
|
|
1665
|
+
}
|
|
1666
|
+
input.itens.forEach((it, n) => {
|
|
1667
|
+
const p = `itens[${n}]`;
|
|
1668
|
+
const esp = it.produto.especifico ?? {};
|
|
1669
|
+
if (esp.veicProd !== undefined)
|
|
1670
|
+
vedado(`${p}.produto.especifico.veicProd`, "sem veículo novo (J01-10, rejeição 736)");
|
|
1671
|
+
if (esp.arma !== undefined)
|
|
1672
|
+
vedado(`${p}.produto.especifico.arma`, "sem armamento (L01-10, rejeição 738)");
|
|
1673
|
+
if (esp.nRECOPI !== undefined)
|
|
1674
|
+
vedado(`${p}.produto.especifico.nRECOPI`, "sem papel imune RECOPI (LB01-10, rejeição 348)");
|
|
1675
|
+
if (it.produto.tpCredPresIBSZFM !== undefined) {
|
|
1676
|
+
vedado(`${p}.produto.tpCredPresIBSZFM`, "sem classificação para subapuração do IBS na ZFM (NT 2025.002, I05k-10, rejeição 1165)");
|
|
1677
|
+
}
|
|
1678
|
+
const cfop = it.produto.CFOP.replace(/\D/g, "");
|
|
1679
|
+
const imp = it.impostos;
|
|
1680
|
+
if (cfop === CFOP_ISSQN && imp.issqn === undefined) {
|
|
1681
|
+
issues.add(`${p}.impostos.issqn`, "combinacao_invalida", "NFC-e com CFOP 5.933 tem o grupo do ISSQN (I08-160, rejeição 374)");
|
|
1682
|
+
}
|
|
1683
|
+
if (cfop !== CFOP_ISSQN && imp.issqn !== undefined) {
|
|
1684
|
+
issues.add(`${p}.produto.CFOP`, "combinacao_invalida", "NFC-e com ISSQN usa o CFOP 5.933 (I08-170, rejeição 374)");
|
|
1685
|
+
}
|
|
1686
|
+
const icms = imp.icms;
|
|
1687
|
+
if (icms?.grupo === "Part")
|
|
1688
|
+
vedado(`${p}.impostos.icms`, "sem partilha do ICMS entre UF (N12-50, rejeição 741)");
|
|
1689
|
+
if (icms?.grupo === "ST")
|
|
1690
|
+
vedado(`${p}.impostos.icms`, "sem repasse do ICMS-ST retido (N12-60, rejeição 740)");
|
|
1691
|
+
if (icms?.grupo === undefined && icms?.CST === "90" && icms.st !== undefined) {
|
|
1692
|
+
vedado(`${p}.impostos.icms.st`, "com CST 90 sem os dados do ICMS-ST (N12-34, rejeição 381)");
|
|
1693
|
+
}
|
|
1694
|
+
if (imp.icmsUfDest !== undefined)
|
|
1695
|
+
vedado(`${p}.impostos.icmsUfDest`, "sem ICMS da UF de destino (NA01-10, rejeição 807)");
|
|
1696
|
+
if (imp.ipi !== undefined)
|
|
1697
|
+
vedado(`${p}.impostos.ipi`, "sem IPI (O01-10, rejeição 742)");
|
|
1698
|
+
if (imp.ii !== undefined)
|
|
1699
|
+
vedado(`${p}.impostos.ii`, "sem imposto de importação (P01-10, rejeição 743)");
|
|
1700
|
+
if (imp.pisSt !== undefined)
|
|
1701
|
+
vedado(`${p}.impostos.pisSt`, "sem PIS-ST (R01-10, rejeição 746)");
|
|
1702
|
+
if (imp.cofinsSt !== undefined)
|
|
1703
|
+
vedado(`${p}.impostos.cofinsSt`, "sem COFINS-ST (T01-10, rejeição 749)");
|
|
1704
|
+
if (it.impostoDevol !== undefined)
|
|
1705
|
+
vedado(`${p}.impostoDevol`, "sem devolução de tributos (UA01-20, rejeição 390)");
|
|
1706
|
+
});
|
|
1707
|
+
const tr = input.transporte;
|
|
1708
|
+
const entrega = ide.indPres === "4";
|
|
1709
|
+
if (tr !== undefined && tr.modFrete !== "9" && !entrega) {
|
|
1710
|
+
invalido("transporte.modFrete", "sem frete fora da entrega a domicílio: modFrete 9 (X02-10, rejeição 753)");
|
|
1711
|
+
}
|
|
1712
|
+
if (tr?.transportador !== undefined && !entrega) {
|
|
1713
|
+
vedado("transporte.transportador", "só tem transportador na entrega a domicílio (X03-10, rejeição 754)");
|
|
1714
|
+
}
|
|
1715
|
+
if (entrega && tr?.transportador === undefined) {
|
|
1716
|
+
issues.add("transporte.transportador", "campo_obrigatorio", "NFC-e com entrega a domicílio identifica o transportador (X03-20, rejeição 786)");
|
|
1717
|
+
}
|
|
1718
|
+
if (tr?.retTransp !== undefined)
|
|
1719
|
+
vedado("transporte.retTransp", "sem retenção do ICMS no transporte (X11-10, rejeição 755)");
|
|
1720
|
+
if (tr?.veicTransp !== undefined)
|
|
1721
|
+
vedado("transporte.veicTransp", "sem veículo de transporte (X18-10, rejeição 756)");
|
|
1722
|
+
if (tr?.reboque !== undefined)
|
|
1723
|
+
vedado("transporte.reboque", "sem reboque (X22-10, rejeição 757)");
|
|
1724
|
+
if (input.cobranca !== undefined)
|
|
1725
|
+
vedado("cobranca", "sem fatura nem duplicata (Y01-10, rejeição 760)");
|
|
1726
|
+
if (input.pagamento === undefined || input.pagamento.detPag.length === 0) {
|
|
1727
|
+
issues.add("pagamento", "campo_obrigatorio", "a NFC-e informa o pagamento: tPag 90 (sem pagamento) é recusado (YA02-40, rejeição 899)");
|
|
1728
|
+
} else {
|
|
1729
|
+
input.pagamento.detPag.forEach((p, n) => {
|
|
1730
|
+
const motivo = TPAG_VEDADOS[p.tPag];
|
|
1731
|
+
if (motivo !== undefined)
|
|
1732
|
+
issues.add(`pagamento.detPag[${n}].tPag`, "pagamento_invalido", motivo);
|
|
1733
|
+
if (["03", "04", "17"].includes(p.tPag) && p.card === undefined) {
|
|
1734
|
+
issues.add(`pagamento.detPag[${n}].card`, "campo_obrigatorio", "pagamento com cartão (tPag 03 ou 04) ou PIX (17) informa o grupo card (NT 2025.001, YA04-10, rejeição 391)");
|
|
1735
|
+
}
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1738
|
+
if (input.exporta !== undefined)
|
|
1739
|
+
vedado("exporta", "sem comércio exterior (ZA01-30, rejeição 814)");
|
|
1740
|
+
if (input.compra !== undefined)
|
|
1741
|
+
vedado("compra", "sem dados de compra (ZB01-10, rejeição 762)");
|
|
1742
|
+
if (input.cana !== undefined)
|
|
1743
|
+
vedado("cana", "sem aquisição de cana (ZC01-10, rejeição 763)");
|
|
1744
|
+
}
|
|
1745
|
+
function pagamentoNfce(pag, vNF, issues) {
|
|
1746
|
+
const total = pag.detPag.reduce((a, p) => a.plus(Decimal.of(p.vPag)), Decimal.ZERO);
|
|
1747
|
+
const troco = total.minus(vNF);
|
|
1748
|
+
const posterior = pag.detPag.some((p) => p.tPag === "91");
|
|
1749
|
+
pag.detPag.forEach((p, n) => {
|
|
1750
|
+
if (p.tPag === "91" && !Decimal.of(p.vPag).isZero()) {
|
|
1751
|
+
issues.add(`pagamento.detPag[${n}].vPag`, "pagamento_invalido", "pagamento posterior (tPag 91) tem vPag zero (NT 2025.001 v1.03, YA03-30, rejeição 904)");
|
|
1752
|
+
}
|
|
1753
|
+
});
|
|
1754
|
+
if (troco.isNegative() && !posterior) {
|
|
1755
|
+
issues.add("pagamento.detPag", "pagamento_invalido", `pagamentos (${total.toFixed(2)}) abaixo do total da NFC-e (${vNF.toFixed(2)}) (NT 2025.001 v1.03, YA03-10, rejeição 865)`);
|
|
1756
|
+
}
|
|
1757
|
+
if (pag.vTroco === undefined) {
|
|
1758
|
+
if (!troco.isNegative() && !troco.isZero())
|
|
1759
|
+
pag.vTroco = troco.toFixed(2);
|
|
1760
|
+
} else if (!Decimal.of(pag.vTroco).eq(troco)) {
|
|
1761
|
+
issues.add("pagamento.vTroco", "valor_divergente", `troco ${pag.vTroco} difere de pagamentos menos o total (${troco.toFixed(2)}) (YA09-10, rejeição 869)`);
|
|
1762
|
+
}
|
|
1763
|
+
pag.detPag.forEach((p, n) => {
|
|
1764
|
+
const c = p.card;
|
|
1765
|
+
if (c === undefined)
|
|
1766
|
+
return;
|
|
1767
|
+
const path = `pagamento.detPag[${n}].card`;
|
|
1768
|
+
if (c.tpIntegra === "1" && (c.CNPJ === undefined || c.cAut === undefined)) {
|
|
1769
|
+
issues.add(path, "campo_obrigatorio", "cartão integrado à automação (tpIntegra 1) informa o CNPJ da credenciadora e o cAut (NT 2025.001, YA05-10, rejeição 392)");
|
|
1770
|
+
}
|
|
1771
|
+
if (c.CNPJ !== undefined) {
|
|
1772
|
+
const r = lerCnpj2(c.CNPJ, { caminho: `${path}.CNPJ` });
|
|
1773
|
+
if (!r.ok)
|
|
1774
|
+
issues.list.push(r.erro);
|
|
1775
|
+
}
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
var digitos2 = (s) => s.replace(/[^0-9A-Za-z]/g, "").toUpperCase();
|
|
1779
|
+
|
|
1780
|
+
// packages/nfe/src/build/pl.ts
|
|
1781
|
+
import { ErroNaoSuportado } from "@sinete/core";
|
|
1782
|
+
import { ehComplexType, ehElementParticle, ehWildcard, selecionarPl } from "@sinete/schemas";
|
|
1783
|
+
import { TNFe_infNFe as Inf010e } from "@sinete/schemas/nfe/PL_010e";
|
|
1784
|
+
import { TNFe_infNFe as Inf010f } from "@sinete/schemas/nfe/PL_010f";
|
|
1785
|
+
var INF_NFE = {
|
|
1786
|
+
"nfe/PL_010e": Inf010e,
|
|
1787
|
+
"nfe/PL_010f": Inf010f
|
|
1788
|
+
};
|
|
1789
|
+
function escolherPl(ambiente, emissao) {
|
|
1790
|
+
const vigencia = selecionarPl("nfe", ambiente, emissao);
|
|
1791
|
+
const infNFe = INF_NFE[vigencia.modulo];
|
|
1792
|
+
if (infNFe === undefined) {
|
|
1793
|
+
throw new ErroNaoSuportado(`@sinete/nfe não conhece o módulo ${vigencia.modulo}; atualize o pacote`);
|
|
1794
|
+
}
|
|
1795
|
+
return { vigencia, infNFe };
|
|
1796
|
+
}
|
|
1797
|
+
function memberNames(p, acc) {
|
|
1798
|
+
if (ehWildcard(p))
|
|
1799
|
+
acc.add("$any");
|
|
1800
|
+
else if (ehElementParticle(p))
|
|
1801
|
+
acc.add(p.e);
|
|
1802
|
+
else
|
|
1803
|
+
for (const i of p.i)
|
|
1804
|
+
memberNames(i, acc);
|
|
1805
|
+
return acc;
|
|
1806
|
+
}
|
|
1807
|
+
function elementTypes(p, acc) {
|
|
1808
|
+
if (ehWildcard(p))
|
|
1809
|
+
return acc;
|
|
1810
|
+
if (ehElementParticle(p)) {
|
|
1811
|
+
if (ehComplexType(p.t))
|
|
1812
|
+
acc.set(p.e, p.t);
|
|
1813
|
+
} else
|
|
1814
|
+
for (const i of p.i)
|
|
1815
|
+
elementTypes(i, acc);
|
|
1816
|
+
return acc;
|
|
1817
|
+
}
|
|
1818
|
+
function camposForaDoPl(ct, value, path, pl, issues) {
|
|
1819
|
+
if (typeof value !== "object" || value === null)
|
|
1820
|
+
return;
|
|
1821
|
+
const allowed = new Set(["$attrs", "$text"]);
|
|
1822
|
+
for (const a of ct.a ?? [])
|
|
1823
|
+
allowed.add(a.a);
|
|
1824
|
+
if (ct.c)
|
|
1825
|
+
memberNames(ct.c, allowed);
|
|
1826
|
+
const children = ct.c ? elementTypes(ct.c, new Map) : new Map;
|
|
1827
|
+
for (const [k, v] of Object.entries(value)) {
|
|
1828
|
+
if (v === undefined)
|
|
1829
|
+
continue;
|
|
1830
|
+
if (!allowed.has(k)) {
|
|
1831
|
+
issues.montagem(`${path}.${k}`, "campo_fora_do_pl", `o campo não existe no ${pl} vigente para esta emissão`);
|
|
1832
|
+
continue;
|
|
1833
|
+
}
|
|
1834
|
+
const child = children.get(k);
|
|
1835
|
+
if (!child)
|
|
1836
|
+
continue;
|
|
1837
|
+
if (Array.isArray(v)) {
|
|
1838
|
+
for (const [n, x] of v.entries())
|
|
1839
|
+
camposForaDoPl(child, x, `${path}.${k}[${n}]`, pl, issues);
|
|
1840
|
+
} else
|
|
1841
|
+
camposForaDoPl(child, v, `${path}.${k}`, pl, issues);
|
|
1842
|
+
}
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1845
|
+
// packages/nfe/src/build/rejeicoes.ts
|
|
1846
|
+
var CFOP_CST50_ISENTO = new Set([
|
|
1847
|
+
"1915",
|
|
1848
|
+
"1916",
|
|
1849
|
+
"2915",
|
|
1850
|
+
"2916",
|
|
1851
|
+
"5915",
|
|
1852
|
+
"5916",
|
|
1853
|
+
"6915",
|
|
1854
|
+
"6916",
|
|
1855
|
+
"1912",
|
|
1856
|
+
"1913",
|
|
1857
|
+
"5912",
|
|
1858
|
+
"5913"
|
|
1859
|
+
]);
|
|
1860
|
+
function cstComIsento(input, idDest, issues) {
|
|
1861
|
+
const d = input.destinatario;
|
|
1862
|
+
if (d?.indIEDest !== "2")
|
|
1863
|
+
return;
|
|
1864
|
+
input.itens.forEach((it, n) => {
|
|
1865
|
+
const icms = it.impostos.icms;
|
|
1866
|
+
if (icms === undefined || !("CST" in icms))
|
|
1867
|
+
return;
|
|
1868
|
+
const cst = icms.CST;
|
|
1869
|
+
if (cst === "50" && CFOP_CST50_ISENTO.has(it.produto.CFOP.replace(/\D/g, "")))
|
|
1870
|
+
return;
|
|
1871
|
+
if (cst === "51" && idDest === "1")
|
|
1872
|
+
return;
|
|
1873
|
+
if (cst !== "50" && cst !== "51")
|
|
1874
|
+
return;
|
|
1875
|
+
issues.add(`itens[${n}].impostos.icms.CST`, "combinacao_invalida", `CST ${cst} não se usa com destinatário contribuinte isento de IE (indIEDest 2) (N12-80, rejeição 529)`);
|
|
1876
|
+
});
|
|
1877
|
+
}
|
|
1878
|
+
var dataNoFuso = (instante, offsetMinutes) => formatarDh(instante, offsetMinutes).slice(0, 10);
|
|
1879
|
+
var OFFSET_BRASILIA = -180;
|
|
1880
|
+
function vencimentos(input, emissao, issues) {
|
|
1881
|
+
const dups = input.cobranca?.duplicatas;
|
|
1882
|
+
if (dups === undefined || dups.length !== 1)
|
|
1883
|
+
return;
|
|
1884
|
+
const unica = dups[0]?.dVenc;
|
|
1885
|
+
if (unica === undefined)
|
|
1886
|
+
return;
|
|
1887
|
+
const local = emissao.dhEmi.slice(0, 10);
|
|
1888
|
+
const datas = new Set([local, dataNoFuso(emissao.instante, OFFSET_BRASILIA), dataNoFuso(emissao.instante, 0)]);
|
|
1889
|
+
if (datas.size === 1 && datas.has(unica)) {
|
|
1890
|
+
issues.add("cobranca.duplicatas", "combinacao_invalida", "uma parcela só, vencendo na data de emissão, é pagamento à vista: não informe a cobrança (Y09-40, rejeição 853)");
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
var soDocumento = (s) => s.replace(/[^0-9A-Za-z]/g, "").toUpperCase();
|
|
1894
|
+
function conferirEmitenteDoCertificado(nfe, titular) {
|
|
1895
|
+
const e = nfe.emitente;
|
|
1896
|
+
if (e.CNPJ !== undefined && titular.cnpj !== undefined) {
|
|
1897
|
+
const base = soDocumento(e.CNPJ).slice(0, 8);
|
|
1898
|
+
if (base !== soDocumento(titular.cnpj).slice(0, 8)) {
|
|
1899
|
+
return [
|
|
1900
|
+
{
|
|
1901
|
+
caminho: "emitente.CNPJ",
|
|
1902
|
+
code: "emitente_difere_do_certificado",
|
|
1903
|
+
mensagem: `CNPJ-base ${base} do emitente difere do CNPJ-base do certificado (F03, rejeição 213)`,
|
|
1904
|
+
origem: "entrada"
|
|
1905
|
+
}
|
|
1906
|
+
];
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
if (e.CPF !== undefined && titular.cpf !== undefined && soDocumento(e.CPF) !== soDocumento(titular.cpf)) {
|
|
1910
|
+
return [
|
|
1911
|
+
{
|
|
1912
|
+
caminho: "emitente.CPF",
|
|
1913
|
+
code: "emitente_difere_do_certificado",
|
|
1914
|
+
mensagem: "CPF do emitente difere do CPF do certificado (F03A, rejeição 227)",
|
|
1915
|
+
origem: "entrada"
|
|
1916
|
+
}
|
|
1917
|
+
];
|
|
1918
|
+
}
|
|
1919
|
+
return [];
|
|
1920
|
+
}
|
|
1921
|
+
|
|
1922
|
+
// packages/nfe/src/build/tributos.ts
|
|
1923
|
+
function buildIpi(ctx, input, vOp, path) {
|
|
1924
|
+
const head = {
|
|
1925
|
+
CNPJProd: input.CNPJProd === undefined ? undefined : input.CNPJProd.replace(/[./-]/g, "").toUpperCase(),
|
|
1926
|
+
cSelo: input.cSelo,
|
|
1927
|
+
qSelo: input.qSelo,
|
|
1928
|
+
cEnq: input.cEnq
|
|
1929
|
+
};
|
|
1930
|
+
if (!["00", "49", "50", "99"].includes(input.CST)) {
|
|
1931
|
+
return { grupo: { ...clean(head), IPINT: { CST: input.CST } }, vIPI: Decimal.ZERO };
|
|
1932
|
+
}
|
|
1933
|
+
const i = input;
|
|
1934
|
+
let trib;
|
|
1935
|
+
let vIPI;
|
|
1936
|
+
if (i.qUnid !== undefined || i.vUnid !== undefined) {
|
|
1937
|
+
const qUnid = ctx.req(i.qUnid, `${path}.qUnid`, D1204V);
|
|
1938
|
+
const vUnid = ctx.req(i.vUnid, `${path}.vUnid`, D1104);
|
|
1939
|
+
vIPI = ctx.calc(i.vIPI, qUnid.times(vUnid), `${path}.vIPI`, D1302, "ipi");
|
|
1940
|
+
trib = { CST: i.CST, qUnid: ctx.s(qUnid, D1204V), vUnid: ctx.s(vUnid, D1104), vIPI: ctx.s(vIPI, D1302) };
|
|
1941
|
+
} else {
|
|
1942
|
+
const pIPI = ctx.req(i.pIPI, `${path}.pIPI`, D0302A04);
|
|
1943
|
+
const vBC = ctx.base(i.vBC, vOp, `${path}.vBC`, D1302, "ipi");
|
|
1944
|
+
vIPI = ctx.calc(i.vIPI, vBC.percent(pIPI), `${path}.vIPI`, D1302, "ipi");
|
|
1945
|
+
trib = { CST: i.CST, vBC: ctx.s(vBC, D1302), pIPI: ctx.s(pIPI, D0302A04), vIPI: ctx.s(vIPI, D1302) };
|
|
1946
|
+
}
|
|
1947
|
+
return { grupo: { ...clean(head), IPITrib: clean(trib) }, vIPI };
|
|
1948
|
+
}
|
|
1949
|
+
function buildIi(ctx, input, path) {
|
|
1950
|
+
const vII = ctx.req(input.vII, `${path}.vII`, D1302);
|
|
1951
|
+
return {
|
|
1952
|
+
grupo: {
|
|
1953
|
+
vBC: ctx.s(ctx.req(input.vBC, `${path}.vBC`, D1302), D1302),
|
|
1954
|
+
vDespAdu: ctx.s(ctx.req(input.vDespAdu, `${path}.vDespAdu`, D1302), D1302),
|
|
1955
|
+
vII: ctx.s(vII, D1302),
|
|
1956
|
+
vIOF: ctx.s(ctx.req(input.vIOF, `${path}.vIOF`, D1302), D1302)
|
|
1957
|
+
},
|
|
1958
|
+
vII
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1961
|
+
function buildPisCofins(ctx, input, tag, path) {
|
|
1962
|
+
const p = `p${tag}`;
|
|
1963
|
+
const v = `v${tag}`;
|
|
1964
|
+
const cst = input.CST;
|
|
1965
|
+
if (!("vBC" in input) && !("qBCProd" in input)) {
|
|
1966
|
+
return { grupo: { [`${tag}NT`]: { CST: cst } }, valor: Decimal.ZERO };
|
|
1967
|
+
}
|
|
1968
|
+
const i = input;
|
|
1969
|
+
let body;
|
|
1970
|
+
let valor;
|
|
1971
|
+
if (i.qBCProd !== undefined) {
|
|
1972
|
+
const q = ctx.req(i.qBCProd, `${path}.qBCProd`, D1204V);
|
|
1973
|
+
const a = ctx.req(i.vAliqProd, `${path}.vAliqProd`, D1104V);
|
|
1974
|
+
valor = ctx.calc(i.valor, q.times(a), `${path}.valor`, D1302, "pisCofins");
|
|
1975
|
+
body = { CST: cst, qBCProd: ctx.s(q, D1204V), vAliqProd: ctx.s(a, D1104V), [v]: ctx.s(valor, D1302) };
|
|
1976
|
+
} else {
|
|
1977
|
+
const vBC = ctx.req(i.vBC, `${path}.vBC`, D1302);
|
|
1978
|
+
const a = ctx.req(i.aliquota, `${path}.aliquota`, D0302A04);
|
|
1979
|
+
valor = ctx.calc(i.valor, vBC.percent(a), `${path}.valor`, D1302, "pisCofins");
|
|
1980
|
+
body = { CST: cst, vBC: ctx.s(vBC, D1302), [p]: ctx.s(a, D0302A04), [v]: ctx.s(valor, D1302) };
|
|
1981
|
+
}
|
|
1982
|
+
const nome = cst === "01" || cst === "02" ? "Aliq" : cst === "03" ? "Qtde" : "Outr";
|
|
1983
|
+
return { grupo: { [`${tag}${nome}`]: body }, valor };
|
|
1984
|
+
}
|
|
1985
|
+
function buildPisCofinsSt(ctx, input, tag, path) {
|
|
1986
|
+
let body;
|
|
1987
|
+
let valor;
|
|
1988
|
+
if (input.qBCProd !== undefined) {
|
|
1989
|
+
const q = ctx.req(input.qBCProd, `${path}.qBCProd`, D1204);
|
|
1990
|
+
const a = ctx.req(input.vAliqProd, `${path}.vAliqProd`, D1104);
|
|
1991
|
+
valor = ctx.calc(input.valor, q.times(a), `${path}.valor`, D1302, "pisCofins");
|
|
1992
|
+
body = { qBCProd: ctx.s(q, D1204), vAliqProd: ctx.s(a, D1104) };
|
|
1993
|
+
} else {
|
|
1994
|
+
const fBC = tag === "PIS" ? D1302_OPC : D1302;
|
|
1995
|
+
const vBC = ctx.req(input.vBC, `${path}.vBC`, fBC);
|
|
1996
|
+
const a = ctx.req(input.aliquota, `${path}.aliquota`, D0302A04);
|
|
1997
|
+
valor = ctx.calc(input.valor, vBC.percent(a), `${path}.valor`, D1302, "pisCofins");
|
|
1998
|
+
body = { vBC: ctx.s(vBC, fBC), [`p${tag}`]: ctx.s(a, D0302A04) };
|
|
1999
|
+
}
|
|
2000
|
+
body[`v${tag}`] = ctx.s(valor, D1302);
|
|
2001
|
+
body[`indSoma${tag}ST`] = input.indSoma;
|
|
2002
|
+
return { grupo: clean(body), valor, soma: input.indSoma === "1" };
|
|
2003
|
+
}
|
|
2004
|
+
function buildIssqn(ctx, input, path) {
|
|
2005
|
+
const vBC = ctx.req(input.vBC, `${path}.vBC`, D1302);
|
|
2006
|
+
const vAliq = ctx.req(input.vAliq, `${path}.vAliq`, D0302A04);
|
|
2007
|
+
const vISSQN = ctx.calc(input.vISSQN, vBC.percent(vAliq), `${path}.vISSQN`, D1302, "issqn");
|
|
2008
|
+
const opcionais = {};
|
|
2009
|
+
const opt = (k) => {
|
|
2010
|
+
const d = ctx.opt(input[k], `${path}.${k}`, D1302);
|
|
2011
|
+
if (d !== undefined)
|
|
2012
|
+
opcionais[k] = d;
|
|
2013
|
+
return ctx.so(d, D1302_OPC);
|
|
2014
|
+
};
|
|
2015
|
+
return {
|
|
2016
|
+
grupo: clean({
|
|
2017
|
+
vBC: ctx.s(vBC, D1302),
|
|
2018
|
+
vAliq: ctx.s(vAliq, D0302A04),
|
|
2019
|
+
vISSQN: ctx.s(vISSQN, D1302),
|
|
2020
|
+
cMunFG: input.cMunFG,
|
|
2021
|
+
cListServ: input.cListServ,
|
|
2022
|
+
vDeducao: opt("vDeducao"),
|
|
2023
|
+
vOutro: opt("vOutro"),
|
|
2024
|
+
vDescIncond: opt("vDescIncond"),
|
|
2025
|
+
vDescCond: opt("vDescCond"),
|
|
2026
|
+
vISSRet: opt("vISSRet"),
|
|
2027
|
+
indISS: input.indISS,
|
|
2028
|
+
cServico: input.cServico,
|
|
2029
|
+
cMun: input.cMun,
|
|
2030
|
+
cPais: input.cPais === undefined ? undefined : digits(input.cPais),
|
|
2031
|
+
nProcesso: input.nProcesso,
|
|
2032
|
+
indIncentivo: input.indIncentivo
|
|
2033
|
+
}),
|
|
2034
|
+
vBC,
|
|
2035
|
+
vISSQN,
|
|
2036
|
+
opcionais
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
function buildIcmsUfDest(ctx, input, path) {
|
|
2040
|
+
const pFCPUFDest = ctx.opt(input.pFCPUFDest, `${path}.pFCPUFDest`, D0302A04);
|
|
2041
|
+
const vFCPUFDest = ctx.opt(input.vFCPUFDest, `${path}.vFCPUFDest`, D1302);
|
|
2042
|
+
if (pFCPUFDest !== undefined && vFCPUFDest === undefined) {
|
|
2043
|
+
ctx.issues.add(`${path}.vFCPUFDest`, "campo_obrigatorio", "pFCPUFDest informado exige vFCPUFDest");
|
|
2044
|
+
}
|
|
2045
|
+
const vICMSUFDest = ctx.req(input.vICMSUFDest, `${path}.vICMSUFDest`, D1302);
|
|
2046
|
+
const vICMSUFRemet = ctx.opt(input.vICMSUFRemet, `${path}.vICMSUFRemet`, D1302) ?? Decimal.ZERO;
|
|
2047
|
+
const vBCFCPUFDest = ctx.opt(input.vBCFCPUFDest, `${path}.vBCFCPUFDest`, D1302);
|
|
2048
|
+
return {
|
|
2049
|
+
grupo: clean({
|
|
2050
|
+
vBCUFDest: ctx.s(ctx.req(input.vBCUFDest, `${path}.vBCUFDest`, D1302), D1302),
|
|
2051
|
+
vBCFCPUFDest: ctx.so(vBCFCPUFDest, D1302),
|
|
2052
|
+
pFCPUFDest: ctx.so(pFCPUFDest, D0302A04),
|
|
2053
|
+
pICMSUFDest: ctx.s(ctx.req(input.pICMSUFDest, `${path}.pICMSUFDest`, D0302A04), D0302A04),
|
|
2054
|
+
pICMSInter: input.pICMSInter,
|
|
2055
|
+
pICMSInterPart: ctx.s(ctx.opt(input.pICMSInterPart, `${path}.pICMSInterPart`, D0302A04) ?? Decimal.HUNDRED, D0302A04),
|
|
2056
|
+
vFCPUFDest: ctx.so(vFCPUFDest, D1302),
|
|
2057
|
+
vICMSUFDest: ctx.s(vICMSUFDest, D1302),
|
|
2058
|
+
vICMSUFRemet: ctx.s(vICMSUFRemet, D1302)
|
|
2059
|
+
}),
|
|
2060
|
+
vFCPUFDest: vFCPUFDest ?? Decimal.ZERO,
|
|
2061
|
+
vICMSUFDest,
|
|
2062
|
+
vICMSUFRemet
|
|
2063
|
+
};
|
|
2064
|
+
}
|
|
2065
|
+
|
|
2066
|
+
// packages/nfe/src/build/build.ts
|
|
2067
|
+
var padrao;
|
|
2068
|
+
function calculadoraPadrao() {
|
|
2069
|
+
padrao ??= calculadoraIbsCbs();
|
|
2070
|
+
return padrao;
|
|
2071
|
+
}
|
|
2072
|
+
var NFE_NS3 = "http://www.portalfiscal.inf.br/nfe";
|
|
2073
|
+
var XNOME_HOMOLOGACAO = "NF-E EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL";
|
|
2074
|
+
var XPROD_HOMOLOGACAO_NFCE = "NOTA FISCAL EMITIDA EM AMBIENTE DE HOMOLOGACAO - SEM VALOR FISCAL";
|
|
2075
|
+
var MODES = Object.fromEntries(Object.entries(arredondamento_default.familias).map(([k, v]) => [k, v.modo]));
|
|
2076
|
+
var SEM_GTIN = "SEM GTIN";
|
|
2077
|
+
var BRASILIA = -180;
|
|
2078
|
+
function diaBrasilia(d) {
|
|
2079
|
+
return formatarDh(d, BRASILIA).slice(0, 10);
|
|
2080
|
+
}
|
|
2081
|
+
function exigenciaRespTec(uf, ambiente, data) {
|
|
2082
|
+
const dia = diaBrasilia(data);
|
|
2083
|
+
const ufs = resp_tec_default.ufs;
|
|
2084
|
+
const regra = Object.hasOwn(ufs, uf) ? ufs[uf] : undefined;
|
|
2085
|
+
const vale = (r, padrao) => {
|
|
2086
|
+
const desde = r?.[ambiente];
|
|
2087
|
+
if (desde !== undefined)
|
|
2088
|
+
return dia >= desde ? "obrigatorio" : padrao;
|
|
2089
|
+
return padrao;
|
|
2090
|
+
};
|
|
2091
|
+
return {
|
|
2092
|
+
infRespTec: vale(regra?.infRespTec, resp_tec_default.padrao.infRespTec),
|
|
2093
|
+
csrt: vale(regra?.csrt, resp_tec_default.padrao.csrt)
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
async function hashCsrt(csrt, chave) {
|
|
2097
|
+
const d = await globalThis.crypto.subtle.digest("SHA-1", new TextEncoder().encode(csrt + chave));
|
|
2098
|
+
return codificarBase642(new Uint8Array(d));
|
|
2099
|
+
}
|
|
2100
|
+
function documento(doc, path, issues) {
|
|
2101
|
+
if (doc.CNPJ !== undefined) {
|
|
2102
|
+
const r = lerCnpj3(doc.CNPJ, { caminho: `${path}.CNPJ` });
|
|
2103
|
+
if (!r.ok)
|
|
2104
|
+
issues.list.push(r.erro);
|
|
2105
|
+
return { CNPJ: r.ok ? r.valor : doc.CNPJ };
|
|
2106
|
+
}
|
|
2107
|
+
const r = lerCpf(doc.CPF ?? "", { caminho: `${path}.CPF` });
|
|
2108
|
+
if (!r.ok)
|
|
2109
|
+
issues.list.push(r.erro);
|
|
2110
|
+
return { CPF: r.ok ? r.valor : doc.CPF ?? "" };
|
|
2111
|
+
}
|
|
2112
|
+
function ie(value, uf, path, issues, allowIsento) {
|
|
2113
|
+
if (value === undefined)
|
|
2114
|
+
return;
|
|
2115
|
+
const r = lerIe(value, uf, { caminho: path, aceitarIsento: allowIsento });
|
|
2116
|
+
if (!r.ok) {
|
|
2117
|
+
issues.list.push(r.erro);
|
|
2118
|
+
return value;
|
|
2119
|
+
}
|
|
2120
|
+
return r.valor.valor;
|
|
2121
|
+
}
|
|
2122
|
+
function endereco(e) {
|
|
2123
|
+
return {
|
|
2124
|
+
xLgr: e.xLgr,
|
|
2125
|
+
nro: e.nro,
|
|
2126
|
+
xCpl: e.xCpl,
|
|
2127
|
+
xBairro: e.xBairro,
|
|
2128
|
+
cMun: e.cMun,
|
|
2129
|
+
xMun: e.xMun,
|
|
2130
|
+
UF: e.UF,
|
|
2131
|
+
CEP: e.CEP === undefined ? undefined : digits(e.CEP),
|
|
2132
|
+
fone: e.fone === undefined ? undefined : digits(e.fone)
|
|
2133
|
+
};
|
|
2134
|
+
}
|
|
2135
|
+
function isExterior(e) {
|
|
2136
|
+
return e !== undefined && "exterior" in e && e.exterior === true;
|
|
2137
|
+
}
|
|
2138
|
+
function gerarChave(parts, cNFInformado, random, issues) {
|
|
2139
|
+
const tentar = (cNF) => {
|
|
2140
|
+
const chave = montarChaveAcesso({ ...parts, cNF });
|
|
2141
|
+
const r = lerChaveAcesso(chave, { emissao: true, caminho: "chave" });
|
|
2142
|
+
return r.ok ? { chave, ok: true } : { chave, ok: false, issue: r.erro };
|
|
2143
|
+
};
|
|
2144
|
+
if (cNFInformado !== undefined) {
|
|
2145
|
+
if (!/^\d{8}$/.test(cNFInformado)) {
|
|
2146
|
+
issues.add("cNF", "campo_invalido", "cNF tem 8 algarismos");
|
|
2147
|
+
return;
|
|
2148
|
+
}
|
|
2149
|
+
const r = tentar(cNFInformado);
|
|
2150
|
+
if (!r.ok && r.issue) {
|
|
2151
|
+
const doCnf = r.issue.code === "chave_cnf_invalido";
|
|
2152
|
+
issues.list.push({
|
|
2153
|
+
...r.issue,
|
|
2154
|
+
caminho: doCnf ? "cNF" : r.issue.caminho,
|
|
2155
|
+
code: "chave_invalida",
|
|
2156
|
+
mensagem: `${r.issue.mensagem} (${r.issue.code})`,
|
|
2157
|
+
origem: doCnf ? "entrada" : "montagem"
|
|
2158
|
+
});
|
|
2159
|
+
}
|
|
2160
|
+
return r.ok ? { chave: r.chave, cNF: cNFInformado } : undefined;
|
|
2161
|
+
}
|
|
2162
|
+
for (let n = 0;n < 32; n++) {
|
|
2163
|
+
const b = random(new Uint8Array(4));
|
|
2164
|
+
const v = ((b[0] ?? 0) * 2 ** 24 + (b[1] ?? 0) * 2 ** 16 + (b[2] ?? 0) * 2 ** 8 + (b[3] ?? 0)) % 1e8;
|
|
2165
|
+
const cNF = String(v).padStart(8, "0");
|
|
2166
|
+
const r = tentar(cNF);
|
|
2167
|
+
if (r.ok)
|
|
2168
|
+
return { chave: r.chave, cNF };
|
|
2169
|
+
if (r.issue && r.issue.code !== "chave_cnf_invalido") {
|
|
2170
|
+
issues.list.push({
|
|
2171
|
+
...r.issue,
|
|
2172
|
+
code: "chave_invalida",
|
|
2173
|
+
mensagem: `${r.issue.mensagem} (${r.issue.code})`,
|
|
2174
|
+
origem: "montagem"
|
|
2175
|
+
});
|
|
2176
|
+
return;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
issues.montagem("cNF", "chave_invalida", "não foi possível gerar um cNF válido");
|
|
2180
|
+
return;
|
|
2181
|
+
}
|
|
2182
|
+
function referencia(ref, path, issues) {
|
|
2183
|
+
const chave = (c, p) => {
|
|
2184
|
+
const r = lerChaveAcesso(c, { caminho: p });
|
|
2185
|
+
if (!r.ok)
|
|
2186
|
+
issues.list.push(r.erro);
|
|
2187
|
+
return r.ok ? r.valor.chave : c;
|
|
2188
|
+
};
|
|
2189
|
+
if ("refNFe" in ref)
|
|
2190
|
+
return { refNFe: chave(ref.refNFe, `${path}.refNFe`) };
|
|
2191
|
+
if ("refNFeSig" in ref) {
|
|
2192
|
+
const c = ref.refNFeSig.replace(/\s/g, "").toUpperCase();
|
|
2193
|
+
if (!/^[0-9]{6}[0-9A-Z]{12}[0-9]{2}55[0-9]{22}$/.test(c) || c.slice(35, 43) !== "00000000") {
|
|
2194
|
+
issues.add(`${path}.refNFeSig`, "chave_invalida", "chave de NF-e (modelo 55) com o código numérico (cNF) zerado");
|
|
2195
|
+
}
|
|
2196
|
+
return { refNFeSig: c };
|
|
2197
|
+
}
|
|
2198
|
+
if ("refCTe" in ref)
|
|
2199
|
+
return { refCTe: chave(ref.refCTe, `${path}.refCTe`) };
|
|
2200
|
+
if ("refNF" in ref)
|
|
2201
|
+
return { refNF: ref.refNF };
|
|
2202
|
+
if ("refECF" in ref)
|
|
2203
|
+
return { refECF: ref.refECF };
|
|
2204
|
+
const nfp = ref.refNFP;
|
|
2205
|
+
if (nfp.mod === "04") {
|
|
2206
|
+
const porUf = produtor_rural_default.refNFP.ufs;
|
|
2207
|
+
const cUfSigla = Object.keys(porUf).find((k) => ufPorSigla2(k)?.cUF === nfp.cUF);
|
|
2208
|
+
const vedadaDesde = cUfSigla ? porUf[cUfSigla]?.vedadaDesde ?? "" : produtor_rural_default.refNFP.modelo04.vedadaDesde;
|
|
2209
|
+
if (nfp.AAMM >= vedadaDesde) {
|
|
2210
|
+
issues.add(`${path}.refNFP.AAMM`, "referencia_vedada", `nota de produtor modelo 04 emitida em ${nfp.AAMM}, depois do fim do modelo (${vedadaDesde}; ${produtor_rural_default.refNFP.modelo04.fonte})`);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
const doc = documento(nfp, `${path}.refNFP`, issues);
|
|
2214
|
+
return {
|
|
2215
|
+
refNFP: {
|
|
2216
|
+
cUF: nfp.cUF,
|
|
2217
|
+
AAMM: nfp.AAMM,
|
|
2218
|
+
...doc,
|
|
2219
|
+
IE: nfp.IE,
|
|
2220
|
+
mod: nfp.mod,
|
|
2221
|
+
serie: String(Number(nfp.serie)),
|
|
2222
|
+
nNF: String(Number(nfp.nNF))
|
|
2223
|
+
}
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
function textoXmlValido(texto) {
|
|
2227
|
+
for (const ch of texto) {
|
|
2228
|
+
const c = ch.codePointAt(0) ?? 0;
|
|
2229
|
+
const ok = c === 9 || c === 10 || c === 13 || c >= 32 && c <= 55295 || c >= 57344 && c <= 65533 || c >= 65536 && c <= 1114111;
|
|
2230
|
+
if (!ok)
|
|
2231
|
+
return false;
|
|
2232
|
+
}
|
|
2233
|
+
return true;
|
|
2234
|
+
}
|
|
2235
|
+
function textosForaDoXml(value, path, issues) {
|
|
2236
|
+
if (typeof value === "string") {
|
|
2237
|
+
if (!textoXmlValido(value))
|
|
2238
|
+
issues.montagem(path, "campo_invalido", "texto com caractere não permitido em XML");
|
|
2239
|
+
} else if (Array.isArray(value)) {
|
|
2240
|
+
for (const [n, v] of value.entries())
|
|
2241
|
+
textosForaDoXml(v, `${path}[${n}]`, issues);
|
|
2242
|
+
} else if (typeof value === "object" && value !== null) {
|
|
2243
|
+
for (const [k, v] of Object.entries(value))
|
|
2244
|
+
textosForaDoXml(v, `${path}.${k}`, issues);
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
function montarItem(ctx, item, n, normal) {
|
|
2248
|
+
const path = `itens[${n}]`;
|
|
2249
|
+
const p = item.produto;
|
|
2250
|
+
const pp = `${path}.produto`;
|
|
2251
|
+
const qCom = ctx.req(p.qCom, `${pp}.qCom`, D1104V);
|
|
2252
|
+
const vUnCom = ctx.req(p.vUnCom, `${pp}.vUnCom`, D1110V);
|
|
2253
|
+
const vProd = (normal ? ctx.calc : ctx.base).call(ctx, p.vProd, qCom.times(vUnCom), `${pp}.vProd`, D1302, "produto");
|
|
2254
|
+
const uTrib = p.uTrib ?? p.uCom;
|
|
2255
|
+
const qTrib = p.qTrib === undefined ? qCom : ctx.req(p.qTrib, `${pp}.qTrib`, D1104V);
|
|
2256
|
+
let vUnTrib;
|
|
2257
|
+
if (p.vUnTrib !== undefined)
|
|
2258
|
+
vUnTrib = ctx.req(p.vUnTrib, `${pp}.vUnTrib`, D1110V);
|
|
2259
|
+
else if (uTrib === p.uCom && qTrib.eq(qCom))
|
|
2260
|
+
vUnTrib = vUnCom;
|
|
2261
|
+
else if (qTrib.isZero())
|
|
2262
|
+
vUnTrib = Decimal.ZERO;
|
|
2263
|
+
else
|
|
2264
|
+
vUnTrib = vProd.dividedBy(qTrib, 10, ctx.modes.produto);
|
|
2265
|
+
if (normal) {
|
|
2266
|
+
const trib = ctx.round(qTrib.times(vUnTrib), D1302, "produto");
|
|
2267
|
+
if (trib.minus(vProd).abs().gt(TOLERANCIA)) {
|
|
2268
|
+
ctx.issues.add(`${pp}.vUnTrib`, "valor_divergente", `qTrib × vUnTrib (${trib.toFixed(2)}) difere de vProd (${vProd.toFixed(2)}) em mais de ${TOLERANCIA.toString()}`);
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
const opt = (v, k) => ctx.opt(v, `${pp}.${k}`, D1302) ?? Decimal.ZERO;
|
|
2272
|
+
const vFrete = opt(p.vFrete, "vFrete");
|
|
2273
|
+
const vSeg = opt(p.vSeg, "vSeg");
|
|
2274
|
+
const vDesc = opt(p.vDesc, "vDesc");
|
|
2275
|
+
const vOutro = opt(p.vOutro, "vOutro");
|
|
2276
|
+
const vOp = vProd.plus(vFrete).plus(vSeg).plus(vOutro).minus(vDesc);
|
|
2277
|
+
const cEAN = p.cEAN ?? SEM_GTIN;
|
|
2278
|
+
const especifico = p.especifico ?? {};
|
|
2279
|
+
const prod = clean({
|
|
2280
|
+
cProd: p.cProd,
|
|
2281
|
+
cEAN,
|
|
2282
|
+
cBarra: p.cBarra,
|
|
2283
|
+
xProd: p.xProd,
|
|
2284
|
+
NCM: digits(p.NCM),
|
|
2285
|
+
NVE: p.NVE,
|
|
2286
|
+
CEST: p.CEST === undefined ? undefined : digits(p.CEST),
|
|
2287
|
+
indEscala: p.indEscala,
|
|
2288
|
+
CNPJFab: p.CNPJFab,
|
|
2289
|
+
cBenef: p.cBenef,
|
|
2290
|
+
gCred: p.gCred,
|
|
2291
|
+
tpCredPresIBSZFM: p.tpCredPresIBSZFM,
|
|
2292
|
+
EXTIPI: p.EXTIPI,
|
|
2293
|
+
CFOP: digits(p.CFOP),
|
|
2294
|
+
uCom: p.uCom,
|
|
2295
|
+
qCom: ctx.s(qCom, D1104V),
|
|
2296
|
+
vUnCom: ctx.s(vUnCom, D1110V),
|
|
2297
|
+
vProd: ctx.s(vProd, D1302),
|
|
2298
|
+
cEANTrib: p.cEANTrib ?? cEAN,
|
|
2299
|
+
cBarraTrib: p.cBarraTrib,
|
|
2300
|
+
uTrib,
|
|
2301
|
+
qTrib: ctx.s(qTrib, D1104V),
|
|
2302
|
+
vUnTrib: ctx.s(vUnTrib, D1110V),
|
|
2303
|
+
vFrete: ctx.so(vFrete, D1302_OPC),
|
|
2304
|
+
vSeg: ctx.so(vSeg, D1302_OPC),
|
|
2305
|
+
vDesc: ctx.so(vDesc, D1302_OPC),
|
|
2306
|
+
vOutro: ctx.so(vOutro, D1302_OPC),
|
|
2307
|
+
indTot: p.indTot ?? "1",
|
|
2308
|
+
indBemMovelUsado: p.indBemMovelUsado,
|
|
2309
|
+
DI: p.DI,
|
|
2310
|
+
detExport: p.detExport,
|
|
2311
|
+
xPed: p.xPed,
|
|
2312
|
+
nItemPed: p.nItemPed,
|
|
2313
|
+
nFCI: p.nFCI,
|
|
2314
|
+
rastro: p.rastro,
|
|
2315
|
+
infProdNFF: p.infProdNFF,
|
|
2316
|
+
infProdEmb: p.infProdEmb,
|
|
2317
|
+
...especifico
|
|
2318
|
+
});
|
|
2319
|
+
const imp = item.impostos;
|
|
2320
|
+
const ip = `${path}.impostos`;
|
|
2321
|
+
const imposto = {};
|
|
2322
|
+
const z = Decimal.ZERO;
|
|
2323
|
+
const v = {
|
|
2324
|
+
vProd,
|
|
2325
|
+
vFrete,
|
|
2326
|
+
vSeg,
|
|
2327
|
+
vDesc,
|
|
2328
|
+
vOutro,
|
|
2329
|
+
vII: z,
|
|
2330
|
+
vIPI: z,
|
|
2331
|
+
vIPIDevol: z,
|
|
2332
|
+
vPIS: z,
|
|
2333
|
+
vCOFINS: z,
|
|
2334
|
+
vPISST: z,
|
|
2335
|
+
vCOFINSST: z,
|
|
2336
|
+
vFCPUFDest: z,
|
|
2337
|
+
vICMSUFDest: z,
|
|
2338
|
+
vICMSUFRemet: z,
|
|
2339
|
+
vTotTrib: z,
|
|
2340
|
+
vISSQN: z,
|
|
2341
|
+
vBCISS: z
|
|
2342
|
+
};
|
|
2343
|
+
let issqnOpcionais = {};
|
|
2344
|
+
const vTotTrib = ctx.opt(imp.vTotTrib, `${ip}.vTotTrib`, D1302);
|
|
2345
|
+
if (vTotTrib !== undefined) {
|
|
2346
|
+
imposto.vTotTrib = ctx.s(vTotTrib, D1302);
|
|
2347
|
+
v.vTotTrib = vTotTrib;
|
|
2348
|
+
}
|
|
2349
|
+
if (imp.icms !== undefined && imp.issqn !== undefined) {
|
|
2350
|
+
ctx.issues.add(ip, "combinacao_invalida", "o item tem ICMS ou ISSQN, nunca os dois");
|
|
2351
|
+
}
|
|
2352
|
+
if (imp.ipi !== undefined) {
|
|
2353
|
+
const r = buildIpi(ctx, imp.ipi, vOp, `${ip}.ipi`);
|
|
2354
|
+
imposto.IPI = r.grupo;
|
|
2355
|
+
v.vIPI = r.vIPI;
|
|
2356
|
+
}
|
|
2357
|
+
let icms = zeroIcmsTotais();
|
|
2358
|
+
if (imp.icms !== undefined) {
|
|
2359
|
+
const r = buildIcms(ctx, imp.icms, { vOp, vIPI: v.vIPI }, `${ip}.icms`);
|
|
2360
|
+
imposto.ICMS = r.grupo;
|
|
2361
|
+
icms = r.totais;
|
|
2362
|
+
} else if (imp.issqn === undefined && imp.ibsCbs === undefined) {
|
|
2363
|
+
ctx.issues.add(`${ip}.icms`, "campo_obrigatorio", "o item precisa de ICMS (ou ISSQN, na NF-e conjugada)");
|
|
2364
|
+
}
|
|
2365
|
+
if (imp.ii !== undefined) {
|
|
2366
|
+
const r = buildIi(ctx, imp.ii, `${ip}.ii`);
|
|
2367
|
+
imposto.II = r.grupo;
|
|
2368
|
+
v.vII = r.vII;
|
|
2369
|
+
}
|
|
2370
|
+
if (imp.issqn !== undefined) {
|
|
2371
|
+
const r = buildIssqn(ctx, imp.issqn, `${ip}.issqn`);
|
|
2372
|
+
imposto.ISSQN = r.grupo;
|
|
2373
|
+
v.vISSQN = r.vISSQN;
|
|
2374
|
+
v.vBCISS = r.vBC;
|
|
2375
|
+
issqnOpcionais = r.opcionais;
|
|
2376
|
+
}
|
|
2377
|
+
if (imp.pis !== undefined) {
|
|
2378
|
+
const r = buildPisCofins(ctx, imp.pis, "PIS", `${ip}.pis`);
|
|
2379
|
+
imposto.PIS = r.grupo;
|
|
2380
|
+
v.vPIS = r.valor;
|
|
2381
|
+
}
|
|
2382
|
+
if (imp.pisSt !== undefined) {
|
|
2383
|
+
const r = buildPisCofinsSt(ctx, imp.pisSt, "PIS", `${ip}.pisSt`);
|
|
2384
|
+
imposto.PISST = r.grupo;
|
|
2385
|
+
if (r.soma)
|
|
2386
|
+
v.vPISST = r.valor;
|
|
2387
|
+
}
|
|
2388
|
+
if (imp.cofins !== undefined) {
|
|
2389
|
+
const r = buildPisCofins(ctx, imp.cofins, "COFINS", `${ip}.cofins`);
|
|
2390
|
+
imposto.COFINS = r.grupo;
|
|
2391
|
+
v.vCOFINS = r.valor;
|
|
2392
|
+
}
|
|
2393
|
+
if (imp.cofinsSt !== undefined) {
|
|
2394
|
+
const r = buildPisCofinsSt(ctx, imp.cofinsSt, "COFINS", `${ip}.cofinsSt`);
|
|
2395
|
+
imposto.COFINSST = r.grupo;
|
|
2396
|
+
if (r.soma)
|
|
2397
|
+
v.vCOFINSST = r.valor;
|
|
2398
|
+
}
|
|
2399
|
+
if (imp.icmsUfDest !== undefined) {
|
|
2400
|
+
const r = buildIcmsUfDest(ctx, imp.icmsUfDest, `${ip}.icmsUfDest`);
|
|
2401
|
+
imposto.ICMSUFDest = r.grupo;
|
|
2402
|
+
v.vFCPUFDest = r.vFCPUFDest;
|
|
2403
|
+
v.vICMSUFDest = r.vICMSUFDest;
|
|
2404
|
+
v.vICMSUFRemet = r.vICMSUFRemet;
|
|
2405
|
+
}
|
|
2406
|
+
if (imp.is !== undefined)
|
|
2407
|
+
imposto.IS = imp.is;
|
|
2408
|
+
if (imp.ibsCbs?.grupo !== undefined)
|
|
2409
|
+
imposto.IBSCBS = imp.ibsCbs.grupo;
|
|
2410
|
+
const det = {
|
|
2411
|
+
nItem: String(n + 1),
|
|
2412
|
+
prod,
|
|
2413
|
+
imposto
|
|
2414
|
+
};
|
|
2415
|
+
if (item.impostoDevol !== undefined) {
|
|
2416
|
+
const pDevol = ctx.req(item.impostoDevol.pDevol, `${path}.impostoDevol.pDevol`, D0302);
|
|
2417
|
+
const vIPIDevol = ctx.req(item.impostoDevol.vIPIDevol, `${path}.impostoDevol.vIPIDevol`, D1302);
|
|
2418
|
+
det.impostoDevol = { pDevol: ctx.s(pDevol, D0302), IPI: { vIPIDevol: ctx.s(vIPIDevol, D1302) } };
|
|
2419
|
+
v.vIPIDevol = vIPIDevol;
|
|
2420
|
+
}
|
|
2421
|
+
if (item.infAdProd !== undefined)
|
|
2422
|
+
det.infAdProd = item.infAdProd;
|
|
2423
|
+
if (item.obsItem !== undefined)
|
|
2424
|
+
det.obsItem = item.obsItem;
|
|
2425
|
+
if (item.DFeReferenciado !== undefined) {
|
|
2426
|
+
const r = lerChaveAcesso(item.DFeReferenciado.chaveAcesso, { caminho: `${path}.DFeReferenciado.chaveAcesso` });
|
|
2427
|
+
if (!r.ok)
|
|
2428
|
+
ctx.issues.list.push(r.erro);
|
|
2429
|
+
det.DFeReferenciado = clean({
|
|
2430
|
+
chaveAcesso: r.ok ? r.valor.chave : item.DFeReferenciado.chaveAcesso,
|
|
2431
|
+
nItem: item.DFeReferenciado.nItem === undefined ? undefined : String(item.DFeReferenciado.nItem)
|
|
2432
|
+
});
|
|
2433
|
+
}
|
|
2434
|
+
return {
|
|
2435
|
+
det,
|
|
2436
|
+
icms,
|
|
2437
|
+
indTot: (p.indTot ?? "1") === "1",
|
|
2438
|
+
issqn: imp.issqn !== undefined,
|
|
2439
|
+
faturamentoDireto: especifico.veicProd?.tpOp === "2",
|
|
2440
|
+
v,
|
|
2441
|
+
temUfDest: imp.icmsUfDest !== undefined,
|
|
2442
|
+
temTotTrib: vTotTrib !== undefined,
|
|
2443
|
+
issqnOpcionais
|
|
2444
|
+
};
|
|
2445
|
+
}
|
|
2446
|
+
function composicao(m, incluirProd) {
|
|
2447
|
+
const v = m.v;
|
|
2448
|
+
let total = (incluirProd ? v.vProd : Decimal.ZERO).minus(v.vDesc).minus(m.icms.vICMSDesonDeduz).plus(v.vFrete).plus(v.vSeg).plus(v.vOutro).plus(v.vII).plus(v.vIPI).plus(v.vPISST).plus(v.vCOFINSST);
|
|
2449
|
+
if (!m.faturamentoDireto) {
|
|
2450
|
+
total = total.plus(m.icms.vST).plus(m.icms.vICMSMonoReten).plus(m.icms.vFCPST).plus(v.vIPIDevol);
|
|
2451
|
+
}
|
|
2452
|
+
return total;
|
|
2453
|
+
}
|
|
2454
|
+
async function montarNfe(entrada, opcoes) {
|
|
2455
|
+
const issues = new Issues;
|
|
2456
|
+
const finNFeIn = entrada.finNFe ?? "1";
|
|
2457
|
+
const mod = entrada.modelo ?? "55";
|
|
2458
|
+
if (mod !== "55" && mod !== "65") {
|
|
2459
|
+
issues.add("modelo", "modelo_nao_suportado", `modelo ${String(mod)}: o builder monta NF-e (55) e NFC-e (65)`);
|
|
2460
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2461
|
+
}
|
|
2462
|
+
const nfce = mod === "65";
|
|
2463
|
+
const indPres = entrada.indPres ?? (nfce ? "1" : finNFeIn === "2" || finNFeIn === "3" ? "0" : "9");
|
|
2464
|
+
const indFinal = entrada.indFinal ?? (nfce || entrada.destinatario?.indIEDest === "9" ? "1" : "0");
|
|
2465
|
+
const ctx = new Ctx(issues, { ...MODES, ...opcoes.arredondamento }, finNFeIn !== "2" && finNFeIn !== "3");
|
|
2466
|
+
const pRedutorGov = entrada.gCompraGov && ctx.req(entrada.gCompraGov.pRedutor, "gCompraGov.pRedutor", D0302A04);
|
|
2467
|
+
const emitUf = entrada.emitente.endereco.UF;
|
|
2468
|
+
if (!ehUf2(emitUf)) {
|
|
2469
|
+
issues.add("emitente.endereco.UF", "campo_invalido", "UF do emitente inválida");
|
|
2470
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2471
|
+
}
|
|
2472
|
+
const cUF = ufPorSigla2(emitUf)?.cUF ?? "";
|
|
2473
|
+
const offset = opcoes.deslocamentoMin ?? deslocamentoDaUf(emitUf);
|
|
2474
|
+
const agora = opcoes.tempo.emissao.agora();
|
|
2475
|
+
const fatoGerador = opcoes.tempo.fatoGerador.agora();
|
|
2476
|
+
const dhEmi = formatarDh(agora, offset);
|
|
2477
|
+
const aamm = dhEmi.slice(2, 4) + dhEmi.slice(5, 7);
|
|
2478
|
+
const tpAmb = tpAmbDoAmbiente2(opcoes.ambiente);
|
|
2479
|
+
const pl = escolherPl(opcoes.ambiente, relogioFixo2(agora));
|
|
2480
|
+
const e = entrada.emitente;
|
|
2481
|
+
const emitDoc = documento(e, "emitente", issues);
|
|
2482
|
+
const serie = Number(entrada.serie);
|
|
2483
|
+
const nNF = Number(entrada.nNF);
|
|
2484
|
+
if (!Number.isInteger(serie) || serie < 0 || serie > 999)
|
|
2485
|
+
issues.add("serie", "serie_invalida", "série de 0 a 999");
|
|
2486
|
+
if (!Number.isInteger(nNF) || nNF < 1 || nNF > 999999999)
|
|
2487
|
+
issues.add("nNF", "campo_invalido", "nNF de 1 a 999999999");
|
|
2488
|
+
const [cpfIni, cpfFim] = produtor_rural_default.series.cpf;
|
|
2489
|
+
const [cnpjIni, cnpjFim] = produtor_rural_default.series.cnpj;
|
|
2490
|
+
if ("CPF" in emitDoc && (serie < cpfIni || serie > cpfFim)) {
|
|
2491
|
+
issues.add("serie", "serie_invalida", `emitente pessoa física usa as séries ${cpfIni} a ${cpfFim} (${produtor_rural_default.series.fonte})`);
|
|
2492
|
+
} else if ("CNPJ" in emitDoc && Number.isInteger(serie) && serie >= 0 && (serie < cnpjIni || serie > cnpjFim)) {
|
|
2493
|
+
issues.add("serie", "serie_invalida", `emitente CNPJ usa as séries ${cnpjIni} a ${cnpjFim} (${produtor_rural_default.series.fonteCnpj})`);
|
|
2494
|
+
}
|
|
2495
|
+
const emit = clean({
|
|
2496
|
+
...emitDoc,
|
|
2497
|
+
xNome: e.xNome,
|
|
2498
|
+
xFant: e.xFant,
|
|
2499
|
+
enderEmit: clean({ ...endereco(e.endereco), cPais: "1058", xPais: "BRASIL" }),
|
|
2500
|
+
IE: ie(e.IE, emitUf, "emitente.IE", issues, true),
|
|
2501
|
+
IEST: e.IEST,
|
|
2502
|
+
IM: e.IM,
|
|
2503
|
+
CNAE: e.CNAE,
|
|
2504
|
+
CRT: e.CRT,
|
|
2505
|
+
ISUFEmit: e.ISUFEmit
|
|
2506
|
+
});
|
|
2507
|
+
const d = entrada.destinatario;
|
|
2508
|
+
let dest;
|
|
2509
|
+
let destUf;
|
|
2510
|
+
if (d === undefined) {
|
|
2511
|
+
if (!nfce)
|
|
2512
|
+
issues.add("destinatario", "campo_obrigatorio", "a NF-e exige o destinatário (E01-10, rejeição 719)");
|
|
2513
|
+
} else {
|
|
2514
|
+
const docDest = "idEstrangeiro" in d && d.idEstrangeiro !== undefined ? { idEstrangeiro: d.idEstrangeiro } : documento(d, "destinatario", issues);
|
|
2515
|
+
let enderDest;
|
|
2516
|
+
if (isExterior(d.endereco)) {
|
|
2517
|
+
destUf = "EX";
|
|
2518
|
+
enderDest = clean({
|
|
2519
|
+
xLgr: d.endereco.xLgr,
|
|
2520
|
+
nro: d.endereco.nro,
|
|
2521
|
+
xCpl: d.endereco.xCpl,
|
|
2522
|
+
xBairro: d.endereco.xBairro,
|
|
2523
|
+
cMun: "9999999",
|
|
2524
|
+
xMun: "EXTERIOR",
|
|
2525
|
+
UF: "EX",
|
|
2526
|
+
cPais: d.endereco.cPais,
|
|
2527
|
+
xPais: d.endereco.xPais,
|
|
2528
|
+
fone: d.endereco.fone === undefined ? undefined : digits(d.endereco.fone)
|
|
2529
|
+
});
|
|
2530
|
+
} else if (d.endereco !== undefined) {
|
|
2531
|
+
destUf = d.endereco.UF;
|
|
2532
|
+
enderDest = clean({ ...endereco(d.endereco), cPais: "1058", xPais: "BRASIL" });
|
|
2533
|
+
}
|
|
2534
|
+
const destIe = d.IE !== undefined && destUf !== undefined && destUf !== "EX" ? ie(d.IE, destUf, "destinatario.IE", issues, false) : d.IE;
|
|
2535
|
+
dest = clean({
|
|
2536
|
+
...docDest,
|
|
2537
|
+
xNome: opcoes.ambiente === "homologacao" ? XNOME_HOMOLOGACAO : d.xNome,
|
|
2538
|
+
enderDest,
|
|
2539
|
+
indIEDest: d.indIEDest,
|
|
2540
|
+
IE: destIe,
|
|
2541
|
+
ISUF: d.ISUF,
|
|
2542
|
+
IM: d.IM,
|
|
2543
|
+
email: d.email
|
|
2544
|
+
});
|
|
2545
|
+
}
|
|
2546
|
+
const cont = entrada.contingencia;
|
|
2547
|
+
const tpEmis = cont?.tpEmis ?? "1";
|
|
2548
|
+
if (cont !== undefined) {
|
|
2549
|
+
if (cont.xJust.length < 15 || cont.xJust.length > 256) {
|
|
2550
|
+
issues.add("contingencia.xJust", "contingencia_invalida", "justificativa da contingência com 15 a 256 caracteres");
|
|
2551
|
+
}
|
|
2552
|
+
if (cont.dhCont.getTime() > agora.getTime()) {
|
|
2553
|
+
issues.add("contingencia.dhCont", "contingencia_invalida", "entrada em contingência posterior à emissão");
|
|
2554
|
+
}
|
|
2555
|
+
if (!nfce && tpEmis === "9") {
|
|
2556
|
+
issues.add("contingencia.tpEmis", "contingencia_invalida", "contingência off-line (tpEmis 9) é só da NFC-e (B22-10, rejeição 711)");
|
|
2557
|
+
}
|
|
2558
|
+
if (nfce && (tpEmis === "6" || tpEmis === "7")) {
|
|
2559
|
+
issues.add("contingencia.tpEmis", "contingencia_invalida", "a NFC-e não é autorizada pela SVC; a contingência dela é off-line, tpEmis 9 (B22-70, rejeição 783)");
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
const idDest = entrada.idDest ?? (nfce ? "1" : destUf === "EX" ? "3" : destUf !== undefined && destUf !== emitUf ? "2" : "1");
|
|
2563
|
+
const tpImp = entrada.tpImp ?? (nfce ? "4" : "1");
|
|
2564
|
+
conferirDestinatario(entrada, {
|
|
2565
|
+
mod,
|
|
2566
|
+
tpNF: entrada.tpNF,
|
|
2567
|
+
idDest,
|
|
2568
|
+
idDestInformado: entrada.idDest !== undefined,
|
|
2569
|
+
indFinal,
|
|
2570
|
+
producao: opcoes.ambiente === "producao"
|
|
2571
|
+
}, issues);
|
|
2572
|
+
if (nfce) {
|
|
2573
|
+
conferirNfce(entrada, {
|
|
2574
|
+
tpNF: entrada.tpNF,
|
|
2575
|
+
idDest,
|
|
2576
|
+
tpImp,
|
|
2577
|
+
finNFe: finNFeIn,
|
|
2578
|
+
indFinal,
|
|
2579
|
+
indPres
|
|
2580
|
+
}, issues);
|
|
2581
|
+
} else if (tpImp === "4" || tpImp === "5") {
|
|
2582
|
+
issues.add("tpImp", "campo_invalido", "tpImp 4 e 5 (DANFC-e) são da NFC-e (B21-20, rejeição 710)");
|
|
2583
|
+
}
|
|
2584
|
+
const qr = opcoes.qrCode ?? { versao: "3" };
|
|
2585
|
+
if (nfce && qr.versao === "2") {
|
|
2586
|
+
if (!/^\d{1,6}$/.test(qr.idCSC) || Number(qr.idCSC) === 0) {
|
|
2587
|
+
issues.montagem("qrCode.idCSC", "qrcode_invalido", "idCSC tem de 1 a 6 algarismos, diferente de zero (Manual do DANFE NFC-e 6.0, 4.6)");
|
|
2588
|
+
}
|
|
2589
|
+
if (qr.CSC.length < 16 || qr.CSC.length > 36) {
|
|
2590
|
+
issues.montagem("qrCode.CSC", "qrcode_invalido", "o CSC tem de 16 a 36 caracteres (Manual do DANFE NFC-e 6.0, 4.6)");
|
|
2591
|
+
}
|
|
2592
|
+
if ("CPF" in emitDoc) {
|
|
2593
|
+
issues.montagem("qrCode.versao", "qrcode_invalido", "emitente pessoa física usa o QR Code versão 3 (NT 2025.001, ZX02-222, rejeição 444)");
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
const random = opcoes.aleatorio ?? ((b) => globalThis.crypto.getRandomValues(b));
|
|
2597
|
+
const emitente14 = "CNPJ" in emitDoc ? emitDoc.CNPJ : emitDoc.CPF;
|
|
2598
|
+
const gerada = issues.empty ? gerarChave({ cUF, aamm, emitente: emitente14, mod, serie: String(serie), nNF: String(nNF), tpEmis }, entrada.cNF, random, issues) : undefined;
|
|
2599
|
+
const chave = gerada?.chave ?? "0".repeat(44);
|
|
2600
|
+
const cNF = gerada?.cNF ?? "00000000";
|
|
2601
|
+
const cDV = chave.slice(43);
|
|
2602
|
+
if (entrada.itens.length === 0 || entrada.itens.length > 990) {
|
|
2603
|
+
issues.add("itens", "itens_limite", "a NF-e tem de 1 a 990 itens");
|
|
2604
|
+
}
|
|
2605
|
+
const itens = entrada.itens.map((it, n) => montarItem(ctx, it, n, finNFeIn === "1"));
|
|
2606
|
+
const primeiro = itens[0];
|
|
2607
|
+
if (nfce && opcoes.ambiente === "homologacao" && primeiro !== undefined) {
|
|
2608
|
+
primeiro.det.prod.xProd = XPROD_HOMOLOGACAO_NFCE;
|
|
2609
|
+
}
|
|
2610
|
+
const classificados = entrada.itens.map((it, n) => ({ it, n })).filter(({ it }) => it.impostos.ibsCbs?.classificacao !== undefined);
|
|
2611
|
+
if (classificados.length > 0) {
|
|
2612
|
+
const calculadora = opcoes.ibsCbs ?? calculadoraPadrao();
|
|
2613
|
+
const reqs = classificados.map(({ it, n }) => {
|
|
2614
|
+
const c = it.impostos.ibsCbs?.classificacao;
|
|
2615
|
+
const m = itens[n];
|
|
2616
|
+
const vBC = ctx.opt(c.vBC, `itens[${n}].impostos.ibsCbs.classificacao.vBC`, D1302);
|
|
2617
|
+
const qTrib = Decimal.of(m.det.prod.qTrib);
|
|
2618
|
+
return {
|
|
2619
|
+
nItem: n + 1,
|
|
2620
|
+
CST: c.CST,
|
|
2621
|
+
cClassTrib: c.cClassTrib,
|
|
2622
|
+
...c.indDoacao ? { indDoacao: c.indDoacao } : {},
|
|
2623
|
+
...c.cCredPres ? { cCredPres: c.cCredPres } : {},
|
|
2624
|
+
...c.gTribRegular ? { gTribRegular: c.gTribRegular } : {},
|
|
2625
|
+
...vBC ? { vBC } : {},
|
|
2626
|
+
NCM: m.det.prod.NCM,
|
|
2627
|
+
CFOP: m.det.prod.CFOP,
|
|
2628
|
+
uTrib: m.det.prod.uTrib,
|
|
2629
|
+
qTrib,
|
|
2630
|
+
vProd: m.v.vProd,
|
|
2631
|
+
vDesc: m.v.vDesc,
|
|
2632
|
+
vFrete: m.v.vFrete,
|
|
2633
|
+
vSeg: m.v.vSeg,
|
|
2634
|
+
vOutro: m.v.vOutro,
|
|
2635
|
+
vICMS: m.icms.vICMS,
|
|
2636
|
+
vICMSST: m.icms.vST,
|
|
2637
|
+
vFCP: m.icms.vFCP,
|
|
2638
|
+
vFCPST: m.icms.vFCPST,
|
|
2639
|
+
vIPI: m.v.vIPI,
|
|
2640
|
+
vPIS: m.v.vPIS,
|
|
2641
|
+
vCOFINS: m.v.vCOFINS,
|
|
2642
|
+
vII: m.v.vII,
|
|
2643
|
+
vISSQN: m.v.vISSQN,
|
|
2644
|
+
vICMSUFDest: m.v.vICMSUFDest,
|
|
2645
|
+
vFCPUFDest: m.v.vFCPUFDest
|
|
2646
|
+
};
|
|
2647
|
+
});
|
|
2648
|
+
const destino = entrada.entrega !== undefined ? { UF: entrada.entrega.UF, cMun: entrada.entrega.cMun } : d?.endereco !== undefined ? isExterior(d.endereco) ? { UF: "EX", cMun: "9999999" } : { UF: d.endereco.UF, cMun: d.endereco.cMun } : undefined;
|
|
2649
|
+
const compra = entrada.gCompraGov;
|
|
2650
|
+
const resp = await calculadora.calcular({
|
|
2651
|
+
nota: {
|
|
2652
|
+
fatoGerador,
|
|
2653
|
+
emissao: agora,
|
|
2654
|
+
ambiente: opcoes.ambiente,
|
|
2655
|
+
mod,
|
|
2656
|
+
tpNF: entrada.tpNF,
|
|
2657
|
+
finNFe: finNFeIn,
|
|
2658
|
+
...entrada.tpNFDebito ? { tpNFDebito: entrada.tpNFDebito } : {},
|
|
2659
|
+
...entrada.tpNFCredito ? { tpNFCredito: entrada.tpNFCredito } : {},
|
|
2660
|
+
indFinal,
|
|
2661
|
+
indPres,
|
|
2662
|
+
emitente: { UF: emitUf, cMun: e.endereco.cMun, CRT: e.CRT },
|
|
2663
|
+
...destino ? { destino } : {},
|
|
2664
|
+
...entrada.cMunFGIBS ? { cMunFGIBS: entrada.cMunFGIBS } : {},
|
|
2665
|
+
...compra && pRedutorGov ? {
|
|
2666
|
+
compraGov: {
|
|
2667
|
+
tpEnteGov: compra.tpEnteGov,
|
|
2668
|
+
pRedutor: pRedutorGov,
|
|
2669
|
+
tpOperGov: compra.tpOperGov
|
|
2670
|
+
}
|
|
2671
|
+
} : {}
|
|
2672
|
+
},
|
|
2673
|
+
itens: reqs
|
|
2674
|
+
});
|
|
2675
|
+
issues.addAll(resp.ocorrencias ?? [], "montagem");
|
|
2676
|
+
for (const { n } of classificados) {
|
|
2677
|
+
const g = resp.itens.find((x) => x.nItem === n + 1);
|
|
2678
|
+
if (g === undefined) {
|
|
2679
|
+
issues.montagem(`itens[${n}].impostos.ibsCbs`, "ibscbs_calculo", "a calculadora não devolveu o grupo IBSCBS do item");
|
|
2680
|
+
continue;
|
|
2681
|
+
}
|
|
2682
|
+
itens[n].det.imposto.IBSCBS = g.IBSCBS;
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
itens.forEach((m, n) => {
|
|
2686
|
+
const imp = m.det.imposto;
|
|
2687
|
+
const ib = `itens[${n}].impostos.ibsCbs`;
|
|
2688
|
+
const is = `itens[${n}].impostos.is`;
|
|
2689
|
+
const ibsDaCalculadora = entrada.itens[n]?.impostos.ibsCbs?.grupo === undefined;
|
|
2690
|
+
const antes = issues.list.length;
|
|
2691
|
+
decimaisInvalidos(imp.IBSCBS, ib, issues);
|
|
2692
|
+
if (ibsDaCalculadora)
|
|
2693
|
+
issues.reclassificarDesde(antes, "montagem");
|
|
2694
|
+
decimaisInvalidos(imp.IS, is, issues);
|
|
2695
|
+
if (issues.list.length === antes) {
|
|
2696
|
+
grupoInvalido(TTribNFeCt, "IBSCBS", imp.IBSCBS, ib, issues);
|
|
2697
|
+
if (ibsDaCalculadora)
|
|
2698
|
+
issues.reclassificarDesde(antes, "montagem");
|
|
2699
|
+
grupoInvalido(TISCt, "IS", imp.IS, is, issues);
|
|
2700
|
+
}
|
|
2701
|
+
});
|
|
2702
|
+
if (!issues.empty)
|
|
2703
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2704
|
+
const gruposIbsCbs = itens.map((m) => m.det.imposto.IBSCBS).filter((g) => g !== undefined);
|
|
2705
|
+
const somaTributosNoItem = diaBrasilia(fatoGerador) >= reforma_default.vItemSomaTributosDesde;
|
|
2706
|
+
let vNFTot = Decimal.ZERO;
|
|
2707
|
+
const temReforma = gruposIbsCbs.length > 0 || itens.some((m) => m.det.imposto.IS !== undefined);
|
|
2708
|
+
if (temReforma) {
|
|
2709
|
+
for (const m of itens) {
|
|
2710
|
+
let vItem = composicao(m, m.indTot);
|
|
2711
|
+
const g = m.det.imposto.IBSCBS;
|
|
2712
|
+
if (somaTributosNoItem) {
|
|
2713
|
+
const is = m.det.imposto.IS?.vIS;
|
|
2714
|
+
if (is !== undefined)
|
|
2715
|
+
vItem = vItem.plus(Decimal.of(is));
|
|
2716
|
+
}
|
|
2717
|
+
if (g !== undefined && somaTributosNoItem) {
|
|
2718
|
+
const t = ibsCbsDoItem(g);
|
|
2719
|
+
vItem = vItem.plus(t.vIBS).plus(t.vCBS);
|
|
2720
|
+
if (!m.faturamentoDireto)
|
|
2721
|
+
vItem = vItem.plus(t.vTotIBSMonoItem).plus(t.vTotCBSMonoItem);
|
|
2722
|
+
}
|
|
2723
|
+
m.det.vItem = ctx.s(vItem, D1302);
|
|
2724
|
+
vNFTot = vNFTot.plus(vItem);
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
const soma = (f, filtro = () => true) => itens.filter(filtro).reduce((acc, m) => acc.plus(f(m)), Decimal.ZERO);
|
|
2728
|
+
const icmsItens = (m) => !m.issqn;
|
|
2729
|
+
const icmsSoma = (k) => soma((m) => m.icms[k]);
|
|
2730
|
+
const vProdTot = soma((m) => m.v.vProd, (m) => m.indTot && !m.issqn);
|
|
2731
|
+
const vServ = soma((m) => m.v.vProd, (m) => m.indTot && m.issqn);
|
|
2732
|
+
const vNF = itens.reduce((acc, m) => acc.plus(composicao(m, m.indTot && !m.issqn)), Decimal.ZERO).plus(vServ);
|
|
2733
|
+
const S = (x) => ctx.s(x, D1302);
|
|
2734
|
+
const mono = itens.some((m) => m.icms.mono);
|
|
2735
|
+
const ufDest = itens.some((m) => m.temUfDest);
|
|
2736
|
+
const ICMSTot = clean({
|
|
2737
|
+
vBC: S(icmsSoma("vBC")),
|
|
2738
|
+
vICMS: S(icmsSoma("vICMS")),
|
|
2739
|
+
vICMSDeson: S(icmsSoma("vICMSDeson")),
|
|
2740
|
+
vFCPUFDest: ufDest ? S(soma((m) => m.v.vFCPUFDest)) : undefined,
|
|
2741
|
+
vICMSUFDest: ufDest ? S(soma((m) => m.v.vICMSUFDest)) : undefined,
|
|
2742
|
+
vICMSUFRemet: ufDest ? S(soma((m) => m.v.vICMSUFRemet)) : undefined,
|
|
2743
|
+
vFCP: S(icmsSoma("vFCP")),
|
|
2744
|
+
vBCST: S(icmsSoma("vBCST")),
|
|
2745
|
+
vST: S(icmsSoma("vST")),
|
|
2746
|
+
vFCPST: S(icmsSoma("vFCPST")),
|
|
2747
|
+
vFCPSTRet: S(icmsSoma("vFCPSTRet")),
|
|
2748
|
+
qBCMono: mono ? S(ctx.round(icmsSoma("qBCMono"), D1302, "icms")) : undefined,
|
|
2749
|
+
vICMSMono: mono ? S(icmsSoma("vICMSMono")) : undefined,
|
|
2750
|
+
qBCMonoReten: mono ? S(ctx.round(icmsSoma("qBCMonoReten"), D1302, "icms")) : undefined,
|
|
2751
|
+
vICMSMonoReten: mono ? S(icmsSoma("vICMSMonoReten")) : undefined,
|
|
2752
|
+
qBCMonoRet: mono ? S(ctx.round(icmsSoma("qBCMonoRet"), D1302, "icms")) : undefined,
|
|
2753
|
+
vICMSMonoRet: mono ? S(icmsSoma("vICMSMonoRet")) : undefined,
|
|
2754
|
+
vProd: S(vProdTot),
|
|
2755
|
+
vFrete: S(soma((m) => m.v.vFrete)),
|
|
2756
|
+
vSeg: S(soma((m) => m.v.vSeg)),
|
|
2757
|
+
vDesc: S(soma((m) => m.v.vDesc)),
|
|
2758
|
+
vII: S(soma((m) => m.v.vII)),
|
|
2759
|
+
vIPI: S(soma((m) => m.v.vIPI)),
|
|
2760
|
+
vIPIDevol: S(soma((m) => m.v.vIPIDevol)),
|
|
2761
|
+
vPIS: S(soma((m) => m.v.vPIS, icmsItens)),
|
|
2762
|
+
vCOFINS: S(soma((m) => m.v.vCOFINS, icmsItens)),
|
|
2763
|
+
vOutro: S(soma((m) => m.v.vOutro)),
|
|
2764
|
+
vNF: S(vNF),
|
|
2765
|
+
vTotTrib: itens.some((m) => m.temTotTrib) ? S(soma((m) => m.v.vTotTrib)) : undefined
|
|
2766
|
+
});
|
|
2767
|
+
const total = { ICMSTot };
|
|
2768
|
+
if (itens.some((m) => m.issqn)) {
|
|
2769
|
+
const iss = itens.filter((m) => m.issqn);
|
|
2770
|
+
const so = (x) => ctx.so(x, D1302_OPC);
|
|
2771
|
+
const opc = (k) => so(iss.reduce((a, m) => a.plus(m.issqnOpcionais[k] ?? Decimal.ZERO), Decimal.ZERO));
|
|
2772
|
+
total.ISSQNtot = clean({
|
|
2773
|
+
vServ: so(vServ),
|
|
2774
|
+
vBC: so(soma((m) => m.v.vBCISS, (m) => m.issqn)),
|
|
2775
|
+
vISS: so(soma((m) => m.v.vISSQN, (m) => m.issqn)),
|
|
2776
|
+
vPIS: so(soma((m) => m.v.vPIS, (m) => m.issqn)),
|
|
2777
|
+
vCOFINS: so(soma((m) => m.v.vCOFINS, (m) => m.issqn)),
|
|
2778
|
+
dCompet: dhEmi.slice(0, 10),
|
|
2779
|
+
vDeducao: opc("vDeducao"),
|
|
2780
|
+
vOutro: opc("vOutro"),
|
|
2781
|
+
vDescIncond: opc("vDescIncond"),
|
|
2782
|
+
vDescCond: opc("vDescCond"),
|
|
2783
|
+
vISSRet: opc("vISSRet")
|
|
2784
|
+
});
|
|
2785
|
+
}
|
|
2786
|
+
const comIs = itens.filter((m) => m.det.imposto.IS !== undefined);
|
|
2787
|
+
if (comIs.length > 0) {
|
|
2788
|
+
total.ISTot = {
|
|
2789
|
+
vIS: S(comIs.reduce((a, m) => a.plus(Decimal.of(m.det.imposto.IS.vIS ?? "0")), Decimal.ZERO))
|
|
2790
|
+
};
|
|
2791
|
+
}
|
|
2792
|
+
if (gruposIbsCbs.length > 0)
|
|
2793
|
+
total.IBSCBSTot = totalIbsCbs(gruposIbsCbs);
|
|
2794
|
+
if (temReforma)
|
|
2795
|
+
total.vNFTot = S(vNFTot);
|
|
2796
|
+
const finNFe = finNFeIn;
|
|
2797
|
+
const ide = clean({
|
|
2798
|
+
cUF,
|
|
2799
|
+
cNF,
|
|
2800
|
+
natOp: entrada.natOp,
|
|
2801
|
+
mod,
|
|
2802
|
+
serie: String(serie),
|
|
2803
|
+
nNF: String(nNF),
|
|
2804
|
+
dhEmi,
|
|
2805
|
+
dhSaiEnt: entrada.dhSaiEnt === undefined ? undefined : formatarDh(entrada.dhSaiEnt, offset),
|
|
2806
|
+
dPrevEntrega: entrada.dPrevEntrega,
|
|
2807
|
+
tpNF: entrada.tpNF,
|
|
2808
|
+
idDest,
|
|
2809
|
+
cMunFG: entrada.cMunFG ?? e.endereco.cMun,
|
|
2810
|
+
cMunFGIBS: entrada.cMunFGIBS,
|
|
2811
|
+
tpImp,
|
|
2812
|
+
tpEmis,
|
|
2813
|
+
cDV,
|
|
2814
|
+
tpAmb,
|
|
2815
|
+
finNFe,
|
|
2816
|
+
tpNFDebito: entrada.tpNFDebito,
|
|
2817
|
+
tpNFCredito: entrada.tpNFCredito,
|
|
2818
|
+
indFinal,
|
|
2819
|
+
indPres,
|
|
2820
|
+
indIntermed: entrada.indIntermed ?? (["2", "3", "4", "9"].includes(indPres) ? "0" : undefined),
|
|
2821
|
+
procEmi: "0",
|
|
2822
|
+
verProc: opcoes.verProc ?? formatarVerProc("sinete", VERSAO_PACOTE),
|
|
2823
|
+
dhCont: cont === undefined ? undefined : formatarDh(cont.dhCont, offset),
|
|
2824
|
+
xJust: cont?.xJust,
|
|
2825
|
+
NFref: entrada.referenciadas?.map((r, n) => referencia(r, `referenciadas[${n}]`, issues)),
|
|
2826
|
+
gCompraGov: entrada.gCompraGov === undefined ? undefined : clean({
|
|
2827
|
+
tpEnteGov: entrada.gCompraGov.tpEnteGov,
|
|
2828
|
+
pRedutor: ctx.s(pRedutorGov ?? Decimal.ZERO, D0302A04),
|
|
2829
|
+
tpOperGov: entrada.gCompraGov.tpOperGov,
|
|
2830
|
+
refDFeAnt: entrada.gCompraGov.refDFeAnt
|
|
2831
|
+
}),
|
|
2832
|
+
gPagAntecipado: entrada.gPagAntecipado === undefined ? undefined : { refNFe: [...entrada.gPagAntecipado] }
|
|
2833
|
+
});
|
|
2834
|
+
const local = (l, path) => l === undefined ? undefined : clean({
|
|
2835
|
+
...documento(l, path, issues),
|
|
2836
|
+
xNome: l.xNome,
|
|
2837
|
+
...endereco(l),
|
|
2838
|
+
cPais: "1058",
|
|
2839
|
+
xPais: "BRASIL",
|
|
2840
|
+
email: l.email,
|
|
2841
|
+
IE: l.IE
|
|
2842
|
+
});
|
|
2843
|
+
if ((entrada.autXML?.length ?? 0) > 10)
|
|
2844
|
+
issues.add("autXML", "campo_invalido", "no máximo 10 autorizados");
|
|
2845
|
+
const autXML = entrada.autXML?.map((a, n) => documento(a, `autXML[${n}]`, issues));
|
|
2846
|
+
const tr = entrada.transporte;
|
|
2847
|
+
const transp = { modFrete: tr?.modFrete ?? "9" };
|
|
2848
|
+
if (tr?.transportador !== undefined) {
|
|
2849
|
+
const t = tr.transportador;
|
|
2850
|
+
const docT = t.CNPJ !== undefined || t.CPF !== undefined ? documento(t, "transporte.transportador", issues) : {};
|
|
2851
|
+
transp.transporta = clean({ ...docT, xNome: t.xNome, IE: t.IE, xEnder: t.xEnder, xMun: t.xMun, UF: t.UF });
|
|
2852
|
+
}
|
|
2853
|
+
if (tr?.retTransp !== undefined) {
|
|
2854
|
+
const r = tr.retTransp;
|
|
2855
|
+
const vBCRet = ctx.req(r.vBCRet, "transporte.retTransp.vBCRet", D1302);
|
|
2856
|
+
const pICMSRet = ctx.req(r.pICMSRet, "transporte.retTransp.pICMSRet", D0302A04);
|
|
2857
|
+
const vICMSRet = ctx.calc(r.vICMSRet, vBCRet.percent(pICMSRet), "transporte.retTransp.vICMSRet", D1302, "icms");
|
|
2858
|
+
transp.retTransp = {
|
|
2859
|
+
vServ: S(ctx.req(r.vServ, "transporte.retTransp.vServ", D1302)),
|
|
2860
|
+
vBCRet: S(vBCRet),
|
|
2861
|
+
pICMSRet: ctx.s(pICMSRet, D0302A04),
|
|
2862
|
+
vICMSRet: S(vICMSRet),
|
|
2863
|
+
CFOP: r.CFOP,
|
|
2864
|
+
cMunFG: r.cMunFG
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2867
|
+
if (tr?.veicTransp !== undefined)
|
|
2868
|
+
transp.veicTransp = tr.veicTransp;
|
|
2869
|
+
if (tr?.reboque !== undefined)
|
|
2870
|
+
transp.reboque = tr.reboque;
|
|
2871
|
+
if (tr?.vagao !== undefined)
|
|
2872
|
+
transp.vagao = tr.vagao;
|
|
2873
|
+
if (tr?.balsa !== undefined)
|
|
2874
|
+
transp.balsa = tr.balsa;
|
|
2875
|
+
if (tr?.volumes !== undefined) {
|
|
2876
|
+
transp.vol = tr.volumes.map((vol, n) => clean({
|
|
2877
|
+
qVol: vol.qVol === undefined ? undefined : String(vol.qVol),
|
|
2878
|
+
esp: vol.esp,
|
|
2879
|
+
marca: vol.marca,
|
|
2880
|
+
nVol: vol.nVol,
|
|
2881
|
+
pesoL: ctx.so(ctx.opt(vol.pesoL, `transporte.volumes[${n}].pesoL`, D1203), D1203),
|
|
2882
|
+
pesoB: ctx.so(ctx.opt(vol.pesoB, `transporte.volumes[${n}].pesoB`, D1203), D1203),
|
|
2883
|
+
lacres: vol.lacres?.map((nLacre) => ({ nLacre }))
|
|
2884
|
+
}));
|
|
2885
|
+
}
|
|
2886
|
+
let cobr;
|
|
2887
|
+
if (entrada.cobranca !== undefined) {
|
|
2888
|
+
const c = entrada.cobranca;
|
|
2889
|
+
cobr = {};
|
|
2890
|
+
if (c.fatura !== undefined) {
|
|
2891
|
+
const f = c.fatura;
|
|
2892
|
+
const vOrig = ctx.opt(f.vOrig, "cobranca.fatura.vOrig", D1302);
|
|
2893
|
+
const vDescF = ctx.opt(f.vDesc, "cobranca.fatura.vDesc", D1302);
|
|
2894
|
+
const vLiq = vOrig === undefined ? ctx.opt(f.vLiq, "cobranca.fatura.vLiq", D1302) : ctx.calc(f.vLiq, vOrig.minus(vDescF ?? Decimal.ZERO), "cobranca.fatura.vLiq", D1302, "produto");
|
|
2895
|
+
cobr.fat = clean({
|
|
2896
|
+
nFat: f.nFat,
|
|
2897
|
+
vOrig: ctx.so(vOrig, D1302),
|
|
2898
|
+
vDesc: ctx.so(vDescF, D1302),
|
|
2899
|
+
vLiq: ctx.so(vLiq, D1302)
|
|
2900
|
+
});
|
|
2901
|
+
}
|
|
2902
|
+
if (c.duplicatas !== undefined) {
|
|
2903
|
+
if (c.duplicatas.length > 120)
|
|
2904
|
+
issues.add("cobranca.duplicatas", "campo_invalido", "no máximo 120 duplicatas");
|
|
2905
|
+
cobr.dup = c.duplicatas.map((dup, n) => clean({
|
|
2906
|
+
nDup: dup.nDup ?? String(n + 1).padStart(3, "0"),
|
|
2907
|
+
dVenc: dup.dVenc,
|
|
2908
|
+
vDup: ctx.s(ctx.req(dup.vDup, `cobranca.duplicatas[${n}].vDup`, D1302_OPC), D1302_OPC)
|
|
2909
|
+
}));
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
const pagIn = entrada.pagamento ?? { detPag: [{ tPag: "90", vPag: "0" }] };
|
|
2913
|
+
const igualTotal = opcoes.pagamentoIgualTotal === true;
|
|
2914
|
+
if (igualTotal) {
|
|
2915
|
+
const unico = entrada.pagamento?.detPag.length === 1 ? entrada.pagamento.detPag[0] : undefined;
|
|
2916
|
+
if (unico === undefined) {
|
|
2917
|
+
issues.add("pagamento.detPag", "pagamento_igual_total", "pagamentoIgualTotal pede exatamente um detPag");
|
|
2918
|
+
} else if (unico.tPag === "90") {
|
|
2919
|
+
issues.add("pagamento.detPag[0].tPag", "pagamento_igual_total", "tPag 90 (sem pagamento) não recebe o total");
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
const pag = clean({
|
|
2923
|
+
detPag: pagIn.detPag.map((p, n) => clean({
|
|
2924
|
+
indPag: p.indPag,
|
|
2925
|
+
tPag: p.tPag,
|
|
2926
|
+
xPag: p.xPag,
|
|
2927
|
+
vPag: igualTotal ? S(vNF) : S(ctx.req(p.vPag, `pagamento.detPag[${n}].vPag`, D1302)),
|
|
2928
|
+
dPag: p.dPag,
|
|
2929
|
+
CNPJPag: p.CNPJPag,
|
|
2930
|
+
UFPag: p.UFPag,
|
|
2931
|
+
card: p.card
|
|
2932
|
+
})),
|
|
2933
|
+
vTroco: ctx.so(ctx.opt(pagIn.vTroco, "pagamento.vTroco", D1302), D1302)
|
|
2934
|
+
});
|
|
2935
|
+
if (nfce && entrada.pagamento !== undefined && entrada.pagamento.detPag.length > 0 && issues.empty) {
|
|
2936
|
+
pagamentoNfce(pag, vNF, issues);
|
|
2937
|
+
}
|
|
2938
|
+
if (nfce && vNF.gt(Decimal.of(NFCE_LIMITE_SEM_DESTINATARIO)) && dest === undefined) {
|
|
2939
|
+
issues.add("destinatario", "campo_obrigatorio", `NFC-e acima de R$ ${NFCE_LIMITE_SEM_DESTINATARIO} identifica o destinatário (W16-40, rejeição 750)`);
|
|
2940
|
+
}
|
|
2941
|
+
const ia = entrada.informacoesAdicionais;
|
|
2942
|
+
const infAdic = ia === undefined || Object.values(ia).every((x) => x === undefined) ? undefined : clean({
|
|
2943
|
+
infAdFisco: ia.infAdFisco,
|
|
2944
|
+
infCpl: ia.infCpl,
|
|
2945
|
+
obsCont: ia.obsCont,
|
|
2946
|
+
obsFisco: ia.obsFisco,
|
|
2947
|
+
procRef: ia.procRef
|
|
2948
|
+
});
|
|
2949
|
+
const exig = { ...exigenciaRespTec(emitUf, opcoes.ambiente, agora), ...opcoes.exigencias };
|
|
2950
|
+
const rt = entrada.respTec ?? opcoes.respTec;
|
|
2951
|
+
let infRespTec;
|
|
2952
|
+
if (rt === undefined) {
|
|
2953
|
+
if (exig.infRespTec === "obrigatorio") {
|
|
2954
|
+
issues.add("respTec", "resp_tec_obrigatorio", `a UF ${emitUf} exige o responsável técnico (rejeição 972)`);
|
|
2955
|
+
}
|
|
2956
|
+
} else {
|
|
2957
|
+
const cnpjRt = lerCnpj3(rt.CNPJ, { caminho: "respTec.CNPJ" });
|
|
2958
|
+
if (!cnpjRt.ok)
|
|
2959
|
+
issues.list.push(cnpjRt.erro);
|
|
2960
|
+
infRespTec = {
|
|
2961
|
+
CNPJ: cnpjRt.ok ? cnpjRt.valor : rt.CNPJ,
|
|
2962
|
+
xContato: rt.xContato,
|
|
2963
|
+
email: rt.email,
|
|
2964
|
+
fone: digits(rt.fone)
|
|
2965
|
+
};
|
|
2966
|
+
if (rt.csrt !== undefined) {
|
|
2967
|
+
infRespTec.idCSRT = rt.csrt.idCSRT;
|
|
2968
|
+
infRespTec.hashCSRT = await hashCsrt(rt.csrt.CSRT, chave);
|
|
2969
|
+
} else if (exig.csrt === "obrigatorio") {
|
|
2970
|
+
issues.add("respTec.csrt", "csrt_obrigatorio", `a UF ${emitUf} exige idCSRT e hashCSRT (rejeição 975)`);
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
const inf = clean({
|
|
2974
|
+
versao: "4.00",
|
|
2975
|
+
Id: `NFe${chave}`,
|
|
2976
|
+
ide,
|
|
2977
|
+
emit,
|
|
2978
|
+
dest,
|
|
2979
|
+
retirada: local(entrada.retirada, "retirada"),
|
|
2980
|
+
entrega: local(entrada.entrega, "entrega"),
|
|
2981
|
+
autXML,
|
|
2982
|
+
det: itens.map((m) => m.det),
|
|
2983
|
+
total,
|
|
2984
|
+
transp,
|
|
2985
|
+
cobr,
|
|
2986
|
+
pag,
|
|
2987
|
+
infIntermed: entrada.infIntermed,
|
|
2988
|
+
infAdic,
|
|
2989
|
+
exporta: entrada.exporta,
|
|
2990
|
+
compra: entrada.compra,
|
|
2991
|
+
cana: entrada.cana,
|
|
2992
|
+
infRespTec,
|
|
2993
|
+
agropecuario: entrada.agropecuario
|
|
2994
|
+
});
|
|
2995
|
+
cstComIsento(entrada, idDest, issues);
|
|
2996
|
+
vencimentos(entrada, { dhEmi, instante: agora }, issues);
|
|
2997
|
+
camposForaDoPl(pl.infNFe, inf, "infNFe", pl.vigencia.pl, issues);
|
|
2998
|
+
textosForaDoXml(inf, "infNFe", issues);
|
|
2999
|
+
if (!issues.empty)
|
|
3000
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
3001
|
+
let xml;
|
|
3002
|
+
try {
|
|
3003
|
+
xml = `<NFe xmlns="${NFE_NS3}">${serializar2(pl.infNFe, "infNFe", inf, NFE_NS3)}</NFe>`;
|
|
3004
|
+
} catch (e) {
|
|
3005
|
+
if (!(e instanceof ErroSerializacao))
|
|
3006
|
+
throw e;
|
|
3007
|
+
return {
|
|
3008
|
+
ok: false,
|
|
3009
|
+
ocorrencias: [{ caminho: e.caminho, code: "schema", mensagem: e.message, origem: "montagem" }]
|
|
3010
|
+
};
|
|
3011
|
+
}
|
|
3012
|
+
const doc = lerXml3(xml);
|
|
3013
|
+
const infEl = primeiroFilho3(doc.raiz, "infNFe", NFE_NS3);
|
|
3014
|
+
const schemaIssues = infEl === undefined ? [] : validar3(pl.infNFe, infEl);
|
|
3015
|
+
if (schemaIssues.length > 0) {
|
|
3016
|
+
return {
|
|
3017
|
+
ok: false,
|
|
3018
|
+
ocorrencias: schemaIssues.map((i) => ({
|
|
3019
|
+
caminho: i.caminho,
|
|
3020
|
+
code: "schema",
|
|
3021
|
+
mensagem: `${i.code}: ${i.mensagem}`,
|
|
3022
|
+
origem: "montagem"
|
|
3023
|
+
}))
|
|
3024
|
+
};
|
|
3025
|
+
}
|
|
3026
|
+
let supl;
|
|
3027
|
+
if (nfce) {
|
|
3028
|
+
const tabela = urlsNfce(emitUf, opcoes.ambiente, diaBrasilia(agora));
|
|
3029
|
+
const urlQr = opcoes.urlQrCode ?? tabela.qrCode;
|
|
3030
|
+
const urlChave = opcoes.urlChave ?? tabela.urlChave;
|
|
3031
|
+
if (urlQr === undefined || !/^https?:\/\//i.test(urlQr)) {
|
|
3032
|
+
issues.montagem("urlQrCode", "qrcode_invalido", `sem endereço completo do QR Code da NFC-e para ${emitUf} em ${opcoes.ambiente}: informe urlQrCode (data/nfce-urls.json)`);
|
|
3033
|
+
}
|
|
3034
|
+
if (urlChave === undefined) {
|
|
3035
|
+
issues.montagem("urlChave", "qrcode_invalido", `sem URL de consulta por chave da NFC-e para ${emitUf}: informe urlChave`);
|
|
3036
|
+
}
|
|
3037
|
+
if (urlQr === undefined || urlChave === undefined || !issues.empty)
|
|
3038
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
3039
|
+
const p = await parametrosQrCode({
|
|
3040
|
+
chave,
|
|
3041
|
+
ambiente: opcoes.ambiente,
|
|
3042
|
+
tpEmis,
|
|
3043
|
+
dhEmi,
|
|
3044
|
+
vNF: inf.total.ICMSTot.vNF,
|
|
3045
|
+
...dest === undefined ? {} : { dest },
|
|
3046
|
+
xml
|
|
3047
|
+
}, qr);
|
|
3048
|
+
supl = { versao: qr.versao, urlChave, base: `${urlQr.replace(/\?+$/, "")}?p=`, ...p };
|
|
3049
|
+
const suplIssues = conferirSupl(inserirSupl({ xml, nfce: supl }, supl.assinar ? ASSINATURA_2048 : undefined));
|
|
3050
|
+
if (suplIssues.length > 0)
|
|
3051
|
+
return { ok: false, ocorrencias: suplIssues };
|
|
3052
|
+
}
|
|
3053
|
+
return {
|
|
3054
|
+
ok: true,
|
|
3055
|
+
valor: {
|
|
3056
|
+
chave,
|
|
3057
|
+
id: `NFe${chave}`,
|
|
3058
|
+
cNF,
|
|
3059
|
+
cDV,
|
|
3060
|
+
mod,
|
|
3061
|
+
tpEmis,
|
|
3062
|
+
dhEmi,
|
|
3063
|
+
...supl === undefined ? {} : { nfce: supl },
|
|
3064
|
+
pl: pl.vigencia,
|
|
3065
|
+
infNFe: inf,
|
|
3066
|
+
xml
|
|
3067
|
+
}
|
|
3068
|
+
};
|
|
3069
|
+
}
|
|
3070
|
+
var ASSINATURA_2048 = codificarBase642(new Uint8Array(256));
|
|
3071
|
+
function conferirSupl(xml) {
|
|
3072
|
+
const el = primeiroFilho3(lerXml3(xml).raiz, "infNFeSupl", NFE_NS3);
|
|
3073
|
+
const erros = el === undefined ? [] : validar3(TNFe_infNFeSupl, el);
|
|
3074
|
+
return erros.map((i) => ({
|
|
3075
|
+
caminho: i.caminho,
|
|
3076
|
+
code: "schema",
|
|
3077
|
+
mensagem: `${i.code}: ${i.mensagem}`,
|
|
3078
|
+
origem: "montagem"
|
|
3079
|
+
}));
|
|
3080
|
+
}
|
|
3081
|
+
var escapeXml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3082
|
+
async function assinaturaQrCode(nota, assinador) {
|
|
3083
|
+
return nota.nfce?.assinar === true ? assinarParametros(nota.nfce.parametros, assinador) : undefined;
|
|
3084
|
+
}
|
|
3085
|
+
function comQrCode(nota, assinatura) {
|
|
3086
|
+
const xml = inserirSupl(nota, assinatura);
|
|
3087
|
+
if (assinatura !== undefined) {
|
|
3088
|
+
const issues = conferirSupl(xml);
|
|
3089
|
+
if (issues.length > 0)
|
|
3090
|
+
throw new ErroDeValidacao("o QR Code da NFC-e não passou no schema", issues);
|
|
3091
|
+
}
|
|
3092
|
+
return xml;
|
|
3093
|
+
}
|
|
3094
|
+
function inserirSupl(built, assinatura) {
|
|
3095
|
+
const s = built.nfce;
|
|
3096
|
+
if (s === undefined) {
|
|
3097
|
+
if (assinatura !== undefined)
|
|
3098
|
+
throw new ErroDeConfiguracao2("a NF-e (modelo 55) não tem QR Code");
|
|
3099
|
+
return built.xml;
|
|
3100
|
+
}
|
|
3101
|
+
if (s.assinar && assinatura === undefined) {
|
|
3102
|
+
throw new ErroDeConfiguracao2("NFC-e em contingência off-line com QR Code versão 3 precisa da assinatura (ZX02-334, rejeição 474)");
|
|
3103
|
+
}
|
|
3104
|
+
if (!s.assinar && assinatura !== undefined) {
|
|
3105
|
+
throw new ErroDeConfiguracao2("este QR Code não leva assinatura (ZX02-330, rejeição 445)");
|
|
3106
|
+
}
|
|
3107
|
+
const fim = "</NFe>";
|
|
3108
|
+
if (!built.xml.endsWith(fim))
|
|
3109
|
+
throw new ErroDeConfiguracao2("NFC-e montada fora da forma esperada");
|
|
3110
|
+
const qrCode = `${s.base}${s.parametros}${assinatura === undefined ? "" : `|${assinatura}`}`;
|
|
3111
|
+
const supl = `<infNFeSupl><qrCode>${escapeXml(qrCode)}</qrCode><urlChave>${escapeXml(s.urlChave)}</urlChave></infNFeSupl>`;
|
|
3112
|
+
return built.xml.slice(0, -fim.length) + supl + fim;
|
|
3113
|
+
}
|
|
3114
|
+
async function assinarNfe(nota, assinador) {
|
|
3115
|
+
return assinarXml(comQrCode(nota, await assinaturaQrCode(nota, assinador)), { id: nota.id }, assinador);
|
|
3116
|
+
}
|
|
3117
|
+
// packages/nfe/src/model.ts
|
|
3118
|
+
var MotivoDesoneracaoIcms = {
|
|
3119
|
+
TAXI: "1",
|
|
3120
|
+
AGROPECUARIA: "3",
|
|
3121
|
+
FROTISTA_LOCADORA: "4",
|
|
3122
|
+
DIPLOMATICO_CONSULAR: "5",
|
|
3123
|
+
UTILITARIOS_MOTOCICLETAS_AMAZONIA_ALC: "6",
|
|
3124
|
+
SUFRAMA: "7",
|
|
3125
|
+
VENDA_ORGAO_PUBLICO: "8",
|
|
3126
|
+
OUTROS: "9",
|
|
3127
|
+
DEFICIENTE_CONDUTOR: "10",
|
|
3128
|
+
DEFICIENTE_NAO_CONDUTOR: "11",
|
|
3129
|
+
FOMENTO_AGROPECUARIO: "12",
|
|
3130
|
+
OLIMPIADAS_RIO_2016: "16",
|
|
3131
|
+
SOLICITADO_PELO_FISCO: "90"
|
|
3132
|
+
};
|
|
3133
|
+
var TipoPagamento = {
|
|
3134
|
+
DINHEIRO: "01",
|
|
3135
|
+
CHEQUE: "02",
|
|
3136
|
+
CARTAO_CREDITO: "03",
|
|
3137
|
+
CARTAO_DEBITO: "04",
|
|
3138
|
+
CREDITO_LOJA: "05",
|
|
3139
|
+
VALE_ALIMENTACAO: "10",
|
|
3140
|
+
VALE_REFEICAO: "11",
|
|
3141
|
+
VALE_PRESENTE: "12",
|
|
3142
|
+
VALE_COMBUSTIVEL: "13",
|
|
3143
|
+
BOLETO: "15",
|
|
3144
|
+
DEPOSITO: "16",
|
|
3145
|
+
PIX_DINAMICO: "17",
|
|
3146
|
+
TRANSFERENCIA_CARTEIRA_DIGITAL: "18",
|
|
3147
|
+
FIDELIDADE_CASHBACK: "19",
|
|
3148
|
+
PIX_ESTATICO: "20",
|
|
3149
|
+
CREDITO_EM_LOJA: "21",
|
|
3150
|
+
FALHA_HARDWARE: "22",
|
|
3151
|
+
SEM_PAGAMENTO: "90",
|
|
3152
|
+
PAGAMENTO_POSTERIOR: "91",
|
|
3153
|
+
OUTROS: "99"
|
|
3154
|
+
};
|
|
3155
|
+
// packages/nfe/src/rotulo.ts
|
|
3156
|
+
import { criarRotuloDoCaminho } from "@sinete/core";
|
|
3157
|
+
var item = (prefixo) => (n) => `${prefixo} ${n}`;
|
|
3158
|
+
var GRUPOS = [
|
|
3159
|
+
{ padrao: /^emitente\b/, rotulo: "Emitente" },
|
|
3160
|
+
{ padrao: /^destinatario\b/, rotulo: "Destinatário" },
|
|
3161
|
+
{ padrao: /^retirada\b/, rotulo: "Local de retirada" },
|
|
3162
|
+
{ padrao: /^entrega\b/, rotulo: "Local de entrega" },
|
|
3163
|
+
{ padrao: /^autXML\b/, rotulo: "Autorizados a baixar o XML" },
|
|
3164
|
+
{ padrao: /^referenciadas\b/, rotulo: "Nota referenciada" },
|
|
3165
|
+
{ padrao: /^itens\[(\d+)\]\.impostos\.icms\b/, rotulo: item("ICMS do item") },
|
|
3166
|
+
{ padrao: /^itens\[(\d+)\]\.impostos\.ibsCbs\b/, rotulo: item("IBS/CBS do item") },
|
|
3167
|
+
{ padrao: /^itens\[(\d+)\]\.impostos\b/, rotulo: item("Impostos do item") },
|
|
3168
|
+
{ padrao: /^itens\[(\d+)\]/, rotulo: item("Item") },
|
|
3169
|
+
{ padrao: /^itens\b/, rotulo: "Itens" },
|
|
3170
|
+
{ padrao: /^transporte\b/, rotulo: "Transporte" },
|
|
3171
|
+
{ padrao: /^cobranca\b/, rotulo: "Cobrança" },
|
|
3172
|
+
{ padrao: /^pagamento\b/, rotulo: "Pagamento" },
|
|
3173
|
+
{ padrao: /^informacoesAdicionais\b/, rotulo: "Informações adicionais" },
|
|
3174
|
+
{ padrao: /^agropecuario\b/, rotulo: "Produtos agropecuários" },
|
|
3175
|
+
{ padrao: /^respTec\b/, rotulo: "Responsável técnico" },
|
|
3176
|
+
{ padrao: /^contingencia\b/, rotulo: "Contingência" },
|
|
3177
|
+
{ padrao: /^gCompraGov\b/, rotulo: "Compra governamental" },
|
|
3178
|
+
{ padrao: /^exporta\b/, rotulo: "Exportação" },
|
|
3179
|
+
{ padrao: /^(?:qrCode|urlQrCode|urlChave)\b/, rotulo: "QR Code da NFC-e" },
|
|
3180
|
+
{ padrao: /^(?:NFe\.)?infNFeSupl\b/, rotulo: "QR Code da NFC-e" },
|
|
3181
|
+
{ padrao: /^infNFe\.ide\.NFref\b/, rotulo: "Nota referenciada" },
|
|
3182
|
+
{ padrao: /^infNFe\.ide\b/, rotulo: "Identificação da nota" },
|
|
3183
|
+
{ padrao: /^infNFe\.emit\b/, rotulo: "Emitente" },
|
|
3184
|
+
{ padrao: /^infNFe\.dest\b/, rotulo: "Destinatário" },
|
|
3185
|
+
{ padrao: /^infNFe\.retirada\b/, rotulo: "Local de retirada" },
|
|
3186
|
+
{ padrao: /^infNFe\.entrega\b/, rotulo: "Local de entrega" },
|
|
3187
|
+
{ padrao: /^infNFe\.autXML\b/, rotulo: "Autorizados a baixar o XML" },
|
|
3188
|
+
{ padrao: /^infNFe\.det(?:\[(\d+)\])?\.imposto\.ICMS\b/, rotulo: item("ICMS do item") },
|
|
3189
|
+
{ padrao: /^infNFe\.det(?:\[(\d+)\])?\.imposto\.IBSCBS\b/, rotulo: item("IBS/CBS do item") },
|
|
3190
|
+
{ padrao: /^infNFe\.det(?:\[(\d+)\])?\.imposto\b/, rotulo: item("Impostos do item") },
|
|
3191
|
+
{ padrao: /^infNFe\.det(?:\[(\d+)\])?/, rotulo: item("Item") },
|
|
3192
|
+
{ padrao: /^infNFe\.total\b/, rotulo: "Totais da nota" },
|
|
3193
|
+
{ padrao: /^infNFe\.transp\b/, rotulo: "Transporte" },
|
|
3194
|
+
{ padrao: /^infNFe\.cobr\b/, rotulo: "Cobrança" },
|
|
3195
|
+
{ padrao: /^infNFe\.pag\b/, rotulo: "Pagamento" },
|
|
3196
|
+
{ padrao: /^infNFe\.infAdic\b/, rotulo: "Informações adicionais" },
|
|
3197
|
+
{ padrao: /^infNFe\.agropecuario\b/, rotulo: "Produtos agropecuários" },
|
|
3198
|
+
{ padrao: /^infNFe\.infRespTec\b/, rotulo: "Responsável técnico" },
|
|
3199
|
+
{ padrao: /^infNFe\.exporta\b/, rotulo: "Exportação" }
|
|
3200
|
+
];
|
|
3201
|
+
var CAMPOS = {
|
|
3202
|
+
IE: "Inscrição estadual",
|
|
3203
|
+
IEST: "Inscrição estadual do substituto tributário",
|
|
3204
|
+
IM: "Inscrição municipal",
|
|
3205
|
+
CNPJ: "CNPJ",
|
|
3206
|
+
CPF: "CPF",
|
|
3207
|
+
idEstrangeiro: "Identificação do estrangeiro",
|
|
3208
|
+
xNome: "Nome",
|
|
3209
|
+
xFant: "Nome fantasia",
|
|
3210
|
+
xLgr: "Logradouro",
|
|
3211
|
+
nro: "Número",
|
|
3212
|
+
xCpl: "Complemento",
|
|
3213
|
+
xBairro: "Bairro",
|
|
3214
|
+
cMun: "Município",
|
|
3215
|
+
xMun: "Município",
|
|
3216
|
+
UF: "UF",
|
|
3217
|
+
CEP: "CEP",
|
|
3218
|
+
fone: "Telefone",
|
|
3219
|
+
email: "E-mail",
|
|
3220
|
+
natOp: "Natureza da operação",
|
|
3221
|
+
serie: "Série",
|
|
3222
|
+
nNF: "Número da nota",
|
|
3223
|
+
cProd: "Código do produto",
|
|
3224
|
+
cEAN: "GTIN",
|
|
3225
|
+
cEANTrib: "GTIN da unidade tributável",
|
|
3226
|
+
xProd: "Descrição do produto",
|
|
3227
|
+
NCM: "NCM",
|
|
3228
|
+
CEST: "CEST",
|
|
3229
|
+
cBenef: "Código de benefício fiscal",
|
|
3230
|
+
CFOP: "CFOP",
|
|
3231
|
+
uCom: "Unidade comercial",
|
|
3232
|
+
qCom: "Quantidade comercial",
|
|
3233
|
+
vUnCom: "Valor unitário comercial",
|
|
3234
|
+
uTrib: "Unidade tributável",
|
|
3235
|
+
qTrib: "Quantidade tributável",
|
|
3236
|
+
vUnTrib: "Valor unitário tributável",
|
|
3237
|
+
vProd: "Valor do produto",
|
|
3238
|
+
vDesc: "Desconto",
|
|
3239
|
+
vFrete: "Frete",
|
|
3240
|
+
vSeg: "Seguro",
|
|
3241
|
+
vOutro: "Outras despesas",
|
|
3242
|
+
CST: "CST",
|
|
3243
|
+
CSOSN: "CSOSN",
|
|
3244
|
+
cClassTrib: "Classificação tributária (cClassTrib)",
|
|
3245
|
+
vBC: "Base de cálculo",
|
|
3246
|
+
refNFe: "Chave da NF-e referenciada",
|
|
3247
|
+
refNFP: "Nota de produtor referenciada",
|
|
3248
|
+
AAMM: "Mês de emissão da nota referenciada",
|
|
3249
|
+
modFrete: "Modalidade do frete",
|
|
3250
|
+
placa: "Placa",
|
|
3251
|
+
RNTC: "RNTC",
|
|
3252
|
+
tPag: "Meio de pagamento",
|
|
3253
|
+
vPag: "Valor do pagamento",
|
|
3254
|
+
vTroco: "Troco",
|
|
3255
|
+
card: "Cartão",
|
|
3256
|
+
CSC: "CSC",
|
|
3257
|
+
idCSC: "Identificador do CSC",
|
|
3258
|
+
versao: "Versão",
|
|
3259
|
+
xJust: "Justificativa",
|
|
3260
|
+
dhCont: "Entrada em contingência",
|
|
3261
|
+
infCpl: "Informações complementares",
|
|
3262
|
+
infAdFisco: "Informações de interesse do fisco"
|
|
3263
|
+
};
|
|
3264
|
+
var rotular = criarRotuloDoCaminho({ grupos: GRUPOS, campos: CAMPOS, padrao: "Dados da NF-e" });
|
|
3265
|
+
function rotuloDoCaminho(caminho) {
|
|
3266
|
+
return rotular(caminho);
|
|
3267
|
+
}
|
|
3268
|
+
// packages/nfe/src/services/client.ts
|
|
3269
|
+
import {
|
|
3270
|
+
criarAutorizado,
|
|
3271
|
+
criarDenegado,
|
|
3272
|
+
criarPendente,
|
|
3273
|
+
ErroDeConfiguracao as ErroDeConfiguracao4,
|
|
3274
|
+
ErroDeValidacao as ErroDeValidacao2,
|
|
3275
|
+
ErroRespostaInvalida as ErroRespostaInvalida4,
|
|
3276
|
+
loggerSilencioso,
|
|
3277
|
+
tpAmbDoAmbiente as tpAmbDoAmbiente3,
|
|
3278
|
+
ufPorCUf as ufPorCUf2,
|
|
3279
|
+
ufPorSigla as ufPorSigla3
|
|
3280
|
+
} from "@sinete/core";
|
|
3281
|
+
import { assinarXml as assinarXml2, elementosFilhos as elementosFilhos2, lerXml as lerXml6, primeiroFilho as primeiroFilho5, textoDe as textoDe2 } from "@sinete/core/xml";
|
|
3282
|
+
import { decodificar, decodificarXml, serializar as serializar3, serializarRaiz, validar as validar4 } from "@sinete/schemas";
|
|
3283
|
+
import { ConsCadElement, TRetConsCad } from "@sinete/schemas/nfe/consulta-cadastro/PL_010d";
|
|
3284
|
+
import { consSitNFeElement, TProtNFe, TRetConsSitNFe } from "@sinete/schemas/nfe/consulta-protocolo/PL_010d";
|
|
3285
|
+
import {
|
|
3286
|
+
distDFeIntElement,
|
|
3287
|
+
resEventoElement,
|
|
3288
|
+
resNFeElement,
|
|
3289
|
+
retDistDFeInt
|
|
3290
|
+
} from "@sinete/schemas/nfe/dist-dfe/PL_NFeDistDFe_104";
|
|
3291
|
+
import { TEvento_infEvento as TEventoCanc, TRetEnvEvento } from "@sinete/schemas/nfe/evento-cancelamento/PL_010d";
|
|
3292
|
+
import { TEvento_infEvento as TEventoCancSubst } from "@sinete/schemas/nfe/evento-cancelamento-substituicao/PL_010d";
|
|
3293
|
+
import { TEvento_infEvento as TEventoCce } from "@sinete/schemas/nfe/evento-cce/PL_010d";
|
|
3294
|
+
import { TEvento_infEvento as TEventoCiencia } from "@sinete/schemas/nfe/evento-ciencia-operacao/PL_010d";
|
|
3295
|
+
import { TEvento_infEvento as TEventoConfirmacao } from "@sinete/schemas/nfe/evento-confirmacao-operacao/PL_010d";
|
|
3296
|
+
import { TEvento_infEvento as TEventoDesconhecimento } from "@sinete/schemas/nfe/evento-desconhecimento-operacao/PL_010d";
|
|
3297
|
+
import { TEvento_infEvento as TEventoNaoRealizada } from "@sinete/schemas/nfe/evento-operacao-nao-realizada/PL_010d";
|
|
3298
|
+
import { TInutNFe_infInut, TRetInutNFe } from "@sinete/schemas/nfe/inutilizacao/PL_010d";
|
|
3299
|
+
import { TRetConsReciNFe, TRetEnviNFe } from "@sinete/schemas/nfe/PL_010f";
|
|
3300
|
+
import { consStatServElement, TRetConsStatServ } from "@sinete/schemas/nfe/status-servico/PL_009q";
|
|
3301
|
+
import { nfceEndpoint, nfeContingenciaDaUf, nfeEndpoint } from "@sinete/transport";
|
|
3302
|
+
import { lerChaveAcesso as lerChaveAcesso2, lerCnpj as lerCnpj4, lerCpf as lerCpf2 } from "@sinete/validators";
|
|
3303
|
+
|
|
3304
|
+
// packages/nfe/src/services/gzip.ts
|
|
3305
|
+
import { ErroNaoSuportado as ErroNaoSuportado2, ErroRespostaInvalida } from "@sinete/core";
|
|
3306
|
+
import { decodificarBase64 } from "@sinete/core/xml";
|
|
3307
|
+
async function descomprimirGzipBase64(b64) {
|
|
3308
|
+
const Ds = globalThis.DecompressionStream;
|
|
3309
|
+
if (Ds === undefined)
|
|
3310
|
+
throw new ErroNaoSuportado2("DecompressionStream indisponível nesta runtime; docZip não pode ser lido");
|
|
3311
|
+
let bytes;
|
|
3312
|
+
try {
|
|
3313
|
+
bytes = decodificarBase64(b64.trim());
|
|
3314
|
+
} catch (cause) {
|
|
3315
|
+
throw new ErroRespostaInvalida("docZip com base64 inválido", { cause });
|
|
3316
|
+
}
|
|
3317
|
+
try {
|
|
3318
|
+
const stream = new Blob([bytes]).stream().pipeThrough(new Ds("gzip"));
|
|
3319
|
+
return await new Response(stream).text();
|
|
3320
|
+
} catch (cause) {
|
|
3321
|
+
throw new ErroRespostaInvalida("docZip não é um gzip válido", { cause });
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
|
|
3325
|
+
// packages/nfe/src/services/outcome.ts
|
|
3326
|
+
import { criarRecusado } from "@sinete/core";
|
|
3327
|
+
import { completarRecusado } from "@sinete/rejeicoes";
|
|
3328
|
+
// packages/nfe/src/data/cstat.json
|
|
3329
|
+
var cstat_default = {
|
|
3330
|
+
descricao: "Códigos de status de sucesso e de processamento (MOC 7.0 Anexo I, tabela 4.4.1) e os códigos que o @sinete/nfe trata de forma própria. Rejeições e denegações com mensagem oficial estão no @sinete/rejeicoes; aqui fica só o desfecho de cada código por serviço.",
|
|
3331
|
+
fonte: "MOC 7.0 Anexo I, tabela 4.4.1 (códigos de sucesso) e 4.4.2 (denegação 301, 302, 303); NT 2014.002 (Distribuição DF-e, 137 e 138); NT 2011.004 (lote em processamento, 105); MOC 7.0 Anexo I, consulta protocolo J03 a J06 (561, 562 e 613: a numeração da chave consultada tem outra NF-e)",
|
|
3332
|
+
atualizadoEm: "2026-09-26",
|
|
3333
|
+
autorizada: ["100", "150"],
|
|
3334
|
+
denegada: ["110", "301", "302", "303"],
|
|
3335
|
+
cancelada: ["101", "151", "155"],
|
|
3336
|
+
loteRecebido: ["103"],
|
|
3337
|
+
loteProcessado: ["104"],
|
|
3338
|
+
loteEmProcessamento: ["105"],
|
|
3339
|
+
loteNaoLocalizado: ["106"],
|
|
3340
|
+
servicoEmOperacao: ["107"],
|
|
3341
|
+
inutilizacaoHomologada: ["102"],
|
|
3342
|
+
eventoRegistrado: ["135", "136", "155"],
|
|
3343
|
+
loteEventoProcessado: ["128"],
|
|
3344
|
+
cadastroEncontrado: ["111", "112"],
|
|
3345
|
+
distribuicaoNenhumDocumento: ["137"],
|
|
3346
|
+
distribuicaoDocumentos: ["138"],
|
|
3347
|
+
duplicidade: ["204"],
|
|
3348
|
+
duplicidadeChaveDiferente: ["539"],
|
|
3349
|
+
naoConsta: ["217"],
|
|
3350
|
+
outraNfeNoNumero: ["561", "562", "613"],
|
|
3351
|
+
consumoIndevido: ["656"],
|
|
3352
|
+
dicas: {
|
|
3353
|
+
"656": {
|
|
3354
|
+
causaProvavel: "Consumo indevido: consultas repetidas à Distribuição DF-e sem documento novo (ultNSU igual a maxNSU) ou acima do limite de requisições por hora.",
|
|
3355
|
+
comoCorrigir: "Aguardar uma hora antes de consultar de novo e só repetir a consulta quando ultNSU for menor que maxNSU; guardar o ultNSU devolvido e continuar dele.",
|
|
3356
|
+
fonte: "NT 2014.002 v1.02 (Distribuição DF-e), regras de consumo indevido"
|
|
3357
|
+
},
|
|
3358
|
+
"217": {
|
|
3359
|
+
causaProvavel: "A chave consultada não consta na base do autorizador consultado: a nota não foi recebida, ou foi autorizada em outro ambiente ou autorizador (SVC).",
|
|
3360
|
+
comoCorrigir: "Se o envio ficou sem resposta, reenviar exatamente o mesmo XML assinado; se foi emitida em contingência SVC, consultar no SVC.",
|
|
3361
|
+
fonte: "MOC 7.0 Anexo I, serviço de consulta protocolo"
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
};
|
|
3365
|
+
|
|
3366
|
+
// packages/nfe/src/services/outcome.ts
|
|
3367
|
+
var CLASSES = cstat_default;
|
|
3368
|
+
var DICAS = cstat_default.dicas;
|
|
3369
|
+
function cstatEm(cStat, classe) {
|
|
3370
|
+
return CLASSES[classe].includes(cStat);
|
|
3371
|
+
}
|
|
3372
|
+
function rejeitado(status) {
|
|
3373
|
+
const r = completarRecusado(criarRecusado(status));
|
|
3374
|
+
if (r.dica !== undefined)
|
|
3375
|
+
return r;
|
|
3376
|
+
const dica = Object.hasOwn(DICAS, status.cStat) ? DICAS[status.cStat] : undefined;
|
|
3377
|
+
return dica === undefined ? r : criarRecusado(status, dica);
|
|
3378
|
+
}
|
|
3379
|
+
|
|
3380
|
+
// packages/nfe/src/services/proc.ts
|
|
3381
|
+
import { ErroDeConfiguracao as ErroDeConfiguracao3, ErroRespostaInvalida as ErroRespostaInvalida2 } from "@sinete/core";
|
|
3382
|
+
import {
|
|
3383
|
+
atributoDe,
|
|
3384
|
+
descendentes,
|
|
3385
|
+
lerXml as lerXml4,
|
|
3386
|
+
namespacesEmEscopo,
|
|
3387
|
+
primeiroFilho as primeiroFilho4,
|
|
3388
|
+
textoDe,
|
|
3389
|
+
XMLDSIG_NS
|
|
3390
|
+
} from "@sinete/core/xml";
|
|
3391
|
+
var NFE_NS4 = "http://www.portalfiscal.inf.br/nfe";
|
|
3392
|
+
var XML_DECL = /^?<\?xml[^?]*\?>\s*/;
|
|
3393
|
+
function recortarElemento(documento, el, nsPadraoDoPai = NFE_NS4) {
|
|
3394
|
+
const slice = documento.texto.slice(el.inicio, el.fim);
|
|
3395
|
+
const used = new Set;
|
|
3396
|
+
const cobertoDentro = (d, p) => {
|
|
3397
|
+
for (let e = d;e; e = e === el ? null : e.pai)
|
|
3398
|
+
if (e.namespaces.has(p))
|
|
3399
|
+
return true;
|
|
3400
|
+
return false;
|
|
3401
|
+
};
|
|
3402
|
+
for (const d of descendentes(el)) {
|
|
3403
|
+
const prefixos = [d.prefixo, ...d.atributos.map((a) => a.prefixo)].filter((p) => p !== "" && p !== "xml");
|
|
3404
|
+
for (const p of prefixos)
|
|
3405
|
+
if (!cobertoDentro(d, p))
|
|
3406
|
+
used.add(p);
|
|
3407
|
+
}
|
|
3408
|
+
const extra = [];
|
|
3409
|
+
const inScope = new Map;
|
|
3410
|
+
for (let e = el.pai;e; e = e.pai) {
|
|
3411
|
+
for (const [p, u] of e.namespaces)
|
|
3412
|
+
if (!inScope.has(p))
|
|
3413
|
+
inScope.set(p, u);
|
|
3414
|
+
}
|
|
3415
|
+
const herdado = inScope.get("") ?? "";
|
|
3416
|
+
if (herdado !== nsPadraoDoPai && usaDefaultHerdado(el))
|
|
3417
|
+
extra.push(` xmlns="${herdado}"`);
|
|
3418
|
+
for (const p of [...used].sort()) {
|
|
3419
|
+
const uri = inScope.get(p);
|
|
3420
|
+
if (uri === undefined)
|
|
3421
|
+
throw new ErroRespostaInvalida2(`prefixo ${p} sem declaração no recorte de ${el.nome}`);
|
|
3422
|
+
extra.push(` xmlns:${p}="${uri}"`);
|
|
3423
|
+
}
|
|
3424
|
+
if (extra.length === 0)
|
|
3425
|
+
return slice;
|
|
3426
|
+
const at = 1 + el.nome.length;
|
|
3427
|
+
return slice.slice(0, at) + extra.join("") + slice.slice(at);
|
|
3428
|
+
}
|
|
3429
|
+
function usaDefaultHerdado(raiz) {
|
|
3430
|
+
for (const d of descendentes(raiz)) {
|
|
3431
|
+
if (d.prefixo !== "")
|
|
3432
|
+
continue;
|
|
3433
|
+
let coberto = false;
|
|
3434
|
+
for (let e = d;e; e = e === raiz ? null : e.pai) {
|
|
3435
|
+
if (e.namespaces.has("")) {
|
|
3436
|
+
coberto = true;
|
|
3437
|
+
break;
|
|
3438
|
+
}
|
|
3439
|
+
}
|
|
3440
|
+
if (!coberto)
|
|
3441
|
+
return true;
|
|
3442
|
+
}
|
|
3443
|
+
return false;
|
|
3444
|
+
}
|
|
3445
|
+
function documentoAssinado(xml, raiz, elemento) {
|
|
3446
|
+
const text = xml.replace(XML_DECL, "");
|
|
3447
|
+
let doc;
|
|
3448
|
+
try {
|
|
3449
|
+
doc = lerXml4(text);
|
|
3450
|
+
} catch (cause) {
|
|
3451
|
+
throw new ErroDeConfiguracao3(`${raiz} assinado malformado`, { cause });
|
|
3452
|
+
}
|
|
3453
|
+
if (doc.raiz.local !== raiz || doc.raiz.ns !== NFE_NS4) {
|
|
3454
|
+
throw new ErroDeConfiguracao3(`esperado <${raiz}> no namespace da NF-e, veio <${doc.raiz.nome}>`);
|
|
3455
|
+
}
|
|
3456
|
+
if (doc.raiz.namespaces.get("") !== NFE_NS4) {
|
|
3457
|
+
throw new ErroDeConfiguracao3(`<${raiz}> assinado precisa declarar xmlns="${NFE_NS4}" na própria raiz`);
|
|
3458
|
+
}
|
|
3459
|
+
const alvo = primeiroFilho4(doc.raiz, elemento, NFE_NS4);
|
|
3460
|
+
const id = alvo ? atributoDe(alvo, "Id") : undefined;
|
|
3461
|
+
const sig = primeiroFilho4(doc.raiz, "Signature", XMLDSIG_NS);
|
|
3462
|
+
const digest = sig && descendantText(sig, "DigestValue");
|
|
3463
|
+
if (!id || digest === undefined)
|
|
3464
|
+
throw new ErroDeConfiguracao3(`${raiz} sem ${elemento} identificado ou sem assinatura`);
|
|
3465
|
+
return { xml: text, id, digestValue: digest, documento: doc };
|
|
3466
|
+
}
|
|
3467
|
+
function descendantText(el, local) {
|
|
3468
|
+
for (const d of descendentes(el))
|
|
3469
|
+
if (d.local === local && d.ns === XMLDSIG_NS)
|
|
3470
|
+
return textoDe(d).trim();
|
|
3471
|
+
return;
|
|
3472
|
+
}
|
|
3473
|
+
function nfeAssinadaDoProc(xml) {
|
|
3474
|
+
const text = xml.replace(XML_DECL, "");
|
|
3475
|
+
let doc;
|
|
3476
|
+
try {
|
|
3477
|
+
doc = lerXml4(text);
|
|
3478
|
+
} catch (cause) {
|
|
3479
|
+
throw new ErroDeConfiguracao3("nfeProc malformado", { cause });
|
|
3480
|
+
}
|
|
3481
|
+
const noProc = doc.raiz.local === "nfeProc" && doc.raiz.ns === NFE_NS4 ? primeiroFilho4(doc.raiz, "NFe", NFE_NS4) : undefined;
|
|
3482
|
+
const el = noProc ?? (doc.raiz.local === "NFe" && doc.raiz.ns === NFE_NS4 ? doc.raiz : undefined);
|
|
3483
|
+
if (el === undefined)
|
|
3484
|
+
throw new ErroDeConfiguracao3(`esperado <nfeProc> ou <NFe> assinada, veio <${doc.raiz.nome}>`);
|
|
3485
|
+
const fatia = doc.texto.slice(el.inicio, el.fim);
|
|
3486
|
+
const herdados = [...namespacesEmEscopo(el)].filter(([p]) => p !== "xml" && !el.namespaces.has(p));
|
|
3487
|
+
const decl = herdados.map(([p, uri]) => ` ${p === "" ? "xmlns" : `xmlns:${p}`}="${uri.replace(/&/g, "&").replace(/</g, "<").replace(/"/g, """)}"`).join("");
|
|
3488
|
+
const at = 1 + el.nome.length;
|
|
3489
|
+
const assinado = decl === "" ? fatia : fatia.slice(0, at) + decl + fatia.slice(at);
|
|
3490
|
+
return documentoAssinado(assinado, "NFe", "infNFe").xml;
|
|
3491
|
+
}
|
|
3492
|
+
function envelope(raiz, versao, partes) {
|
|
3493
|
+
return `<${raiz} xmlns="${NFE_NS4}" versao="${versao}">${partes.join("")}</${raiz}>`;
|
|
3494
|
+
}
|
|
3495
|
+
|
|
3496
|
+
// packages/nfe/src/services/soap.ts
|
|
3497
|
+
import { ErroRespostaInvalida as ErroRespostaInvalida3 } from "@sinete/core";
|
|
3498
|
+
import { descendentes as descendentes2, elementosFilhos, lerXml as lerXml5 } from "@sinete/core/xml";
|
|
3499
|
+
import { contentTypeSoap12, envelopeSoap12, lerSoapFault } from "@sinete/transport";
|
|
3500
|
+
// packages/nfe/src/data/servicos.json
|
|
3501
|
+
var servicos_default = {
|
|
3502
|
+
descricao: "Web services SOAP 1.2 da NF-e 4.00: namespace do WSDL e operação (a action do Content-Type é <namespace>/<operação>). Na NF-e 4.00 não existe cabeçalho nfeCabecMsg; a mensagem vai em nfeDadosMsg no namespace do WSDL, e a resposta volta em nfeResultMsg. A Distribuição DF-e usa o envelope do WSDL próprio, com nfeDadosMsg dentro de nfeDistDFeInteresse.",
|
|
3503
|
+
fonte: "MOC 7.0, Visão Geral, item 3 (padrão de comunicação e WSDL dos serviços) e WSDLs do portal da NF-e; NT 2014.002 (Distribuição DF-e)",
|
|
3504
|
+
atualizadoEm: "2026-09-28",
|
|
3505
|
+
servicos: {
|
|
3506
|
+
NfeStatusServico: {
|
|
3507
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeStatusServico4",
|
|
3508
|
+
operacao: "nfeStatusServicoNF"
|
|
3509
|
+
},
|
|
3510
|
+
NFeAutorizacao: {
|
|
3511
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeAutorizacao4",
|
|
3512
|
+
operacao: "nfeAutorizacaoLote"
|
|
3513
|
+
},
|
|
3514
|
+
NFeRetAutorizacao: {
|
|
3515
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeRetAutorizacao4",
|
|
3516
|
+
operacao: "nfeRetAutorizacaoLote"
|
|
3517
|
+
},
|
|
3518
|
+
NfeConsultaProtocolo: {
|
|
3519
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeConsultaProtocolo4",
|
|
3520
|
+
operacao: "nfeConsultaNF"
|
|
3521
|
+
},
|
|
3522
|
+
NfeInutilizacao: {
|
|
3523
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeInutilizacao4",
|
|
3524
|
+
operacao: "nfeInutilizacaoNF"
|
|
3525
|
+
},
|
|
3526
|
+
RecepcaoEvento: {
|
|
3527
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeRecepcaoEvento4",
|
|
3528
|
+
operacao: "nfeRecepcaoEvento"
|
|
3529
|
+
},
|
|
3530
|
+
NfeConsultaCadastro: {
|
|
3531
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/CadConsultaCadastro4",
|
|
3532
|
+
operacao: "consultaCadastro",
|
|
3533
|
+
envelopeNoAutorizador: {
|
|
3534
|
+
MT: "operacao"
|
|
3535
|
+
},
|
|
3536
|
+
fonteEnvelope: "Resposta da SEFAZ-MT em homologação em 28/09/2026: com a mensagem só em nfeDadosMsg, o MT responde 215 (falha no schema) e devolve o retorno dentro de consultaCadastroResult; com nfeDadosMsg dentro de consultaCadastro (o elemento da operação do WSDL), responde a consulta (259)."
|
|
3537
|
+
},
|
|
3538
|
+
NFeDistribuicaoDFe: {
|
|
3539
|
+
namespace: "http://www.portalfiscal.inf.br/nfe/wsdl/NFeDistribuicaoDFe",
|
|
3540
|
+
operacao: "nfeDistDFeInteresse",
|
|
3541
|
+
envelope: "distDFeInteresse"
|
|
3542
|
+
}
|
|
3543
|
+
}
|
|
3544
|
+
};
|
|
3545
|
+
|
|
3546
|
+
// packages/nfe/src/services/soap.ts
|
|
3547
|
+
var SERVICOS = servicos_default.servicos;
|
|
3548
|
+
function servicoInfo(servico) {
|
|
3549
|
+
const s = SERVICOS[servico];
|
|
3550
|
+
if (!s)
|
|
3551
|
+
throw new ErroRespostaInvalida3(`serviço sem descrição em data/servicos.json: ${servico}`);
|
|
3552
|
+
return s;
|
|
3553
|
+
}
|
|
3554
|
+
function soapBodyFor(servico, mensagem, autorizador) {
|
|
3555
|
+
const s = servicoInfo(servico);
|
|
3556
|
+
if (s.envelope === "distDFeInteresse" || autorizador && s.envelopeNoAutorizador?.[autorizador] === "operacao") {
|
|
3557
|
+
return `<${s.operacao} xmlns="${s.namespace}"><nfeDadosMsg>${mensagem}</nfeDadosMsg></${s.operacao}>`;
|
|
3558
|
+
}
|
|
3559
|
+
return `<nfeDadosMsg xmlns="${s.namespace}">${mensagem}</nfeDadosMsg>`;
|
|
3560
|
+
}
|
|
3561
|
+
async function chamar(c) {
|
|
3562
|
+
const s = servicoInfo(c.servico);
|
|
3563
|
+
const started = { servico: c.servico, autorizador: c.endpoint.autorizador, host: c.endpoint.host };
|
|
3564
|
+
const res = await c.transport.enviar({
|
|
3565
|
+
url: c.endpoint.url,
|
|
3566
|
+
endpoint: c.endpoint,
|
|
3567
|
+
metodo: "POST",
|
|
3568
|
+
cabecalhos: { "content-type": contentTypeSoap12(`${s.namespace}/${s.operacao}`) },
|
|
3569
|
+
corpo: envelopeSoap12(soapBodyFor(c.servico, c.mensagem, c.endpoint.autorizador)),
|
|
3570
|
+
...c.timeoutMs === undefined ? {} : { timeoutMs: c.timeoutMs },
|
|
3571
|
+
...c.signal === undefined ? {} : { signal: c.signal }
|
|
3572
|
+
});
|
|
3573
|
+
const text = res.texto();
|
|
3574
|
+
const fault = lerSoapFault(text);
|
|
3575
|
+
if (fault) {
|
|
3576
|
+
c.logger.warn("nfe.soap.fault", { ...started, status: res.status, code: fault.code });
|
|
3577
|
+
throw new ErroRespostaInvalida3(`SOAP fault de ${c.endpoint.host}: ${fault.reason ?? fault.code ?? "sem motivo"}`, {
|
|
3578
|
+
detalhes: { status: res.status, code: fault.code, reason: fault.reason, servico: c.servico }
|
|
3579
|
+
});
|
|
3580
|
+
}
|
|
3581
|
+
let doc;
|
|
3582
|
+
try {
|
|
3583
|
+
doc = lerXml5(text.replace(/^/, ""));
|
|
3584
|
+
} catch (cause) {
|
|
3585
|
+
throw new ErroRespostaInvalida3(`resposta de ${c.endpoint.host} não é XML (HTTP ${res.status})`, {
|
|
3586
|
+
cause,
|
|
3587
|
+
detalhes: { status: res.status, servico: c.servico }
|
|
3588
|
+
});
|
|
3589
|
+
}
|
|
3590
|
+
let ret;
|
|
3591
|
+
for (const el of descendentes2(doc.raiz)) {
|
|
3592
|
+
if (el.local === c.retorno && el.ns === NFE_NS4) {
|
|
3593
|
+
ret = el;
|
|
3594
|
+
break;
|
|
3595
|
+
}
|
|
3596
|
+
}
|
|
3597
|
+
if (!ret)
|
|
3598
|
+
ret = retornoForaDoNamespace(doc.raiz, c.retorno);
|
|
3599
|
+
if (ret && ret.ns !== NFE_NS4) {
|
|
3600
|
+
c.logger.warn("nfe.soap.retorno_fora_do_namespace", { ...started, retorno: c.retorno, ns: ret.ns });
|
|
3601
|
+
}
|
|
3602
|
+
if (!ret) {
|
|
3603
|
+
throw new ErroRespostaInvalida3(`resposta de ${c.endpoint.host} sem <${c.retorno}> (HTTP ${res.status})`, {
|
|
3604
|
+
detalhes: { status: res.status, servico: c.servico }
|
|
3605
|
+
});
|
|
3606
|
+
}
|
|
3607
|
+
if (!Array.from(descendentes2(ret)).some((el) => el.local === "cStat" && el.ns === NFE_NS4)) {
|
|
3608
|
+
throw new ErroRespostaInvalida3(`<${c.retorno}> de ${c.endpoint.host} sem cStat (HTTP ${res.status})`, {
|
|
3609
|
+
detalhes: { status: res.status, servico: c.servico }
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3612
|
+
c.logger.debug("nfe.soap.resposta", { ...started, status: res.status });
|
|
3613
|
+
return { doc, ret, status: res.status };
|
|
3614
|
+
}
|
|
3615
|
+
function retornoForaDoNamespace(root, retorno) {
|
|
3616
|
+
for (const el of descendentes2(root)) {
|
|
3617
|
+
if (el.local !== retorno)
|
|
3618
|
+
continue;
|
|
3619
|
+
const filhos = elementosFilhos(el);
|
|
3620
|
+
if (filhos.length > 0 && filhos.every((f) => f.ns === NFE_NS4))
|
|
3621
|
+
return el;
|
|
3622
|
+
}
|
|
3623
|
+
return;
|
|
3624
|
+
}
|
|
3625
|
+
|
|
3626
|
+
// packages/nfe/src/services/client.ts
|
|
3627
|
+
function autorizadorContingencia(uf, ambiente) {
|
|
3628
|
+
const autorizador = nfeContingenciaDaUf(uf, ambiente);
|
|
3629
|
+
return { autorizador, tpEmis: autorizador === "SVC-AN" ? "6" : "7" };
|
|
3630
|
+
}
|
|
3631
|
+
var defaultSleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
3632
|
+
if (signal?.aborted) {
|
|
3633
|
+
reject(signal.reason);
|
|
3634
|
+
return;
|
|
3635
|
+
}
|
|
3636
|
+
const onAbort = () => {
|
|
3637
|
+
clearTimeout(t);
|
|
3638
|
+
reject(signal?.reason);
|
|
3639
|
+
};
|
|
3640
|
+
const t = setTimeout(() => {
|
|
3641
|
+
signal?.removeEventListener("abort", onAbort);
|
|
3642
|
+
resolve();
|
|
3643
|
+
}, ms);
|
|
3644
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
3645
|
+
});
|
|
3646
|
+
function chaveValida(chave, path) {
|
|
3647
|
+
const r = lerChaveAcesso2(chave, { caminho: path });
|
|
3648
|
+
if (!r.ok)
|
|
3649
|
+
throw new ErroDeValidacao2(`chave de acesso inválida: ${r.erro.mensagem}`, [r.erro]);
|
|
3650
|
+
return r.valor;
|
|
3651
|
+
}
|
|
3652
|
+
function schemaIssues(what, issues) {
|
|
3653
|
+
if (issues.length > 0)
|
|
3654
|
+
throw new ErroDeValidacao2(`${what} não confere com o schema`, issues);
|
|
3655
|
+
}
|
|
3656
|
+
function documentoAutor(a, path) {
|
|
3657
|
+
if (a.CNPJ !== undefined) {
|
|
3658
|
+
const r = lerCnpj4(a.CNPJ, { caminho: `${path}.CNPJ` });
|
|
3659
|
+
if (!r.ok)
|
|
3660
|
+
throw new ErroDeValidacao2("CNPJ do autor inválido", [r.erro]);
|
|
3661
|
+
return { CNPJ: r.valor };
|
|
3662
|
+
}
|
|
3663
|
+
const r = lerCpf2(a.CPF ?? "", { caminho: `${path}.CPF` });
|
|
3664
|
+
if (!r.ok)
|
|
3665
|
+
throw new ErroDeValidacao2("CPF do autor inválido", [r.erro]);
|
|
3666
|
+
return { CPF: r.valor };
|
|
3667
|
+
}
|
|
3668
|
+
function autorDaChave(c) {
|
|
3669
|
+
return c.cnpj !== undefined ? { CNPJ: c.cnpj } : { CPF: c.cpf ?? c.emitente.slice(3) };
|
|
3670
|
+
}
|
|
3671
|
+
function autorDoEmitente(a, c) {
|
|
3672
|
+
const daChave = autorDaChave(c);
|
|
3673
|
+
if (a === undefined)
|
|
3674
|
+
return daChave;
|
|
3675
|
+
const autor = documentoAutor(a, "autor");
|
|
3676
|
+
const [campo, valor] = "CNPJ" in autor ? ["CNPJ", autor.CNPJ] : ["CPF", autor.CPF];
|
|
3677
|
+
if (valor !== ("CNPJ" in daChave ? daChave.CNPJ : daChave.CPF) || campo !== ("CNPJ" in daChave ? "CNPJ" : "CPF")) {
|
|
3678
|
+
throw new ErroDeValidacao2("o autor do evento não é o emitente da NF-e", [
|
|
3679
|
+
{
|
|
3680
|
+
caminho: `autor.${campo}`,
|
|
3681
|
+
code: "autor_difere_do_emitente",
|
|
3682
|
+
mensagem: `o autor de um evento do emitente é o ${"CNPJ" in daChave ? "CNPJ" : "CPF"} da chave (P12-44, rejeição 574)`,
|
|
3683
|
+
origem: "entrada"
|
|
3684
|
+
}
|
|
3685
|
+
]);
|
|
3686
|
+
}
|
|
3687
|
+
return autor;
|
|
3688
|
+
}
|
|
3689
|
+
var SVC_DO_TPEMIS = { "6": "SVC-AN", "7": "SVC-RS" };
|
|
3690
|
+
function chaveDoDocumento(a) {
|
|
3691
|
+
const r = lerChaveAcesso2(a.id.slice(3), { caminho: "infNFe.Id", conferirEmitente: false });
|
|
3692
|
+
if (!r.ok)
|
|
3693
|
+
throw new ErroDeConfiguracao4(`Id da NF-e assinada não é uma chave de acesso: ${r.erro.mensagem}`);
|
|
3694
|
+
return r.valor;
|
|
3695
|
+
}
|
|
3696
|
+
function avulso(doc, el) {
|
|
3697
|
+
return recortarElemento(doc, el, "");
|
|
3698
|
+
}
|
|
3699
|
+
function lerProtocolo(doc, el) {
|
|
3700
|
+
const { valor: value } = decodificar(TProtNFe, el, doc.texto);
|
|
3701
|
+
const inf = value.infProt;
|
|
3702
|
+
if (!inf)
|
|
3703
|
+
throw new ErroRespostaInvalida4("protNFe sem infProt");
|
|
3704
|
+
const p = {
|
|
3705
|
+
chNFe: inf.chNFe,
|
|
3706
|
+
cStat: inf.cStat,
|
|
3707
|
+
xMotivo: inf.xMotivo,
|
|
3708
|
+
dhRecbto: inf.dhRecbto,
|
|
3709
|
+
verAplic: inf.verAplic,
|
|
3710
|
+
protNFe: avulso(doc, el),
|
|
3711
|
+
...inf.nProt === undefined ? {} : { nProt: inf.nProt },
|
|
3712
|
+
...inf.digVal === undefined ? {} : { digVal: inf.digVal }
|
|
3713
|
+
};
|
|
3714
|
+
return { p, embutido: recortarElemento(doc, el) };
|
|
3715
|
+
}
|
|
3716
|
+
function desfechoDoProtocolo({ p, embutido }, a) {
|
|
3717
|
+
const status = { cStat: p.cStat, xMotivo: p.xMotivo };
|
|
3718
|
+
const autorizada = cstatEm(p.cStat, "autorizada");
|
|
3719
|
+
const denegada = cstatEm(p.cStat, "denegada");
|
|
3720
|
+
if (!autorizada && !denegada)
|
|
3721
|
+
return rejeitado(status);
|
|
3722
|
+
let full = p;
|
|
3723
|
+
if (a) {
|
|
3724
|
+
if (`NFe${p.chNFe}` !== a.id) {
|
|
3725
|
+
throw new ErroRespostaInvalida4("protocolo de outra chave de acesso", { detalhes: { chNFe: p.chNFe } });
|
|
3726
|
+
}
|
|
3727
|
+
if (p.digVal !== undefined && p.digVal !== a.digestValue) {
|
|
3728
|
+
throw new ErroRespostaInvalida4("digVal do protocolo difere do DigestValue da NF-e enviada", {
|
|
3729
|
+
detalhes: { chNFe: p.chNFe, cStat: p.cStat }
|
|
3730
|
+
});
|
|
3731
|
+
}
|
|
3732
|
+
if (p.digVal !== undefined)
|
|
3733
|
+
full = { ...p, nfeProc: envelope("nfeProc", "4.00", [a.xml, embutido]) };
|
|
3734
|
+
}
|
|
3735
|
+
return autorizada ? criarAutorizado(status, full) : criarDenegado(status, full);
|
|
3736
|
+
}
|
|
3737
|
+
function protNFeDaChave(parent, a) {
|
|
3738
|
+
const prots = elementosFilhos2(parent).filter((e) => e.local === "protNFe" && e.ns === NFE_NS4);
|
|
3739
|
+
if (!a)
|
|
3740
|
+
return prots[0];
|
|
3741
|
+
const chave = a.id.slice(3);
|
|
3742
|
+
return prots.find((e) => {
|
|
3743
|
+
const inf = primeiroFilho5(e, "infProt", NFE_NS4);
|
|
3744
|
+
const ch = inf && primeiroFilho5(inf, "chNFe", NFE_NS4);
|
|
3745
|
+
return ch !== undefined && textoDe2(ch).trim() === chave;
|
|
3746
|
+
}) ?? (prots.length === 1 ? prots[0] : undefined);
|
|
3747
|
+
}
|
|
3748
|
+
var EVENTO_VERSAO = "1.00";
|
|
3749
|
+
var XCONDUSO = "A Carta de Correção é disciplinada pelo § 1º-A do art. 7º do Convênio S/N, de 15 de dezembro de 1970 e pode ser utilizada para regularização de erro ocorrido na emissão de documento fiscal, desde que o erro não esteja relacionado com: I - as variáveis que determinam o valor do imposto tais como: base de cálculo, alíquota, diferença de preço, quantidade, valor da operação ou da prestação; II - a correção de dados cadastrais que implique mudança do remetente ou do destinatário; III - a data de emissão ou de saída.";
|
|
3750
|
+
var MANIFESTACOES = {
|
|
3751
|
+
confirmacao: { tpEvento: "210200", descEvento: "Confirmacao da Operacao", ct: TEventoConfirmacao },
|
|
3752
|
+
ciencia: { tpEvento: "210210", descEvento: "Ciencia da Operacao", ct: TEventoCiencia },
|
|
3753
|
+
desconhecimento: { tpEvento: "210220", descEvento: "Desconhecimento da Operacao", ct: TEventoDesconhecimento },
|
|
3754
|
+
"nao-realizada": { tpEvento: "210240", descEvento: "Operacao nao Realizada", ct: TEventoNaoRealizada }
|
|
3755
|
+
};
|
|
3756
|
+
function criarClienteNfe(opcoesDoCliente) {
|
|
3757
|
+
const logger = (opcoesDoCliente.logger ?? loggerSilencioso).child({
|
|
3758
|
+
modulo: "nfe",
|
|
3759
|
+
ambiente: opcoesDoCliente.ambiente
|
|
3760
|
+
});
|
|
3761
|
+
const sleep = opcoesDoCliente.esperar ?? defaultSleep;
|
|
3762
|
+
const tpAmb = tpAmbDoAmbiente3(opcoesDoCliente.ambiente);
|
|
3763
|
+
const ufInfo = opcoesDoCliente.uf === undefined ? undefined : ufPorSigla3(opcoesDoCliente.uf);
|
|
3764
|
+
if (opcoesDoCliente.uf !== undefined && !ufInfo)
|
|
3765
|
+
throw new ErroDeConfiguracao4(`UF inválida: ${String(opcoesDoCliente.uf)}`);
|
|
3766
|
+
const ufPadrao = (servico) => {
|
|
3767
|
+
if (opcoesDoCliente.uf === undefined || ufInfo === undefined) {
|
|
3768
|
+
throw new ErroDeConfiguracao4(`${servico} precisa da UF: informe ClienteNfeOpcoes.uf`);
|
|
3769
|
+
}
|
|
3770
|
+
return { uf: opcoesDoCliente.uf, cUF: ufInfo.cUF };
|
|
3771
|
+
};
|
|
3772
|
+
const offsetDe = (uf) => opcoesDoCliente.deslocamentoMin ?? deslocamentoDaUf(uf);
|
|
3773
|
+
const idLote = () => {
|
|
3774
|
+
const id = opcoesDoCliente.idLote ? opcoesDoCliente.idLote() : String(opcoesDoCliente.relogio.agora().getTime()).slice(-15);
|
|
3775
|
+
if (!/^[0-9]{1,15}$/.test(id))
|
|
3776
|
+
throw new ErroDeConfiguracao4(`idLote inválido: ${id}`);
|
|
3777
|
+
return id;
|
|
3778
|
+
};
|
|
3779
|
+
const endpointNfce = (servico, uf) => opcoesDoCliente.endpointNfce ? opcoesDoCliente.endpointNfce(servico, uf) : nfceEndpoint({ ambiente: opcoesDoCliente.ambiente, servico, uf });
|
|
3780
|
+
const endpoint = (servico, mod = "55") => {
|
|
3781
|
+
const { uf } = ufPadrao(servico);
|
|
3782
|
+
if (mod === "65")
|
|
3783
|
+
return endpointNfce(servico, uf);
|
|
3784
|
+
return nfeEndpoint({
|
|
3785
|
+
ambiente: opcoesDoCliente.ambiente,
|
|
3786
|
+
servico,
|
|
3787
|
+
uf,
|
|
3788
|
+
...opcoesDoCliente.contingencia === undefined ? {} : { contingencia: opcoesDoCliente.contingencia }
|
|
3789
|
+
});
|
|
3790
|
+
};
|
|
3791
|
+
const endpointDaChave = (servico, c, naUf = false) => {
|
|
3792
|
+
if (c.mod === "65")
|
|
3793
|
+
return endpointNfce(servico, c.uf);
|
|
3794
|
+
const svc = naUf || c.tpEmis === undefined ? undefined : SVC_DO_TPEMIS[c.tpEmis];
|
|
3795
|
+
return nfeEndpoint({
|
|
3796
|
+
ambiente: opcoesDoCliente.ambiente,
|
|
3797
|
+
servico,
|
|
3798
|
+
...svc === undefined ? { uf: c.uf } : { autorizador: svc }
|
|
3799
|
+
});
|
|
3800
|
+
};
|
|
3801
|
+
const call = (ep, servico, mensagem, retorno, signal) => chamar({
|
|
3802
|
+
transport: opcoesDoCliente.transporte,
|
|
3803
|
+
endpoint: ep,
|
|
3804
|
+
servico,
|
|
3805
|
+
mensagem,
|
|
3806
|
+
retorno,
|
|
3807
|
+
logger,
|
|
3808
|
+
...opcoesDoCliente.timeoutMs === undefined ? {} : { timeoutMs: opcoesDoCliente.timeoutMs },
|
|
3809
|
+
...signal === undefined ? {} : { signal }
|
|
3810
|
+
});
|
|
3811
|
+
const autorPadrao = (a, path) => {
|
|
3812
|
+
const autor = a ?? opcoesDoCliente.autor;
|
|
3813
|
+
if (!autor)
|
|
3814
|
+
throw new ErroDeConfiguracao4(`informe o CNPJ ou CPF do autor (${path} ou ClienteNfeOpcoes.autor)`);
|
|
3815
|
+
return documentoAutor(autor, path);
|
|
3816
|
+
};
|
|
3817
|
+
async function consultarRecibo(nRec, nfeAssinada, opcoes = {}) {
|
|
3818
|
+
if (!/^[0-9]{15}$/.test(nRec))
|
|
3819
|
+
throw new ErroDeConfiguracao4(`número de recibo inválido: ${nRec}`);
|
|
3820
|
+
const a = nfeAssinada === undefined ? undefined : documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
3821
|
+
const c = a === undefined ? undefined : chaveDoDocumento(a);
|
|
3822
|
+
if (c !== undefined && opcoes.mod !== undefined && opcoes.mod !== c.mod) {
|
|
3823
|
+
throw new ErroDeConfiguracao4(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
|
|
3824
|
+
}
|
|
3825
|
+
const msg = envelope("consReciNFe", "4.00", [`<tpAmb>${tpAmb}</tpAmb><nRec>${nRec}</nRec>`]);
|
|
3826
|
+
const ep = c === undefined ? endpoint("NFeRetAutorizacao", opcoes.mod ?? "55") : endpointDaChave("NFeRetAutorizacao", c);
|
|
3827
|
+
const r = await call(ep, "NFeRetAutorizacao", msg, "retConsReciNFe", opcoes.signal);
|
|
3828
|
+
const v = decodificar(TRetConsReciNFe, r.ret, r.doc.texto).valor;
|
|
3829
|
+
if (v.nRec !== undefined && v.nRec !== nRec) {
|
|
3830
|
+
throw new ErroRespostaInvalida4("retorno de outro recibo", { detalhes: { nRec: v.nRec } });
|
|
3831
|
+
}
|
|
3832
|
+
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3833
|
+
logger.info("nfe.recibo", { nRec, cStat: v.cStat });
|
|
3834
|
+
if (cstatEm(v.cStat, "loteEmProcessamento") || cstatEm(v.cStat, "loteRecebido"))
|
|
3835
|
+
return criarPendente(status, { referencia: nRec });
|
|
3836
|
+
if (cstatEm(v.cStat, "loteProcessado")) {
|
|
3837
|
+
const el = protNFeDaChave(r.ret, a);
|
|
3838
|
+
if (!el)
|
|
3839
|
+
throw new ErroRespostaInvalida4("lote processado sem o protNFe da NF-e", { detalhes: { nRec } });
|
|
3840
|
+
return desfechoDoProtocolo(lerProtocolo(r.doc, el), a);
|
|
3841
|
+
}
|
|
3842
|
+
return rejeitado(status);
|
|
3843
|
+
}
|
|
3844
|
+
async function consultar(chave, nfeAssinada, opcoes) {
|
|
3845
|
+
const c = chaveValida(chave, "chNFe");
|
|
3846
|
+
const a = nfeAssinada === undefined ? undefined : documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
3847
|
+
if (a && a.id !== `NFe${c.chave}`)
|
|
3848
|
+
throw new ErroDeConfiguracao4("a NF-e assinada não é a da chave consultada");
|
|
3849
|
+
const msg = serializarRaiz(consSitNFeElement, { versao: "4.00", tpAmb, xServ: "CONSULTAR", chNFe: c.chave });
|
|
3850
|
+
const ep = endpointDaChave("NfeConsultaProtocolo", c);
|
|
3851
|
+
const r = await call(ep, "NfeConsultaProtocolo", msg, "retConsSitNFe", opcoes?.signal);
|
|
3852
|
+
const v = decodificar(TRetConsSitNFe, r.ret, r.doc.texto).valor;
|
|
3853
|
+
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3854
|
+
logger.info("nfe.consulta", { chNFe: c.chave, cStat: v.cStat });
|
|
3855
|
+
const situacao = cstatEm(v.cStat, "autorizada") ? "autorizada" : cstatEm(v.cStat, "cancelada") ? "cancelada" : cstatEm(v.cStat, "denegada") ? "denegada" : undefined;
|
|
3856
|
+
if (situacao === undefined)
|
|
3857
|
+
return rejeitado(status);
|
|
3858
|
+
const protEl = primeiroFilho5(r.ret, "protNFe", NFE_NS4);
|
|
3859
|
+
const eventos = elementosFilhos2(r.ret).filter((e) => e.local === "procEventoNFe" && e.ns === NFE_NS4).map((e) => avulso(r.doc, e));
|
|
3860
|
+
let protocolo;
|
|
3861
|
+
let digValConfere;
|
|
3862
|
+
if (protEl) {
|
|
3863
|
+
const { p, embutido } = lerProtocolo(r.doc, protEl);
|
|
3864
|
+
if (p.chNFe !== c.chave) {
|
|
3865
|
+
throw new ErroRespostaInvalida4("protocolo de outra chave de acesso na consulta", {
|
|
3866
|
+
detalhes: { chNFe: p.chNFe }
|
|
3867
|
+
});
|
|
3868
|
+
}
|
|
3869
|
+
protocolo = p;
|
|
3870
|
+
if (a) {
|
|
3871
|
+
digValConfere = p.digVal !== undefined && p.digVal === a.digestValue;
|
|
3872
|
+
if (digValConfere)
|
|
3873
|
+
protocolo = { ...p, nfeProc: envelope("nfeProc", "4.00", [a.xml, embutido]) };
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
const value = {
|
|
3877
|
+
chNFe: c.chave,
|
|
3878
|
+
situacao,
|
|
3879
|
+
eventos,
|
|
3880
|
+
...protocolo === undefined ? {} : { protocolo },
|
|
3881
|
+
...digValConfere === undefined ? {} : { digValConfere }
|
|
3882
|
+
};
|
|
3883
|
+
return situacao === "denegada" ? criarDenegado(status, value) : criarAutorizado(status, value);
|
|
3884
|
+
}
|
|
3885
|
+
async function enviarEvento(p) {
|
|
3886
|
+
const nSeq = p.nSeqEvento;
|
|
3887
|
+
if (!Number.isInteger(nSeq) || nSeq < 1 || nSeq > 99)
|
|
3888
|
+
throw new ErroDeConfiguracao4(`nSeqEvento inválido: ${nSeq}`);
|
|
3889
|
+
const nSeqEvento = String(nSeq);
|
|
3890
|
+
const id = `ID${p.tpEvento}${p.chave}${nSeqEvento.padStart(2, "0")}`;
|
|
3891
|
+
const inf = {
|
|
3892
|
+
Id: id,
|
|
3893
|
+
cOrgao: p.cOrgao,
|
|
3894
|
+
tpAmb,
|
|
3895
|
+
...p.autor,
|
|
3896
|
+
chNFe: p.chave,
|
|
3897
|
+
dhEvento: formatarDh(opcoesDoCliente.relogio.agora(), p.offsetMinutes),
|
|
3898
|
+
tpEvento: p.tpEvento,
|
|
3899
|
+
nSeqEvento,
|
|
3900
|
+
verEvento: EVENTO_VERSAO,
|
|
3901
|
+
detEvento: p.detEvento
|
|
3902
|
+
};
|
|
3903
|
+
const infXml = serializar3(p.ct, "infEvento", inf, NFE_NS4);
|
|
3904
|
+
const evento = `<evento xmlns="${NFE_NS4}" versao="${EVENTO_VERSAO}">${infXml}</evento>`;
|
|
3905
|
+
const infEl = primeiroFilho5(lerXml6(evento).raiz, "infEvento", NFE_NS4);
|
|
3906
|
+
schemaIssues("evento", validar4(p.ct, infEl));
|
|
3907
|
+
const assinado = await assinarXml2(evento, { id }, opcoesDoCliente.assinador);
|
|
3908
|
+
const msg = envelope("envEvento", EVENTO_VERSAO, [`<idLote>${idLote()}</idLote>`, assinado]);
|
|
3909
|
+
const r = await call(p.endpoint, "RecepcaoEvento", msg, "retEnvEvento", p.signal);
|
|
3910
|
+
const v = decodificar(TRetEnvEvento, r.ret, r.doc.texto).valor;
|
|
3911
|
+
logger.info("nfe.evento", { chNFe: p.chave, tpEvento: p.tpEvento, cStat: v.cStat });
|
|
3912
|
+
if (!cstatEm(v.cStat, "loteEventoProcessado"))
|
|
3913
|
+
return rejeitado({ cStat: v.cStat, xMotivo: v.xMotivo });
|
|
3914
|
+
const retEl = elementosFilhos2(r.ret).find((e) => e.local === "retEvento" && e.ns === NFE_NS4);
|
|
3915
|
+
const ret = v.retEvento?.[0]?.infEvento;
|
|
3916
|
+
if (!retEl || !ret)
|
|
3917
|
+
throw new ErroRespostaInvalida4("lote de evento processado sem retEvento");
|
|
3918
|
+
const divergentes = [
|
|
3919
|
+
["chNFe", ret.chNFe, p.chave],
|
|
3920
|
+
["tpEvento", ret.tpEvento, p.tpEvento],
|
|
3921
|
+
["nSeqEvento", ret.nSeqEvento === undefined ? undefined : String(Number(ret.nSeqEvento)), nSeqEvento]
|
|
3922
|
+
].filter(([, veio, enviado]) => veio !== undefined && veio !== enviado);
|
|
3923
|
+
if (divergentes.length > 0) {
|
|
3924
|
+
throw new ErroRespostaInvalida4("retEvento de outro evento", {
|
|
3925
|
+
detalhes: Object.fromEntries(divergentes.map(([k, veio]) => [k, veio]))
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3928
|
+
const status = { cStat: ret.cStat, xMotivo: ret.xMotivo };
|
|
3929
|
+
if (!cstatEm(ret.cStat, "eventoRegistrado"))
|
|
3930
|
+
return rejeitado(status);
|
|
3931
|
+
return criarAutorizado(status, {
|
|
3932
|
+
chNFe: p.chave,
|
|
3933
|
+
tpEvento: p.tpEvento,
|
|
3934
|
+
nSeqEvento,
|
|
3935
|
+
dhRegEvento: ret.dhRegEvento,
|
|
3936
|
+
retEvento: avulso(r.doc, retEl),
|
|
3937
|
+
procEventoNFe: envelope("procEventoNFe", EVENTO_VERSAO, [assinado, recortarElemento(r.doc, retEl)]),
|
|
3938
|
+
...ret.nProt === undefined ? {} : { nProt: ret.nProt }
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
const client = {
|
|
3942
|
+
opcoes: opcoesDoCliente,
|
|
3943
|
+
async statusServico(opcoes) {
|
|
3944
|
+
const { cUF } = ufPadrao("NfeStatusServico");
|
|
3945
|
+
const msg = serializarRaiz(consStatServElement, { versao: "4.00", tpAmb, cUF, xServ: "STATUS" });
|
|
3946
|
+
const r = await call(endpoint("NfeStatusServico", opcoes?.mod), "NfeStatusServico", msg, "retConsStatServ", opcoes?.signal);
|
|
3947
|
+
const v = decodificar(TRetConsStatServ, r.ret, r.doc.texto).valor;
|
|
3948
|
+
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3949
|
+
logger.info("nfe.status", { cStat: v.cStat });
|
|
3950
|
+
if (!cstatEm(v.cStat, "servicoEmOperacao"))
|
|
3951
|
+
return rejeitado(status);
|
|
3952
|
+
return criarAutorizado(status, {
|
|
3953
|
+
cUF: v.cUF,
|
|
3954
|
+
verAplic: v.verAplic,
|
|
3955
|
+
dhRecbto: v.dhRecbto,
|
|
3956
|
+
...v.tMed === undefined ? {} : { tMed: v.tMed },
|
|
3957
|
+
...v.dhRetorno === undefined ? {} : { dhRetorno: v.dhRetorno },
|
|
3958
|
+
...v.xObs === undefined ? {} : { xObs: v.xObs }
|
|
3959
|
+
});
|
|
3960
|
+
},
|
|
3961
|
+
async autorizar(nfeAssinada, opcoes = {}) {
|
|
3962
|
+
const a = documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
3963
|
+
const sincrono = opcoes.sincrono ?? true;
|
|
3964
|
+
const msg = envelope("enviNFe", "4.00", [
|
|
3965
|
+
`<idLote>${idLote()}</idLote><indSinc>${sincrono ? "1" : "0"}</indSinc>`,
|
|
3966
|
+
a.xml
|
|
3967
|
+
]);
|
|
3968
|
+
const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a));
|
|
3969
|
+
const r = await call(ep, "NFeAutorizacao", msg, "retEnviNFe", opcoes.signal);
|
|
3970
|
+
const v = decodificar(TRetEnviNFe, r.ret, r.doc.texto).valor;
|
|
3971
|
+
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3972
|
+
logger.info("nfe.autorizacao", { chNFe: a.id.slice(3), cStat: v.cStat, sincrono });
|
|
3973
|
+
if (cstatEm(v.cStat, "loteRecebido")) {
|
|
3974
|
+
const nRec = v.infRec?.nRec;
|
|
3975
|
+
if (!nRec)
|
|
3976
|
+
throw new ErroRespostaInvalida4("lote recebido sem número de recibo");
|
|
3977
|
+
const tMed = Number(v.infRec?.tMed ?? "0");
|
|
3978
|
+
return criarPendente(status, { referencia: nRec, aguardarMs: Math.max(1, tMed) * 1000 });
|
|
3979
|
+
}
|
|
3980
|
+
const protEl = protNFeDaChave(r.ret, a);
|
|
3981
|
+
if (protEl)
|
|
3982
|
+
return desfechoDoProtocolo(lerProtocolo(r.doc, protEl), a);
|
|
3983
|
+
return rejeitado(status);
|
|
3984
|
+
},
|
|
3985
|
+
consultarRecibo,
|
|
3986
|
+
async aguardarRecibo(nRec, nfeAssinada, politica = {}) {
|
|
3987
|
+
const max = politica.maxTentativas ?? 10;
|
|
3988
|
+
const minimo = politica.esperaMinimaMs ?? 2000;
|
|
3989
|
+
const mult = politica.multiplicador ?? 1.5;
|
|
3990
|
+
const teto = politica.esperaMaximaMs ?? 30000;
|
|
3991
|
+
if (!(max >= 1) || !(minimo >= 0) || !(mult >= 1) || !(teto >= minimo)) {
|
|
3992
|
+
throw new ErroDeConfiguracao4("política de consulta do recibo inválida", {
|
|
3993
|
+
detalhes: { max, minimo, mult, teto }
|
|
3994
|
+
});
|
|
3995
|
+
}
|
|
3996
|
+
let espera = minimo;
|
|
3997
|
+
let ultimo;
|
|
3998
|
+
for (let i = 0;i < max; i++) {
|
|
3999
|
+
await sleep(espera, politica.signal);
|
|
4000
|
+
ultimo = await consultarRecibo(nRec, nfeAssinada, politica);
|
|
4001
|
+
if (ultimo.tipo !== "pendente")
|
|
4002
|
+
return ultimo;
|
|
4003
|
+
espera = Math.min(teto, Math.max(minimo, Math.round(espera * mult), ultimo.aguardarMs ?? 0));
|
|
4004
|
+
}
|
|
4005
|
+
return ultimo;
|
|
4006
|
+
},
|
|
4007
|
+
consultar,
|
|
4008
|
+
async cancelar(p, opcoes) {
|
|
4009
|
+
const c = chaveValida(p.chave, "chave");
|
|
4010
|
+
return enviarEvento({
|
|
4011
|
+
ct: TEventoCanc,
|
|
4012
|
+
tpEvento: "110111",
|
|
4013
|
+
chave: c.chave,
|
|
4014
|
+
nSeqEvento: 1,
|
|
4015
|
+
cOrgao: c.cUF,
|
|
4016
|
+
autor: autorDoEmitente(p.autor, c),
|
|
4017
|
+
detEvento: { versao: EVENTO_VERSAO, descEvento: "Cancelamento", nProt: p.nProt, xJust: p.xJust },
|
|
4018
|
+
endpoint: endpointDaChave("RecepcaoEvento", c),
|
|
4019
|
+
offsetMinutes: offsetDe(c.uf),
|
|
4020
|
+
signal: opcoes?.signal
|
|
4021
|
+
});
|
|
4022
|
+
},
|
|
4023
|
+
async cancelarPorSubstituicao(p, opcoes) {
|
|
4024
|
+
const c = chaveValida(p.chave, "chave");
|
|
4025
|
+
if (c.mod !== "65") {
|
|
4026
|
+
throw new ErroDeValidacao2("cancelamento por substituição só existe para NFC-e", [
|
|
4027
|
+
{
|
|
4028
|
+
caminho: "chave",
|
|
4029
|
+
code: "modelo_nao_suportado",
|
|
4030
|
+
mensagem: "O evento 110112 é exclusivo da NFC-e (modelo 65)"
|
|
4031
|
+
}
|
|
4032
|
+
]);
|
|
4033
|
+
}
|
|
4034
|
+
const ref = chaveValida(p.chNFeRef, "chNFeRef");
|
|
4035
|
+
const detEvento = {
|
|
4036
|
+
versao: EVENTO_VERSAO,
|
|
4037
|
+
descEvento: "Cancelamento por substituicao",
|
|
4038
|
+
cOrgaoAutor: p.cOrgaoAutor,
|
|
4039
|
+
tpAutor: p.tpAutor ?? "1",
|
|
4040
|
+
verAplic: p.verAplic,
|
|
4041
|
+
nProt: p.nProt,
|
|
4042
|
+
xJust: p.xJust,
|
|
4043
|
+
chNFeRef: ref.chave
|
|
4044
|
+
};
|
|
4045
|
+
return enviarEvento({
|
|
4046
|
+
ct: TEventoCancSubst,
|
|
4047
|
+
tpEvento: "110112",
|
|
4048
|
+
chave: c.chave,
|
|
4049
|
+
nSeqEvento: 1,
|
|
4050
|
+
cOrgao: c.cUF,
|
|
4051
|
+
autor: autorDoEmitente(p.autor, c),
|
|
4052
|
+
detEvento,
|
|
4053
|
+
endpoint: endpointDaChave("RecepcaoEvento", c),
|
|
4054
|
+
offsetMinutes: offsetDe(c.uf),
|
|
4055
|
+
signal: opcoes?.signal
|
|
4056
|
+
});
|
|
4057
|
+
},
|
|
4058
|
+
async cartaCorrecao(p, opcoes) {
|
|
4059
|
+
const c = chaveValida(p.chave, "chave");
|
|
4060
|
+
if (!Number.isInteger(p.nSeqEvento) || p.nSeqEvento < 1 || p.nSeqEvento > 20) {
|
|
4061
|
+
throw new ErroDeConfiguracao4(`nSeqEvento da CC-e vai de 1 a 20: ${p.nSeqEvento}`);
|
|
4062
|
+
}
|
|
4063
|
+
return enviarEvento({
|
|
4064
|
+
ct: TEventoCce,
|
|
4065
|
+
tpEvento: "110110",
|
|
4066
|
+
chave: c.chave,
|
|
4067
|
+
nSeqEvento: p.nSeqEvento,
|
|
4068
|
+
cOrgao: c.cUF,
|
|
4069
|
+
autor: autorDoEmitente(p.autor, c),
|
|
4070
|
+
detEvento: {
|
|
4071
|
+
versao: EVENTO_VERSAO,
|
|
4072
|
+
descEvento: "Carta de Correção",
|
|
4073
|
+
xCorrecao: p.xCorrecao,
|
|
4074
|
+
xCondUso: XCONDUSO
|
|
4075
|
+
},
|
|
4076
|
+
endpoint: endpointDaChave("RecepcaoEvento", c, true),
|
|
4077
|
+
offsetMinutes: offsetDe(c.uf),
|
|
4078
|
+
signal: opcoes?.signal
|
|
4079
|
+
});
|
|
4080
|
+
},
|
|
4081
|
+
async manifestar(p, opcoes) {
|
|
4082
|
+
const c = chaveValida(p.chave, "chave");
|
|
4083
|
+
const m = MANIFESTACOES[p.tipo];
|
|
4084
|
+
if (!m)
|
|
4085
|
+
throw new ErroDeConfiguracao4(`tipo de manifestação desconhecido: ${String(p.tipo)}`);
|
|
4086
|
+
return enviarEvento({
|
|
4087
|
+
ct: m.ct,
|
|
4088
|
+
tpEvento: m.tpEvento,
|
|
4089
|
+
chave: c.chave,
|
|
4090
|
+
nSeqEvento: 1,
|
|
4091
|
+
cOrgao: "91",
|
|
4092
|
+
autor: autorPadrao(p.autor, "autor"),
|
|
4093
|
+
detEvento: {
|
|
4094
|
+
versao: EVENTO_VERSAO,
|
|
4095
|
+
descEvento: m.descEvento,
|
|
4096
|
+
...p.xJust === undefined ? {} : { xJust: p.xJust }
|
|
4097
|
+
},
|
|
4098
|
+
endpoint: nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: "RecepcaoEvento", autorizador: "AN" }),
|
|
4099
|
+
offsetMinutes: offsetDe(opcoesDoCliente.uf ?? c.uf),
|
|
4100
|
+
signal: opcoes?.signal
|
|
4101
|
+
});
|
|
4102
|
+
},
|
|
4103
|
+
async inutilizar(p, opcoes) {
|
|
4104
|
+
const autor = autorPadrao(p.autor, "autor");
|
|
4105
|
+
if (!("CNPJ" in autor)) {
|
|
4106
|
+
throw new ErroDeValidacao2("inutilização não se aplica ao emitente pessoa física", [
|
|
4107
|
+
{
|
|
4108
|
+
caminho: "autor.CPF",
|
|
4109
|
+
code: "inutilizacao_emitente_cpf",
|
|
4110
|
+
mensagem: "O pedido de inutilização só existe para emitente CNPJ (NT 2018.001 v1.10, item 6.1)"
|
|
4111
|
+
}
|
|
4112
|
+
]);
|
|
4113
|
+
}
|
|
4114
|
+
const cnpj = autor.CNPJ;
|
|
4115
|
+
const { uf, cUF } = ufPadrao("NfeInutilizacao");
|
|
4116
|
+
const anoTxt = String(p.ano);
|
|
4117
|
+
const ano = anoTxt.length === 4 ? anoTxt.slice(2) : anoTxt.padStart(2, "0");
|
|
4118
|
+
const mod = p.mod ?? "55";
|
|
4119
|
+
const serie = String(p.serie);
|
|
4120
|
+
const ini = String(p.nNFIni);
|
|
4121
|
+
const fin = String(p.nNFFin);
|
|
4122
|
+
for (const [k, x, re] of [
|
|
4123
|
+
["ano", ano, /^[0-9]{2}$/],
|
|
4124
|
+
["serie", serie, /^(0|[1-9][0-9]{0,2})$/],
|
|
4125
|
+
["nNFIni", ini, /^[1-9][0-9]{0,8}$/],
|
|
4126
|
+
["nNFFin", fin, /^[1-9][0-9]{0,8}$/]
|
|
4127
|
+
]) {
|
|
4128
|
+
if (!re.test(x))
|
|
4129
|
+
throw new ErroDeConfiguracao4(`${k} inválido para inutilização: ${x}`);
|
|
4130
|
+
}
|
|
4131
|
+
if (Number(fin) < Number(ini))
|
|
4132
|
+
throw new ErroDeConfiguracao4("nNFFin menor que nNFIni");
|
|
4133
|
+
if (Number(serie) >= 910 && Number(serie) <= 969) {
|
|
4134
|
+
throw new ErroDeValidacao2("série de emitente pessoa física não se inutiliza", [
|
|
4135
|
+
{
|
|
4136
|
+
caminho: "serie",
|
|
4137
|
+
code: "inutilizacao_serie_cpf",
|
|
4138
|
+
mensagem: "Série 910 a 969 identifica emitente CPF: a SEFAZ rejeita com 266 (NT 2018.001 v1.10, regra I02a)"
|
|
4139
|
+
}
|
|
4140
|
+
]);
|
|
4141
|
+
}
|
|
4142
|
+
const id = `ID${cUF}${ano}${cnpj}${mod}${serie.padStart(3, "0")}${ini.padStart(9, "0")}${fin.padStart(9, "0")}`;
|
|
4143
|
+
const inf = {
|
|
4144
|
+
Id: id,
|
|
4145
|
+
tpAmb,
|
|
4146
|
+
xServ: "INUTILIZAR",
|
|
4147
|
+
cUF,
|
|
4148
|
+
ano,
|
|
4149
|
+
CNPJ: cnpj,
|
|
4150
|
+
mod,
|
|
4151
|
+
serie,
|
|
4152
|
+
nNFIni: ini,
|
|
4153
|
+
nNFFin: fin,
|
|
4154
|
+
xJust: p.xJust
|
|
4155
|
+
};
|
|
4156
|
+
const infXml = serializar3(TInutNFe_infInut, "infInut", inf, NFE_NS4);
|
|
4157
|
+
const inut = envelope("inutNFe", "4.00", [infXml]);
|
|
4158
|
+
const infEl = primeiroFilho5(lerXml6(inut).raiz, "infInut", NFE_NS4);
|
|
4159
|
+
schemaIssues("pedido de inutilização", validar4(TInutNFe_infInut, infEl));
|
|
4160
|
+
const assinado = await assinarXml2(inut, { id }, opcoesDoCliente.assinador);
|
|
4161
|
+
const ep = mod === "65" ? endpointNfce("NfeInutilizacao", uf) : nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: "NfeInutilizacao", uf });
|
|
4162
|
+
const r = await call(ep, "NfeInutilizacao", assinado, "retInutNFe", opcoes?.signal);
|
|
4163
|
+
const v = decodificar(TRetInutNFe, r.ret, r.doc.texto).valor;
|
|
4164
|
+
const status = { cStat: v.infInut.cStat, xMotivo: v.infInut.xMotivo };
|
|
4165
|
+
logger.info("nfe.inutilizacao", { id, cStat: status.cStat });
|
|
4166
|
+
if (!cstatEm(status.cStat, "inutilizacaoHomologada"))
|
|
4167
|
+
return rejeitado(status);
|
|
4168
|
+
const r0 = v.infInut;
|
|
4169
|
+
const n = (x) => x === undefined ? undefined : String(Number(x));
|
|
4170
|
+
const confere = [
|
|
4171
|
+
["ano", r0.ano, ano],
|
|
4172
|
+
["CNPJ", r0.CNPJ ?? r0.CPF, cnpj],
|
|
4173
|
+
["mod", r0.mod, mod],
|
|
4174
|
+
["serie", n(r0.serie), String(Number(serie))],
|
|
4175
|
+
["nNFIni", n(r0.nNFIni), String(Number(ini))],
|
|
4176
|
+
["nNFFin", n(r0.nNFFin), String(Number(fin))]
|
|
4177
|
+
];
|
|
4178
|
+
const fora = confere.filter(([, veio, pedido]) => veio !== undefined && veio !== pedido);
|
|
4179
|
+
if (fora.length > 0) {
|
|
4180
|
+
throw new ErroRespostaInvalida4("retInutNFe de outra faixa", {
|
|
4181
|
+
detalhes: Object.fromEntries(fora.map(([k, v]) => [k, v]))
|
|
4182
|
+
});
|
|
4183
|
+
}
|
|
4184
|
+
return criarAutorizado(status, {
|
|
4185
|
+
dhRecbto: v.infInut.dhRecbto,
|
|
4186
|
+
retInutNFe: avulso(r.doc, r.ret),
|
|
4187
|
+
procInutNFe: envelope("ProcInutNFe", "4.00", [assinado, recortarElemento(r.doc, r.ret)]),
|
|
4188
|
+
...v.infInut.nProt === undefined ? {} : { nProt: v.infInut.nProt }
|
|
4189
|
+
});
|
|
4190
|
+
},
|
|
4191
|
+
async consultarCadastro(p, opcoes) {
|
|
4192
|
+
const doc = "CNPJ" in p ? documentoAutor({ CNPJ: p.CNPJ }, "CNPJ") : ("CPF" in p) ? documentoAutor({ CPF: p.CPF }, "CPF") : { IE: p.IE.replace(/[^0-9A-Za-z]/g, "").toUpperCase() };
|
|
4193
|
+
const msg = serializarRaiz(ConsCadElement, { versao: "2.00", infCons: { xServ: "CONS-CAD", UF: p.uf, ...doc } });
|
|
4194
|
+
const ep = nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: "NfeConsultaCadastro", uf: p.uf });
|
|
4195
|
+
const r = await call(ep, "NfeConsultaCadastro", msg, "retConsCad", opcoes?.signal);
|
|
4196
|
+
const v = decodificar(TRetConsCad, r.ret, r.doc.texto).valor;
|
|
4197
|
+
const i = v.infCons;
|
|
4198
|
+
const status = { cStat: i.cStat, xMotivo: i.xMotivo };
|
|
4199
|
+
logger.info("nfe.cadastro", { uf: p.uf, cStat: i.cStat });
|
|
4200
|
+
if (!cstatEm(i.cStat, "cadastroEncontrado"))
|
|
4201
|
+
return rejeitado(status);
|
|
4202
|
+
return criarAutorizado(status, { UF: i.UF, dhCons: i.dhCons, infCad: i.infCad ?? [] });
|
|
4203
|
+
},
|
|
4204
|
+
async distribuicaoDFe(consulta, opcoes = {}) {
|
|
4205
|
+
const autor = autorPadrao(opcoes.autor, "autor");
|
|
4206
|
+
const nsu = (x, k) => {
|
|
4207
|
+
const s = String(x);
|
|
4208
|
+
if (!/^[0-9]{1,15}$/.test(s))
|
|
4209
|
+
throw new ErroDeConfiguracao4(`${k} inválido: ${s}`);
|
|
4210
|
+
return s.padStart(15, "0");
|
|
4211
|
+
};
|
|
4212
|
+
const grupo = "ultNSU" in consulta ? { distNSU: { ultNSU: nsu(consulta.ultNSU, "ultNSU") } } : ("NSU" in consulta) ? { consNSU: { NSU: nsu(consulta.NSU, "NSU") } } : { consChNFe: { chNFe: chaveValida(consulta.chNFe, "chNFe").chave } };
|
|
4213
|
+
const cUFAutor = opcoes.cUFAutor ?? ufPadrao("NFeDistribuicaoDFe").cUF;
|
|
4214
|
+
if (ufPorCUf2(cUFAutor) === undefined)
|
|
4215
|
+
throw new ErroDeConfiguracao4(`cUFAutor inválido: ${cUFAutor}`);
|
|
4216
|
+
const msg = serializarRaiz(distDFeIntElement, {
|
|
4217
|
+
versao: "1.01",
|
|
4218
|
+
tpAmb,
|
|
4219
|
+
cUFAutor,
|
|
4220
|
+
...autor,
|
|
4221
|
+
...grupo
|
|
4222
|
+
});
|
|
4223
|
+
const ep = nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: "NFeDistribuicaoDFe" });
|
|
4224
|
+
const r = await call(ep, "NFeDistribuicaoDFe", msg, "retDistDFeInt", opcoes.signal);
|
|
4225
|
+
const v = decodificar(retDistDFeInt, r.ret, r.doc.texto).valor;
|
|
4226
|
+
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
4227
|
+
logger.info("nfe.distribuicao", { cStat: v.cStat, ultNSU: v.ultNSU, maxNSU: v.maxNSU });
|
|
4228
|
+
const base = { ultNSU: v.ultNSU, maxNSU: v.maxNSU, dhResp: v.dhResp };
|
|
4229
|
+
if (cstatEm(v.cStat, "distribuicaoNenhumDocumento"))
|
|
4230
|
+
return criarAutorizado(status, { ...base, documentos: [] });
|
|
4231
|
+
if (!cstatEm(v.cStat, "distribuicaoDocumentos"))
|
|
4232
|
+
return rejeitado(status);
|
|
4233
|
+
const documentos = [];
|
|
4234
|
+
for (const z of v.loteDistDFeInt?.docZip ?? []) {
|
|
4235
|
+
const xml = await descomprimirGzipBase64(z.$text);
|
|
4236
|
+
documentos.push(documentoDistribuido(z.NSU ?? "", z.schema, xml));
|
|
4237
|
+
}
|
|
4238
|
+
return criarAutorizado(status, { ...base, documentos });
|
|
4239
|
+
}
|
|
4240
|
+
};
|
|
4241
|
+
return client;
|
|
4242
|
+
}
|
|
4243
|
+
function documentoDistribuido(NSU, schema, xml) {
|
|
4244
|
+
const nome = schema.replace(/_v?\d.*$/, "");
|
|
4245
|
+
const base = { NSU, schema, xml };
|
|
4246
|
+
if (nome === "resNFe")
|
|
4247
|
+
return { ...base, tipo: "resNFe", resNFe: decodificarXml(resNFeElement, xml).valor };
|
|
4248
|
+
if (nome === "resEvento")
|
|
4249
|
+
return { ...base, tipo: "resEvento", resEvento: decodificarXml(resEventoElement, xml).valor };
|
|
4250
|
+
if (nome === "procNFe")
|
|
4251
|
+
return { ...base, tipo: "procNFe" };
|
|
4252
|
+
if (nome === "procEventoNFe")
|
|
4253
|
+
return { ...base, tipo: "procEventoNFe" };
|
|
4254
|
+
return { ...base, tipo: "outro" };
|
|
4255
|
+
}
|
|
4256
|
+
// packages/nfe/src/services/recuperar.ts
|
|
4257
|
+
import { lerXml as lerXml7, primeiroFilho as primeiroFilho6, textoDe as textoDe3 } from "@sinete/core/xml";
|
|
4258
|
+
function campo(el, local) {
|
|
4259
|
+
const c = primeiroFilho6(el, local, NFE_NS4);
|
|
4260
|
+
return c === undefined ? undefined : textoDe3(c).trim();
|
|
4261
|
+
}
|
|
4262
|
+
function lerProcEvento(xml) {
|
|
4263
|
+
let doc;
|
|
4264
|
+
try {
|
|
4265
|
+
doc = lerXml7(xml);
|
|
4266
|
+
} catch {
|
|
4267
|
+
return;
|
|
4268
|
+
}
|
|
4269
|
+
const evento = primeiroFilho6(doc.raiz, "evento", NFE_NS4);
|
|
4270
|
+
const pedido = evento === undefined ? undefined : primeiroFilho6(evento, "infEvento", NFE_NS4);
|
|
4271
|
+
const retEl = primeiroFilho6(doc.raiz, "retEvento", NFE_NS4);
|
|
4272
|
+
const ret = retEl === undefined ? undefined : primeiroFilho6(retEl, "infEvento", NFE_NS4);
|
|
4273
|
+
if (doc.raiz.local !== "procEventoNFe" || pedido === undefined || retEl === undefined || ret === undefined) {
|
|
4274
|
+
return;
|
|
4275
|
+
}
|
|
4276
|
+
const cStat = campo(ret, "cStat");
|
|
4277
|
+
const chNFe = campo(ret, "chNFe");
|
|
4278
|
+
const tpEvento = campo(ret, "tpEvento");
|
|
4279
|
+
const nSeq = campo(ret, "nSeqEvento");
|
|
4280
|
+
const dhRegEvento = campo(ret, "dhRegEvento");
|
|
4281
|
+
if (cStat === undefined || !cstatEm(cStat, "eventoRegistrado"))
|
|
4282
|
+
return;
|
|
4283
|
+
if (chNFe === undefined || tpEvento === undefined || nSeq === undefined)
|
|
4284
|
+
return;
|
|
4285
|
+
const nSeqPedido = campo(pedido, "nSeqEvento");
|
|
4286
|
+
if (campo(pedido, "chNFe") !== chNFe || campo(pedido, "tpEvento") !== tpEvento)
|
|
4287
|
+
return;
|
|
4288
|
+
if (nSeqPedido === undefined || Number(nSeqPedido) !== Number(nSeq))
|
|
4289
|
+
return;
|
|
4290
|
+
if (chNFe === undefined || tpEvento === undefined || nSeq === undefined || dhRegEvento === undefined)
|
|
4291
|
+
return;
|
|
4292
|
+
const nProt = campo(ret, "nProt");
|
|
4293
|
+
return {
|
|
4294
|
+
chNFe,
|
|
4295
|
+
tpEvento,
|
|
4296
|
+
nSeqEvento: String(Number(nSeq)),
|
|
4297
|
+
dhRegEvento,
|
|
4298
|
+
retEvento: recortarElemento(doc, retEl, ""),
|
|
4299
|
+
procEventoNFe: xml,
|
|
4300
|
+
...nProt === undefined ? {} : { nProt }
|
|
4301
|
+
};
|
|
4302
|
+
}
|
|
4303
|
+
async function recuperarEventoRegistrado(cliente, chave, tpEvento, nSeqEvento) {
|
|
4304
|
+
const consulta = await cliente.consultar(chave);
|
|
4305
|
+
if (consulta.tipo !== "autorizado" && consulta.tipo !== "denegado")
|
|
4306
|
+
return { registrado: false, consulta };
|
|
4307
|
+
let achado;
|
|
4308
|
+
for (const xml of consulta.valor.eventos) {
|
|
4309
|
+
const e = lerProcEvento(xml);
|
|
4310
|
+
if (e === undefined || e.chNFe !== consulta.valor.chNFe || e.tpEvento !== tpEvento)
|
|
4311
|
+
continue;
|
|
4312
|
+
if (nSeqEvento !== undefined && Number(e.nSeqEvento) !== nSeqEvento)
|
|
4313
|
+
continue;
|
|
4314
|
+
if (achado === undefined || Number(e.nSeqEvento) > Number(achado.nSeqEvento))
|
|
4315
|
+
achado = e;
|
|
4316
|
+
}
|
|
4317
|
+
return achado === undefined ? { registrado: false, consulta } : { registrado: true, evento: achado, consulta };
|
|
4318
|
+
}
|
|
4319
|
+
// packages/nfe/src/services/resolver.ts
|
|
4320
|
+
import { criarAutorizado as criarAutorizado2, criarDenegado as criarDenegado2 } from "@sinete/core";
|
|
4321
|
+
var CHAVE_NO_MOTIVO = /\[\s*chNFe\s*:\s*([0-9]{6}[0-9A-Z]{12}[0-9]{26})\s*\]/i;
|
|
4322
|
+
function chaveDaDuplicidade(xMotivo) {
|
|
4323
|
+
return CHAVE_NO_MOTIVO.exec(xMotivo)?.[1]?.toUpperCase();
|
|
4324
|
+
}
|
|
4325
|
+
async function resolverEnvioSemResposta(cliente, nfeAssinada, anterior) {
|
|
4326
|
+
const a = documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
4327
|
+
const chave = a.id.slice(3);
|
|
4328
|
+
if (anterior && anterior.tipo === "recusado" && cstatEm(anterior.cStat, "duplicidadeChaveDiferente")) {
|
|
4329
|
+
const outra = chaveDaDuplicidade(anterior.xMotivo);
|
|
4330
|
+
return { acao: "divergente", motivo: anterior, ...outra === undefined ? {} : { chNFe: outra } };
|
|
4331
|
+
}
|
|
4332
|
+
const consulta = await cliente.consultar(chave, nfeAssinada);
|
|
4333
|
+
if (consulta.tipo === "recusado") {
|
|
4334
|
+
if (cstatEm(consulta.cStat, "naoConsta"))
|
|
4335
|
+
return { acao: "reenviar", nfeAssinada: a.xml };
|
|
4336
|
+
if (cstatEm(consulta.cStat, "outraNfeNoNumero")) {
|
|
4337
|
+
const outra = chaveDaDuplicidade(consulta.xMotivo);
|
|
4338
|
+
return { acao: "divergente", motivo: consulta, ...outra === undefined ? {} : { chNFe: outra } };
|
|
4339
|
+
}
|
|
4340
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4341
|
+
}
|
|
4342
|
+
if (consulta.tipo === "pendente")
|
|
4343
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4344
|
+
const v = consulta.valor;
|
|
4345
|
+
const p = v.protocolo;
|
|
4346
|
+
if (!p)
|
|
4347
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4348
|
+
const conteudo = p.digVal === undefined ? "sem-digval" : v.digValConfere === true ? "confere" : "difere";
|
|
4349
|
+
const protStatus = { cStat: p.cStat, xMotivo: p.xMotivo };
|
|
4350
|
+
if (v.situacao === "denegada")
|
|
4351
|
+
return { acao: "concluida", situacao: "denegada", conteudo, resultado: criarDenegado2(protStatus, p) };
|
|
4352
|
+
if (conteudo === "difere")
|
|
4353
|
+
return { acao: "divergente", chNFe: chave, consulta, motivo: consulta };
|
|
4354
|
+
if (conteudo === "sem-digval")
|
|
4355
|
+
return { acao: "sem-prova", situacao: v.situacao, consulta };
|
|
4356
|
+
if (p.nfeProc === undefined)
|
|
4357
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4358
|
+
return { acao: "concluida", situacao: v.situacao, conteudo, resultado: criarAutorizado2(protStatus, p) };
|
|
4359
|
+
}
|
|
4360
|
+
export {
|
|
4361
|
+
CODIGOS_OCORRENCIA_NFE,
|
|
4362
|
+
Decimal,
|
|
4363
|
+
MotivoDesoneracaoIcms,
|
|
4364
|
+
NFCE_LIMITE_SEM_DESTINATARIO,
|
|
4365
|
+
NFE_NS3 as NFE_NS,
|
|
4366
|
+
TipoPagamento,
|
|
4367
|
+
XNOME_HOMOLOGACAO,
|
|
4368
|
+
XPROD_HOMOLOGACAO_NFCE,
|
|
4369
|
+
assinarNfe,
|
|
4370
|
+
assinaturaQrCode,
|
|
4371
|
+
autorizadorContingencia,
|
|
4372
|
+
calculadoraIbsCbs,
|
|
4373
|
+
carregarDatasetEmbarcado,
|
|
4374
|
+
chaveDaDuplicidade,
|
|
4375
|
+
comQrCode,
|
|
4376
|
+
conferirEmitenteDoCertificado,
|
|
4377
|
+
criarClienteNfe,
|
|
4378
|
+
dec,
|
|
4379
|
+
descomprimirGzipBase64,
|
|
4380
|
+
deslocamentoDaUf,
|
|
4381
|
+
documentoAssinado,
|
|
4382
|
+
exigenciaRespTec,
|
|
4383
|
+
formatarDecimal,
|
|
4384
|
+
formatarDh,
|
|
4385
|
+
hashCsrt,
|
|
4386
|
+
localDaOperacao,
|
|
4387
|
+
montarNfe,
|
|
4388
|
+
nfeAssinadaDoProc,
|
|
4389
|
+
problemaDeFormato,
|
|
4390
|
+
recortarElemento,
|
|
4391
|
+
recuperarEventoRegistrado,
|
|
4392
|
+
resolverEnvioSemResposta,
|
|
4393
|
+
rotuloDoCaminho,
|
|
4394
|
+
sum,
|
|
4395
|
+
urlsNfce
|
|
4396
|
+
};
|
|
4397
|
+
|
|
4398
|
+
//# debugId=82CED6CBF6EFA38F64756E2164756E21
|
|
4399
|
+
//# sourceMappingURL=index.js.map
|