@sinete/nfe 0.4.0 → 0.5.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/dist/index.js CHANGED
@@ -594,7 +594,7 @@ function formatarDh(data, deslocamentoMin) {
594
594
  }
595
595
 
596
596
  // packages/nfe/src/versao-gerada.ts
597
- var VERSAO_PACOTE = "0.4.0";
597
+ var VERSAO_PACOTE = "0.5.0";
598
598
 
599
599
  // packages/nfe/src/build/destinatario.ts
600
600
  import { ufPorSigla } from "@sinete/core";
@@ -1859,6 +1859,7 @@ function camposForaDoPl(ct, value, path, pl, issues) {
1859
1859
  }
1860
1860
 
1861
1861
  // packages/nfe/src/build/rejeicoes.ts
1862
+ import { indicadoresCfop } from "@sinete/validators";
1862
1863
  var CFOP_CST50_ISENTO = new Set([
1863
1864
  "1915",
1864
1865
  "1916",
@@ -1934,18 +1935,120 @@ function conferirEmitenteDoCertificado(nfe, titular) {
1934
1935
  }
1935
1936
  return [];
1936
1937
  }
1938
+ var NFCE_SEM_IE_ATE = "2033-01-01";
1939
+ function exclusivoIbsCbs(input, contexto, issues) {
1940
+ const e = input.emitente;
1941
+ if (e.IE !== undefined)
1942
+ return;
1943
+ if (contexto.nfce) {
1944
+ const datas = [
1945
+ contexto.dhEmi.slice(0, 10),
1946
+ ...contexto.instantes.flatMap((i) => [dataNoFuso(i, OFFSET_BRASILIA), dataNoFuso(i, 0)])
1947
+ ];
1948
+ if (datas.every((d) => d < NFCE_SEM_IE_ATE)) {
1949
+ issues.add("emitente.IE", "campo_obrigatorio", "a NFC-e exige a IE do emitente: contribuinte exclusivo do IBS/CBS, sem IE, emite só NF-e (C17-42, rejeição 156)");
1950
+ }
1951
+ return;
1952
+ }
1953
+ if (e.CNPJ === undefined) {
1954
+ issues.add("emitente.CNPJ", "campo_obrigatorio", "NF-e sem IE do emitente (contribuinte exclusivo do IBS/CBS) exige o CNPJ do emitente (C17-43, rejeição 157)");
1955
+ }
1956
+ if (e.IEST !== undefined) {
1957
+ issues.add("emitente.IEST", "combinacao_invalida", "NF-e sem IE do emitente (contribuinte exclusivo do IBS/CBS) não leva a IE do substituto tributário (C18-50, rejeição 158)");
1958
+ }
1959
+ const icmsLiberado = (input.finNFe ?? "1") === "4" || input.tpNFCredito === "03";
1960
+ input.itens.forEach((it, n) => {
1961
+ if (!icmsLiberado) {
1962
+ for (const [campo, grupo] of [
1963
+ ["icms", it.impostos.icms],
1964
+ ["icmsUfDest", it.impostos.icmsUfDest]
1965
+ ]) {
1966
+ if (grupo === undefined)
1967
+ continue;
1968
+ issues.add(`itens[${n}].impostos.${campo}`, "grupo_vedado", "NF-e sem IE do emitente (contribuinte exclusivo do IBS/CBS) não leva ICMS no item (N01-10, rejeição 161)");
1969
+ }
1970
+ }
1971
+ if (it.impostos.ibsCbs === undefined) {
1972
+ issues.add(`itens[${n}].impostos.ibsCbs`, "campo_obrigatorio", "NF-e sem IE do emitente (contribuinte exclusivo do IBS/CBS) exige o grupo IBS/CBS em todo item (UB12-11, rejeição 162)");
1973
+ }
1974
+ });
1975
+ }
1976
+ var CREDITO_COM_DEVOLUCAO = new Set(["03", "04", "06"]);
1977
+ function cfopDeDevolucao(input, issues) {
1978
+ const fin = input.finNFe ?? "1";
1979
+ if (fin === "2" || fin === "4")
1980
+ return;
1981
+ if (fin === "5" && input.tpNFCredito !== undefined && CREDITO_COM_DEVOLUCAO.has(input.tpNFCredito))
1982
+ return;
1983
+ input.itens.forEach((it, n) => {
1984
+ if (indicadoresCfop(it.produto.CFOP.replace(/\D/g, ""))?.indDevol !== true)
1985
+ return;
1986
+ issues.add(`itens[${n}].produto.CFOP`, "combinacao_invalida", `CFOP ${it.produto.CFOP} é de devolução e a nota não é de devolução (finNFe ${fin}) (I08-144, rejeição 328)`);
1987
+ });
1988
+ }
1989
+ var CST_NAO_CONTRIBUINTE = new Set(["00", "20", "40", "41", "60", "61"]);
1990
+ var ANP_FORA_DA_EXCECAO_5 = new Set([
1991
+ "820101001",
1992
+ "820101010",
1993
+ "810102001",
1994
+ "810102004",
1995
+ "810102002",
1996
+ "810102003",
1997
+ "810101002",
1998
+ "810101001",
1999
+ "810101003",
2000
+ "220101003",
2001
+ "220101004",
2002
+ "220101002",
2003
+ "220101001",
2004
+ "220101005",
2005
+ "220101006",
2006
+ "560101001"
2007
+ ]);
2008
+ var CFOP_CST51 = new Set(["5123", "5922", "6123", "6922"]);
2009
+ function cstComNaoContribuinte(input, contexto, issues) {
2010
+ if (input.destinatario?.indIEDest !== "9" || input.tpNF === "0")
2011
+ return;
2012
+ if (input.itens.some((it) => it.produto.especifico !== undefined && ("veicProd" in it.produto.especifico)))
2013
+ return;
2014
+ const fin = input.finNFe ?? "1";
2015
+ const interna = contexto.idDest === "1";
2016
+ const interestadual = contexto.idDest === "2";
2017
+ input.itens.forEach((it, n) => {
2018
+ const icms = it.impostos.icms;
2019
+ if (icms === undefined || !("CST" in icms))
2020
+ return;
2021
+ const cst = icms.CST;
2022
+ if (CST_NAO_CONTRIBUINTE.has(cst))
2023
+ return;
2024
+ const cfop = it.produto.CFOP.replace(/\D/g, "");
2025
+ const esp = it.produto.especifico;
2026
+ if ((cst === "50" || cst === "51") && fin === "4")
2027
+ return;
2028
+ if (cst === "50") {
2029
+ const ind = indicadoresCfop(cfop);
2030
+ if (ind === undefined || ind.indRetor || ind.indRemes || cfop === "5949" || cfop === "6949")
2031
+ return;
2032
+ }
2033
+ if (cst === "51" && (CFOP_CST51.has(cfop) || interna))
2034
+ return;
2035
+ if ((cst === "10" || cst === "02") && interna)
2036
+ return;
2037
+ if (cst === "30" && interestadual) {
2038
+ if (esp !== undefined && "comb" in esp && !ANP_FORA_DA_EXCECAO_5.has(esp.comb.cProdANP))
2039
+ return;
2040
+ if (it.produto.NCM.replace(/\D/g, "") === "27160000")
2041
+ return;
2042
+ }
2043
+ if (cst === "90" && contexto.uf === "CE" && (cfop === "5403" || cfop === "5405"))
2044
+ return;
2045
+ issues.add(`itens[${n}].impostos.icms.CST`, "combinacao_invalida", `CST ${cst} não se usa com destinatário não contribuinte (indIEDest 9) (N12-70, rejeição 508)`);
2046
+ });
2047
+ }
1937
2048
 
1938
2049
  // packages/nfe/src/build/textos.ts
1939
- import { conferirTipoSimples, ehComplexType as ehComplexType2, ehElementParticle as ehElementParticle2, ehWildcard as ehWildcard2 } from "@sinete/schemas";
1940
- function textoXmlValido(texto) {
1941
- for (const ch of texto) {
1942
- const c = ch.codePointAt(0) ?? 0;
1943
- const ok = c === 9 || c === 10 || c === 13 || c >= 32 && c <= 55295 || c >= 57344 && c <= 65533 || c >= 65536 && c <= 1114111;
1944
- if (!ok)
1945
- return false;
1946
- }
1947
- return true;
1948
- }
2050
+ import { conferirTextos } from "@sinete/schemas";
2051
+ import { textoXmlValido } from "@sinete/schemas";
1949
2052
  var CAMPOS = [
1950
2053
  ["natOp", "ide.natOp"],
1951
2054
  ["emitente.xNome", "emit.xNome"],
@@ -1987,138 +2090,10 @@ var CAMPOS = [
1987
2090
  ["compra.xPed", "compra.xPed"],
1988
2091
  ["compra.xCont", "compra.xCont"]
1989
2092
  ];
1990
- function elemento(p, nome) {
1991
- if (p === undefined || ehWildcard2(p))
1992
- return;
1993
- if (ehElementParticle2(p))
1994
- return p.e === nome ? p.t : undefined;
1995
- for (const i of p.i) {
1996
- const t = elemento(i, nome);
1997
- if (t !== undefined)
1998
- return t;
1999
- }
2000
- return;
2001
- }
2002
- function tipoEm(infNFe, caminho) {
2003
- let t = infNFe;
2004
- for (const nome of caminho.split(".")) {
2005
- if (t === undefined || !ehComplexType2(t))
2006
- return;
2007
- t = elemento(t.c, nome);
2008
- }
2009
- return t === undefined || ehComplexType2(t) ? undefined : t;
2010
- }
2011
- var tiposPorPl = new WeakMap;
2012
- function tiposDoPl(infNFe) {
2013
- let m = tiposPorPl.get(infNFe);
2014
- if (m === undefined) {
2015
- const novo = new Map;
2016
- for (const [entrada, xml] of CAMPOS) {
2017
- const t = tipoEm(infNFe, xml);
2018
- if (t !== undefined)
2019
- novo.set(entrada, t);
2020
- }
2021
- m = novo;
2022
- tiposPorPl.set(infNFe, m);
2023
- }
2024
- return m;
2025
- }
2026
- function valoresEm(raiz, caminho) {
2027
- let atuais = [["", raiz]];
2028
- for (const parte of caminho.split(".")) {
2029
- const lista = parte.endsWith("[]");
2030
- const chave = lista ? parte.slice(0, -2) : parte;
2031
- const proximos = [];
2032
- for (const [c, v] of atuais) {
2033
- if (typeof v !== "object" || v === null)
2034
- continue;
2035
- const filho = v[chave];
2036
- const base = c === "" ? chave : `${c}.${chave}`;
2037
- if (!lista)
2038
- proximos.push([base, filho]);
2039
- else if (Array.isArray(filho))
2040
- for (const [n, f] of filho.entries())
2041
- proximos.push([`${base}[${n}]`, f]);
2042
- }
2043
- atuais = proximos;
2044
- }
2045
- return atuais;
2046
- }
2047
- function textosForaDoXml(valor, caminho, saida) {
2048
- if (typeof valor === "string") {
2049
- if (!textoXmlValido(valor))
2050
- saida.push(caminho);
2051
- } else if (Array.isArray(valor)) {
2052
- for (const [n, v] of valor.entries())
2053
- textosForaDoXml(v, `${caminho}[${n}]`, saida);
2054
- } else if (typeof valor === "object" && valor !== null) {
2055
- for (const [k, v] of Object.entries(valor))
2056
- textosForaDoXml(v, caminho === "" ? k : `${caminho}.${k}`, saida);
2057
- }
2058
- }
2059
- var CARACTERE_INVISIVEL = "caractere não aceito (símbolo ou caractere de controle)";
2060
- var VISIVEL = /^[\p{L}\p{M}\p{N}\p{P}\p{S}]$/u;
2061
- function caractereRecusado(tipo, valor) {
2062
- for (const ch of new Set(valor)) {
2063
- const saida = [];
2064
- conferirTipoSimples(tipo, `A${ch}A`, "", saida);
2065
- if (saida.some((o) => o.code === "padrao"))
2066
- return ch;
2067
- }
2068
- return;
2069
- }
2070
- function mensagensDoTexto(tipo, valor, violadas) {
2071
- if (violadas.length === 0)
2072
- return [];
2073
- if (valor.trim() === "")
2074
- return ["não pode ficar em branco"];
2075
- const tamanho = [...valor].length;
2076
- const mensagens = new Set;
2077
- for (const o of violadas) {
2078
- if (o.code === "tamanho_maximo" && tipo.mx !== undefined)
2079
- mensagens.add(`no máximo ${tipo.mx} caracteres (tem ${tamanho})`);
2080
- else if (o.code === "tamanho_minimo" && tipo.mn !== undefined)
2081
- mensagens.add(`no mínimo ${tipo.mn} caracteres (tem ${tamanho})`);
2082
- else if (o.code === "tamanho" && tipo.l !== undefined)
2083
- mensagens.add(`exatamente ${tipo.l} caracteres (tem ${tamanho})`);
2084
- else if (o.code === "padrao") {
2085
- const espaco = valor !== valor.trim();
2086
- const ch = caractereRecusado(tipo, valor);
2087
- if (espaco)
2088
- mensagens.add("sem espaço no começo nem no fim");
2089
- if (ch !== undefined)
2090
- mensagens.add(VISIVEL.test(ch) ? `caractere não aceito: “${ch}”` : CARACTERE_INVISIVEL);
2091
- if (!espaco && ch === undefined)
2092
- mensagens.add("formato não aceito");
2093
- } else
2094
- mensagens.add("valor não aceito neste campo");
2095
- }
2096
- return [...mensagens];
2097
- }
2098
2093
  function conferirTextosDaEntrada(entrada, infNFe, issues, substituidos = new Set) {
2099
- const jaRecusados = new Set(issues.list.map((i) => i.caminho));
2100
- const foraDoXml = [];
2101
- textosForaDoXml(entrada, "", foraDoXml);
2102
- for (const c of foraDoXml) {
2103
- if (jaRecusados.has(c) || substituidos.has(c))
2104
- continue;
2105
- issues.add(c, "campo_invalido", CARACTERE_INVISIVEL);
2106
- jaRecusados.add(c);
2107
- }
2108
- const tipos = tiposDoPl(infNFe);
2109
- for (const [campo] of CAMPOS) {
2110
- const tipo = tipos.get(campo);
2111
- if (tipo === undefined)
2112
- continue;
2113
- for (const [caminho, valor] of valoresEm(entrada, campo)) {
2114
- if (typeof valor !== "string" || jaRecusados.has(caminho) || substituidos.has(caminho))
2115
- continue;
2116
- const saida = [];
2117
- conferirTipoSimples(tipo, valor, caminho, saida);
2118
- for (const m of mensagensDoTexto(tipo, valor, saida))
2119
- issues.add(caminho, "campo_invalido", m);
2120
- }
2121
- }
2094
+ const pular = new Set([...issues.list.map((i) => i.caminho), ...substituidos]);
2095
+ for (const t of conferirTextos(entrada, infNFe, CAMPOS, pular))
2096
+ issues.add(t.caminho, "campo_invalido", t.mensagem);
2122
2097
  }
2123
2098
 
2124
2099
  // packages/nfe/src/build/tributos.ts
@@ -2425,19 +2400,19 @@ function referencia(ref, path, issues) {
2425
2400
  }
2426
2401
  };
2427
2402
  }
2428
- function textosForaDoXml2(value, path, issues) {
2403
+ function textosForaDoXml(value, path, issues) {
2429
2404
  if (typeof value === "string") {
2430
2405
  if (!textoXmlValido(value))
2431
2406
  issues.montagem(path, "campo_invalido", "texto com caractere não permitido em XML");
2432
2407
  } else if (Array.isArray(value)) {
2433
2408
  for (const [n, v] of value.entries())
2434
- textosForaDoXml2(v, `${path}[${n}]`, issues);
2409
+ textosForaDoXml(v, `${path}[${n}]`, issues);
2435
2410
  } else if (typeof value === "object" && value !== null) {
2436
2411
  for (const [k, v] of Object.entries(value))
2437
- textosForaDoXml2(v, `${path}.${k}`, issues);
2412
+ textosForaDoXml(v, `${path}.${k}`, issues);
2438
2413
  }
2439
2414
  }
2440
- function montarItem(ctx, item, n, normal) {
2415
+ function montarItem(ctx, item, n, normal, semIe) {
2441
2416
  const path = `itens[${n}]`;
2442
2417
  const p = item.produto;
2443
2418
  const pp = `${path}.produto`;
@@ -2552,7 +2527,7 @@ function montarItem(ctx, item, n, normal) {
2552
2527
  const r = buildIcms(ctx, imp.icms, { vOp, vIPI: v.vIPI }, `${ip}.icms`);
2553
2528
  imposto.ICMS = r.grupo;
2554
2529
  icms = r.totais;
2555
- } else if (imp.issqn === undefined && imp.ibsCbs === undefined) {
2530
+ } else if (imp.issqn === undefined && imp.ibsCbs === undefined && !semIe) {
2556
2531
  ctx.issues.add(`${ip}.icms`, "campo_obrigatorio", "o item precisa de ICMS (ou ISSQN, na NF-e conjugada)");
2557
2532
  }
2558
2533
  if (imp.ii !== undefined) {
@@ -2745,8 +2720,8 @@ async function montarNfe(entrada, opcoes) {
2745
2720
  if (cont.dhCont.getTime() > agora.getTime()) {
2746
2721
  issues.add("contingencia.dhCont", "contingencia_invalida", "entrada em contingência posterior à emissão");
2747
2722
  }
2748
- if (!nfce && tpEmis === "9") {
2749
- issues.add("contingencia.tpEmis", "contingencia_invalida", "contingência off-line (tpEmis 9) é só da NFC-e (B22-10, rejeição 711)");
2723
+ if (!nfce && tpEmis === "9" && (entrada.tpImp ?? "1") !== "6") {
2724
+ issues.add("contingencia.tpEmis", "contingencia_invalida", "contingência off-line (tpEmis 9) é da NFC-e e da NF-e com DANFE Simplificado Tipo 2, tpImp 6 (B22-10, rejeição 711)");
2750
2725
  }
2751
2726
  if (nfce && (tpEmis === "6" || tpEmis === "7")) {
2752
2727
  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)");
@@ -2774,7 +2749,11 @@ async function montarNfe(entrada, opcoes) {
2774
2749
  } else if (tpImp === "4" || tpImp === "5") {
2775
2750
  issues.add("tpImp", "campo_invalido", "tpImp 4 e 5 (DANFC-e) são da NFC-e (B21-20, rejeição 710)");
2776
2751
  }
2752
+ const comQr = nfce || tpImp === "6";
2777
2753
  const qr = opcoes.qrCode ?? { versao: "3" };
2754
+ if (!nfce && comQr && qr.versao === "2") {
2755
+ issues.montagem("qrCode.versao", "qrcode_invalido", "a NF-e com DANFE Simplificado Tipo 2 usa só o QR Code versão 3 (ZX02-220, rejeição 672)");
2756
+ }
2778
2757
  if (nfce && qr.versao === "2") {
2779
2758
  if (!/^\d{1,6}$/.test(qr.idCSC) || Number(qr.idCSC) === 0) {
2780
2759
  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)");
@@ -2795,7 +2774,8 @@ async function montarNfe(entrada, opcoes) {
2795
2774
  if (entrada.itens.length === 0 || entrada.itens.length > 990) {
2796
2775
  issues.add("itens", "itens_limite", "a NF-e tem de 1 a 990 itens");
2797
2776
  }
2798
- const itens = entrada.itens.map((it, n) => montarItem(ctx, it, n, finNFeIn === "1"));
2777
+ const semIe = !nfce && entrada.emitente.IE === undefined;
2778
+ const itens = entrada.itens.map((it, n) => montarItem(ctx, it, n, finNFeIn === "1", semIe));
2799
2779
  const primeiro = itens[0];
2800
2780
  if (nfce && opcoes.ambiente === "homologacao" && primeiro !== undefined) {
2801
2781
  primeiro.det.prod.xProd = XPROD_HOMOLOGACAO_NFCE;
@@ -2898,6 +2878,7 @@ async function montarNfe(entrada, opcoes) {
2898
2878
  });
2899
2879
  const substituidos = opcoes.ambiente === "homologacao" ? ["destinatario.xNome", ...nfce ? ["itens[0].produto.xProd"] : []] : [];
2900
2880
  conferirTextosDaEntrada(entrada, pl.infNFe, issues, new Set(substituidos));
2881
+ exclusivoIbsCbs(entrada, { nfce, dhEmi, instantes: [agora, fatoGerador] }, issues);
2901
2882
  if (!issues.empty)
2902
2883
  return { ok: false, ocorrencias: issues.classificadas };
2903
2884
  const gruposIbsCbs = itens.map((m) => m.det.imposto.IBSCBS).filter((g) => g !== undefined);
@@ -3192,9 +3173,13 @@ async function montarNfe(entrada, opcoes) {
3192
3173
  agropecuario: entrada.agropecuario
3193
3174
  });
3194
3175
  cstComIsento(entrada, idDest, issues);
3176
+ if (!nfce) {
3177
+ cfopDeDevolucao(entrada, issues);
3178
+ cstComNaoContribuinte(entrada, { idDest, uf: emitUf }, issues);
3179
+ }
3195
3180
  vencimentos(entrada, { dhEmi, instante: agora }, issues);
3196
3181
  camposForaDoPl(pl.infNFe, inf, "infNFe", pl.vigencia.pl, issues);
3197
- textosForaDoXml2(inf, "infNFe", issues);
3182
+ textosForaDoXml(inf, "infNFe", issues);
3198
3183
  if (!issues.empty)
3199
3184
  return { ok: false, ocorrencias: issues.classificadas };
3200
3185
  let xml;
@@ -3223,7 +3208,7 @@ async function montarNfe(entrada, opcoes) {
3223
3208
  };
3224
3209
  }
3225
3210
  let supl;
3226
- if (nfce) {
3211
+ if (comQr) {
3227
3212
  const tabela = urlsNfce(emitUf, opcoes.ambiente, diaBrasilia(agora));
3228
3213
  const urlQr = opcoes.urlQrCode ?? tabela.qrCode;
3229
3214
  const urlChave = opcoes.urlChave ?? tabela.urlChave;
@@ -3287,7 +3272,7 @@ function comQrCode(nota, assinatura) {
3287
3272
  if (assinatura !== undefined) {
3288
3273
  const issues = conferirSupl(xml);
3289
3274
  if (issues.length > 0)
3290
- throw new ErroDeValidacao("o QR Code da NFC-e não passou no schema", issues);
3275
+ throw new ErroDeValidacao("o QR Code não passou no schema", issues);
3291
3276
  }
3292
3277
  return xml;
3293
3278
  }
@@ -3295,18 +3280,18 @@ function inserirSupl(built, assinatura) {
3295
3280
  const s = built.nfce;
3296
3281
  if (s === undefined) {
3297
3282
  if (assinatura !== undefined)
3298
- throw new ErroDeConfiguracao2("a NF-e (modelo 55) não tem QR Code");
3283
+ throw new ErroDeConfiguracao2("esta NF-e não tem QR Code: só a NF-e com DANFE Simplificado Tipo 2 (tpImp 6) leva");
3299
3284
  return built.xml;
3300
3285
  }
3301
3286
  if (s.assinar && assinatura === undefined) {
3302
- throw new ErroDeConfiguracao2("NFC-e em contingência off-line com QR Code versão 3 precisa da assinatura (ZX02-334, rejeição 474)");
3287
+ throw new ErroDeConfiguracao2("contingência off-line com QR Code versão 3 precisa da assinatura (ZX02-334, rejeição 474)");
3303
3288
  }
3304
3289
  if (!s.assinar && assinatura !== undefined) {
3305
3290
  throw new ErroDeConfiguracao2("este QR Code não leva assinatura (ZX02-330, rejeição 445)");
3306
3291
  }
3307
3292
  const fim = "</NFe>";
3308
3293
  if (!built.xml.endsWith(fim))
3309
- throw new ErroDeConfiguracao2("NFC-e montada fora da forma esperada");
3294
+ throw new ErroDeConfiguracao2("nota montada fora da forma esperada");
3310
3295
  const qrCode = `${s.base}${s.parametros}${assinatura === undefined ? "" : `|${assinatura}`}`;
3311
3296
  const supl = `<infNFeSupl><qrCode>${escapeXml(qrCode)}</qrCode><urlChave>${escapeXml(s.urlChave)}</urlChave></infNFeSupl>`;
3312
3297
  return built.xml.slice(0, -fim.length) + supl + fim;
@@ -3528,7 +3513,7 @@ import { completarRecusado } from "@sinete/rejeicoes";
3528
3513
  // packages/nfe/src/data/cstat.json
3529
3514
  var cstat_default = {
3530
3515
  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.",
3531
- fonte: "MOC 7.0 Anexo I, tabela 4.4.1 (códigos de sucesso) e 4.4.2 (denegação 301, 302, 303); NT 2014.002 (Distribuição DF-e, 137 e 138); NT 2011.004 (lote em processamento, 105); MOC 7.0 Anexo I, consulta protocolo J03 a J06 (561, 562 e 613: a numeração da chave consultada tem outra NF-e)",
3516
+ fonte: "MOC 7.0 Anexo I, tabela 4.4.1 (códigos de sucesso) e 4.4.2 (denegação 301, 302, 303); NT 2014.002 (Distribuição DF-e, 137 e 138); NT 2011.004 (lote em processamento, 105); MOC 7.0 Anexo I, consulta protocolo J03 a J06 (561, 562 e 613: a numeração da chave consultada tem outra NF-e); MOC 7.0 Visão Geral, tabela 5-12, regra I07 (563: a mesma faixa já inutilizada, com o nProt anterior)",
3532
3517
  atualizadoEm: "2026-09-26",
3533
3518
  autorizada: ["100", "150"],
3534
3519
  denegada: ["110", "301", "302", "303"],
@@ -3539,6 +3524,7 @@ var cstat_default = {
3539
3524
  loteNaoLocalizado: ["106"],
3540
3525
  servicoEmOperacao: ["107"],
3541
3526
  inutilizacaoHomologada: ["102"],
3527
+ inutilizacaoJaHomologada: ["563"],
3542
3528
  eventoRegistrado: ["135", "136", "155"],
3543
3529
  loteEventoProcessado: ["128"],
3544
3530
  cadastroEncontrado: ["111", "112"],
@@ -3887,6 +3873,11 @@ function autorDoEmitente(a, c) {
3887
3873
  return autor;
3888
3874
  }
3889
3875
  var SVC_DO_TPEMIS = { "6": "SVC-AN", "7": "SVC-RS" };
3876
+ function emitenteSemIe(a) {
3877
+ const inf = primeiroFilho5(a.documento.raiz, "infNFe", NFE_NS4);
3878
+ const emit = inf === undefined ? undefined : primeiroFilho5(inf, "emit", NFE_NS4);
3879
+ return emit !== undefined && primeiroFilho5(emit, "IE", NFE_NS4) === undefined;
3880
+ }
3890
3881
  function chaveDoDocumento(a) {
3891
3882
  const r = lerChaveAcesso2(a.id.slice(3), { caminho: "infNFe.Id", conferirEmitente: false });
3892
3883
  if (!r.ok)
@@ -3988,9 +3979,12 @@ function criarClienteNfe(opcoesDoCliente) {
3988
3979
  ...opcoesDoCliente.contingencia === undefined ? {} : { contingencia: opcoesDoCliente.contingencia }
3989
3980
  });
3990
3981
  };
3991
- const endpointDaChave = (servico, c, naUf = false) => {
3982
+ const endpointDaChave = (servico, c, naUf = false, semIe = opcoesDoCliente.contribuinteExclusivoIbsCbs === true) => {
3992
3983
  if (c.mod === "65")
3993
3984
  return endpointNfce(servico, c.uf);
3985
+ const serie = Number(c.serie);
3986
+ if (semIe && !(servico === "RecepcaoEvento" && serie >= 890 && serie <= 919))
3987
+ return nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico, autorizador: "SVRS" });
3994
3988
  const svc = naUf || c.tpEmis === undefined ? undefined : SVC_DO_TPEMIS[c.tpEmis];
3995
3989
  return nfeEndpoint({
3996
3990
  ambiente: opcoesDoCliente.ambiente,
@@ -3998,6 +3992,7 @@ function criarClienteNfe(opcoesDoCliente) {
3998
3992
  ...svc === undefined ? { uf: c.uf } : { autorizador: svc }
3999
3993
  });
4000
3994
  };
3995
+ const semIeOuOpcao = (a) => a === undefined ? opcoesDoCliente.contribuinteExclusivoIbsCbs === true : emitenteSemIe(a);
4001
3996
  const call = (ep, servico, mensagem, retorno, signal) => chamar({
4002
3997
  transport: opcoesDoCliente.transporte,
4003
3998
  endpoint: ep,
@@ -4023,7 +4018,7 @@ function criarClienteNfe(opcoesDoCliente) {
4023
4018
  throw new ErroDeConfiguracao4(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
4024
4019
  }
4025
4020
  const msg = envelope("consReciNFe", "4.00", [`<tpAmb>${tpAmb}</tpAmb><nRec>${nRec}</nRec>`]);
4026
- const ep = c === undefined ? endpoint("NFeRetAutorizacao", opcoes.mod ?? "55") : endpointDaChave("NFeRetAutorizacao", c);
4021
+ const ep = c === undefined ? (opcoes.mod ?? "55") === "55" && opcoesDoCliente.contribuinteExclusivoIbsCbs === true ? nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico: "NFeRetAutorizacao", autorizador: "SVRS" }) : endpoint("NFeRetAutorizacao", opcoes.mod ?? "55") : endpointDaChave("NFeRetAutorizacao", c, false, semIeOuOpcao(a));
4027
4022
  const r = await call(ep, "NFeRetAutorizacao", msg, "retConsReciNFe", opcoes.signal);
4028
4023
  const v = decodificar(TRetConsReciNFe, r.ret, r.doc.texto).valor;
4029
4024
  if (v.nRec !== undefined && v.nRec !== nRec) {
@@ -4047,7 +4042,7 @@ function criarClienteNfe(opcoesDoCliente) {
4047
4042
  if (a && a.id !== `NFe${c.chave}`)
4048
4043
  throw new ErroDeConfiguracao4("a NF-e assinada não é a da chave consultada");
4049
4044
  const msg = serializarRaiz(consSitNFeElement, { versao: "4.00", tpAmb, xServ: "CONSULTAR", chNFe: c.chave });
4050
- const ep = endpointDaChave("NfeConsultaProtocolo", c);
4045
+ const ep = endpointDaChave("NfeConsultaProtocolo", c, false, semIeOuOpcao(a));
4051
4046
  const r = await call(ep, "NfeConsultaProtocolo", msg, "retConsSitNFe", opcoes?.signal);
4052
4047
  const v = decodificar(TRetConsSitNFe, r.ret, r.doc.texto).valor;
4053
4048
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
@@ -4165,7 +4160,7 @@ function criarClienteNfe(opcoesDoCliente) {
4165
4160
  `<idLote>${idLote()}</idLote><indSinc>${sincrono ? "1" : "0"}</indSinc>`,
4166
4161
  a.xml
4167
4162
  ]);
4168
- const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a));
4163
+ const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a), false, semIeOuOpcao(a));
4169
4164
  const r = await call(ep, "NFeAutorizacao", msg, "retEnviNFe", opcoes.signal);
4170
4165
  const v = decodificar(TRetEnviNFe, r.ret, r.doc.texto).valor;
4171
4166
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
@@ -4363,7 +4358,9 @@ function criarClienteNfe(opcoesDoCliente) {
4363
4358
  const v = decodificar(TRetInutNFe, r.ret, r.doc.texto).valor;
4364
4359
  const status = { cStat: v.infInut.cStat, xMotivo: v.infInut.xMotivo };
4365
4360
  logger.info("nfe.inutilizacao", { id, cStat: status.cStat });
4366
- if (!cstatEm(status.cStat, "inutilizacaoHomologada"))
4361
+ const homologada = cstatEm(status.cStat, "inutilizacaoHomologada");
4362
+ const anterior = cstatEm(status.cStat, "inutilizacaoJaHomologada") ? v.infInut.nProt || undefined : undefined;
4363
+ if (!homologada && anterior === undefined)
4367
4364
  return rejeitado(status);
4368
4365
  const r0 = v.infInut;
4369
4366
  const n = (x) => x === undefined ? undefined : String(Number(x));
@@ -4381,6 +4378,9 @@ function criarClienteNfe(opcoesDoCliente) {
4381
4378
  detalhes: Object.fromEntries(fora.map(([k, v]) => [k, v]))
4382
4379
  });
4383
4380
  }
4381
+ if (anterior !== undefined) {
4382
+ return { ...rejeitado(status), anterior: { nProt: anterior, retInutNFe: avulso(r.doc, r.ret) } };
4383
+ }
4384
4384
  return criarAutorizado(status, {
4385
4385
  dhRecbto: v.infInut.dhRecbto,
4386
4386
  retInutNFe: avulso(r.doc, r.ret),
@@ -4595,5 +4595,5 @@ export {
4595
4595
  urlsNfce
4596
4596
  };
4597
4597
 
4598
- //# debugId=74A78D3EACEECD4D64756E2164756E21
4598
+ //# debugId=ED0E3E2F03183E8464756E2164756E21
4599
4599
  //# sourceMappingURL=index.js.map