@sinete/nfe 0.1.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/README.md +49 -48
- package/dist/build/build.d.ts +23 -23
- package/dist/build/build.d.ts.map +1 -1
- package/dist/build/destinatario.d.ts +2 -2
- package/dist/build/ibscbs.d.ts.map +1 -1
- package/dist/build/nfce.d.ts +5 -5
- package/dist/build/nfce.d.ts.map +1 -1
- package/dist/build/pl.d.ts +4 -4
- package/dist/build/pl.d.ts.map +1 -1
- package/dist/build/rejeicoes.d.ts +7 -7
- package/dist/build/rejeicoes.d.ts.map +1 -1
- package/dist/build/values.d.ts +8 -8
- package/dist/build/values.d.ts.map +1 -1
- package/dist/decimal.d.ts +2 -2
- package/dist/decimal.d.ts.map +1 -1
- package/dist/format.d.ts +19 -19
- package/dist/format.d.ts.map +1 -1
- package/dist/ibs-cbs.d.ts +5 -5
- package/dist/ibs-cbs.d.ts.map +1 -1
- package/dist/ibs-cbs.js +35 -35
- package/dist/ibs-cbs.js.map +2 -2
- package/dist/index.d.ts +18 -18
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +602 -573
- package/dist/index.js.map +25 -25
- package/dist/issues.d.ts +10 -10
- package/dist/issues.d.ts.map +1 -1
- package/dist/model.d.ts +4 -4
- package/dist/ports.d.ts +15 -15
- package/dist/ports.d.ts.map +1 -1
- package/dist/rotulo.d.ts +2 -2
- package/dist/rotulo.d.ts.map +1 -1
- package/dist/rtc.d.ts +23 -23
- package/dist/rtc.d.ts.map +1 -1
- package/dist/services/client.d.ts +44 -40
- package/dist/services/client.d.ts.map +1 -1
- package/dist/services/gzip.d.ts +1 -1
- package/dist/services/gzip.d.ts.map +1 -1
- package/dist/services/index.d.ts +4 -4
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/outcome.d.ts +3 -3
- package/dist/services/outcome.d.ts.map +1 -1
- package/dist/services/proc.d.ts +6 -6
- package/dist/services/proc.d.ts.map +1 -1
- package/dist/services/recuperar.d.ts +7 -7
- package/dist/services/recuperar.d.ts.map +1 -1
- package/dist/services/resolver.d.ts +10 -10
- package/dist/services/resolver.d.ts.map +1 -1
- package/dist/services/soap.d.ts +8 -8
- package/dist/services/soap.d.ts.map +1 -1
- package/dist/time.d.ts +4 -4
- package/dist/time.d.ts.map +1 -1
- package/dist/versao-gerada.d.ts +1 -1
- package/package.json +9 -9
- package/src/build/build.ts +202 -185
- package/src/build/destinatario.ts +8 -8
- package/src/build/ibscbs.ts +10 -6
- package/src/build/icms.ts +6 -6
- package/src/build/nfce.ts +19 -19
- package/src/build/pl.ts +12 -12
- package/src/build/rejeicoes.ts +13 -13
- package/src/build/values.ts +14 -14
- package/src/data/arredondamento.json +1 -1
- package/src/data/cstat.json +6 -6
- package/src/data/fusos.json +1 -1
- package/src/data/nfce-urls.json +2 -2
- package/src/data/produtor-rural.json +1 -1
- package/src/data/resp-tec.json +1 -1
- package/src/decimal.ts +10 -9
- package/src/format.ts +29 -28
- package/src/ibs-cbs.ts +74 -74
- package/src/index.ts +29 -27
- package/src/issues.ts +11 -11
- package/src/model.ts +4 -4
- package/src/ports.ts +15 -15
- package/src/rotulo.ts +4 -4
- package/src/rtc.ts +91 -91
- package/src/services/client.ts +248 -217
- package/src/services/gzip.ts +7 -7
- package/src/services/index.ts +12 -10
- package/src/services/outcome.ts +9 -9
- package/src/services/proc.ts +50 -49
- package/src/services/recuperar.ts +27 -25
- package/src/services/resolver.ts +22 -22
- package/src/services/soap.ts +35 -35
- package/src/time.ts +6 -6
- package/src/versao-gerada.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
// packages/nfe/src/build/build.ts
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
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";
|
|
5
13
|
import { TIS as TISCt, TNFe_infNFeSupl, TTribNFe as TTribNFeCt } from "@sinete/schemas/nfe/PL_010f";
|
|
6
|
-
import {
|
|
14
|
+
import { lerChaveAcesso, lerCnpj as lerCnpj3, lerCpf, lerIe, montarChaveAcesso } from "@sinete/validators";
|
|
7
15
|
// packages/nfe/src/data/arredondamento.json
|
|
8
16
|
var arredondamento_default = {
|
|
9
|
-
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
|
|
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.",
|
|
10
18
|
atualizadoEm: "2026-09-26",
|
|
11
19
|
familias: {
|
|
12
20
|
produto: {
|
|
@@ -37,7 +45,7 @@ var arredondamento_default = {
|
|
|
37
45
|
};
|
|
38
46
|
// packages/nfe/src/data/produtor-rural.json
|
|
39
47
|
var produtor_rural_default = {
|
|
40
|
-
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
|
|
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).",
|
|
41
49
|
atualizadoEm: "2026-09-28",
|
|
42
50
|
refNFP: {
|
|
43
51
|
modelo04: {
|
|
@@ -62,7 +70,7 @@ var reforma_default = {
|
|
|
62
70
|
};
|
|
63
71
|
// packages/nfe/src/data/resp-tec.json
|
|
64
72
|
var resp_tec_default = {
|
|
65
|
-
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
|
|
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.",
|
|
66
74
|
atualizadoEm: "2026-09-26",
|
|
67
75
|
fonte: "NT 2018.005 v1.50 (responsável técnico e CSRT, adesão a critério da UF)",
|
|
68
76
|
padrao: { infRespTec: "opcional", csrt: "opcional" },
|
|
@@ -76,7 +84,7 @@ var resp_tec_default = {
|
|
|
76
84
|
};
|
|
77
85
|
|
|
78
86
|
// packages/nfe/src/decimal.ts
|
|
79
|
-
import {
|
|
87
|
+
import { ErroDeConfiguracao } from "@sinete/core";
|
|
80
88
|
var DECIMAL_TEXT = /^([+-])?(\d+)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$|^([+-])?\.(\d+)(?:[eE]([+-]?\d+))?$/;
|
|
81
89
|
var MAX_SCALE = 64;
|
|
82
90
|
function pow10(n) {
|
|
@@ -95,13 +103,13 @@ class Decimal {
|
|
|
95
103
|
static HUNDRED = new Decimal(100n, 0);
|
|
96
104
|
static fromParts(coef, scale) {
|
|
97
105
|
if (!Number.isInteger(scale) || scale < 0 || scale > MAX_SCALE)
|
|
98
|
-
throw new
|
|
106
|
+
throw new ErroDeConfiguracao(`escala inválida: ${scale}`);
|
|
99
107
|
return new Decimal(coef, scale);
|
|
100
108
|
}
|
|
101
109
|
static of(input) {
|
|
102
110
|
const d = Decimal.tryOf(input);
|
|
103
111
|
if (d === undefined)
|
|
104
|
-
throw new
|
|
112
|
+
throw new ErroDeConfiguracao(`número decimal inválido: ${JSON.stringify(String(input))}`);
|
|
105
113
|
return d;
|
|
106
114
|
}
|
|
107
115
|
static tryOf(input) {
|
|
@@ -161,7 +169,7 @@ class Decimal {
|
|
|
161
169
|
dividedBy(other, scale, mode) {
|
|
162
170
|
const o = Decimal.of(other);
|
|
163
171
|
if (o.coef === 0n)
|
|
164
|
-
throw new
|
|
172
|
+
throw new ErroDeConfiguracao("divisão por zero");
|
|
165
173
|
const shift = o.scale + scale + 1 - this.scale;
|
|
166
174
|
const num = shift >= 0 ? this.coef * pow10(shift) : this.coef;
|
|
167
175
|
const den = shift >= 0 ? o.coef : o.coef * pow10(-shift);
|
|
@@ -181,7 +189,7 @@ class Decimal {
|
|
|
181
189
|
}
|
|
182
190
|
round(scale, mode) {
|
|
183
191
|
if (!Number.isInteger(scale) || scale < 0)
|
|
184
|
-
throw new
|
|
192
|
+
throw new ErroDeConfiguracao(`casas decimais inválidas: ${scale}`);
|
|
185
193
|
if (scale >= this.scale)
|
|
186
194
|
return new Decimal(this.coef * pow10(scale - this.scale), scale);
|
|
187
195
|
return roundCoef(this.coef, this.scale, scale, mode, false);
|
|
@@ -246,50 +254,50 @@ function roundCoef(coef, from, to, mode, sticky) {
|
|
|
246
254
|
}
|
|
247
255
|
return Decimal.fromParts(neg ? -q : q, to);
|
|
248
256
|
}
|
|
249
|
-
function dec(
|
|
250
|
-
return Decimal.of(
|
|
257
|
+
function dec(valor) {
|
|
258
|
+
return Decimal.of(valor);
|
|
251
259
|
}
|
|
252
|
-
function sum(
|
|
260
|
+
function sum(valores) {
|
|
253
261
|
let acc = Decimal.ZERO;
|
|
254
|
-
for (const v of
|
|
262
|
+
for (const v of valores)
|
|
255
263
|
acc = acc.plus(v);
|
|
256
264
|
return acc;
|
|
257
265
|
}
|
|
258
266
|
|
|
259
267
|
// packages/nfe/src/format.ts
|
|
260
|
-
var D1302 = {
|
|
261
|
-
var D1302_OPC = {
|
|
262
|
-
var D0302A04 = {
|
|
263
|
-
var D0302A04_OPC = {
|
|
264
|
-
var D0302 = {
|
|
265
|
-
var D1104V = {
|
|
266
|
-
var D1104 = {
|
|
267
|
-
var D1110V = {
|
|
268
|
-
var D1204V = {
|
|
269
|
-
var D1204 = {
|
|
270
|
-
var D1203 = {
|
|
271
|
-
function
|
|
272
|
-
const r =
|
|
273
|
-
let places = Math.max(
|
|
274
|
-
if (
|
|
275
|
-
places = Math.max(places,
|
|
276
|
-
return r.toFixed(places,
|
|
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);
|
|
277
285
|
}
|
|
278
|
-
function
|
|
279
|
-
if (
|
|
286
|
+
function problemaDeFormato(valor, formato) {
|
|
287
|
+
if (valor.isNegative())
|
|
280
288
|
return "valor negativo";
|
|
281
|
-
if (
|
|
289
|
+
if (formato.naoNulo && valor.isZero())
|
|
282
290
|
return "valor zero não é aceito neste campo";
|
|
283
|
-
if (
|
|
284
|
-
return `mais de ${
|
|
285
|
-
const intDigits =
|
|
286
|
-
if (intDigits >
|
|
287
|
-
return `mais de ${
|
|
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`;
|
|
288
296
|
return;
|
|
289
297
|
}
|
|
290
298
|
|
|
291
299
|
// packages/nfe/src/issues.ts
|
|
292
|
-
var
|
|
300
|
+
var CODIGOS_OCORRENCIA_NFE = [
|
|
293
301
|
"campo_obrigatorio",
|
|
294
302
|
"campo_invalido",
|
|
295
303
|
"campo_fora_do_pl",
|
|
@@ -326,7 +334,7 @@ class Issues {
|
|
|
326
334
|
this.list = [];
|
|
327
335
|
}
|
|
328
336
|
add(path, code, message, origem = "entrada") {
|
|
329
|
-
this.list.push({ path, code, message, origem });
|
|
337
|
+
this.list.push({ caminho: path, code, mensagem: message, origem });
|
|
330
338
|
}
|
|
331
339
|
montagem(path, code, message) {
|
|
332
340
|
this.add(path, code, message, "montagem");
|
|
@@ -350,10 +358,10 @@ class Issues {
|
|
|
350
358
|
}
|
|
351
359
|
|
|
352
360
|
// packages/nfe/src/rtc.ts
|
|
353
|
-
import {
|
|
354
|
-
import {
|
|
355
|
-
import {
|
|
356
|
-
import {
|
|
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";
|
|
357
365
|
var BASE = /^\d{1,13}(\.\d{1,2})?$/;
|
|
358
366
|
function normalizado(v) {
|
|
359
367
|
const [int = "0", frac = ""] = v.split(".");
|
|
@@ -363,7 +371,7 @@ function normalizado(v) {
|
|
|
363
371
|
}
|
|
364
372
|
var caminho = (nItem) => `itens[${nItem - 1}].impostos.ibsCbs`;
|
|
365
373
|
function ufDoMunicipio(cMun) {
|
|
366
|
-
return
|
|
374
|
+
return ufPorCUf(cMun.slice(0, 2))?.sigla;
|
|
367
375
|
}
|
|
368
376
|
function localDaOperacao(nota) {
|
|
369
377
|
if (nota.cMunFGIBS !== undefined) {
|
|
@@ -372,7 +380,7 @@ function localDaOperacao(nota) {
|
|
|
372
380
|
return { uf, cMun: nota.cMunFGIBS };
|
|
373
381
|
}
|
|
374
382
|
const d = nota.destino;
|
|
375
|
-
if (d !== undefined && d.UF !== "EX" &&
|
|
383
|
+
if (d !== undefined && d.UF !== "EX" && ehUf(d.UF))
|
|
376
384
|
return { uf: d.UF, cMun: d.cMun };
|
|
377
385
|
return { uf: nota.emitente.UF, cMun: nota.emitente.cMun };
|
|
378
386
|
}
|
|
@@ -391,30 +399,30 @@ function grupoDoLeiaute(g, indDoacao) {
|
|
|
391
399
|
};
|
|
392
400
|
}
|
|
393
401
|
function ocorrenciaDoMotor(e, itens) {
|
|
394
|
-
if (e instanceof
|
|
402
|
+
if (e instanceof ErroClassificacao || e instanceof ErroRegimeNaoSuportado) {
|
|
395
403
|
const path = e.item !== undefined ? caminho(e.item) : caminho(itens[0]?.nItem ?? 1);
|
|
396
|
-
return { path, code: e.code,
|
|
404
|
+
return { caminho: path, code: e.code, mensagem: e.message, origem: "entrada" };
|
|
397
405
|
}
|
|
398
|
-
if (e instanceof
|
|
399
|
-
return {
|
|
406
|
+
if (e instanceof ErroAliquotaDesconhecida)
|
|
407
|
+
return { caminho: "impostos.ibsCbs", code: e.code, mensagem: e.message, origem: "montagem" };
|
|
400
408
|
return;
|
|
401
409
|
}
|
|
402
410
|
var embarcado;
|
|
403
411
|
function carregarDatasetEmbarcado() {
|
|
404
|
-
embarcado ??= import("@sinete/ibs-cbs-dados/
|
|
412
|
+
embarcado ??= import("@sinete/ibs-cbs-dados/embarcado").then((m) => m.datasetEmbarcado(), (e) => {
|
|
405
413
|
embarcado = undefined;
|
|
406
414
|
throw e;
|
|
407
415
|
});
|
|
408
416
|
return embarcado;
|
|
409
417
|
}
|
|
410
|
-
function
|
|
411
|
-
const rates =
|
|
412
|
-
const dataset =
|
|
418
|
+
function calculadoraIbsCbs(opcoes = {}) {
|
|
419
|
+
const rates = opcoes.aliquotas ?? aliquotasOficiais();
|
|
420
|
+
const dataset = opcoes.dataset;
|
|
413
421
|
return {
|
|
414
422
|
calcular(request) {
|
|
415
423
|
if (dataset !== undefined)
|
|
416
|
-
return calcularCom(dataset, rates,
|
|
417
|
-
return carregarDatasetEmbarcado().then((ds) => calcularCom(ds, rates,
|
|
424
|
+
return calcularCom(dataset, rates, opcoes, request);
|
|
425
|
+
return carregarDatasetEmbarcado().then((ds) => calcularCom(ds, rates, opcoes, request));
|
|
418
426
|
}
|
|
419
427
|
};
|
|
420
428
|
}
|
|
@@ -427,9 +435,9 @@ function calcularCom(dataset, rates, options, {
|
|
|
427
435
|
for (const it of itens) {
|
|
428
436
|
if (it.cCredPres !== undefined) {
|
|
429
437
|
issues.push({
|
|
430
|
-
|
|
438
|
+
caminho: caminho(it.nItem),
|
|
431
439
|
code: "ibscbs_nao_suportado",
|
|
432
|
-
|
|
440
|
+
mensagem: "crédito presumido (cCredPres) precisa do grupo gCredPresOper pronto (ibsCbs.grupo)",
|
|
433
441
|
origem: "entrada"
|
|
434
442
|
});
|
|
435
443
|
continue;
|
|
@@ -437,18 +445,18 @@ function calcularCom(dataset, rates, options, {
|
|
|
437
445
|
const base = it.vBC !== undefined ? it.vBC.toFixed(2) : options.base?.(it, nota);
|
|
438
446
|
if (base === undefined) {
|
|
439
447
|
issues.push({
|
|
440
|
-
|
|
448
|
+
caminho: `${caminho(it.nItem)}.classificacao.vBC`,
|
|
441
449
|
code: "ibscbs_base_ausente",
|
|
442
|
-
|
|
450
|
+
mensagem: "informe vBC do IBS/CBS ou CalculadoraIbsCbsOpcoes.base: a composição da base (UB16-10) ainda não tem regra publicada",
|
|
443
451
|
origem: "entrada"
|
|
444
452
|
});
|
|
445
453
|
continue;
|
|
446
454
|
}
|
|
447
455
|
if (!BASE.test(base)) {
|
|
448
456
|
issues.push({
|
|
449
|
-
|
|
457
|
+
caminho: `${caminho(it.nItem)}.classificacao.vBC`,
|
|
450
458
|
code: "decimal_invalido",
|
|
451
|
-
|
|
459
|
+
mensagem: base,
|
|
452
460
|
origem: it.vBC !== undefined ? "entrada" : "montagem"
|
|
453
461
|
});
|
|
454
462
|
continue;
|
|
@@ -458,92 +466,92 @@ function calcularCom(dataset, rates, options, {
|
|
|
458
466
|
cst: it.CST,
|
|
459
467
|
cClassTrib: it.cClassTrib,
|
|
460
468
|
base,
|
|
461
|
-
|
|
462
|
-
|
|
469
|
+
quantidade: it.qTrib.toString(),
|
|
470
|
+
unidade: it.uTrib,
|
|
463
471
|
...it.gTribRegular === undefined ? {} : { regular: { cst: it.gTribRegular.CSTReg, cClassTrib: it.gTribRegular.cClassTribReg } }
|
|
464
472
|
});
|
|
465
473
|
}
|
|
466
474
|
if (issues.length > 0)
|
|
467
|
-
return { itens: [], issues };
|
|
475
|
+
return { itens: [], ocorrencias: issues };
|
|
468
476
|
const op = {
|
|
469
477
|
modelo: Number(nota.mod),
|
|
470
|
-
|
|
478
|
+
local: localDaOperacao(nota),
|
|
471
479
|
...nota.compraGov === undefined ? {} : {
|
|
472
|
-
|
|
480
|
+
compraGovernamental: {
|
|
473
481
|
tpEnteGov: Number(nota.compraGov.tpEnteGov),
|
|
474
482
|
...nota.compraGov.tpOperGov === "1" || nota.compraGov.tpOperGov === "2" ? { tpOperGov: Number(nota.compraGov.tpOperGov) } : {}
|
|
475
483
|
}
|
|
476
484
|
},
|
|
477
|
-
|
|
485
|
+
itens: classificados
|
|
478
486
|
};
|
|
479
|
-
const time =
|
|
487
|
+
const time = contextoDeTempo({ emissao: relogioFixo(nota.emissao), fatoGerador: relogioFixo(nota.fatoGerador) });
|
|
480
488
|
let roc;
|
|
481
489
|
try {
|
|
482
|
-
roc =
|
|
490
|
+
roc = calcular(op, {
|
|
483
491
|
dataset,
|
|
484
|
-
rates,
|
|
485
|
-
time,
|
|
486
|
-
...options.
|
|
492
|
+
aliquotas: rates,
|
|
493
|
+
tempo: time,
|
|
494
|
+
...options.deslocamentoMin === undefined ? {} : { deslocamentoMin: options.deslocamentoMin }
|
|
487
495
|
});
|
|
488
496
|
} catch (e) {
|
|
489
497
|
const issue = ocorrenciaDoMotor(e, itens);
|
|
490
498
|
if (issue === undefined)
|
|
491
499
|
throw e;
|
|
492
|
-
return { itens: [],
|
|
500
|
+
return { itens: [], ocorrencias: [issue] };
|
|
493
501
|
}
|
|
494
502
|
const redutor = roc.oper?.gCompraGov.pRedutor;
|
|
495
503
|
if (nota.compraGov !== undefined && redutor !== undefined && normalizado(nota.compraGov.pRedutor.toString()) !== normalizado(redutor)) {
|
|
496
504
|
issues.push({
|
|
497
|
-
|
|
505
|
+
caminho: "gCompraGov.pRedutor",
|
|
498
506
|
code: "ibscbs_redutor_divergente",
|
|
499
|
-
|
|
507
|
+
mensagem: `pRedutor informado (${nota.compraGov.pRedutor.toString()}) difere do vigente no fato gerador (${redutor})`,
|
|
500
508
|
origem: "entrada"
|
|
501
509
|
});
|
|
502
510
|
}
|
|
503
511
|
if (options.regras !== false) {
|
|
504
|
-
const doc =
|
|
512
|
+
const doc = documentoDoRoc(roc, {
|
|
505
513
|
modelo: op.modelo,
|
|
506
514
|
crt: Number(nota.emitente.CRT),
|
|
507
515
|
finNFe: Number(nota.finNFe),
|
|
508
516
|
...nota.tpNFDebito === undefined ? {} : { tpNFDebito: nota.tpNFDebito },
|
|
509
517
|
...nota.tpNFCredito === undefined ? {} : { tpNFCredito: nota.tpNFCredito },
|
|
510
|
-
|
|
511
|
-
...nota.destino === undefined ? {} : {
|
|
512
|
-
|
|
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) }))
|
|
513
521
|
});
|
|
514
|
-
const report =
|
|
522
|
+
const report = validar(doc, {
|
|
515
523
|
dataset,
|
|
516
|
-
time,
|
|
524
|
+
tempo: time,
|
|
517
525
|
ambiente: nota.ambiente,
|
|
518
|
-
rates,
|
|
519
|
-
...options.
|
|
520
|
-
...options.regras?.
|
|
521
|
-
...options.regras?.
|
|
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 }
|
|
522
530
|
});
|
|
523
|
-
for (const v of report.
|
|
531
|
+
for (const v of report.violacoes) {
|
|
524
532
|
issues.push({
|
|
525
|
-
|
|
533
|
+
caminho: v.item === undefined ? "total.IBSCBSTot" : caminho(v.item),
|
|
526
534
|
code: "ibscbs_regra_nt",
|
|
527
|
-
|
|
535
|
+
mensagem: `${v.regra} (rejeição ${v.cStat}): ${v.message} [${v.fonte}]`,
|
|
528
536
|
origem: "montagem"
|
|
529
537
|
});
|
|
530
538
|
}
|
|
531
539
|
}
|
|
532
540
|
const porItem = new Map(itens.map((it) => [it.nItem, it]));
|
|
533
541
|
return {
|
|
534
|
-
itens: roc.
|
|
542
|
+
itens: roc.itens.map((r) => ({
|
|
535
543
|
nItem: r.nItem,
|
|
536
544
|
IBSCBS: grupoDoLeiaute(r.IBSCBS, porItem.get(r.nItem)?.indDoacao)
|
|
537
545
|
})),
|
|
538
|
-
...issues.length === 0 ? {} : { issues }
|
|
546
|
+
...issues.length === 0 ? {} : { ocorrencias: issues }
|
|
539
547
|
};
|
|
540
548
|
}
|
|
541
549
|
|
|
542
550
|
// packages/nfe/src/time.ts
|
|
543
|
-
import {
|
|
551
|
+
import { formatarDataHoraComFuso } from "@sinete/core";
|
|
544
552
|
// packages/nfe/src/data/fusos.json
|
|
545
553
|
var fusos_default = {
|
|
546
|
-
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
|
|
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.",
|
|
547
555
|
atualizadoEm: "2026-09-26",
|
|
548
556
|
fontes: [
|
|
549
557
|
"Lei 11.662/2008 e Lei 12.876/2013 (fusos horários do Brasil; Acre em UTC-5)",
|
|
@@ -562,19 +570,19 @@ var fusos_default = {
|
|
|
562
570
|
|
|
563
571
|
// packages/nfe/src/time.ts
|
|
564
572
|
var UF_OFFSETS = fusos_default.ufs;
|
|
565
|
-
function
|
|
573
|
+
function deslocamentoDaUf(uf) {
|
|
566
574
|
return Object.hasOwn(UF_OFFSETS, uf) ? UF_OFFSETS[uf] : fusos_default.padrao;
|
|
567
575
|
}
|
|
568
|
-
function
|
|
569
|
-
return
|
|
576
|
+
function formatarDh(data, deslocamentoMin) {
|
|
577
|
+
return formatarDataHoraComFuso(data, deslocamentoMin);
|
|
570
578
|
}
|
|
571
579
|
|
|
572
580
|
// packages/nfe/src/versao-gerada.ts
|
|
573
|
-
var VERSAO_PACOTE = "0.
|
|
581
|
+
var VERSAO_PACOTE = "0.2.0";
|
|
574
582
|
|
|
575
583
|
// packages/nfe/src/build/destinatario.ts
|
|
576
|
-
import {
|
|
577
|
-
import {
|
|
584
|
+
import { ufPorSigla } from "@sinete/core";
|
|
585
|
+
import { lerCnpj } from "@sinete/validators";
|
|
578
586
|
// packages/nfe/src/data/suframa.json
|
|
579
587
|
var suframa_default = {
|
|
580
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.",
|
|
@@ -617,7 +625,7 @@ function conferirDestinatario(input, ide, issues) {
|
|
|
617
625
|
}
|
|
618
626
|
if (end !== undefined && !exterior) {
|
|
619
627
|
const e = end;
|
|
620
|
-
const cUF =
|
|
628
|
+
const cUF = ufPorSigla(e.UF)?.cUF;
|
|
621
629
|
if (cUF !== undefined && digitos(e.cMun).slice(0, 2) !== cUF) {
|
|
622
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)`);
|
|
623
631
|
}
|
|
@@ -636,8 +644,8 @@ function conferirDestinatario(input, ide, issues) {
|
|
|
636
644
|
const cnpj = (v) => {
|
|
637
645
|
if (v === undefined)
|
|
638
646
|
return;
|
|
639
|
-
const r =
|
|
640
|
-
return r.ok ? r.
|
|
647
|
+
const r = lerCnpj(v);
|
|
648
|
+
return r.ok ? r.valor : undefined;
|
|
641
649
|
};
|
|
642
650
|
const cnpjDest = "CNPJ" in d ? cnpj(d.CNPJ) : undefined;
|
|
643
651
|
const mesmoCnpj = cnpjDest !== undefined && cnpjDest === cnpj(input.emitente.CNPJ);
|
|
@@ -685,18 +693,18 @@ function conferirDestinatario(input, ide, issues) {
|
|
|
685
693
|
}
|
|
686
694
|
|
|
687
695
|
// packages/nfe/src/build/ibscbs.ts
|
|
688
|
-
import {
|
|
689
|
-
import {
|
|
696
|
+
import { lerXml, primeiroFilho } from "@sinete/core/xml";
|
|
697
|
+
import { serializar, validar as validar2 } from "@sinete/schemas";
|
|
690
698
|
var NFE_NS = "http://www.portalfiscal.inf.br/nfe";
|
|
691
699
|
function grupoInvalido(ct, nome, value, path, issues) {
|
|
692
700
|
if (value === undefined)
|
|
693
701
|
return false;
|
|
694
702
|
try {
|
|
695
|
-
const doc =
|
|
696
|
-
const el =
|
|
697
|
-
const erros = el === undefined ? [{
|
|
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);
|
|
698
706
|
for (const e of erros)
|
|
699
|
-
issues.add(`${path}${e.
|
|
707
|
+
issues.add(`${path}${e.caminho.replace(/^\/[^/]+/, "").replace(/\//g, ".")}`, "schema", `${e.code}: ${e.mensagem}`);
|
|
700
708
|
return erros.length > 0;
|
|
701
709
|
} catch (e) {
|
|
702
710
|
issues.add(path, "schema", `grupo malformado: ${e.message}`);
|
|
@@ -809,9 +817,9 @@ class Ctx {
|
|
|
809
817
|
this.issues.add(path, "decimal_invalido", "número decimal inválido (use ponto como separador, sem milhar)");
|
|
810
818
|
return;
|
|
811
819
|
}
|
|
812
|
-
const problem =
|
|
820
|
+
const problem = problemaDeFormato(d, format);
|
|
813
821
|
if (problem !== undefined) {
|
|
814
|
-
this.issues.add(path, "decimal_invalido", `${problem} (${format.
|
|
822
|
+
this.issues.add(path, "decimal_invalido", `${problem} (${format.nome})`);
|
|
815
823
|
return;
|
|
816
824
|
}
|
|
817
825
|
return d;
|
|
@@ -842,14 +850,14 @@ class Ctx {
|
|
|
842
850
|
return g;
|
|
843
851
|
}
|
|
844
852
|
s(value, format) {
|
|
845
|
-
return
|
|
853
|
+
return formatarDecimal(value, format);
|
|
846
854
|
}
|
|
847
855
|
so(value, format) {
|
|
848
856
|
if (value === undefined)
|
|
849
857
|
return;
|
|
850
|
-
if (format.
|
|
858
|
+
if (format.naoNulo && value.isZero())
|
|
851
859
|
return;
|
|
852
|
-
return
|
|
860
|
+
return formatarDecimal(value, format);
|
|
853
861
|
}
|
|
854
862
|
}
|
|
855
863
|
function clean(o) {
|
|
@@ -1362,17 +1370,17 @@ function buildIcms(ctx, input, base, path) {
|
|
|
1362
1370
|
}
|
|
1363
1371
|
|
|
1364
1372
|
// packages/nfe/src/build/nfce.ts
|
|
1365
|
-
import {
|
|
1366
|
-
import {
|
|
1367
|
-
import {
|
|
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";
|
|
1368
1376
|
// packages/nfe/src/data/nfce-urls.json
|
|
1369
1377
|
var nfce_urls_default = {
|
|
1370
|
-
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
|
|
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.",
|
|
1371
1379
|
atualizadoEm: "2026-09-26",
|
|
1372
1380
|
fontes: [
|
|
1373
1381
|
"Portal Nacional da NFC-e (ENCAT), URL por UF utilizada QR code: https://nfce.encat.org/desenvolvedor/qrcode/ (coletada em 26/09/2026)",
|
|
1374
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)",
|
|
1375
|
-
"SEFAZ-MG, web services da NFC-e: https://portalsped.fazenda.mg.gov.br/spedmg/nfce/web-services/ (a mesma fonte do
|
|
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)",
|
|
1376
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)"
|
|
1377
1385
|
],
|
|
1378
1386
|
qrCode: {
|
|
@@ -1558,11 +1566,11 @@ async function sha1(bytes) {
|
|
|
1558
1566
|
}
|
|
1559
1567
|
var hex = (b) => Array.from(b, (x) => x.toString(16).padStart(2, "0")).join("");
|
|
1560
1568
|
async function digValHex(xml) {
|
|
1561
|
-
const doc =
|
|
1562
|
-
const inf =
|
|
1569
|
+
const doc = lerXml2(xml);
|
|
1570
|
+
const inf = primeiroFilho2(doc.raiz, "infNFe", NFE_NS2);
|
|
1563
1571
|
if (inf === undefined)
|
|
1564
1572
|
throw new Error("NF-e montada sem infNFe");
|
|
1565
|
-
return hexDoDigestValue(
|
|
1573
|
+
return hexDoDigestValue(codificarBase64(await sha1(te.encode(c14n(inf)))));
|
|
1566
1574
|
}
|
|
1567
1575
|
function hexDoDigestValue(digestValue) {
|
|
1568
1576
|
return hex(te.encode(digestValue));
|
|
@@ -1571,7 +1579,7 @@ async function hashQrCodeV2(parametros, csc) {
|
|
|
1571
1579
|
return hex(await sha1(te.encode(parametros + csc))).toUpperCase();
|
|
1572
1580
|
}
|
|
1573
1581
|
async function parametrosQrCode(d, qr) {
|
|
1574
|
-
const tpAmb =
|
|
1582
|
+
const tpAmb = tpAmbDoAmbiente(d.ambiente);
|
|
1575
1583
|
const offline = d.tpEmis === "9";
|
|
1576
1584
|
const dia = d.dhEmi.slice(8, 10);
|
|
1577
1585
|
if (qr.versao === "3") {
|
|
@@ -1587,13 +1595,13 @@ async function parametrosQrCode(d, qr) {
|
|
|
1587
1595
|
}
|
|
1588
1596
|
async function assinarParametros(parametros, signer) {
|
|
1589
1597
|
const bytes = te.encode(parametros);
|
|
1590
|
-
if (signer.
|
|
1591
|
-
return
|
|
1598
|
+
if (signer.tipo === "dados")
|
|
1599
|
+
return codificarBase64(await signer.assinar(bytes, "SHA-1"));
|
|
1592
1600
|
const h = await sha1(bytes);
|
|
1593
|
-
const di = new Uint8Array(
|
|
1594
|
-
di.set(
|
|
1595
|
-
di.set(h,
|
|
1596
|
-
return
|
|
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));
|
|
1597
1605
|
}
|
|
1598
1606
|
var CFOP_ISSQN = "5933";
|
|
1599
1607
|
var NFCE_LIMITE_SEM_DESTINATARIO = "10000.00";
|
|
@@ -1761,17 +1769,17 @@ function pagamentoNfce(pag, vNF, issues) {
|
|
|
1761
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)");
|
|
1762
1770
|
}
|
|
1763
1771
|
if (c.CNPJ !== undefined) {
|
|
1764
|
-
const r =
|
|
1772
|
+
const r = lerCnpj2(c.CNPJ, { caminho: `${path}.CNPJ` });
|
|
1765
1773
|
if (!r.ok)
|
|
1766
|
-
issues.list.push(r.
|
|
1774
|
+
issues.list.push(r.erro);
|
|
1767
1775
|
}
|
|
1768
1776
|
});
|
|
1769
1777
|
}
|
|
1770
1778
|
var digitos2 = (s) => s.replace(/[^0-9A-Za-z]/g, "").toUpperCase();
|
|
1771
1779
|
|
|
1772
1780
|
// packages/nfe/src/build/pl.ts
|
|
1773
|
-
import {
|
|
1774
|
-
import {
|
|
1781
|
+
import { ErroNaoSuportado } from "@sinete/core";
|
|
1782
|
+
import { ehComplexType, ehElementParticle, ehWildcard, selecionarPl } from "@sinete/schemas";
|
|
1775
1783
|
import { TNFe_infNFe as Inf010e } from "@sinete/schemas/nfe/PL_010e";
|
|
1776
1784
|
import { TNFe_infNFe as Inf010f } from "@sinete/schemas/nfe/PL_010f";
|
|
1777
1785
|
var INF_NFE = {
|
|
@@ -1782,14 +1790,14 @@ function escolherPl(ambiente, emissao) {
|
|
|
1782
1790
|
const vigencia = selecionarPl("nfe", ambiente, emissao);
|
|
1783
1791
|
const infNFe = INF_NFE[vigencia.modulo];
|
|
1784
1792
|
if (infNFe === undefined) {
|
|
1785
|
-
throw new
|
|
1793
|
+
throw new ErroNaoSuportado(`@sinete/nfe não conhece o módulo ${vigencia.modulo}; atualize o pacote`);
|
|
1786
1794
|
}
|
|
1787
1795
|
return { vigencia, infNFe };
|
|
1788
1796
|
}
|
|
1789
1797
|
function memberNames(p, acc) {
|
|
1790
|
-
if (
|
|
1798
|
+
if (ehWildcard(p))
|
|
1791
1799
|
acc.add("$any");
|
|
1792
|
-
else if (
|
|
1800
|
+
else if (ehElementParticle(p))
|
|
1793
1801
|
acc.add(p.e);
|
|
1794
1802
|
else
|
|
1795
1803
|
for (const i of p.i)
|
|
@@ -1797,10 +1805,10 @@ function memberNames(p, acc) {
|
|
|
1797
1805
|
return acc;
|
|
1798
1806
|
}
|
|
1799
1807
|
function elementTypes(p, acc) {
|
|
1800
|
-
if (
|
|
1808
|
+
if (ehWildcard(p))
|
|
1801
1809
|
return acc;
|
|
1802
|
-
if (
|
|
1803
|
-
if (
|
|
1810
|
+
if (ehElementParticle(p)) {
|
|
1811
|
+
if (ehComplexType(p.t))
|
|
1804
1812
|
acc.set(p.e, p.t);
|
|
1805
1813
|
} else
|
|
1806
1814
|
for (const i of p.i)
|
|
@@ -1867,7 +1875,7 @@ function cstComIsento(input, idDest, issues) {
|
|
|
1867
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)`);
|
|
1868
1876
|
});
|
|
1869
1877
|
}
|
|
1870
|
-
var dataNoFuso = (instante, offsetMinutes) =>
|
|
1878
|
+
var dataNoFuso = (instante, offsetMinutes) => formatarDh(instante, offsetMinutes).slice(0, 10);
|
|
1871
1879
|
var OFFSET_BRASILIA = -180;
|
|
1872
1880
|
function vencimentos(input, emissao, issues) {
|
|
1873
1881
|
const dups = input.cobranca?.duplicatas;
|
|
@@ -1890,9 +1898,9 @@ function conferirEmitenteDoCertificado(nfe, titular) {
|
|
|
1890
1898
|
if (base !== soDocumento(titular.cnpj).slice(0, 8)) {
|
|
1891
1899
|
return [
|
|
1892
1900
|
{
|
|
1893
|
-
|
|
1901
|
+
caminho: "emitente.CNPJ",
|
|
1894
1902
|
code: "emitente_difere_do_certificado",
|
|
1895
|
-
|
|
1903
|
+
mensagem: `CNPJ-base ${base} do emitente difere do CNPJ-base do certificado (F03, rejeição 213)`,
|
|
1896
1904
|
origem: "entrada"
|
|
1897
1905
|
}
|
|
1898
1906
|
];
|
|
@@ -1901,9 +1909,9 @@ function conferirEmitenteDoCertificado(nfe, titular) {
|
|
|
1901
1909
|
if (e.CPF !== undefined && titular.cpf !== undefined && soDocumento(e.CPF) !== soDocumento(titular.cpf)) {
|
|
1902
1910
|
return [
|
|
1903
1911
|
{
|
|
1904
|
-
|
|
1912
|
+
caminho: "emitente.CPF",
|
|
1905
1913
|
code: "emitente_difere_do_certificado",
|
|
1906
|
-
|
|
1914
|
+
mensagem: "CPF do emitente difere do CPF do certificado (F03A, rejeição 227)",
|
|
1907
1915
|
origem: "entrada"
|
|
1908
1916
|
}
|
|
1909
1917
|
];
|
|
@@ -2058,7 +2066,7 @@ function buildIcmsUfDest(ctx, input, path) {
|
|
|
2058
2066
|
// packages/nfe/src/build/build.ts
|
|
2059
2067
|
var padrao;
|
|
2060
2068
|
function calculadoraPadrao() {
|
|
2061
|
-
padrao ??=
|
|
2069
|
+
padrao ??= calculadoraIbsCbs();
|
|
2062
2070
|
return padrao;
|
|
2063
2071
|
}
|
|
2064
2072
|
var NFE_NS3 = "http://www.portalfiscal.inf.br/nfe";
|
|
@@ -2068,7 +2076,7 @@ var MODES = Object.fromEntries(Object.entries(arredondamento_default.familias).m
|
|
|
2068
2076
|
var SEM_GTIN = "SEM GTIN";
|
|
2069
2077
|
var BRASILIA = -180;
|
|
2070
2078
|
function diaBrasilia(d) {
|
|
2071
|
-
return
|
|
2079
|
+
return formatarDh(d, BRASILIA).slice(0, 10);
|
|
2072
2080
|
}
|
|
2073
2081
|
function exigenciaRespTec(uf, ambiente, data) {
|
|
2074
2082
|
const dia = diaBrasilia(data);
|
|
@@ -2087,29 +2095,29 @@ function exigenciaRespTec(uf, ambiente, data) {
|
|
|
2087
2095
|
}
|
|
2088
2096
|
async function hashCsrt(csrt, chave) {
|
|
2089
2097
|
const d = await globalThis.crypto.subtle.digest("SHA-1", new TextEncoder().encode(csrt + chave));
|
|
2090
|
-
return
|
|
2098
|
+
return codificarBase642(new Uint8Array(d));
|
|
2091
2099
|
}
|
|
2092
2100
|
function documento(doc, path, issues) {
|
|
2093
2101
|
if (doc.CNPJ !== undefined) {
|
|
2094
|
-
const r =
|
|
2102
|
+
const r = lerCnpj3(doc.CNPJ, { caminho: `${path}.CNPJ` });
|
|
2095
2103
|
if (!r.ok)
|
|
2096
|
-
issues.list.push(r.
|
|
2097
|
-
return { CNPJ: r.ok ? r.
|
|
2104
|
+
issues.list.push(r.erro);
|
|
2105
|
+
return { CNPJ: r.ok ? r.valor : doc.CNPJ };
|
|
2098
2106
|
}
|
|
2099
|
-
const r =
|
|
2107
|
+
const r = lerCpf(doc.CPF ?? "", { caminho: `${path}.CPF` });
|
|
2100
2108
|
if (!r.ok)
|
|
2101
|
-
issues.list.push(r.
|
|
2102
|
-
return { CPF: r.ok ? r.
|
|
2109
|
+
issues.list.push(r.erro);
|
|
2110
|
+
return { CPF: r.ok ? r.valor : doc.CPF ?? "" };
|
|
2103
2111
|
}
|
|
2104
2112
|
function ie(value, uf, path, issues, allowIsento) {
|
|
2105
2113
|
if (value === undefined)
|
|
2106
2114
|
return;
|
|
2107
|
-
const r =
|
|
2115
|
+
const r = lerIe(value, uf, { caminho: path, aceitarIsento: allowIsento });
|
|
2108
2116
|
if (!r.ok) {
|
|
2109
|
-
issues.list.push(r.
|
|
2117
|
+
issues.list.push(r.erro);
|
|
2110
2118
|
return value;
|
|
2111
2119
|
}
|
|
2112
|
-
return r.
|
|
2120
|
+
return r.valor.valor;
|
|
2113
2121
|
}
|
|
2114
2122
|
function endereco(e) {
|
|
2115
2123
|
return {
|
|
@@ -2129,9 +2137,9 @@ function isExterior(e) {
|
|
|
2129
2137
|
}
|
|
2130
2138
|
function gerarChave(parts, cNFInformado, random, issues) {
|
|
2131
2139
|
const tentar = (cNF) => {
|
|
2132
|
-
const chave =
|
|
2133
|
-
const r =
|
|
2134
|
-
return r.ok ? { chave, ok: true } : { chave, ok: false, issue: r.
|
|
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 };
|
|
2135
2143
|
};
|
|
2136
2144
|
if (cNFInformado !== undefined) {
|
|
2137
2145
|
if (!/^\d{8}$/.test(cNFInformado)) {
|
|
@@ -2143,9 +2151,9 @@ function gerarChave(parts, cNFInformado, random, issues) {
|
|
|
2143
2151
|
const doCnf = r.issue.code === "chave_cnf_invalido";
|
|
2144
2152
|
issues.list.push({
|
|
2145
2153
|
...r.issue,
|
|
2146
|
-
|
|
2154
|
+
caminho: doCnf ? "cNF" : r.issue.caminho,
|
|
2147
2155
|
code: "chave_invalida",
|
|
2148
|
-
|
|
2156
|
+
mensagem: `${r.issue.mensagem} (${r.issue.code})`,
|
|
2149
2157
|
origem: doCnf ? "entrada" : "montagem"
|
|
2150
2158
|
});
|
|
2151
2159
|
}
|
|
@@ -2162,7 +2170,7 @@ function gerarChave(parts, cNFInformado, random, issues) {
|
|
|
2162
2170
|
issues.list.push({
|
|
2163
2171
|
...r.issue,
|
|
2164
2172
|
code: "chave_invalida",
|
|
2165
|
-
|
|
2173
|
+
mensagem: `${r.issue.mensagem} (${r.issue.code})`,
|
|
2166
2174
|
origem: "montagem"
|
|
2167
2175
|
});
|
|
2168
2176
|
return;
|
|
@@ -2173,10 +2181,10 @@ function gerarChave(parts, cNFInformado, random, issues) {
|
|
|
2173
2181
|
}
|
|
2174
2182
|
function referencia(ref, path, issues) {
|
|
2175
2183
|
const chave = (c, p) => {
|
|
2176
|
-
const r =
|
|
2184
|
+
const r = lerChaveAcesso(c, { caminho: p });
|
|
2177
2185
|
if (!r.ok)
|
|
2178
|
-
issues.list.push(r.
|
|
2179
|
-
return r.ok ? r.
|
|
2186
|
+
issues.list.push(r.erro);
|
|
2187
|
+
return r.ok ? r.valor.chave : c;
|
|
2180
2188
|
};
|
|
2181
2189
|
if ("refNFe" in ref)
|
|
2182
2190
|
return { refNFe: chave(ref.refNFe, `${path}.refNFe`) };
|
|
@@ -2196,7 +2204,7 @@ function referencia(ref, path, issues) {
|
|
|
2196
2204
|
const nfp = ref.refNFP;
|
|
2197
2205
|
if (nfp.mod === "04") {
|
|
2198
2206
|
const porUf = produtor_rural_default.refNFP.ufs;
|
|
2199
|
-
const cUfSigla = Object.keys(porUf).find((k) =>
|
|
2207
|
+
const cUfSigla = Object.keys(porUf).find((k) => ufPorSigla2(k)?.cUF === nfp.cUF);
|
|
2200
2208
|
const vedadaDesde = cUfSigla ? porUf[cUfSigla]?.vedadaDesde ?? "" : produtor_rural_default.refNFP.modelo04.vedadaDesde;
|
|
2201
2209
|
if (nfp.AAMM >= vedadaDesde) {
|
|
2202
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})`);
|
|
@@ -2415,11 +2423,11 @@ function montarItem(ctx, item, n, normal) {
|
|
|
2415
2423
|
if (item.obsItem !== undefined)
|
|
2416
2424
|
det.obsItem = item.obsItem;
|
|
2417
2425
|
if (item.DFeReferenciado !== undefined) {
|
|
2418
|
-
const r =
|
|
2426
|
+
const r = lerChaveAcesso(item.DFeReferenciado.chaveAcesso, { caminho: `${path}.DFeReferenciado.chaveAcesso` });
|
|
2419
2427
|
if (!r.ok)
|
|
2420
|
-
ctx.issues.list.push(r.
|
|
2428
|
+
ctx.issues.list.push(r.erro);
|
|
2421
2429
|
det.DFeReferenciado = clean({
|
|
2422
|
-
chaveAcesso: r.ok ? r.
|
|
2430
|
+
chaveAcesso: r.ok ? r.valor.chave : item.DFeReferenciado.chaveAcesso,
|
|
2423
2431
|
nItem: item.DFeReferenciado.nItem === undefined ? undefined : String(item.DFeReferenciado.nItem)
|
|
2424
2432
|
});
|
|
2425
2433
|
}
|
|
@@ -2443,36 +2451,36 @@ function composicao(m, incluirProd) {
|
|
|
2443
2451
|
}
|
|
2444
2452
|
return total;
|
|
2445
2453
|
}
|
|
2446
|
-
async function
|
|
2454
|
+
async function montarNfe(entrada, opcoes) {
|
|
2447
2455
|
const issues = new Issues;
|
|
2448
|
-
const finNFeIn =
|
|
2449
|
-
const mod =
|
|
2456
|
+
const finNFeIn = entrada.finNFe ?? "1";
|
|
2457
|
+
const mod = entrada.modelo ?? "55";
|
|
2450
2458
|
if (mod !== "55" && mod !== "65") {
|
|
2451
2459
|
issues.add("modelo", "modelo_nao_suportado", `modelo ${String(mod)}: o builder monta NF-e (55) e NFC-e (65)`);
|
|
2452
|
-
return { ok: false,
|
|
2460
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2453
2461
|
}
|
|
2454
2462
|
const nfce = mod === "65";
|
|
2455
|
-
const indPres =
|
|
2456
|
-
const indFinal =
|
|
2457
|
-
const ctx = new Ctx(issues, { ...MODES, ...
|
|
2458
|
-
const pRedutorGov =
|
|
2459
|
-
const emitUf =
|
|
2460
|
-
if (!
|
|
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)) {
|
|
2461
2469
|
issues.add("emitente.endereco.UF", "campo_invalido", "UF do emitente inválida");
|
|
2462
|
-
return { ok: false,
|
|
2470
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2463
2471
|
}
|
|
2464
|
-
const cUF =
|
|
2465
|
-
const offset =
|
|
2466
|
-
const agora =
|
|
2467
|
-
const fatoGerador =
|
|
2468
|
-
const dhEmi =
|
|
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);
|
|
2469
2477
|
const aamm = dhEmi.slice(2, 4) + dhEmi.slice(5, 7);
|
|
2470
|
-
const tpAmb =
|
|
2471
|
-
const pl = escolherPl(
|
|
2472
|
-
const e =
|
|
2478
|
+
const tpAmb = tpAmbDoAmbiente2(opcoes.ambiente);
|
|
2479
|
+
const pl = escolherPl(opcoes.ambiente, relogioFixo2(agora));
|
|
2480
|
+
const e = entrada.emitente;
|
|
2473
2481
|
const emitDoc = documento(e, "emitente", issues);
|
|
2474
|
-
const serie = Number(
|
|
2475
|
-
const nNF = Number(
|
|
2482
|
+
const serie = Number(entrada.serie);
|
|
2483
|
+
const nNF = Number(entrada.nNF);
|
|
2476
2484
|
if (!Number.isInteger(serie) || serie < 0 || serie > 999)
|
|
2477
2485
|
issues.add("serie", "serie_invalida", "série de 0 a 999");
|
|
2478
2486
|
if (!Number.isInteger(nNF) || nNF < 1 || nNF > 999999999)
|
|
@@ -2496,7 +2504,7 @@ async function buildNfe(input, options) {
|
|
|
2496
2504
|
CRT: e.CRT,
|
|
2497
2505
|
ISUFEmit: e.ISUFEmit
|
|
2498
2506
|
});
|
|
2499
|
-
const d =
|
|
2507
|
+
const d = entrada.destinatario;
|
|
2500
2508
|
let dest;
|
|
2501
2509
|
let destUf;
|
|
2502
2510
|
if (d === undefined) {
|
|
@@ -2526,7 +2534,7 @@ async function buildNfe(input, options) {
|
|
|
2526
2534
|
const destIe = d.IE !== undefined && destUf !== undefined && destUf !== "EX" ? ie(d.IE, destUf, "destinatario.IE", issues, false) : d.IE;
|
|
2527
2535
|
dest = clean({
|
|
2528
2536
|
...docDest,
|
|
2529
|
-
xNome:
|
|
2537
|
+
xNome: opcoes.ambiente === "homologacao" ? XNOME_HOMOLOGACAO : d.xNome,
|
|
2530
2538
|
enderDest,
|
|
2531
2539
|
indIEDest: d.indIEDest,
|
|
2532
2540
|
IE: destIe,
|
|
@@ -2535,7 +2543,7 @@ async function buildNfe(input, options) {
|
|
|
2535
2543
|
email: d.email
|
|
2536
2544
|
});
|
|
2537
2545
|
}
|
|
2538
|
-
const cont =
|
|
2546
|
+
const cont = entrada.contingencia;
|
|
2539
2547
|
const tpEmis = cont?.tpEmis ?? "1";
|
|
2540
2548
|
if (cont !== undefined) {
|
|
2541
2549
|
if (cont.xJust.length < 15 || cont.xJust.length > 256) {
|
|
@@ -2551,19 +2559,19 @@ async function buildNfe(input, options) {
|
|
|
2551
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)");
|
|
2552
2560
|
}
|
|
2553
2561
|
}
|
|
2554
|
-
const idDest =
|
|
2555
|
-
const tpImp =
|
|
2556
|
-
conferirDestinatario(
|
|
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, {
|
|
2557
2565
|
mod,
|
|
2558
|
-
tpNF:
|
|
2566
|
+
tpNF: entrada.tpNF,
|
|
2559
2567
|
idDest,
|
|
2560
|
-
idDestInformado:
|
|
2568
|
+
idDestInformado: entrada.idDest !== undefined,
|
|
2561
2569
|
indFinal,
|
|
2562
|
-
producao:
|
|
2570
|
+
producao: opcoes.ambiente === "producao"
|
|
2563
2571
|
}, issues);
|
|
2564
2572
|
if (nfce) {
|
|
2565
|
-
conferirNfce(
|
|
2566
|
-
tpNF:
|
|
2573
|
+
conferirNfce(entrada, {
|
|
2574
|
+
tpNF: entrada.tpNF,
|
|
2567
2575
|
idDest,
|
|
2568
2576
|
tpImp,
|
|
2569
2577
|
finNFe: finNFeIn,
|
|
@@ -2573,7 +2581,7 @@ async function buildNfe(input, options) {
|
|
|
2573
2581
|
} else if (tpImp === "4" || tpImp === "5") {
|
|
2574
2582
|
issues.add("tpImp", "campo_invalido", "tpImp 4 e 5 (DANFC-e) são da NFC-e (B21-20, rejeição 710)");
|
|
2575
2583
|
}
|
|
2576
|
-
const qr =
|
|
2584
|
+
const qr = opcoes.qrCode ?? { versao: "3" };
|
|
2577
2585
|
if (nfce && qr.versao === "2") {
|
|
2578
2586
|
if (!/^\d{1,6}$/.test(qr.idCSC) || Number(qr.idCSC) === 0) {
|
|
2579
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)");
|
|
@@ -2585,23 +2593,23 @@ async function buildNfe(input, options) {
|
|
|
2585
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)");
|
|
2586
2594
|
}
|
|
2587
2595
|
}
|
|
2588
|
-
const random =
|
|
2596
|
+
const random = opcoes.aleatorio ?? ((b) => globalThis.crypto.getRandomValues(b));
|
|
2589
2597
|
const emitente14 = "CNPJ" in emitDoc ? emitDoc.CNPJ : emitDoc.CPF;
|
|
2590
|
-
const gerada = issues.empty ? gerarChave({ cUF, aamm, emitente: emitente14, mod, serie: String(serie), nNF: String(nNF), tpEmis },
|
|
2598
|
+
const gerada = issues.empty ? gerarChave({ cUF, aamm, emitente: emitente14, mod, serie: String(serie), nNF: String(nNF), tpEmis }, entrada.cNF, random, issues) : undefined;
|
|
2591
2599
|
const chave = gerada?.chave ?? "0".repeat(44);
|
|
2592
2600
|
const cNF = gerada?.cNF ?? "00000000";
|
|
2593
2601
|
const cDV = chave.slice(43);
|
|
2594
|
-
if (
|
|
2602
|
+
if (entrada.itens.length === 0 || entrada.itens.length > 990) {
|
|
2595
2603
|
issues.add("itens", "itens_limite", "a NF-e tem de 1 a 990 itens");
|
|
2596
2604
|
}
|
|
2597
|
-
const itens =
|
|
2605
|
+
const itens = entrada.itens.map((it, n) => montarItem(ctx, it, n, finNFeIn === "1"));
|
|
2598
2606
|
const primeiro = itens[0];
|
|
2599
|
-
if (nfce &&
|
|
2607
|
+
if (nfce && opcoes.ambiente === "homologacao" && primeiro !== undefined) {
|
|
2600
2608
|
primeiro.det.prod.xProd = XPROD_HOMOLOGACAO_NFCE;
|
|
2601
2609
|
}
|
|
2602
|
-
const classificados =
|
|
2610
|
+
const classificados = entrada.itens.map((it, n) => ({ it, n })).filter(({ it }) => it.impostos.ibsCbs?.classificacao !== undefined);
|
|
2603
2611
|
if (classificados.length > 0) {
|
|
2604
|
-
const calculadora =
|
|
2612
|
+
const calculadora = opcoes.ibsCbs ?? calculadoraPadrao();
|
|
2605
2613
|
const reqs = classificados.map(({ it, n }) => {
|
|
2606
2614
|
const c = it.impostos.ibsCbs?.classificacao;
|
|
2607
2615
|
const m = itens[n];
|
|
@@ -2637,23 +2645,23 @@ async function buildNfe(input, options) {
|
|
|
2637
2645
|
vFCPUFDest: m.v.vFCPUFDest
|
|
2638
2646
|
};
|
|
2639
2647
|
});
|
|
2640
|
-
const destino =
|
|
2641
|
-
const compra =
|
|
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;
|
|
2642
2650
|
const resp = await calculadora.calcular({
|
|
2643
2651
|
nota: {
|
|
2644
2652
|
fatoGerador,
|
|
2645
2653
|
emissao: agora,
|
|
2646
|
-
ambiente:
|
|
2654
|
+
ambiente: opcoes.ambiente,
|
|
2647
2655
|
mod,
|
|
2648
|
-
tpNF:
|
|
2656
|
+
tpNF: entrada.tpNF,
|
|
2649
2657
|
finNFe: finNFeIn,
|
|
2650
|
-
...
|
|
2651
|
-
...
|
|
2658
|
+
...entrada.tpNFDebito ? { tpNFDebito: entrada.tpNFDebito } : {},
|
|
2659
|
+
...entrada.tpNFCredito ? { tpNFCredito: entrada.tpNFCredito } : {},
|
|
2652
2660
|
indFinal,
|
|
2653
2661
|
indPres,
|
|
2654
2662
|
emitente: { UF: emitUf, cMun: e.endereco.cMun, CRT: e.CRT },
|
|
2655
2663
|
...destino ? { destino } : {},
|
|
2656
|
-
...
|
|
2664
|
+
...entrada.cMunFGIBS ? { cMunFGIBS: entrada.cMunFGIBS } : {},
|
|
2657
2665
|
...compra && pRedutorGov ? {
|
|
2658
2666
|
compraGov: {
|
|
2659
2667
|
tpEnteGov: compra.tpEnteGov,
|
|
@@ -2664,7 +2672,7 @@ async function buildNfe(input, options) {
|
|
|
2664
2672
|
},
|
|
2665
2673
|
itens: reqs
|
|
2666
2674
|
});
|
|
2667
|
-
issues.addAll(resp.
|
|
2675
|
+
issues.addAll(resp.ocorrencias ?? [], "montagem");
|
|
2668
2676
|
for (const { n } of classificados) {
|
|
2669
2677
|
const g = resp.itens.find((x) => x.nItem === n + 1);
|
|
2670
2678
|
if (g === undefined) {
|
|
@@ -2678,7 +2686,7 @@ async function buildNfe(input, options) {
|
|
|
2678
2686
|
const imp = m.det.imposto;
|
|
2679
2687
|
const ib = `itens[${n}].impostos.ibsCbs`;
|
|
2680
2688
|
const is = `itens[${n}].impostos.is`;
|
|
2681
|
-
const ibsDaCalculadora =
|
|
2689
|
+
const ibsDaCalculadora = entrada.itens[n]?.impostos.ibsCbs?.grupo === undefined;
|
|
2682
2690
|
const antes = issues.list.length;
|
|
2683
2691
|
decimaisInvalidos(imp.IBSCBS, ib, issues);
|
|
2684
2692
|
if (ibsDaCalculadora)
|
|
@@ -2692,7 +2700,7 @@ async function buildNfe(input, options) {
|
|
|
2692
2700
|
}
|
|
2693
2701
|
});
|
|
2694
2702
|
if (!issues.empty)
|
|
2695
|
-
return { ok: false,
|
|
2703
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2696
2704
|
const gruposIbsCbs = itens.map((m) => m.det.imposto.IBSCBS).filter((g) => g !== undefined);
|
|
2697
2705
|
const somaTributosNoItem = diaBrasilia(fatoGerador) >= reforma_default.vItemSomaTributosDesde;
|
|
2698
2706
|
let vNFTot = Decimal.ZERO;
|
|
@@ -2789,39 +2797,39 @@ async function buildNfe(input, options) {
|
|
|
2789
2797
|
const ide = clean({
|
|
2790
2798
|
cUF,
|
|
2791
2799
|
cNF,
|
|
2792
|
-
natOp:
|
|
2800
|
+
natOp: entrada.natOp,
|
|
2793
2801
|
mod,
|
|
2794
2802
|
serie: String(serie),
|
|
2795
2803
|
nNF: String(nNF),
|
|
2796
2804
|
dhEmi,
|
|
2797
|
-
dhSaiEnt:
|
|
2798
|
-
dPrevEntrega:
|
|
2799
|
-
tpNF:
|
|
2805
|
+
dhSaiEnt: entrada.dhSaiEnt === undefined ? undefined : formatarDh(entrada.dhSaiEnt, offset),
|
|
2806
|
+
dPrevEntrega: entrada.dPrevEntrega,
|
|
2807
|
+
tpNF: entrada.tpNF,
|
|
2800
2808
|
idDest,
|
|
2801
|
-
cMunFG:
|
|
2802
|
-
cMunFGIBS:
|
|
2809
|
+
cMunFG: entrada.cMunFG ?? e.endereco.cMun,
|
|
2810
|
+
cMunFGIBS: entrada.cMunFGIBS,
|
|
2803
2811
|
tpImp,
|
|
2804
2812
|
tpEmis,
|
|
2805
2813
|
cDV,
|
|
2806
2814
|
tpAmb,
|
|
2807
2815
|
finNFe,
|
|
2808
|
-
tpNFDebito:
|
|
2809
|
-
tpNFCredito:
|
|
2816
|
+
tpNFDebito: entrada.tpNFDebito,
|
|
2817
|
+
tpNFCredito: entrada.tpNFCredito,
|
|
2810
2818
|
indFinal,
|
|
2811
2819
|
indPres,
|
|
2812
|
-
indIntermed:
|
|
2820
|
+
indIntermed: entrada.indIntermed ?? (["2", "3", "4", "9"].includes(indPres) ? "0" : undefined),
|
|
2813
2821
|
procEmi: "0",
|
|
2814
|
-
verProc:
|
|
2815
|
-
dhCont: cont === undefined ? undefined :
|
|
2822
|
+
verProc: opcoes.verProc ?? formatarVerProc("sinete", VERSAO_PACOTE),
|
|
2823
|
+
dhCont: cont === undefined ? undefined : formatarDh(cont.dhCont, offset),
|
|
2816
2824
|
xJust: cont?.xJust,
|
|
2817
|
-
NFref:
|
|
2818
|
-
gCompraGov:
|
|
2819
|
-
tpEnteGov:
|
|
2825
|
+
NFref: entrada.referenciadas?.map((r, n) => referencia(r, `referenciadas[${n}]`, issues)),
|
|
2826
|
+
gCompraGov: entrada.gCompraGov === undefined ? undefined : clean({
|
|
2827
|
+
tpEnteGov: entrada.gCompraGov.tpEnteGov,
|
|
2820
2828
|
pRedutor: ctx.s(pRedutorGov ?? Decimal.ZERO, D0302A04),
|
|
2821
|
-
tpOperGov:
|
|
2822
|
-
refDFeAnt:
|
|
2829
|
+
tpOperGov: entrada.gCompraGov.tpOperGov,
|
|
2830
|
+
refDFeAnt: entrada.gCompraGov.refDFeAnt
|
|
2823
2831
|
}),
|
|
2824
|
-
gPagAntecipado:
|
|
2832
|
+
gPagAntecipado: entrada.gPagAntecipado === undefined ? undefined : { refNFe: [...entrada.gPagAntecipado] }
|
|
2825
2833
|
});
|
|
2826
2834
|
const local = (l, path) => l === undefined ? undefined : clean({
|
|
2827
2835
|
...documento(l, path, issues),
|
|
@@ -2832,10 +2840,10 @@ async function buildNfe(input, options) {
|
|
|
2832
2840
|
email: l.email,
|
|
2833
2841
|
IE: l.IE
|
|
2834
2842
|
});
|
|
2835
|
-
if ((
|
|
2843
|
+
if ((entrada.autXML?.length ?? 0) > 10)
|
|
2836
2844
|
issues.add("autXML", "campo_invalido", "no máximo 10 autorizados");
|
|
2837
|
-
const autXML =
|
|
2838
|
-
const tr =
|
|
2845
|
+
const autXML = entrada.autXML?.map((a, n) => documento(a, `autXML[${n}]`, issues));
|
|
2846
|
+
const tr = entrada.transporte;
|
|
2839
2847
|
const transp = { modFrete: tr?.modFrete ?? "9" };
|
|
2840
2848
|
if (tr?.transportador !== undefined) {
|
|
2841
2849
|
const t = tr.transportador;
|
|
@@ -2876,8 +2884,8 @@ async function buildNfe(input, options) {
|
|
|
2876
2884
|
}));
|
|
2877
2885
|
}
|
|
2878
2886
|
let cobr;
|
|
2879
|
-
if (
|
|
2880
|
-
const c =
|
|
2887
|
+
if (entrada.cobranca !== undefined) {
|
|
2888
|
+
const c = entrada.cobranca;
|
|
2881
2889
|
cobr = {};
|
|
2882
2890
|
if (c.fatura !== undefined) {
|
|
2883
2891
|
const f = c.fatura;
|
|
@@ -2901,10 +2909,10 @@ async function buildNfe(input, options) {
|
|
|
2901
2909
|
}));
|
|
2902
2910
|
}
|
|
2903
2911
|
}
|
|
2904
|
-
const pagIn =
|
|
2905
|
-
const igualTotal =
|
|
2912
|
+
const pagIn = entrada.pagamento ?? { detPag: [{ tPag: "90", vPag: "0" }] };
|
|
2913
|
+
const igualTotal = opcoes.pagamentoIgualTotal === true;
|
|
2906
2914
|
if (igualTotal) {
|
|
2907
|
-
const unico =
|
|
2915
|
+
const unico = entrada.pagamento?.detPag.length === 1 ? entrada.pagamento.detPag[0] : undefined;
|
|
2908
2916
|
if (unico === undefined) {
|
|
2909
2917
|
issues.add("pagamento.detPag", "pagamento_igual_total", "pagamentoIgualTotal pede exatamente um detPag");
|
|
2910
2918
|
} else if (unico.tPag === "90") {
|
|
@@ -2924,13 +2932,13 @@ async function buildNfe(input, options) {
|
|
|
2924
2932
|
})),
|
|
2925
2933
|
vTroco: ctx.so(ctx.opt(pagIn.vTroco, "pagamento.vTroco", D1302), D1302)
|
|
2926
2934
|
});
|
|
2927
|
-
if (nfce &&
|
|
2935
|
+
if (nfce && entrada.pagamento !== undefined && entrada.pagamento.detPag.length > 0 && issues.empty) {
|
|
2928
2936
|
pagamentoNfce(pag, vNF, issues);
|
|
2929
2937
|
}
|
|
2930
2938
|
if (nfce && vNF.gt(Decimal.of(NFCE_LIMITE_SEM_DESTINATARIO)) && dest === undefined) {
|
|
2931
2939
|
issues.add("destinatario", "campo_obrigatorio", `NFC-e acima de R$ ${NFCE_LIMITE_SEM_DESTINATARIO} identifica o destinatário (W16-40, rejeição 750)`);
|
|
2932
2940
|
}
|
|
2933
|
-
const ia =
|
|
2941
|
+
const ia = entrada.informacoesAdicionais;
|
|
2934
2942
|
const infAdic = ia === undefined || Object.values(ia).every((x) => x === undefined) ? undefined : clean({
|
|
2935
2943
|
infAdFisco: ia.infAdFisco,
|
|
2936
2944
|
infCpl: ia.infCpl,
|
|
@@ -2938,19 +2946,19 @@ async function buildNfe(input, options) {
|
|
|
2938
2946
|
obsFisco: ia.obsFisco,
|
|
2939
2947
|
procRef: ia.procRef
|
|
2940
2948
|
});
|
|
2941
|
-
const exig = { ...exigenciaRespTec(emitUf,
|
|
2942
|
-
const rt =
|
|
2949
|
+
const exig = { ...exigenciaRespTec(emitUf, opcoes.ambiente, agora), ...opcoes.exigencias };
|
|
2950
|
+
const rt = entrada.respTec ?? opcoes.respTec;
|
|
2943
2951
|
let infRespTec;
|
|
2944
2952
|
if (rt === undefined) {
|
|
2945
2953
|
if (exig.infRespTec === "obrigatorio") {
|
|
2946
2954
|
issues.add("respTec", "resp_tec_obrigatorio", `a UF ${emitUf} exige o responsável técnico (rejeição 972)`);
|
|
2947
2955
|
}
|
|
2948
2956
|
} else {
|
|
2949
|
-
const cnpjRt =
|
|
2957
|
+
const cnpjRt = lerCnpj3(rt.CNPJ, { caminho: "respTec.CNPJ" });
|
|
2950
2958
|
if (!cnpjRt.ok)
|
|
2951
|
-
issues.list.push(cnpjRt.
|
|
2959
|
+
issues.list.push(cnpjRt.erro);
|
|
2952
2960
|
infRespTec = {
|
|
2953
|
-
CNPJ: cnpjRt.ok ? cnpjRt.
|
|
2961
|
+
CNPJ: cnpjRt.ok ? cnpjRt.valor : rt.CNPJ,
|
|
2954
2962
|
xContato: rt.xContato,
|
|
2955
2963
|
email: rt.email,
|
|
2956
2964
|
fone: digits(rt.fone)
|
|
@@ -2968,66 +2976,69 @@ async function buildNfe(input, options) {
|
|
|
2968
2976
|
ide,
|
|
2969
2977
|
emit,
|
|
2970
2978
|
dest,
|
|
2971
|
-
retirada: local(
|
|
2972
|
-
entrega: local(
|
|
2979
|
+
retirada: local(entrada.retirada, "retirada"),
|
|
2980
|
+
entrega: local(entrada.entrega, "entrega"),
|
|
2973
2981
|
autXML,
|
|
2974
2982
|
det: itens.map((m) => m.det),
|
|
2975
2983
|
total,
|
|
2976
2984
|
transp,
|
|
2977
2985
|
cobr,
|
|
2978
2986
|
pag,
|
|
2979
|
-
infIntermed:
|
|
2987
|
+
infIntermed: entrada.infIntermed,
|
|
2980
2988
|
infAdic,
|
|
2981
|
-
exporta:
|
|
2982
|
-
compra:
|
|
2983
|
-
cana:
|
|
2989
|
+
exporta: entrada.exporta,
|
|
2990
|
+
compra: entrada.compra,
|
|
2991
|
+
cana: entrada.cana,
|
|
2984
2992
|
infRespTec,
|
|
2985
|
-
agropecuario:
|
|
2993
|
+
agropecuario: entrada.agropecuario
|
|
2986
2994
|
});
|
|
2987
|
-
cstComIsento(
|
|
2988
|
-
vencimentos(
|
|
2995
|
+
cstComIsento(entrada, idDest, issues);
|
|
2996
|
+
vencimentos(entrada, { dhEmi, instante: agora }, issues);
|
|
2989
2997
|
camposForaDoPl(pl.infNFe, inf, "infNFe", pl.vigencia.pl, issues);
|
|
2990
2998
|
textosForaDoXml(inf, "infNFe", issues);
|
|
2991
2999
|
if (!issues.empty)
|
|
2992
|
-
return { ok: false,
|
|
3000
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
2993
3001
|
let xml;
|
|
2994
3002
|
try {
|
|
2995
|
-
xml = `<NFe xmlns="${NFE_NS3}">${
|
|
3003
|
+
xml = `<NFe xmlns="${NFE_NS3}">${serializar2(pl.infNFe, "infNFe", inf, NFE_NS3)}</NFe>`;
|
|
2996
3004
|
} catch (e) {
|
|
2997
|
-
if (!(e instanceof
|
|
3005
|
+
if (!(e instanceof ErroSerializacao))
|
|
2998
3006
|
throw e;
|
|
2999
|
-
return {
|
|
3007
|
+
return {
|
|
3008
|
+
ok: false,
|
|
3009
|
+
ocorrencias: [{ caminho: e.caminho, code: "schema", mensagem: e.message, origem: "montagem" }]
|
|
3010
|
+
};
|
|
3000
3011
|
}
|
|
3001
|
-
const doc =
|
|
3002
|
-
const infEl =
|
|
3003
|
-
const schemaIssues = infEl === undefined ? [] :
|
|
3012
|
+
const doc = lerXml3(xml);
|
|
3013
|
+
const infEl = primeiroFilho3(doc.raiz, "infNFe", NFE_NS3);
|
|
3014
|
+
const schemaIssues = infEl === undefined ? [] : validar3(pl.infNFe, infEl);
|
|
3004
3015
|
if (schemaIssues.length > 0) {
|
|
3005
3016
|
return {
|
|
3006
3017
|
ok: false,
|
|
3007
|
-
|
|
3008
|
-
|
|
3018
|
+
ocorrencias: schemaIssues.map((i) => ({
|
|
3019
|
+
caminho: i.caminho,
|
|
3009
3020
|
code: "schema",
|
|
3010
|
-
|
|
3021
|
+
mensagem: `${i.code}: ${i.mensagem}`,
|
|
3011
3022
|
origem: "montagem"
|
|
3012
3023
|
}))
|
|
3013
3024
|
};
|
|
3014
3025
|
}
|
|
3015
3026
|
let supl;
|
|
3016
3027
|
if (nfce) {
|
|
3017
|
-
const tabela = urlsNfce(emitUf,
|
|
3018
|
-
const urlQr =
|
|
3019
|
-
const urlChave =
|
|
3028
|
+
const tabela = urlsNfce(emitUf, opcoes.ambiente, diaBrasilia(agora));
|
|
3029
|
+
const urlQr = opcoes.urlQrCode ?? tabela.qrCode;
|
|
3030
|
+
const urlChave = opcoes.urlChave ?? tabela.urlChave;
|
|
3020
3031
|
if (urlQr === undefined || !/^https?:\/\//i.test(urlQr)) {
|
|
3021
|
-
issues.montagem("urlQrCode", "qrcode_invalido", `sem endereço completo do QR Code da NFC-e para ${emitUf} em ${
|
|
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)`);
|
|
3022
3033
|
}
|
|
3023
3034
|
if (urlChave === undefined) {
|
|
3024
3035
|
issues.montagem("urlChave", "qrcode_invalido", `sem URL de consulta por chave da NFC-e para ${emitUf}: informe urlChave`);
|
|
3025
3036
|
}
|
|
3026
3037
|
if (urlQr === undefined || urlChave === undefined || !issues.empty)
|
|
3027
|
-
return { ok: false,
|
|
3038
|
+
return { ok: false, ocorrencias: issues.classificadas };
|
|
3028
3039
|
const p = await parametrosQrCode({
|
|
3029
3040
|
chave,
|
|
3030
|
-
ambiente:
|
|
3041
|
+
ambiente: opcoes.ambiente,
|
|
3031
3042
|
tpEmis,
|
|
3032
3043
|
dhEmi,
|
|
3033
3044
|
vNF: inf.total.ICMSTot.vNF,
|
|
@@ -3037,11 +3048,11 @@ async function buildNfe(input, options) {
|
|
|
3037
3048
|
supl = { versao: qr.versao, urlChave, base: `${urlQr.replace(/\?+$/, "")}?p=`, ...p };
|
|
3038
3049
|
const suplIssues = conferirSupl(inserirSupl({ xml, nfce: supl }, supl.assinar ? ASSINATURA_2048 : undefined));
|
|
3039
3050
|
if (suplIssues.length > 0)
|
|
3040
|
-
return { ok: false,
|
|
3051
|
+
return { ok: false, ocorrencias: suplIssues };
|
|
3041
3052
|
}
|
|
3042
3053
|
return {
|
|
3043
3054
|
ok: true,
|
|
3044
|
-
|
|
3055
|
+
valor: {
|
|
3045
3056
|
chave,
|
|
3046
3057
|
id: `NFe${chave}`,
|
|
3047
3058
|
cNF,
|
|
@@ -3056,22 +3067,27 @@ async function buildNfe(input, options) {
|
|
|
3056
3067
|
}
|
|
3057
3068
|
};
|
|
3058
3069
|
}
|
|
3059
|
-
var ASSINATURA_2048 =
|
|
3070
|
+
var ASSINATURA_2048 = codificarBase642(new Uint8Array(256));
|
|
3060
3071
|
function conferirSupl(xml) {
|
|
3061
|
-
const el =
|
|
3062
|
-
const erros = el === undefined ? [] :
|
|
3063
|
-
return erros.map((i) => ({
|
|
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
|
+
}));
|
|
3064
3080
|
}
|
|
3065
3081
|
var escapeXml = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
3066
|
-
async function assinaturaQrCode(
|
|
3067
|
-
return
|
|
3082
|
+
async function assinaturaQrCode(nota, assinador) {
|
|
3083
|
+
return nota.nfce?.assinar === true ? assinarParametros(nota.nfce.parametros, assinador) : undefined;
|
|
3068
3084
|
}
|
|
3069
|
-
function comQrCode(
|
|
3070
|
-
const xml = inserirSupl(
|
|
3085
|
+
function comQrCode(nota, assinatura) {
|
|
3086
|
+
const xml = inserirSupl(nota, assinatura);
|
|
3071
3087
|
if (assinatura !== undefined) {
|
|
3072
3088
|
const issues = conferirSupl(xml);
|
|
3073
3089
|
if (issues.length > 0)
|
|
3074
|
-
throw new
|
|
3090
|
+
throw new ErroDeValidacao("o QR Code da NFC-e não passou no schema", issues);
|
|
3075
3091
|
}
|
|
3076
3092
|
return xml;
|
|
3077
3093
|
}
|
|
@@ -3079,24 +3095,24 @@ function inserirSupl(built, assinatura) {
|
|
|
3079
3095
|
const s = built.nfce;
|
|
3080
3096
|
if (s === undefined) {
|
|
3081
3097
|
if (assinatura !== undefined)
|
|
3082
|
-
throw new
|
|
3098
|
+
throw new ErroDeConfiguracao2("a NF-e (modelo 55) não tem QR Code");
|
|
3083
3099
|
return built.xml;
|
|
3084
3100
|
}
|
|
3085
3101
|
if (s.assinar && assinatura === undefined) {
|
|
3086
|
-
throw new
|
|
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)");
|
|
3087
3103
|
}
|
|
3088
3104
|
if (!s.assinar && assinatura !== undefined) {
|
|
3089
|
-
throw new
|
|
3105
|
+
throw new ErroDeConfiguracao2("este QR Code não leva assinatura (ZX02-330, rejeição 445)");
|
|
3090
3106
|
}
|
|
3091
3107
|
const fim = "</NFe>";
|
|
3092
3108
|
if (!built.xml.endsWith(fim))
|
|
3093
|
-
throw new
|
|
3109
|
+
throw new ErroDeConfiguracao2("NFC-e montada fora da forma esperada");
|
|
3094
3110
|
const qrCode = `${s.base}${s.parametros}${assinatura === undefined ? "" : `|${assinatura}`}`;
|
|
3095
3111
|
const supl = `<infNFeSupl><qrCode>${escapeXml(qrCode)}</qrCode><urlChave>${escapeXml(s.urlChave)}</urlChave></infNFeSupl>`;
|
|
3096
3112
|
return built.xml.slice(0, -fim.length) + supl + fim;
|
|
3097
3113
|
}
|
|
3098
|
-
async function
|
|
3099
|
-
return
|
|
3114
|
+
async function assinarNfe(nota, assinador) {
|
|
3115
|
+
return assinarXml(comQrCode(nota, await assinaturaQrCode(nota, assinador)), { id: nota.id }, assinador);
|
|
3100
3116
|
}
|
|
3101
3117
|
// packages/nfe/src/model.ts
|
|
3102
3118
|
var MotivoDesoneracaoIcms = {
|
|
@@ -3246,24 +3262,24 @@ var CAMPOS = {
|
|
|
3246
3262
|
infAdFisco: "Informações de interesse do fisco"
|
|
3247
3263
|
};
|
|
3248
3264
|
var rotular = criarRotuloDoCaminho({ grupos: GRUPOS, campos: CAMPOS, padrao: "Dados da NF-e" });
|
|
3249
|
-
function rotuloDoCaminho(
|
|
3250
|
-
return rotular(
|
|
3265
|
+
function rotuloDoCaminho(caminho) {
|
|
3266
|
+
return rotular(caminho);
|
|
3251
3267
|
}
|
|
3252
3268
|
// packages/nfe/src/services/client.ts
|
|
3253
3269
|
import {
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
|
|
3262
|
-
|
|
3263
|
-
|
|
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
|
|
3264
3280
|
} from "@sinete/core";
|
|
3265
|
-
import {
|
|
3266
|
-
import {
|
|
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";
|
|
3267
3283
|
import { ConsCadElement, TRetConsCad } from "@sinete/schemas/nfe/consulta-cadastro/PL_010d";
|
|
3268
3284
|
import { consSitNFeElement, TProtNFe, TRetConsSitNFe } from "@sinete/schemas/nfe/consulta-protocolo/PL_010d";
|
|
3269
3285
|
import {
|
|
@@ -3283,32 +3299,32 @@ import { TInutNFe_infInut, TRetInutNFe } from "@sinete/schemas/nfe/inutilizacao/
|
|
|
3283
3299
|
import { TRetConsReciNFe, TRetEnviNFe } from "@sinete/schemas/nfe/PL_010f";
|
|
3284
3300
|
import { consStatServElement, TRetConsStatServ } from "@sinete/schemas/nfe/status-servico/PL_009q";
|
|
3285
3301
|
import { nfceEndpoint, nfeContingenciaDaUf, nfeEndpoint } from "@sinete/transport";
|
|
3286
|
-
import {
|
|
3302
|
+
import { lerChaveAcesso as lerChaveAcesso2, lerCnpj as lerCnpj4, lerCpf as lerCpf2 } from "@sinete/validators";
|
|
3287
3303
|
|
|
3288
3304
|
// packages/nfe/src/services/gzip.ts
|
|
3289
|
-
import {
|
|
3290
|
-
import {
|
|
3291
|
-
async function
|
|
3305
|
+
import { ErroNaoSuportado as ErroNaoSuportado2, ErroRespostaInvalida } from "@sinete/core";
|
|
3306
|
+
import { decodificarBase64 } from "@sinete/core/xml";
|
|
3307
|
+
async function descomprimirGzipBase64(b64) {
|
|
3292
3308
|
const Ds = globalThis.DecompressionStream;
|
|
3293
3309
|
if (Ds === undefined)
|
|
3294
|
-
throw new
|
|
3310
|
+
throw new ErroNaoSuportado2("DecompressionStream indisponível nesta runtime; docZip não pode ser lido");
|
|
3295
3311
|
let bytes;
|
|
3296
3312
|
try {
|
|
3297
|
-
bytes =
|
|
3313
|
+
bytes = decodificarBase64(b64.trim());
|
|
3298
3314
|
} catch (cause) {
|
|
3299
|
-
throw new
|
|
3315
|
+
throw new ErroRespostaInvalida("docZip com base64 inválido", { cause });
|
|
3300
3316
|
}
|
|
3301
3317
|
try {
|
|
3302
3318
|
const stream = new Blob([bytes]).stream().pipeThrough(new Ds("gzip"));
|
|
3303
3319
|
return await new Response(stream).text();
|
|
3304
3320
|
} catch (cause) {
|
|
3305
|
-
throw new
|
|
3321
|
+
throw new ErroRespostaInvalida("docZip não é um gzip válido", { cause });
|
|
3306
3322
|
}
|
|
3307
3323
|
}
|
|
3308
3324
|
|
|
3309
3325
|
// packages/nfe/src/services/outcome.ts
|
|
3310
|
-
import {
|
|
3311
|
-
import {
|
|
3326
|
+
import { criarRecusado } from "@sinete/core";
|
|
3327
|
+
import { completarRecusado } from "@sinete/rejeicoes";
|
|
3312
3328
|
// packages/nfe/src/data/cstat.json
|
|
3313
3329
|
var cstat_default = {
|
|
3314
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.",
|
|
@@ -3335,14 +3351,14 @@ var cstat_default = {
|
|
|
3335
3351
|
consumoIndevido: ["656"],
|
|
3336
3352
|
dicas: {
|
|
3337
3353
|
"656": {
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
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"
|
|
3341
3357
|
},
|
|
3342
3358
|
"217": {
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
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"
|
|
3346
3362
|
}
|
|
3347
3363
|
}
|
|
3348
3364
|
};
|
|
@@ -3354,68 +3370,68 @@ function cstatEm(cStat, classe) {
|
|
|
3354
3370
|
return CLASSES[classe].includes(cStat);
|
|
3355
3371
|
}
|
|
3356
3372
|
function rejeitado(status) {
|
|
3357
|
-
const r =
|
|
3358
|
-
if (r.
|
|
3373
|
+
const r = completarRecusado(criarRecusado(status));
|
|
3374
|
+
if (r.dica !== undefined)
|
|
3359
3375
|
return r;
|
|
3360
3376
|
const dica = Object.hasOwn(DICAS, status.cStat) ? DICAS[status.cStat] : undefined;
|
|
3361
|
-
return dica === undefined ? r :
|
|
3377
|
+
return dica === undefined ? r : criarRecusado(status, dica);
|
|
3362
3378
|
}
|
|
3363
3379
|
|
|
3364
3380
|
// packages/nfe/src/services/proc.ts
|
|
3365
|
-
import {
|
|
3381
|
+
import { ErroDeConfiguracao as ErroDeConfiguracao3, ErroRespostaInvalida as ErroRespostaInvalida2 } from "@sinete/core";
|
|
3366
3382
|
import {
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3383
|
+
atributoDe,
|
|
3384
|
+
descendentes,
|
|
3385
|
+
lerXml as lerXml4,
|
|
3386
|
+
namespacesEmEscopo,
|
|
3387
|
+
primeiroFilho as primeiroFilho4,
|
|
3388
|
+
textoDe,
|
|
3373
3389
|
XMLDSIG_NS
|
|
3374
3390
|
} from "@sinete/core/xml";
|
|
3375
3391
|
var NFE_NS4 = "http://www.portalfiscal.inf.br/nfe";
|
|
3376
3392
|
var XML_DECL = /^?<\?xml[^?]*\?>\s*/;
|
|
3377
|
-
function
|
|
3378
|
-
const slice =
|
|
3393
|
+
function recortarElemento(documento, el, nsPadraoDoPai = NFE_NS4) {
|
|
3394
|
+
const slice = documento.texto.slice(el.inicio, el.fim);
|
|
3379
3395
|
const used = new Set;
|
|
3380
3396
|
const cobertoDentro = (d, p) => {
|
|
3381
|
-
for (let e = d;e; e = e === el ? null : e.
|
|
3397
|
+
for (let e = d;e; e = e === el ? null : e.pai)
|
|
3382
3398
|
if (e.namespaces.has(p))
|
|
3383
3399
|
return true;
|
|
3384
3400
|
return false;
|
|
3385
3401
|
};
|
|
3386
|
-
for (const d of
|
|
3387
|
-
const prefixos = [d.
|
|
3402
|
+
for (const d of descendentes(el)) {
|
|
3403
|
+
const prefixos = [d.prefixo, ...d.atributos.map((a) => a.prefixo)].filter((p) => p !== "" && p !== "xml");
|
|
3388
3404
|
for (const p of prefixos)
|
|
3389
3405
|
if (!cobertoDentro(d, p))
|
|
3390
3406
|
used.add(p);
|
|
3391
3407
|
}
|
|
3392
3408
|
const extra = [];
|
|
3393
3409
|
const inScope = new Map;
|
|
3394
|
-
for (let e = el.
|
|
3410
|
+
for (let e = el.pai;e; e = e.pai) {
|
|
3395
3411
|
for (const [p, u] of e.namespaces)
|
|
3396
3412
|
if (!inScope.has(p))
|
|
3397
3413
|
inScope.set(p, u);
|
|
3398
3414
|
}
|
|
3399
3415
|
const herdado = inScope.get("") ?? "";
|
|
3400
|
-
if (herdado !==
|
|
3416
|
+
if (herdado !== nsPadraoDoPai && usaDefaultHerdado(el))
|
|
3401
3417
|
extra.push(` xmlns="${herdado}"`);
|
|
3402
3418
|
for (const p of [...used].sort()) {
|
|
3403
3419
|
const uri = inScope.get(p);
|
|
3404
3420
|
if (uri === undefined)
|
|
3405
|
-
throw new
|
|
3421
|
+
throw new ErroRespostaInvalida2(`prefixo ${p} sem declaração no recorte de ${el.nome}`);
|
|
3406
3422
|
extra.push(` xmlns:${p}="${uri}"`);
|
|
3407
3423
|
}
|
|
3408
3424
|
if (extra.length === 0)
|
|
3409
3425
|
return slice;
|
|
3410
|
-
const at = 1 + el.
|
|
3426
|
+
const at = 1 + el.nome.length;
|
|
3411
3427
|
return slice.slice(0, at) + extra.join("") + slice.slice(at);
|
|
3412
3428
|
}
|
|
3413
3429
|
function usaDefaultHerdado(raiz) {
|
|
3414
|
-
for (const d of
|
|
3415
|
-
if (d.
|
|
3430
|
+
for (const d of descendentes(raiz)) {
|
|
3431
|
+
if (d.prefixo !== "")
|
|
3416
3432
|
continue;
|
|
3417
3433
|
let coberto = false;
|
|
3418
|
-
for (let e = d;e; e = e === raiz ? null : e.
|
|
3434
|
+
for (let e = d;e; e = e === raiz ? null : e.pai) {
|
|
3419
3435
|
if (e.namespaces.has("")) {
|
|
3420
3436
|
coberto = true;
|
|
3421
3437
|
break;
|
|
@@ -3430,46 +3446,46 @@ function documentoAssinado(xml, raiz, elemento) {
|
|
|
3430
3446
|
const text = xml.replace(XML_DECL, "");
|
|
3431
3447
|
let doc;
|
|
3432
3448
|
try {
|
|
3433
|
-
doc =
|
|
3449
|
+
doc = lerXml4(text);
|
|
3434
3450
|
} catch (cause) {
|
|
3435
|
-
throw new
|
|
3451
|
+
throw new ErroDeConfiguracao3(`${raiz} assinado malformado`, { cause });
|
|
3436
3452
|
}
|
|
3437
|
-
if (doc.
|
|
3438
|
-
throw new
|
|
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}>`);
|
|
3439
3455
|
}
|
|
3440
|
-
if (doc.
|
|
3441
|
-
throw new
|
|
3456
|
+
if (doc.raiz.namespaces.get("") !== NFE_NS4) {
|
|
3457
|
+
throw new ErroDeConfiguracao3(`<${raiz}> assinado precisa declarar xmlns="${NFE_NS4}" na própria raiz`);
|
|
3442
3458
|
}
|
|
3443
|
-
const alvo =
|
|
3444
|
-
const id = alvo ?
|
|
3445
|
-
const sig =
|
|
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);
|
|
3446
3462
|
const digest = sig && descendantText(sig, "DigestValue");
|
|
3447
3463
|
if (!id || digest === undefined)
|
|
3448
|
-
throw new
|
|
3449
|
-
return { xml: text, id, digestValue: digest, doc };
|
|
3464
|
+
throw new ErroDeConfiguracao3(`${raiz} sem ${elemento} identificado ou sem assinatura`);
|
|
3465
|
+
return { xml: text, id, digestValue: digest, documento: doc };
|
|
3450
3466
|
}
|
|
3451
3467
|
function descendantText(el, local) {
|
|
3452
|
-
for (const d of
|
|
3468
|
+
for (const d of descendentes(el))
|
|
3453
3469
|
if (d.local === local && d.ns === XMLDSIG_NS)
|
|
3454
|
-
return
|
|
3470
|
+
return textoDe(d).trim();
|
|
3455
3471
|
return;
|
|
3456
3472
|
}
|
|
3457
3473
|
function nfeAssinadaDoProc(xml) {
|
|
3458
3474
|
const text = xml.replace(XML_DECL, "");
|
|
3459
3475
|
let doc;
|
|
3460
3476
|
try {
|
|
3461
|
-
doc =
|
|
3477
|
+
doc = lerXml4(text);
|
|
3462
3478
|
} catch (cause) {
|
|
3463
|
-
throw new
|
|
3479
|
+
throw new ErroDeConfiguracao3("nfeProc malformado", { cause });
|
|
3464
3480
|
}
|
|
3465
|
-
const noProc = doc.
|
|
3466
|
-
const el = noProc ?? (doc.
|
|
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);
|
|
3467
3483
|
if (el === undefined)
|
|
3468
|
-
throw new
|
|
3469
|
-
const fatia = doc.
|
|
3470
|
-
const herdados = [...
|
|
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));
|
|
3471
3487
|
const decl = herdados.map(([p, uri]) => ` ${p === "" ? "xmlns" : `xmlns:${p}`}="${uri.replace(/&/g, "&").replace(/</g, "<").replace(/"/g, """)}"`).join("");
|
|
3472
|
-
const at = 1 + el.
|
|
3488
|
+
const at = 1 + el.nome.length;
|
|
3473
3489
|
const assinado = decl === "" ? fatia : fatia.slice(0, at) + decl + fatia.slice(at);
|
|
3474
3490
|
return documentoAssinado(assinado, "NFe", "infNFe").xml;
|
|
3475
3491
|
}
|
|
@@ -3478,9 +3494,9 @@ function envelope(raiz, versao, partes) {
|
|
|
3478
3494
|
}
|
|
3479
3495
|
|
|
3480
3496
|
// packages/nfe/src/services/soap.ts
|
|
3481
|
-
import {
|
|
3482
|
-
import {
|
|
3483
|
-
import {
|
|
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";
|
|
3484
3500
|
// packages/nfe/src/data/servicos.json
|
|
3485
3501
|
var servicos_default = {
|
|
3486
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.",
|
|
@@ -3532,7 +3548,7 @@ var SERVICOS = servicos_default.servicos;
|
|
|
3532
3548
|
function servicoInfo(servico) {
|
|
3533
3549
|
const s = SERVICOS[servico];
|
|
3534
3550
|
if (!s)
|
|
3535
|
-
throw new
|
|
3551
|
+
throw new ErroRespostaInvalida3(`serviço sem descrição em data/servicos.json: ${servico}`);
|
|
3536
3552
|
return s;
|
|
3537
3553
|
}
|
|
3538
3554
|
function soapBodyFor(servico, mensagem, autorizador) {
|
|
@@ -3545,62 +3561,62 @@ function soapBodyFor(servico, mensagem, autorizador) {
|
|
|
3545
3561
|
async function chamar(c) {
|
|
3546
3562
|
const s = servicoInfo(c.servico);
|
|
3547
3563
|
const started = { servico: c.servico, autorizador: c.endpoint.autorizador, host: c.endpoint.host };
|
|
3548
|
-
const res = await c.transport.
|
|
3564
|
+
const res = await c.transport.enviar({
|
|
3549
3565
|
url: c.endpoint.url,
|
|
3550
3566
|
endpoint: c.endpoint,
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3567
|
+
metodo: "POST",
|
|
3568
|
+
cabecalhos: { "content-type": contentTypeSoap12(`${s.namespace}/${s.operacao}`) },
|
|
3569
|
+
corpo: envelopeSoap12(soapBodyFor(c.servico, c.mensagem, c.endpoint.autorizador)),
|
|
3554
3570
|
...c.timeoutMs === undefined ? {} : { timeoutMs: c.timeoutMs },
|
|
3555
3571
|
...c.signal === undefined ? {} : { signal: c.signal }
|
|
3556
3572
|
});
|
|
3557
|
-
const text = res.
|
|
3558
|
-
const fault =
|
|
3573
|
+
const text = res.texto();
|
|
3574
|
+
const fault = lerSoapFault(text);
|
|
3559
3575
|
if (fault) {
|
|
3560
3576
|
c.logger.warn("nfe.soap.fault", { ...started, status: res.status, code: fault.code });
|
|
3561
|
-
throw new
|
|
3562
|
-
|
|
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 }
|
|
3563
3579
|
});
|
|
3564
3580
|
}
|
|
3565
3581
|
let doc;
|
|
3566
3582
|
try {
|
|
3567
|
-
doc =
|
|
3583
|
+
doc = lerXml5(text.replace(/^/, ""));
|
|
3568
3584
|
} catch (cause) {
|
|
3569
|
-
throw new
|
|
3585
|
+
throw new ErroRespostaInvalida3(`resposta de ${c.endpoint.host} não é XML (HTTP ${res.status})`, {
|
|
3570
3586
|
cause,
|
|
3571
|
-
|
|
3587
|
+
detalhes: { status: res.status, servico: c.servico }
|
|
3572
3588
|
});
|
|
3573
3589
|
}
|
|
3574
3590
|
let ret;
|
|
3575
|
-
for (const el of
|
|
3591
|
+
for (const el of descendentes2(doc.raiz)) {
|
|
3576
3592
|
if (el.local === c.retorno && el.ns === NFE_NS4) {
|
|
3577
3593
|
ret = el;
|
|
3578
3594
|
break;
|
|
3579
3595
|
}
|
|
3580
3596
|
}
|
|
3581
3597
|
if (!ret)
|
|
3582
|
-
ret = retornoForaDoNamespace(doc.
|
|
3598
|
+
ret = retornoForaDoNamespace(doc.raiz, c.retorno);
|
|
3583
3599
|
if (ret && ret.ns !== NFE_NS4) {
|
|
3584
3600
|
c.logger.warn("nfe.soap.retorno_fora_do_namespace", { ...started, retorno: c.retorno, ns: ret.ns });
|
|
3585
3601
|
}
|
|
3586
3602
|
if (!ret) {
|
|
3587
|
-
throw new
|
|
3588
|
-
|
|
3603
|
+
throw new ErroRespostaInvalida3(`resposta de ${c.endpoint.host} sem <${c.retorno}> (HTTP ${res.status})`, {
|
|
3604
|
+
detalhes: { status: res.status, servico: c.servico }
|
|
3589
3605
|
});
|
|
3590
3606
|
}
|
|
3591
|
-
if (!Array.from(
|
|
3592
|
-
throw new
|
|
3593
|
-
|
|
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 }
|
|
3594
3610
|
});
|
|
3595
3611
|
}
|
|
3596
3612
|
c.logger.debug("nfe.soap.resposta", { ...started, status: res.status });
|
|
3597
3613
|
return { doc, ret, status: res.status };
|
|
3598
3614
|
}
|
|
3599
3615
|
function retornoForaDoNamespace(root, retorno) {
|
|
3600
|
-
for (const el of
|
|
3616
|
+
for (const el of descendentes2(root)) {
|
|
3601
3617
|
if (el.local !== retorno)
|
|
3602
3618
|
continue;
|
|
3603
|
-
const filhos =
|
|
3619
|
+
const filhos = elementosFilhos(el);
|
|
3604
3620
|
if (filhos.length > 0 && filhos.every((f) => f.ns === NFE_NS4))
|
|
3605
3621
|
return el;
|
|
3606
3622
|
}
|
|
@@ -3628,26 +3644,26 @@ var defaultSleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
3628
3644
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
3629
3645
|
});
|
|
3630
3646
|
function chaveValida(chave, path) {
|
|
3631
|
-
const r =
|
|
3647
|
+
const r = lerChaveAcesso2(chave, { caminho: path });
|
|
3632
3648
|
if (!r.ok)
|
|
3633
|
-
throw new
|
|
3634
|
-
return r.
|
|
3649
|
+
throw new ErroDeValidacao2(`chave de acesso inválida: ${r.erro.mensagem}`, [r.erro]);
|
|
3650
|
+
return r.valor;
|
|
3635
3651
|
}
|
|
3636
3652
|
function schemaIssues(what, issues) {
|
|
3637
3653
|
if (issues.length > 0)
|
|
3638
|
-
throw new
|
|
3654
|
+
throw new ErroDeValidacao2(`${what} não confere com o schema`, issues);
|
|
3639
3655
|
}
|
|
3640
3656
|
function documentoAutor(a, path) {
|
|
3641
3657
|
if (a.CNPJ !== undefined) {
|
|
3642
|
-
const r =
|
|
3658
|
+
const r = lerCnpj4(a.CNPJ, { caminho: `${path}.CNPJ` });
|
|
3643
3659
|
if (!r.ok)
|
|
3644
|
-
throw new
|
|
3645
|
-
return { CNPJ: r.
|
|
3660
|
+
throw new ErroDeValidacao2("CNPJ do autor inválido", [r.erro]);
|
|
3661
|
+
return { CNPJ: r.valor };
|
|
3646
3662
|
}
|
|
3647
|
-
const r =
|
|
3663
|
+
const r = lerCpf2(a.CPF ?? "", { caminho: `${path}.CPF` });
|
|
3648
3664
|
if (!r.ok)
|
|
3649
|
-
throw new
|
|
3650
|
-
return { CPF: r.
|
|
3665
|
+
throw new ErroDeValidacao2("CPF do autor inválido", [r.erro]);
|
|
3666
|
+
return { CPF: r.valor };
|
|
3651
3667
|
}
|
|
3652
3668
|
function autorDaChave(c) {
|
|
3653
3669
|
return c.cnpj !== undefined ? { CNPJ: c.cnpj } : { CPF: c.cpf ?? c.emitente.slice(3) };
|
|
@@ -3659,11 +3675,11 @@ function autorDoEmitente(a, c) {
|
|
|
3659
3675
|
const autor = documentoAutor(a, "autor");
|
|
3660
3676
|
const [campo, valor] = "CNPJ" in autor ? ["CNPJ", autor.CNPJ] : ["CPF", autor.CPF];
|
|
3661
3677
|
if (valor !== ("CNPJ" in daChave ? daChave.CNPJ : daChave.CPF) || campo !== ("CNPJ" in daChave ? "CNPJ" : "CPF")) {
|
|
3662
|
-
throw new
|
|
3678
|
+
throw new ErroDeValidacao2("o autor do evento não é o emitente da NF-e", [
|
|
3663
3679
|
{
|
|
3664
|
-
|
|
3680
|
+
caminho: `autor.${campo}`,
|
|
3665
3681
|
code: "autor_difere_do_emitente",
|
|
3666
|
-
|
|
3682
|
+
mensagem: `o autor de um evento do emitente é o ${"CNPJ" in daChave ? "CNPJ" : "CPF"} da chave (P12-44, rejeição 574)`,
|
|
3667
3683
|
origem: "entrada"
|
|
3668
3684
|
}
|
|
3669
3685
|
]);
|
|
@@ -3672,19 +3688,19 @@ function autorDoEmitente(a, c) {
|
|
|
3672
3688
|
}
|
|
3673
3689
|
var SVC_DO_TPEMIS = { "6": "SVC-AN", "7": "SVC-RS" };
|
|
3674
3690
|
function chaveDoDocumento(a) {
|
|
3675
|
-
const r =
|
|
3691
|
+
const r = lerChaveAcesso2(a.id.slice(3), { caminho: "infNFe.Id", conferirEmitente: false });
|
|
3676
3692
|
if (!r.ok)
|
|
3677
|
-
throw new
|
|
3678
|
-
return r.
|
|
3693
|
+
throw new ErroDeConfiguracao4(`Id da NF-e assinada não é uma chave de acesso: ${r.erro.mensagem}`);
|
|
3694
|
+
return r.valor;
|
|
3679
3695
|
}
|
|
3680
3696
|
function avulso(doc, el) {
|
|
3681
|
-
return
|
|
3697
|
+
return recortarElemento(doc, el, "");
|
|
3682
3698
|
}
|
|
3683
3699
|
function lerProtocolo(doc, el) {
|
|
3684
|
-
const { value } =
|
|
3700
|
+
const { valor: value } = decodificar(TProtNFe, el, doc.texto);
|
|
3685
3701
|
const inf = value.infProt;
|
|
3686
3702
|
if (!inf)
|
|
3687
|
-
throw new
|
|
3703
|
+
throw new ErroRespostaInvalida4("protNFe sem infProt");
|
|
3688
3704
|
const p = {
|
|
3689
3705
|
chNFe: inf.chNFe,
|
|
3690
3706
|
cStat: inf.cStat,
|
|
@@ -3695,7 +3711,7 @@ function lerProtocolo(doc, el) {
|
|
|
3695
3711
|
...inf.nProt === undefined ? {} : { nProt: inf.nProt },
|
|
3696
3712
|
...inf.digVal === undefined ? {} : { digVal: inf.digVal }
|
|
3697
3713
|
};
|
|
3698
|
-
return { p, embutido:
|
|
3714
|
+
return { p, embutido: recortarElemento(doc, el) };
|
|
3699
3715
|
}
|
|
3700
3716
|
function desfechoDoProtocolo({ p, embutido }, a) {
|
|
3701
3717
|
const status = { cStat: p.cStat, xMotivo: p.xMotivo };
|
|
@@ -3706,27 +3722,27 @@ function desfechoDoProtocolo({ p, embutido }, a) {
|
|
|
3706
3722
|
let full = p;
|
|
3707
3723
|
if (a) {
|
|
3708
3724
|
if (`NFe${p.chNFe}` !== a.id) {
|
|
3709
|
-
throw new
|
|
3725
|
+
throw new ErroRespostaInvalida4("protocolo de outra chave de acesso", { detalhes: { chNFe: p.chNFe } });
|
|
3710
3726
|
}
|
|
3711
3727
|
if (p.digVal !== undefined && p.digVal !== a.digestValue) {
|
|
3712
|
-
throw new
|
|
3713
|
-
|
|
3728
|
+
throw new ErroRespostaInvalida4("digVal do protocolo difere do DigestValue da NF-e enviada", {
|
|
3729
|
+
detalhes: { chNFe: p.chNFe, cStat: p.cStat }
|
|
3714
3730
|
});
|
|
3715
3731
|
}
|
|
3716
3732
|
if (p.digVal !== undefined)
|
|
3717
3733
|
full = { ...p, nfeProc: envelope("nfeProc", "4.00", [a.xml, embutido]) };
|
|
3718
3734
|
}
|
|
3719
|
-
return autorizada ?
|
|
3735
|
+
return autorizada ? criarAutorizado(status, full) : criarDenegado(status, full);
|
|
3720
3736
|
}
|
|
3721
3737
|
function protNFeDaChave(parent, a) {
|
|
3722
|
-
const prots =
|
|
3738
|
+
const prots = elementosFilhos2(parent).filter((e) => e.local === "protNFe" && e.ns === NFE_NS4);
|
|
3723
3739
|
if (!a)
|
|
3724
3740
|
return prots[0];
|
|
3725
3741
|
const chave = a.id.slice(3);
|
|
3726
3742
|
return prots.find((e) => {
|
|
3727
|
-
const inf =
|
|
3728
|
-
const ch = inf &&
|
|
3729
|
-
return ch !== undefined &&
|
|
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;
|
|
3730
3746
|
}) ?? (prots.length === 1 ? prots[0] : undefined);
|
|
3731
3747
|
}
|
|
3732
3748
|
var EVENTO_VERSAO = "1.00";
|
|
@@ -3737,36 +3753,39 @@ var MANIFESTACOES = {
|
|
|
3737
3753
|
desconhecimento: { tpEvento: "210220", descEvento: "Desconhecimento da Operacao", ct: TEventoDesconhecimento },
|
|
3738
3754
|
"nao-realizada": { tpEvento: "210240", descEvento: "Operacao nao Realizada", ct: TEventoNaoRealizada }
|
|
3739
3755
|
};
|
|
3740
|
-
function
|
|
3741
|
-
const logger = (
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
|
|
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)}`);
|
|
3747
3766
|
const ufPadrao = (servico) => {
|
|
3748
|
-
if (
|
|
3749
|
-
throw new
|
|
3767
|
+
if (opcoesDoCliente.uf === undefined || ufInfo === undefined) {
|
|
3768
|
+
throw new ErroDeConfiguracao4(`${servico} precisa da UF: informe ClienteNfeOpcoes.uf`);
|
|
3750
3769
|
}
|
|
3751
|
-
return { uf:
|
|
3770
|
+
return { uf: opcoesDoCliente.uf, cUF: ufInfo.cUF };
|
|
3752
3771
|
};
|
|
3753
|
-
const offsetDe = (uf) =>
|
|
3772
|
+
const offsetDe = (uf) => opcoesDoCliente.deslocamentoMin ?? deslocamentoDaUf(uf);
|
|
3754
3773
|
const idLote = () => {
|
|
3755
|
-
const id =
|
|
3774
|
+
const id = opcoesDoCliente.idLote ? opcoesDoCliente.idLote() : String(opcoesDoCliente.relogio.agora().getTime()).slice(-15);
|
|
3756
3775
|
if (!/^[0-9]{1,15}$/.test(id))
|
|
3757
|
-
throw new
|
|
3776
|
+
throw new ErroDeConfiguracao4(`idLote inválido: ${id}`);
|
|
3758
3777
|
return id;
|
|
3759
3778
|
};
|
|
3760
|
-
const endpointNfce = (servico, uf) =>
|
|
3779
|
+
const endpointNfce = (servico, uf) => opcoesDoCliente.endpointNfce ? opcoesDoCliente.endpointNfce(servico, uf) : nfceEndpoint({ ambiente: opcoesDoCliente.ambiente, servico, uf });
|
|
3761
3780
|
const endpoint = (servico, mod = "55") => {
|
|
3762
3781
|
const { uf } = ufPadrao(servico);
|
|
3763
3782
|
if (mod === "65")
|
|
3764
3783
|
return endpointNfce(servico, uf);
|
|
3765
3784
|
return nfeEndpoint({
|
|
3766
|
-
ambiente:
|
|
3785
|
+
ambiente: opcoesDoCliente.ambiente,
|
|
3767
3786
|
servico,
|
|
3768
3787
|
uf,
|
|
3769
|
-
...
|
|
3788
|
+
...opcoesDoCliente.contingencia === undefined ? {} : { contingencia: opcoesDoCliente.contingencia }
|
|
3770
3789
|
});
|
|
3771
3790
|
};
|
|
3772
3791
|
const endpointDaChave = (servico, c, naUf = false) => {
|
|
@@ -3774,76 +3793,78 @@ function createNfeClient(options) {
|
|
|
3774
3793
|
return endpointNfce(servico, c.uf);
|
|
3775
3794
|
const svc = naUf || c.tpEmis === undefined ? undefined : SVC_DO_TPEMIS[c.tpEmis];
|
|
3776
3795
|
return nfeEndpoint({
|
|
3777
|
-
ambiente:
|
|
3796
|
+
ambiente: opcoesDoCliente.ambiente,
|
|
3778
3797
|
servico,
|
|
3779
3798
|
...svc === undefined ? { uf: c.uf } : { autorizador: svc }
|
|
3780
3799
|
});
|
|
3781
3800
|
};
|
|
3782
3801
|
const call = (ep, servico, mensagem, retorno, signal) => chamar({
|
|
3783
|
-
transport:
|
|
3802
|
+
transport: opcoesDoCliente.transporte,
|
|
3784
3803
|
endpoint: ep,
|
|
3785
3804
|
servico,
|
|
3786
3805
|
mensagem,
|
|
3787
3806
|
retorno,
|
|
3788
3807
|
logger,
|
|
3789
|
-
...
|
|
3808
|
+
...opcoesDoCliente.timeoutMs === undefined ? {} : { timeoutMs: opcoesDoCliente.timeoutMs },
|
|
3790
3809
|
...signal === undefined ? {} : { signal }
|
|
3791
3810
|
});
|
|
3792
3811
|
const autorPadrao = (a, path) => {
|
|
3793
|
-
const autor = a ??
|
|
3812
|
+
const autor = a ?? opcoesDoCliente.autor;
|
|
3794
3813
|
if (!autor)
|
|
3795
|
-
throw new
|
|
3814
|
+
throw new ErroDeConfiguracao4(`informe o CNPJ ou CPF do autor (${path} ou ClienteNfeOpcoes.autor)`);
|
|
3796
3815
|
return documentoAutor(autor, path);
|
|
3797
3816
|
};
|
|
3798
3817
|
async function consultarRecibo(nRec, nfeAssinada, opcoes = {}) {
|
|
3799
3818
|
if (!/^[0-9]{15}$/.test(nRec))
|
|
3800
|
-
throw new
|
|
3819
|
+
throw new ErroDeConfiguracao4(`número de recibo inválido: ${nRec}`);
|
|
3801
3820
|
const a = nfeAssinada === undefined ? undefined : documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
3802
3821
|
const c = a === undefined ? undefined : chaveDoDocumento(a);
|
|
3803
3822
|
if (c !== undefined && opcoes.mod !== undefined && opcoes.mod !== c.mod) {
|
|
3804
|
-
throw new
|
|
3823
|
+
throw new ErroDeConfiguracao4(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
|
|
3805
3824
|
}
|
|
3806
3825
|
const msg = envelope("consReciNFe", "4.00", [`<tpAmb>${tpAmb}</tpAmb><nRec>${nRec}</nRec>`]);
|
|
3807
3826
|
const ep = c === undefined ? endpoint("NFeRetAutorizacao", opcoes.mod ?? "55") : endpointDaChave("NFeRetAutorizacao", c);
|
|
3808
3827
|
const r = await call(ep, "NFeRetAutorizacao", msg, "retConsReciNFe", opcoes.signal);
|
|
3809
|
-
const v =
|
|
3828
|
+
const v = decodificar(TRetConsReciNFe, r.ret, r.doc.texto).valor;
|
|
3810
3829
|
if (v.nRec !== undefined && v.nRec !== nRec) {
|
|
3811
|
-
throw new
|
|
3830
|
+
throw new ErroRespostaInvalida4("retorno de outro recibo", { detalhes: { nRec: v.nRec } });
|
|
3812
3831
|
}
|
|
3813
3832
|
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3814
3833
|
logger.info("nfe.recibo", { nRec, cStat: v.cStat });
|
|
3815
3834
|
if (cstatEm(v.cStat, "loteEmProcessamento") || cstatEm(v.cStat, "loteRecebido"))
|
|
3816
|
-
return
|
|
3835
|
+
return criarPendente(status, { referencia: nRec });
|
|
3817
3836
|
if (cstatEm(v.cStat, "loteProcessado")) {
|
|
3818
3837
|
const el = protNFeDaChave(r.ret, a);
|
|
3819
3838
|
if (!el)
|
|
3820
|
-
throw new
|
|
3839
|
+
throw new ErroRespostaInvalida4("lote processado sem o protNFe da NF-e", { detalhes: { nRec } });
|
|
3821
3840
|
return desfechoDoProtocolo(lerProtocolo(r.doc, el), a);
|
|
3822
3841
|
}
|
|
3823
3842
|
return rejeitado(status);
|
|
3824
3843
|
}
|
|
3825
|
-
async function consultar(chave, nfeAssinada) {
|
|
3844
|
+
async function consultar(chave, nfeAssinada, opcoes) {
|
|
3826
3845
|
const c = chaveValida(chave, "chNFe");
|
|
3827
3846
|
const a = nfeAssinada === undefined ? undefined : documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
3828
3847
|
if (a && a.id !== `NFe${c.chave}`)
|
|
3829
|
-
throw new
|
|
3830
|
-
const msg =
|
|
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 });
|
|
3831
3850
|
const ep = endpointDaChave("NfeConsultaProtocolo", c);
|
|
3832
|
-
const r = await call(ep, "NfeConsultaProtocolo", msg, "retConsSitNFe");
|
|
3833
|
-
const v =
|
|
3851
|
+
const r = await call(ep, "NfeConsultaProtocolo", msg, "retConsSitNFe", opcoes?.signal);
|
|
3852
|
+
const v = decodificar(TRetConsSitNFe, r.ret, r.doc.texto).valor;
|
|
3834
3853
|
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3835
3854
|
logger.info("nfe.consulta", { chNFe: c.chave, cStat: v.cStat });
|
|
3836
3855
|
const situacao = cstatEm(v.cStat, "autorizada") ? "autorizada" : cstatEm(v.cStat, "cancelada") ? "cancelada" : cstatEm(v.cStat, "denegada") ? "denegada" : undefined;
|
|
3837
3856
|
if (situacao === undefined)
|
|
3838
3857
|
return rejeitado(status);
|
|
3839
|
-
const protEl =
|
|
3840
|
-
const eventos =
|
|
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));
|
|
3841
3860
|
let protocolo;
|
|
3842
3861
|
let digValConfere;
|
|
3843
3862
|
if (protEl) {
|
|
3844
3863
|
const { p, embutido } = lerProtocolo(r.doc, protEl);
|
|
3845
3864
|
if (p.chNFe !== c.chave) {
|
|
3846
|
-
throw new
|
|
3865
|
+
throw new ErroRespostaInvalida4("protocolo de outra chave de acesso na consulta", {
|
|
3866
|
+
detalhes: { chNFe: p.chNFe }
|
|
3867
|
+
});
|
|
3847
3868
|
}
|
|
3848
3869
|
protocolo = p;
|
|
3849
3870
|
if (a) {
|
|
@@ -3859,12 +3880,12 @@ function createNfeClient(options) {
|
|
|
3859
3880
|
...protocolo === undefined ? {} : { protocolo },
|
|
3860
3881
|
...digValConfere === undefined ? {} : { digValConfere }
|
|
3861
3882
|
};
|
|
3862
|
-
return situacao === "denegada" ?
|
|
3883
|
+
return situacao === "denegada" ? criarDenegado(status, value) : criarAutorizado(status, value);
|
|
3863
3884
|
}
|
|
3864
3885
|
async function enviarEvento(p) {
|
|
3865
3886
|
const nSeq = p.nSeqEvento;
|
|
3866
3887
|
if (!Number.isInteger(nSeq) || nSeq < 1 || nSeq > 99)
|
|
3867
|
-
throw new
|
|
3888
|
+
throw new ErroDeConfiguracao4(`nSeqEvento inválido: ${nSeq}`);
|
|
3868
3889
|
const nSeqEvento = String(nSeq);
|
|
3869
3890
|
const id = `ID${p.tpEvento}${p.chave}${nSeqEvento.padStart(2, "0")}`;
|
|
3870
3891
|
const inf = {
|
|
@@ -3873,62 +3894,62 @@ function createNfeClient(options) {
|
|
|
3873
3894
|
tpAmb,
|
|
3874
3895
|
...p.autor,
|
|
3875
3896
|
chNFe: p.chave,
|
|
3876
|
-
dhEvento:
|
|
3897
|
+
dhEvento: formatarDh(opcoesDoCliente.relogio.agora(), p.offsetMinutes),
|
|
3877
3898
|
tpEvento: p.tpEvento,
|
|
3878
3899
|
nSeqEvento,
|
|
3879
3900
|
verEvento: EVENTO_VERSAO,
|
|
3880
3901
|
detEvento: p.detEvento
|
|
3881
3902
|
};
|
|
3882
|
-
const infXml =
|
|
3903
|
+
const infXml = serializar3(p.ct, "infEvento", inf, NFE_NS4);
|
|
3883
3904
|
const evento = `<evento xmlns="${NFE_NS4}" versao="${EVENTO_VERSAO}">${infXml}</evento>`;
|
|
3884
|
-
const infEl =
|
|
3885
|
-
schemaIssues("evento",
|
|
3886
|
-
const assinado = await
|
|
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);
|
|
3887
3908
|
const msg = envelope("envEvento", EVENTO_VERSAO, [`<idLote>${idLote()}</idLote>`, assinado]);
|
|
3888
|
-
const r = await call(p.endpoint, "RecepcaoEvento", msg, "retEnvEvento");
|
|
3889
|
-
const v =
|
|
3909
|
+
const r = await call(p.endpoint, "RecepcaoEvento", msg, "retEnvEvento", p.signal);
|
|
3910
|
+
const v = decodificar(TRetEnvEvento, r.ret, r.doc.texto).valor;
|
|
3890
3911
|
logger.info("nfe.evento", { chNFe: p.chave, tpEvento: p.tpEvento, cStat: v.cStat });
|
|
3891
3912
|
if (!cstatEm(v.cStat, "loteEventoProcessado"))
|
|
3892
3913
|
return rejeitado({ cStat: v.cStat, xMotivo: v.xMotivo });
|
|
3893
|
-
const retEl =
|
|
3914
|
+
const retEl = elementosFilhos2(r.ret).find((e) => e.local === "retEvento" && e.ns === NFE_NS4);
|
|
3894
3915
|
const ret = v.retEvento?.[0]?.infEvento;
|
|
3895
3916
|
if (!retEl || !ret)
|
|
3896
|
-
throw new
|
|
3917
|
+
throw new ErroRespostaInvalida4("lote de evento processado sem retEvento");
|
|
3897
3918
|
const divergentes = [
|
|
3898
3919
|
["chNFe", ret.chNFe, p.chave],
|
|
3899
3920
|
["tpEvento", ret.tpEvento, p.tpEvento],
|
|
3900
3921
|
["nSeqEvento", ret.nSeqEvento === undefined ? undefined : String(Number(ret.nSeqEvento)), nSeqEvento]
|
|
3901
3922
|
].filter(([, veio, enviado]) => veio !== undefined && veio !== enviado);
|
|
3902
3923
|
if (divergentes.length > 0) {
|
|
3903
|
-
throw new
|
|
3904
|
-
|
|
3924
|
+
throw new ErroRespostaInvalida4("retEvento de outro evento", {
|
|
3925
|
+
detalhes: Object.fromEntries(divergentes.map(([k, veio]) => [k, veio]))
|
|
3905
3926
|
});
|
|
3906
3927
|
}
|
|
3907
3928
|
const status = { cStat: ret.cStat, xMotivo: ret.xMotivo };
|
|
3908
3929
|
if (!cstatEm(ret.cStat, "eventoRegistrado"))
|
|
3909
3930
|
return rejeitado(status);
|
|
3910
|
-
return
|
|
3931
|
+
return criarAutorizado(status, {
|
|
3911
3932
|
chNFe: p.chave,
|
|
3912
3933
|
tpEvento: p.tpEvento,
|
|
3913
3934
|
nSeqEvento,
|
|
3914
3935
|
dhRegEvento: ret.dhRegEvento,
|
|
3915
3936
|
retEvento: avulso(r.doc, retEl),
|
|
3916
|
-
procEventoNFe: envelope("procEventoNFe", EVENTO_VERSAO, [assinado,
|
|
3937
|
+
procEventoNFe: envelope("procEventoNFe", EVENTO_VERSAO, [assinado, recortarElemento(r.doc, retEl)]),
|
|
3917
3938
|
...ret.nProt === undefined ? {} : { nProt: ret.nProt }
|
|
3918
3939
|
});
|
|
3919
3940
|
}
|
|
3920
3941
|
const client = {
|
|
3921
|
-
|
|
3942
|
+
opcoes: opcoesDoCliente,
|
|
3922
3943
|
async statusServico(opcoes) {
|
|
3923
3944
|
const { cUF } = ufPadrao("NfeStatusServico");
|
|
3924
|
-
const msg =
|
|
3925
|
-
const r = await call(endpoint("NfeStatusServico", opcoes?.mod), "NfeStatusServico", msg, "retConsStatServ");
|
|
3926
|
-
const v =
|
|
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;
|
|
3927
3948
|
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3928
3949
|
logger.info("nfe.status", { cStat: v.cStat });
|
|
3929
3950
|
if (!cstatEm(v.cStat, "servicoEmOperacao"))
|
|
3930
3951
|
return rejeitado(status);
|
|
3931
|
-
return
|
|
3952
|
+
return criarAutorizado(status, {
|
|
3932
3953
|
cUF: v.cUF,
|
|
3933
3954
|
verAplic: v.verAplic,
|
|
3934
3955
|
dhRecbto: v.dhRecbto,
|
|
@@ -3946,15 +3967,15 @@ function createNfeClient(options) {
|
|
|
3946
3967
|
]);
|
|
3947
3968
|
const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a));
|
|
3948
3969
|
const r = await call(ep, "NFeAutorizacao", msg, "retEnviNFe", opcoes.signal);
|
|
3949
|
-
const v =
|
|
3970
|
+
const v = decodificar(TRetEnviNFe, r.ret, r.doc.texto).valor;
|
|
3950
3971
|
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
3951
3972
|
logger.info("nfe.autorizacao", { chNFe: a.id.slice(3), cStat: v.cStat, sincrono });
|
|
3952
3973
|
if (cstatEm(v.cStat, "loteRecebido")) {
|
|
3953
3974
|
const nRec = v.infRec?.nRec;
|
|
3954
3975
|
if (!nRec)
|
|
3955
|
-
throw new
|
|
3976
|
+
throw new ErroRespostaInvalida4("lote recebido sem número de recibo");
|
|
3956
3977
|
const tMed = Number(v.infRec?.tMed ?? "0");
|
|
3957
|
-
return
|
|
3978
|
+
return criarPendente(status, { referencia: nRec, aguardarMs: Math.max(1, tMed) * 1000 });
|
|
3958
3979
|
}
|
|
3959
3980
|
const protEl = protNFeDaChave(r.ret, a);
|
|
3960
3981
|
if (protEl)
|
|
@@ -3968,21 +3989,23 @@ function createNfeClient(options) {
|
|
|
3968
3989
|
const mult = politica.multiplicador ?? 1.5;
|
|
3969
3990
|
const teto = politica.esperaMaximaMs ?? 30000;
|
|
3970
3991
|
if (!(max >= 1) || !(minimo >= 0) || !(mult >= 1) || !(teto >= minimo)) {
|
|
3971
|
-
throw new
|
|
3992
|
+
throw new ErroDeConfiguracao4("política de consulta do recibo inválida", {
|
|
3993
|
+
detalhes: { max, minimo, mult, teto }
|
|
3994
|
+
});
|
|
3972
3995
|
}
|
|
3973
3996
|
let espera = minimo;
|
|
3974
3997
|
let ultimo;
|
|
3975
3998
|
for (let i = 0;i < max; i++) {
|
|
3976
3999
|
await sleep(espera, politica.signal);
|
|
3977
4000
|
ultimo = await consultarRecibo(nRec, nfeAssinada, politica);
|
|
3978
|
-
if (ultimo.
|
|
4001
|
+
if (ultimo.tipo !== "pendente")
|
|
3979
4002
|
return ultimo;
|
|
3980
|
-
espera = Math.min(teto, Math.max(minimo, Math.round(espera * mult), ultimo.
|
|
4003
|
+
espera = Math.min(teto, Math.max(minimo, Math.round(espera * mult), ultimo.aguardarMs ?? 0));
|
|
3981
4004
|
}
|
|
3982
4005
|
return ultimo;
|
|
3983
4006
|
},
|
|
3984
4007
|
consultar,
|
|
3985
|
-
async cancelar(p) {
|
|
4008
|
+
async cancelar(p, opcoes) {
|
|
3986
4009
|
const c = chaveValida(p.chave, "chave");
|
|
3987
4010
|
return enviarEvento({
|
|
3988
4011
|
ct: TEventoCanc,
|
|
@@ -3993,17 +4016,18 @@ function createNfeClient(options) {
|
|
|
3993
4016
|
autor: autorDoEmitente(p.autor, c),
|
|
3994
4017
|
detEvento: { versao: EVENTO_VERSAO, descEvento: "Cancelamento", nProt: p.nProt, xJust: p.xJust },
|
|
3995
4018
|
endpoint: endpointDaChave("RecepcaoEvento", c),
|
|
3996
|
-
offsetMinutes: offsetDe(c.uf)
|
|
4019
|
+
offsetMinutes: offsetDe(c.uf),
|
|
4020
|
+
signal: opcoes?.signal
|
|
3997
4021
|
});
|
|
3998
4022
|
},
|
|
3999
|
-
async cancelarPorSubstituicao(p) {
|
|
4023
|
+
async cancelarPorSubstituicao(p, opcoes) {
|
|
4000
4024
|
const c = chaveValida(p.chave, "chave");
|
|
4001
4025
|
if (c.mod !== "65") {
|
|
4002
|
-
throw new
|
|
4026
|
+
throw new ErroDeValidacao2("cancelamento por substituição só existe para NFC-e", [
|
|
4003
4027
|
{
|
|
4004
|
-
|
|
4028
|
+
caminho: "chave",
|
|
4005
4029
|
code: "modelo_nao_suportado",
|
|
4006
|
-
|
|
4030
|
+
mensagem: "O evento 110112 é exclusivo da NFC-e (modelo 65)"
|
|
4007
4031
|
}
|
|
4008
4032
|
]);
|
|
4009
4033
|
}
|
|
@@ -4027,13 +4051,14 @@ function createNfeClient(options) {
|
|
|
4027
4051
|
autor: autorDoEmitente(p.autor, c),
|
|
4028
4052
|
detEvento,
|
|
4029
4053
|
endpoint: endpointDaChave("RecepcaoEvento", c),
|
|
4030
|
-
offsetMinutes: offsetDe(c.uf)
|
|
4054
|
+
offsetMinutes: offsetDe(c.uf),
|
|
4055
|
+
signal: opcoes?.signal
|
|
4031
4056
|
});
|
|
4032
4057
|
},
|
|
4033
|
-
async cartaCorrecao(p) {
|
|
4058
|
+
async cartaCorrecao(p, opcoes) {
|
|
4034
4059
|
const c = chaveValida(p.chave, "chave");
|
|
4035
4060
|
if (!Number.isInteger(p.nSeqEvento) || p.nSeqEvento < 1 || p.nSeqEvento > 20) {
|
|
4036
|
-
throw new
|
|
4061
|
+
throw new ErroDeConfiguracao4(`nSeqEvento da CC-e vai de 1 a 20: ${p.nSeqEvento}`);
|
|
4037
4062
|
}
|
|
4038
4063
|
return enviarEvento({
|
|
4039
4064
|
ct: TEventoCce,
|
|
@@ -4049,14 +4074,15 @@ function createNfeClient(options) {
|
|
|
4049
4074
|
xCondUso: XCONDUSO
|
|
4050
4075
|
},
|
|
4051
4076
|
endpoint: endpointDaChave("RecepcaoEvento", c, true),
|
|
4052
|
-
offsetMinutes: offsetDe(c.uf)
|
|
4077
|
+
offsetMinutes: offsetDe(c.uf),
|
|
4078
|
+
signal: opcoes?.signal
|
|
4053
4079
|
});
|
|
4054
4080
|
},
|
|
4055
|
-
async manifestar(p) {
|
|
4081
|
+
async manifestar(p, opcoes) {
|
|
4056
4082
|
const c = chaveValida(p.chave, "chave");
|
|
4057
4083
|
const m = MANIFESTACOES[p.tipo];
|
|
4058
4084
|
if (!m)
|
|
4059
|
-
throw new
|
|
4085
|
+
throw new ErroDeConfiguracao4(`tipo de manifestação desconhecido: ${String(p.tipo)}`);
|
|
4060
4086
|
return enviarEvento({
|
|
4061
4087
|
ct: m.ct,
|
|
4062
4088
|
tpEvento: m.tpEvento,
|
|
@@ -4069,18 +4095,19 @@ function createNfeClient(options) {
|
|
|
4069
4095
|
descEvento: m.descEvento,
|
|
4070
4096
|
...p.xJust === undefined ? {} : { xJust: p.xJust }
|
|
4071
4097
|
},
|
|
4072
|
-
endpoint: nfeEndpoint({ ambiente:
|
|
4073
|
-
offsetMinutes: offsetDe(
|
|
4098
|
+
endpoint: nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: "RecepcaoEvento", autorizador: "AN" }),
|
|
4099
|
+
offsetMinutes: offsetDe(opcoesDoCliente.uf ?? c.uf),
|
|
4100
|
+
signal: opcoes?.signal
|
|
4074
4101
|
});
|
|
4075
4102
|
},
|
|
4076
|
-
async inutilizar(p) {
|
|
4103
|
+
async inutilizar(p, opcoes) {
|
|
4077
4104
|
const autor = autorPadrao(p.autor, "autor");
|
|
4078
4105
|
if (!("CNPJ" in autor)) {
|
|
4079
|
-
throw new
|
|
4106
|
+
throw new ErroDeValidacao2("inutilização não se aplica ao emitente pessoa física", [
|
|
4080
4107
|
{
|
|
4081
|
-
|
|
4108
|
+
caminho: "autor.CPF",
|
|
4082
4109
|
code: "inutilizacao_emitente_cpf",
|
|
4083
|
-
|
|
4110
|
+
mensagem: "O pedido de inutilização só existe para emitente CNPJ (NT 2018.001 v1.10, item 6.1)"
|
|
4084
4111
|
}
|
|
4085
4112
|
]);
|
|
4086
4113
|
}
|
|
@@ -4099,16 +4126,16 @@ function createNfeClient(options) {
|
|
|
4099
4126
|
["nNFFin", fin, /^[1-9][0-9]{0,8}$/]
|
|
4100
4127
|
]) {
|
|
4101
4128
|
if (!re.test(x))
|
|
4102
|
-
throw new
|
|
4129
|
+
throw new ErroDeConfiguracao4(`${k} inválido para inutilização: ${x}`);
|
|
4103
4130
|
}
|
|
4104
4131
|
if (Number(fin) < Number(ini))
|
|
4105
|
-
throw new
|
|
4132
|
+
throw new ErroDeConfiguracao4("nNFFin menor que nNFIni");
|
|
4106
4133
|
if (Number(serie) >= 910 && Number(serie) <= 969) {
|
|
4107
|
-
throw new
|
|
4134
|
+
throw new ErroDeValidacao2("série de emitente pessoa física não se inutiliza", [
|
|
4108
4135
|
{
|
|
4109
|
-
|
|
4136
|
+
caminho: "serie",
|
|
4110
4137
|
code: "inutilizacao_serie_cpf",
|
|
4111
|
-
|
|
4138
|
+
mensagem: "Série 910 a 969 identifica emitente CPF: a SEFAZ rejeita com 266 (NT 2018.001 v1.10, regra I02a)"
|
|
4112
4139
|
}
|
|
4113
4140
|
]);
|
|
4114
4141
|
}
|
|
@@ -4126,14 +4153,14 @@ function createNfeClient(options) {
|
|
|
4126
4153
|
nNFFin: fin,
|
|
4127
4154
|
xJust: p.xJust
|
|
4128
4155
|
};
|
|
4129
|
-
const infXml =
|
|
4156
|
+
const infXml = serializar3(TInutNFe_infInut, "infInut", inf, NFE_NS4);
|
|
4130
4157
|
const inut = envelope("inutNFe", "4.00", [infXml]);
|
|
4131
|
-
const infEl =
|
|
4132
|
-
schemaIssues("pedido de inutilização",
|
|
4133
|
-
const assinado = await
|
|
4134
|
-
const ep = mod === "65" ? endpointNfce("NfeInutilizacao", uf) : nfeEndpoint({ ambiente:
|
|
4135
|
-
const r = await call(ep, "NfeInutilizacao", assinado, "retInutNFe");
|
|
4136
|
-
const v =
|
|
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;
|
|
4137
4164
|
const status = { cStat: v.infInut.cStat, xMotivo: v.infInut.xMotivo };
|
|
4138
4165
|
logger.info("nfe.inutilizacao", { id, cStat: status.cStat });
|
|
4139
4166
|
if (!cstatEm(status.cStat, "inutilizacaoHomologada"))
|
|
@@ -4150,65 +4177,65 @@ function createNfeClient(options) {
|
|
|
4150
4177
|
];
|
|
4151
4178
|
const fora = confere.filter(([, veio, pedido]) => veio !== undefined && veio !== pedido);
|
|
4152
4179
|
if (fora.length > 0) {
|
|
4153
|
-
throw new
|
|
4154
|
-
|
|
4180
|
+
throw new ErroRespostaInvalida4("retInutNFe de outra faixa", {
|
|
4181
|
+
detalhes: Object.fromEntries(fora.map(([k, v]) => [k, v]))
|
|
4155
4182
|
});
|
|
4156
4183
|
}
|
|
4157
|
-
return
|
|
4184
|
+
return criarAutorizado(status, {
|
|
4158
4185
|
dhRecbto: v.infInut.dhRecbto,
|
|
4159
4186
|
retInutNFe: avulso(r.doc, r.ret),
|
|
4160
|
-
procInutNFe: envelope("ProcInutNFe", "4.00", [assinado,
|
|
4187
|
+
procInutNFe: envelope("ProcInutNFe", "4.00", [assinado, recortarElemento(r.doc, r.ret)]),
|
|
4161
4188
|
...v.infInut.nProt === undefined ? {} : { nProt: v.infInut.nProt }
|
|
4162
4189
|
});
|
|
4163
4190
|
},
|
|
4164
|
-
async consultarCadastro(p) {
|
|
4191
|
+
async consultarCadastro(p, opcoes) {
|
|
4165
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() };
|
|
4166
|
-
const msg =
|
|
4167
|
-
const ep = nfeEndpoint({ ambiente:
|
|
4168
|
-
const r = await call(ep, "NfeConsultaCadastro", msg, "retConsCad");
|
|
4169
|
-
const v =
|
|
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;
|
|
4170
4197
|
const i = v.infCons;
|
|
4171
4198
|
const status = { cStat: i.cStat, xMotivo: i.xMotivo };
|
|
4172
4199
|
logger.info("nfe.cadastro", { uf: p.uf, cStat: i.cStat });
|
|
4173
4200
|
if (!cstatEm(i.cStat, "cadastroEncontrado"))
|
|
4174
4201
|
return rejeitado(status);
|
|
4175
|
-
return
|
|
4202
|
+
return criarAutorizado(status, { UF: i.UF, dhCons: i.dhCons, infCad: i.infCad ?? [] });
|
|
4176
4203
|
},
|
|
4177
4204
|
async distribuicaoDFe(consulta, opcoes = {}) {
|
|
4178
4205
|
const autor = autorPadrao(opcoes.autor, "autor");
|
|
4179
4206
|
const nsu = (x, k) => {
|
|
4180
4207
|
const s = String(x);
|
|
4181
4208
|
if (!/^[0-9]{1,15}$/.test(s))
|
|
4182
|
-
throw new
|
|
4209
|
+
throw new ErroDeConfiguracao4(`${k} inválido: ${s}`);
|
|
4183
4210
|
return s.padStart(15, "0");
|
|
4184
4211
|
};
|
|
4185
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 } };
|
|
4186
4213
|
const cUFAutor = opcoes.cUFAutor ?? ufPadrao("NFeDistribuicaoDFe").cUF;
|
|
4187
|
-
if (
|
|
4188
|
-
throw new
|
|
4189
|
-
const msg =
|
|
4214
|
+
if (ufPorCUf2(cUFAutor) === undefined)
|
|
4215
|
+
throw new ErroDeConfiguracao4(`cUFAutor inválido: ${cUFAutor}`);
|
|
4216
|
+
const msg = serializarRaiz(distDFeIntElement, {
|
|
4190
4217
|
versao: "1.01",
|
|
4191
4218
|
tpAmb,
|
|
4192
4219
|
cUFAutor,
|
|
4193
4220
|
...autor,
|
|
4194
4221
|
...grupo
|
|
4195
4222
|
});
|
|
4196
|
-
const ep = nfeEndpoint({ ambiente:
|
|
4197
|
-
const r = await call(ep, "NFeDistribuicaoDFe", msg, "retDistDFeInt");
|
|
4198
|
-
const v =
|
|
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;
|
|
4199
4226
|
const status = { cStat: v.cStat, xMotivo: v.xMotivo };
|
|
4200
4227
|
logger.info("nfe.distribuicao", { cStat: v.cStat, ultNSU: v.ultNSU, maxNSU: v.maxNSU });
|
|
4201
4228
|
const base = { ultNSU: v.ultNSU, maxNSU: v.maxNSU, dhResp: v.dhResp };
|
|
4202
4229
|
if (cstatEm(v.cStat, "distribuicaoNenhumDocumento"))
|
|
4203
|
-
return
|
|
4230
|
+
return criarAutorizado(status, { ...base, documentos: [] });
|
|
4204
4231
|
if (!cstatEm(v.cStat, "distribuicaoDocumentos"))
|
|
4205
4232
|
return rejeitado(status);
|
|
4206
4233
|
const documentos = [];
|
|
4207
4234
|
for (const z of v.loteDistDFeInt?.docZip ?? []) {
|
|
4208
|
-
const xml = await
|
|
4235
|
+
const xml = await descomprimirGzipBase64(z.$text);
|
|
4209
4236
|
documentos.push(documentoDistribuido(z.NSU ?? "", z.schema, xml));
|
|
4210
4237
|
}
|
|
4211
|
-
return
|
|
4238
|
+
return criarAutorizado(status, { ...base, documentos });
|
|
4212
4239
|
}
|
|
4213
4240
|
};
|
|
4214
4241
|
return client;
|
|
@@ -4217,9 +4244,9 @@ function documentoDistribuido(NSU, schema, xml) {
|
|
|
4217
4244
|
const nome = schema.replace(/_v?\d.*$/, "");
|
|
4218
4245
|
const base = { NSU, schema, xml };
|
|
4219
4246
|
if (nome === "resNFe")
|
|
4220
|
-
return { ...base, tipo: "resNFe", resNFe:
|
|
4247
|
+
return { ...base, tipo: "resNFe", resNFe: decodificarXml(resNFeElement, xml).valor };
|
|
4221
4248
|
if (nome === "resEvento")
|
|
4222
|
-
return { ...base, tipo: "resEvento", resEvento:
|
|
4249
|
+
return { ...base, tipo: "resEvento", resEvento: decodificarXml(resEventoElement, xml).valor };
|
|
4223
4250
|
if (nome === "procNFe")
|
|
4224
4251
|
return { ...base, tipo: "procNFe" };
|
|
4225
4252
|
if (nome === "procEventoNFe")
|
|
@@ -4227,23 +4254,23 @@ function documentoDistribuido(NSU, schema, xml) {
|
|
|
4227
4254
|
return { ...base, tipo: "outro" };
|
|
4228
4255
|
}
|
|
4229
4256
|
// packages/nfe/src/services/recuperar.ts
|
|
4230
|
-
import {
|
|
4257
|
+
import { lerXml as lerXml7, primeiroFilho as primeiroFilho6, textoDe as textoDe3 } from "@sinete/core/xml";
|
|
4231
4258
|
function campo(el, local) {
|
|
4232
|
-
const c =
|
|
4233
|
-
return c === undefined ? undefined :
|
|
4259
|
+
const c = primeiroFilho6(el, local, NFE_NS4);
|
|
4260
|
+
return c === undefined ? undefined : textoDe3(c).trim();
|
|
4234
4261
|
}
|
|
4235
4262
|
function lerProcEvento(xml) {
|
|
4236
4263
|
let doc;
|
|
4237
4264
|
try {
|
|
4238
|
-
doc =
|
|
4265
|
+
doc = lerXml7(xml);
|
|
4239
4266
|
} catch {
|
|
4240
4267
|
return;
|
|
4241
4268
|
}
|
|
4242
|
-
const evento =
|
|
4243
|
-
const pedido = evento === undefined ? undefined :
|
|
4244
|
-
const retEl =
|
|
4245
|
-
const ret = retEl === undefined ? undefined :
|
|
4246
|
-
if (doc.
|
|
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) {
|
|
4247
4274
|
return;
|
|
4248
4275
|
}
|
|
4249
4276
|
const cStat = campo(ret, "cStat");
|
|
@@ -4268,19 +4295,21 @@ function lerProcEvento(xml) {
|
|
|
4268
4295
|
tpEvento,
|
|
4269
4296
|
nSeqEvento: String(Number(nSeq)),
|
|
4270
4297
|
dhRegEvento,
|
|
4271
|
-
retEvento:
|
|
4298
|
+
retEvento: recortarElemento(doc, retEl, ""),
|
|
4272
4299
|
procEventoNFe: xml,
|
|
4273
4300
|
...nProt === undefined ? {} : { nProt }
|
|
4274
4301
|
};
|
|
4275
4302
|
}
|
|
4276
|
-
async function recuperarEventoRegistrado(
|
|
4277
|
-
const consulta = await
|
|
4278
|
-
if (consulta.
|
|
4303
|
+
async function recuperarEventoRegistrado(cliente, chave, tpEvento, nSeqEvento) {
|
|
4304
|
+
const consulta = await cliente.consultar(chave);
|
|
4305
|
+
if (consulta.tipo !== "autorizado" && consulta.tipo !== "denegado")
|
|
4279
4306
|
return { registrado: false, consulta };
|
|
4280
4307
|
let achado;
|
|
4281
|
-
for (const xml of consulta.
|
|
4308
|
+
for (const xml of consulta.valor.eventos) {
|
|
4282
4309
|
const e = lerProcEvento(xml);
|
|
4283
|
-
if (e === undefined || e.chNFe !== consulta.
|
|
4310
|
+
if (e === undefined || e.chNFe !== consulta.valor.chNFe || e.tpEvento !== tpEvento)
|
|
4311
|
+
continue;
|
|
4312
|
+
if (nSeqEvento !== undefined && Number(e.nSeqEvento) !== nSeqEvento)
|
|
4284
4313
|
continue;
|
|
4285
4314
|
if (achado === undefined || Number(e.nSeqEvento) > Number(achado.nSeqEvento))
|
|
4286
4315
|
achado = e;
|
|
@@ -4288,83 +4317,83 @@ async function recuperarEventoRegistrado(client, chave, tpEvento) {
|
|
|
4288
4317
|
return achado === undefined ? { registrado: false, consulta } : { registrado: true, evento: achado, consulta };
|
|
4289
4318
|
}
|
|
4290
4319
|
// packages/nfe/src/services/resolver.ts
|
|
4291
|
-
import {
|
|
4320
|
+
import { criarAutorizado as criarAutorizado2, criarDenegado as criarDenegado2 } from "@sinete/core";
|
|
4292
4321
|
var CHAVE_NO_MOTIVO = /\[\s*chNFe\s*:\s*([0-9]{6}[0-9A-Z]{12}[0-9]{26})\s*\]/i;
|
|
4293
4322
|
function chaveDaDuplicidade(xMotivo) {
|
|
4294
4323
|
return CHAVE_NO_MOTIVO.exec(xMotivo)?.[1]?.toUpperCase();
|
|
4295
4324
|
}
|
|
4296
|
-
async function resolverEnvioSemResposta(
|
|
4325
|
+
async function resolverEnvioSemResposta(cliente, nfeAssinada, anterior) {
|
|
4297
4326
|
const a = documentoAssinado(nfeAssinada, "NFe", "infNFe");
|
|
4298
4327
|
const chave = a.id.slice(3);
|
|
4299
|
-
if (anterior && anterior.
|
|
4328
|
+
if (anterior && anterior.tipo === "recusado" && cstatEm(anterior.cStat, "duplicidadeChaveDiferente")) {
|
|
4300
4329
|
const outra = chaveDaDuplicidade(anterior.xMotivo);
|
|
4301
4330
|
return { acao: "divergente", motivo: anterior, ...outra === undefined ? {} : { chNFe: outra } };
|
|
4302
4331
|
}
|
|
4303
|
-
const consulta = await
|
|
4304
|
-
if (consulta.
|
|
4332
|
+
const consulta = await cliente.consultar(chave, nfeAssinada);
|
|
4333
|
+
if (consulta.tipo === "recusado") {
|
|
4305
4334
|
if (cstatEm(consulta.cStat, "naoConsta"))
|
|
4306
4335
|
return { acao: "reenviar", nfeAssinada: a.xml };
|
|
4307
4336
|
if (cstatEm(consulta.cStat, "outraNfeNoNumero")) {
|
|
4308
4337
|
const outra = chaveDaDuplicidade(consulta.xMotivo);
|
|
4309
4338
|
return { acao: "divergente", motivo: consulta, ...outra === undefined ? {} : { chNFe: outra } };
|
|
4310
4339
|
}
|
|
4311
|
-
return { acao: "indefinida",
|
|
4340
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4312
4341
|
}
|
|
4313
|
-
if (consulta.
|
|
4314
|
-
return { acao: "indefinida",
|
|
4315
|
-
const v = consulta.
|
|
4342
|
+
if (consulta.tipo === "pendente")
|
|
4343
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4344
|
+
const v = consulta.valor;
|
|
4316
4345
|
const p = v.protocolo;
|
|
4317
4346
|
if (!p)
|
|
4318
|
-
return { acao: "indefinida",
|
|
4347
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4319
4348
|
const conteudo = p.digVal === undefined ? "sem-digval" : v.digValConfere === true ? "confere" : "difere";
|
|
4320
4349
|
const protStatus = { cStat: p.cStat, xMotivo: p.xMotivo };
|
|
4321
4350
|
if (v.situacao === "denegada")
|
|
4322
|
-
return { acao: "concluida", situacao: "denegada", conteudo,
|
|
4351
|
+
return { acao: "concluida", situacao: "denegada", conteudo, resultado: criarDenegado2(protStatus, p) };
|
|
4323
4352
|
if (conteudo === "difere")
|
|
4324
4353
|
return { acao: "divergente", chNFe: chave, consulta, motivo: consulta };
|
|
4325
4354
|
if (conteudo === "sem-digval")
|
|
4326
4355
|
return { acao: "sem-prova", situacao: v.situacao, consulta };
|
|
4327
4356
|
if (p.nfeProc === undefined)
|
|
4328
|
-
return { acao: "indefinida",
|
|
4329
|
-
return { acao: "concluida", situacao: v.situacao, conteudo,
|
|
4357
|
+
return { acao: "indefinida", resultado: consulta };
|
|
4358
|
+
return { acao: "concluida", situacao: v.situacao, conteudo, resultado: criarAutorizado2(protStatus, p) };
|
|
4330
4359
|
}
|
|
4331
4360
|
export {
|
|
4361
|
+
CODIGOS_OCORRENCIA_NFE,
|
|
4332
4362
|
Decimal,
|
|
4333
4363
|
MotivoDesoneracaoIcms,
|
|
4334
4364
|
NFCE_LIMITE_SEM_DESTINATARIO,
|
|
4335
|
-
NFE_ISSUE_CODES,
|
|
4336
4365
|
NFE_NS3 as NFE_NS,
|
|
4337
4366
|
TipoPagamento,
|
|
4338
4367
|
XNOME_HOMOLOGACAO,
|
|
4339
4368
|
XPROD_HOMOLOGACAO_NFCE,
|
|
4369
|
+
assinarNfe,
|
|
4340
4370
|
assinaturaQrCode,
|
|
4341
4371
|
autorizadorContingencia,
|
|
4342
|
-
|
|
4372
|
+
calculadoraIbsCbs,
|
|
4343
4373
|
carregarDatasetEmbarcado,
|
|
4344
4374
|
chaveDaDuplicidade,
|
|
4345
4375
|
comQrCode,
|
|
4346
4376
|
conferirEmitenteDoCertificado,
|
|
4347
|
-
|
|
4377
|
+
criarClienteNfe,
|
|
4348
4378
|
dec,
|
|
4379
|
+
descomprimirGzipBase64,
|
|
4380
|
+
deslocamentoDaUf,
|
|
4349
4381
|
documentoAssinado,
|
|
4350
4382
|
exigenciaRespTec,
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
formatProblem,
|
|
4354
|
-
gunzipBase64,
|
|
4383
|
+
formatarDecimal,
|
|
4384
|
+
formatarDh,
|
|
4355
4385
|
hashCsrt,
|
|
4356
|
-
ibsCbsCalculator,
|
|
4357
4386
|
localDaOperacao,
|
|
4387
|
+
montarNfe,
|
|
4358
4388
|
nfeAssinadaDoProc,
|
|
4359
|
-
|
|
4389
|
+
problemaDeFormato,
|
|
4390
|
+
recortarElemento,
|
|
4360
4391
|
recuperarEventoRegistrado,
|
|
4361
4392
|
resolverEnvioSemResposta,
|
|
4362
4393
|
rotuloDoCaminho,
|
|
4363
|
-
signNfe,
|
|
4364
|
-
sliceElement,
|
|
4365
4394
|
sum,
|
|
4366
4395
|
urlsNfce
|
|
4367
4396
|
};
|
|
4368
4397
|
|
|
4369
|
-
//# debugId=
|
|
4398
|
+
//# debugId=82CED6CBF6EFA38F64756E2164756E21
|
|
4370
4399
|
//# sourceMappingURL=index.js.map
|