@sinete/nfe 0.3.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
@@ -398,13 +398,26 @@ function grupoDoLeiaute(g, indDoacao) {
398
398
  }
399
399
  };
400
400
  }
401
- function ocorrenciaDoMotor(e, itens) {
401
+ function ocorrenciaDoMotor(e, itens, semAliquota) {
402
402
  if (e instanceof ErroClassificacao || e instanceof ErroRegimeNaoSuportado) {
403
403
  const path = e.item !== undefined ? caminho(e.item) : caminho(itens[0]?.nItem ?? 1);
404
404
  return { caminho: path, code: e.code, mensagem: e.message, origem: "entrada" };
405
405
  }
406
- if (e instanceof ErroAliquotaDesconhecida)
407
- return { caminho: "impostos.ibsCbs", code: e.code, mensagem: e.message, origem: "montagem" };
406
+ if (e instanceof ErroAliquotaDesconhecida) {
407
+ const n = semAliquota() ?? itens[0]?.nItem ?? 1;
408
+ return { caminho: caminho(n), code: e.code, mensagem: e.message, origem: "montagem" };
409
+ }
410
+ return;
411
+ }
412
+ function primeiroItemSemAliquota(op, calc) {
413
+ for (const it of [...op.itens].sort((a, b) => a.n - b.n)) {
414
+ try {
415
+ calc({ ...op, itens: [it] });
416
+ } catch (e) {
417
+ if (e instanceof ErroAliquotaDesconhecida)
418
+ return it.n;
419
+ }
420
+ }
408
421
  return;
409
422
  }
410
423
  var embarcado;
@@ -485,16 +498,17 @@ function calcularCom(dataset, rates, options, {
485
498
  itens: classificados
486
499
  };
487
500
  const time = contextoDeTempo({ emissao: relogioFixo(nota.emissao), fatoGerador: relogioFixo(nota.fatoGerador) });
501
+ const calc = (o) => calcular(o, {
502
+ dataset,
503
+ aliquotas: rates,
504
+ tempo: time,
505
+ ...options.deslocamentoMin === undefined ? {} : { deslocamentoMin: options.deslocamentoMin }
506
+ });
488
507
  let roc;
489
508
  try {
490
- roc = calcular(op, {
491
- dataset,
492
- aliquotas: rates,
493
- tempo: time,
494
- ...options.deslocamentoMin === undefined ? {} : { deslocamentoMin: options.deslocamentoMin }
495
- });
509
+ roc = calc(op);
496
510
  } catch (e) {
497
- const issue = ocorrenciaDoMotor(e, itens);
511
+ const issue = ocorrenciaDoMotor(e, itens, () => primeiroItemSemAliquota(op, calc));
498
512
  if (issue === undefined)
499
513
  throw e;
500
514
  return { itens: [], ocorrencias: [issue] };
@@ -538,11 +552,13 @@ function calcularCom(dataset, rates, options, {
538
552
  }
539
553
  }
540
554
  const porItem = new Map(itens.map((it) => [it.nItem, it]));
555
+ const informadas = roc.itens.flatMap((r) => r.aliquotas.filter((a) => a.situacao === "informada").map((a) => ({ nItem: r.nItem, tributo: a.tributo, valor: a.valor, motivo: a.motivo ?? "" })));
541
556
  return {
542
557
  itens: roc.itens.map((r) => ({
543
558
  nItem: r.nItem,
544
559
  IBSCBS: grupoDoLeiaute(r.IBSCBS, porItem.get(r.nItem)?.indDoacao)
545
560
  })),
561
+ ...informadas.length === 0 ? {} : { aliquotasInformadas: informadas },
546
562
  ...issues.length === 0 ? {} : { ocorrencias: issues }
547
563
  };
548
564
  }
@@ -578,7 +594,7 @@ function formatarDh(data, deslocamentoMin) {
578
594
  }
579
595
 
580
596
  // packages/nfe/src/versao-gerada.ts
581
- var VERSAO_PACOTE = "0.3.0";
597
+ var VERSAO_PACOTE = "0.5.0";
582
598
 
583
599
  // packages/nfe/src/build/destinatario.ts
584
600
  import { ufPorSigla } from "@sinete/core";
@@ -1843,6 +1859,7 @@ function camposForaDoPl(ct, value, path, pl, issues) {
1843
1859
  }
1844
1860
 
1845
1861
  // packages/nfe/src/build/rejeicoes.ts
1862
+ import { indicadoresCfop } from "@sinete/validators";
1846
1863
  var CFOP_CST50_ISENTO = new Set([
1847
1864
  "1915",
1848
1865
  "1916",
@@ -1918,18 +1935,120 @@ function conferirEmitenteDoCertificado(nfe, titular) {
1918
1935
  }
1919
1936
  return [];
1920
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
+ }
1921
2048
 
1922
2049
  // packages/nfe/src/build/textos.ts
1923
- import { conferirTipoSimples, ehComplexType as ehComplexType2, ehElementParticle as ehElementParticle2, ehWildcard as ehWildcard2 } from "@sinete/schemas";
1924
- function textoXmlValido(texto) {
1925
- for (const ch of texto) {
1926
- const c = ch.codePointAt(0) ?? 0;
1927
- const ok = c === 9 || c === 10 || c === 13 || c >= 32 && c <= 55295 || c >= 57344 && c <= 65533 || c >= 65536 && c <= 1114111;
1928
- if (!ok)
1929
- return false;
1930
- }
1931
- return true;
1932
- }
2050
+ import { conferirTextos } from "@sinete/schemas";
2051
+ import { textoXmlValido } from "@sinete/schemas";
1933
2052
  var CAMPOS = [
1934
2053
  ["natOp", "ide.natOp"],
1935
2054
  ["emitente.xNome", "emit.xNome"],
@@ -1971,138 +2090,10 @@ var CAMPOS = [
1971
2090
  ["compra.xPed", "compra.xPed"],
1972
2091
  ["compra.xCont", "compra.xCont"]
1973
2092
  ];
1974
- function elemento(p, nome) {
1975
- if (p === undefined || ehWildcard2(p))
1976
- return;
1977
- if (ehElementParticle2(p))
1978
- return p.e === nome ? p.t : undefined;
1979
- for (const i of p.i) {
1980
- const t = elemento(i, nome);
1981
- if (t !== undefined)
1982
- return t;
1983
- }
1984
- return;
1985
- }
1986
- function tipoEm(infNFe, caminho) {
1987
- let t = infNFe;
1988
- for (const nome of caminho.split(".")) {
1989
- if (t === undefined || !ehComplexType2(t))
1990
- return;
1991
- t = elemento(t.c, nome);
1992
- }
1993
- return t === undefined || ehComplexType2(t) ? undefined : t;
1994
- }
1995
- var tiposPorPl = new WeakMap;
1996
- function tiposDoPl(infNFe) {
1997
- let m = tiposPorPl.get(infNFe);
1998
- if (m === undefined) {
1999
- const novo = new Map;
2000
- for (const [entrada, xml] of CAMPOS) {
2001
- const t = tipoEm(infNFe, xml);
2002
- if (t !== undefined)
2003
- novo.set(entrada, t);
2004
- }
2005
- m = novo;
2006
- tiposPorPl.set(infNFe, m);
2007
- }
2008
- return m;
2009
- }
2010
- function valoresEm(raiz, caminho) {
2011
- let atuais = [["", raiz]];
2012
- for (const parte of caminho.split(".")) {
2013
- const lista = parte.endsWith("[]");
2014
- const chave = lista ? parte.slice(0, -2) : parte;
2015
- const proximos = [];
2016
- for (const [c, v] of atuais) {
2017
- if (typeof v !== "object" || v === null)
2018
- continue;
2019
- const filho = v[chave];
2020
- const base = c === "" ? chave : `${c}.${chave}`;
2021
- if (!lista)
2022
- proximos.push([base, filho]);
2023
- else if (Array.isArray(filho))
2024
- for (const [n, f] of filho.entries())
2025
- proximos.push([`${base}[${n}]`, f]);
2026
- }
2027
- atuais = proximos;
2028
- }
2029
- return atuais;
2030
- }
2031
- function textosForaDoXml(valor, caminho, saida) {
2032
- if (typeof valor === "string") {
2033
- if (!textoXmlValido(valor))
2034
- saida.push(caminho);
2035
- } else if (Array.isArray(valor)) {
2036
- for (const [n, v] of valor.entries())
2037
- textosForaDoXml(v, `${caminho}[${n}]`, saida);
2038
- } else if (typeof valor === "object" && valor !== null) {
2039
- for (const [k, v] of Object.entries(valor))
2040
- textosForaDoXml(v, caminho === "" ? k : `${caminho}.${k}`, saida);
2041
- }
2042
- }
2043
- var CARACTERE_INVISIVEL = "caractere não aceito (símbolo ou caractere de controle)";
2044
- var VISIVEL = /^[\p{L}\p{M}\p{N}\p{P}\p{S}]$/u;
2045
- function caractereRecusado(tipo, valor) {
2046
- for (const ch of new Set(valor)) {
2047
- const saida = [];
2048
- conferirTipoSimples(tipo, `A${ch}A`, "", saida);
2049
- if (saida.some((o) => o.code === "padrao"))
2050
- return ch;
2051
- }
2052
- return;
2053
- }
2054
- function mensagensDoTexto(tipo, valor, violadas) {
2055
- if (violadas.length === 0)
2056
- return [];
2057
- if (valor.trim() === "")
2058
- return ["não pode ficar em branco"];
2059
- const tamanho = [...valor].length;
2060
- const mensagens = new Set;
2061
- for (const o of violadas) {
2062
- if (o.code === "tamanho_maximo" && tipo.mx !== undefined)
2063
- mensagens.add(`no máximo ${tipo.mx} caracteres (tem ${tamanho})`);
2064
- else if (o.code === "tamanho_minimo" && tipo.mn !== undefined)
2065
- mensagens.add(`no mínimo ${tipo.mn} caracteres (tem ${tamanho})`);
2066
- else if (o.code === "tamanho" && tipo.l !== undefined)
2067
- mensagens.add(`exatamente ${tipo.l} caracteres (tem ${tamanho})`);
2068
- else if (o.code === "padrao") {
2069
- const espaco = valor !== valor.trim();
2070
- const ch = caractereRecusado(tipo, valor);
2071
- if (espaco)
2072
- mensagens.add("sem espaço no começo nem no fim");
2073
- if (ch !== undefined)
2074
- mensagens.add(VISIVEL.test(ch) ? `caractere não aceito: “${ch}”` : CARACTERE_INVISIVEL);
2075
- if (!espaco && ch === undefined)
2076
- mensagens.add("formato não aceito");
2077
- } else
2078
- mensagens.add("valor não aceito neste campo");
2079
- }
2080
- return [...mensagens];
2081
- }
2082
2093
  function conferirTextosDaEntrada(entrada, infNFe, issues, substituidos = new Set) {
2083
- const jaRecusados = new Set(issues.list.map((i) => i.caminho));
2084
- const foraDoXml = [];
2085
- textosForaDoXml(entrada, "", foraDoXml);
2086
- for (const c of foraDoXml) {
2087
- if (jaRecusados.has(c) || substituidos.has(c))
2088
- continue;
2089
- issues.add(c, "campo_invalido", CARACTERE_INVISIVEL);
2090
- jaRecusados.add(c);
2091
- }
2092
- const tipos = tiposDoPl(infNFe);
2093
- for (const [campo] of CAMPOS) {
2094
- const tipo = tipos.get(campo);
2095
- if (tipo === undefined)
2096
- continue;
2097
- for (const [caminho, valor] of valoresEm(entrada, campo)) {
2098
- if (typeof valor !== "string" || jaRecusados.has(caminho) || substituidos.has(caminho))
2099
- continue;
2100
- const saida = [];
2101
- conferirTipoSimples(tipo, valor, caminho, saida);
2102
- for (const m of mensagensDoTexto(tipo, valor, saida))
2103
- issues.add(caminho, "campo_invalido", m);
2104
- }
2105
- }
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);
2106
2097
  }
2107
2098
 
2108
2099
  // packages/nfe/src/build/tributos.ts
@@ -2409,19 +2400,19 @@ function referencia(ref, path, issues) {
2409
2400
  }
2410
2401
  };
2411
2402
  }
2412
- function textosForaDoXml2(value, path, issues) {
2403
+ function textosForaDoXml(value, path, issues) {
2413
2404
  if (typeof value === "string") {
2414
2405
  if (!textoXmlValido(value))
2415
2406
  issues.montagem(path, "campo_invalido", "texto com caractere não permitido em XML");
2416
2407
  } else if (Array.isArray(value)) {
2417
2408
  for (const [n, v] of value.entries())
2418
- textosForaDoXml2(v, `${path}[${n}]`, issues);
2409
+ textosForaDoXml(v, `${path}[${n}]`, issues);
2419
2410
  } else if (typeof value === "object" && value !== null) {
2420
2411
  for (const [k, v] of Object.entries(value))
2421
- textosForaDoXml2(v, `${path}.${k}`, issues);
2412
+ textosForaDoXml(v, `${path}.${k}`, issues);
2422
2413
  }
2423
2414
  }
2424
- function montarItem(ctx, item, n, normal) {
2415
+ function montarItem(ctx, item, n, normal, semIe) {
2425
2416
  const path = `itens[${n}]`;
2426
2417
  const p = item.produto;
2427
2418
  const pp = `${path}.produto`;
@@ -2536,7 +2527,7 @@ function montarItem(ctx, item, n, normal) {
2536
2527
  const r = buildIcms(ctx, imp.icms, { vOp, vIPI: v.vIPI }, `${ip}.icms`);
2537
2528
  imposto.ICMS = r.grupo;
2538
2529
  icms = r.totais;
2539
- } else if (imp.issqn === undefined && imp.ibsCbs === undefined) {
2530
+ } else if (imp.issqn === undefined && imp.ibsCbs === undefined && !semIe) {
2540
2531
  ctx.issues.add(`${ip}.icms`, "campo_obrigatorio", "o item precisa de ICMS (ou ISSQN, na NF-e conjugada)");
2541
2532
  }
2542
2533
  if (imp.ii !== undefined) {
@@ -2729,8 +2720,8 @@ async function montarNfe(entrada, opcoes) {
2729
2720
  if (cont.dhCont.getTime() > agora.getTime()) {
2730
2721
  issues.add("contingencia.dhCont", "contingencia_invalida", "entrada em contingência posterior à emissão");
2731
2722
  }
2732
- if (!nfce && tpEmis === "9") {
2733
- 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)");
2734
2725
  }
2735
2726
  if (nfce && (tpEmis === "6" || tpEmis === "7")) {
2736
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)");
@@ -2758,7 +2749,11 @@ async function montarNfe(entrada, opcoes) {
2758
2749
  } else if (tpImp === "4" || tpImp === "5") {
2759
2750
  issues.add("tpImp", "campo_invalido", "tpImp 4 e 5 (DANFC-e) são da NFC-e (B21-20, rejeição 710)");
2760
2751
  }
2752
+ const comQr = nfce || tpImp === "6";
2761
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
+ }
2762
2757
  if (nfce && qr.versao === "2") {
2763
2758
  if (!/^\d{1,6}$/.test(qr.idCSC) || Number(qr.idCSC) === 0) {
2764
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)");
@@ -2779,12 +2774,14 @@ async function montarNfe(entrada, opcoes) {
2779
2774
  if (entrada.itens.length === 0 || entrada.itens.length > 990) {
2780
2775
  issues.add("itens", "itens_limite", "a NF-e tem de 1 a 990 itens");
2781
2776
  }
2782
- 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));
2783
2779
  const primeiro = itens[0];
2784
2780
  if (nfce && opcoes.ambiente === "homologacao" && primeiro !== undefined) {
2785
2781
  primeiro.det.prod.xProd = XPROD_HOMOLOGACAO_NFCE;
2786
2782
  }
2787
2783
  const classificados = entrada.itens.map((it, n) => ({ it, n })).filter(({ it }) => it.impostos.ibsCbs?.classificacao !== undefined);
2784
+ let aliquotasInformadas = [];
2788
2785
  if (classificados.length > 0) {
2789
2786
  const calculadora = opcoes.ibsCbs ?? calculadoraPadrao();
2790
2787
  const reqs = classificados.map(({ it, n }) => {
@@ -2850,10 +2847,13 @@ async function montarNfe(entrada, opcoes) {
2850
2847
  itens: reqs
2851
2848
  });
2852
2849
  issues.addAll(resp.ocorrencias ?? [], "montagem");
2850
+ aliquotasInformadas = resp.aliquotasInformadas ?? [];
2851
+ const explicou = (resp.ocorrencias?.length ?? 0) > 0;
2853
2852
  for (const { n } of classificados) {
2854
2853
  const g = resp.itens.find((x) => x.nItem === n + 1);
2855
2854
  if (g === undefined) {
2856
- issues.montagem(`itens[${n}].impostos.ibsCbs`, "ibscbs_calculo", "a calculadora não devolveu o grupo IBSCBS do item");
2855
+ if (!explicou)
2856
+ issues.montagem(`itens[${n}].impostos.ibsCbs`, "ibscbs_calculo", "a calculadora não devolveu o grupo IBSCBS do item");
2857
2857
  continue;
2858
2858
  }
2859
2859
  itens[n].det.imposto.IBSCBS = g.IBSCBS;
@@ -2878,6 +2878,7 @@ async function montarNfe(entrada, opcoes) {
2878
2878
  });
2879
2879
  const substituidos = opcoes.ambiente === "homologacao" ? ["destinatario.xNome", ...nfce ? ["itens[0].produto.xProd"] : []] : [];
2880
2880
  conferirTextosDaEntrada(entrada, pl.infNFe, issues, new Set(substituidos));
2881
+ exclusivoIbsCbs(entrada, { nfce, dhEmi, instantes: [agora, fatoGerador] }, issues);
2881
2882
  if (!issues.empty)
2882
2883
  return { ok: false, ocorrencias: issues.classificadas };
2883
2884
  const gruposIbsCbs = itens.map((m) => m.det.imposto.IBSCBS).filter((g) => g !== undefined);
@@ -3172,9 +3173,13 @@ async function montarNfe(entrada, opcoes) {
3172
3173
  agropecuario: entrada.agropecuario
3173
3174
  });
3174
3175
  cstComIsento(entrada, idDest, issues);
3176
+ if (!nfce) {
3177
+ cfopDeDevolucao(entrada, issues);
3178
+ cstComNaoContribuinte(entrada, { idDest, uf: emitUf }, issues);
3179
+ }
3175
3180
  vencimentos(entrada, { dhEmi, instante: agora }, issues);
3176
3181
  camposForaDoPl(pl.infNFe, inf, "infNFe", pl.vigencia.pl, issues);
3177
- textosForaDoXml2(inf, "infNFe", issues);
3182
+ textosForaDoXml(inf, "infNFe", issues);
3178
3183
  if (!issues.empty)
3179
3184
  return { ok: false, ocorrencias: issues.classificadas };
3180
3185
  let xml;
@@ -3203,7 +3208,7 @@ async function montarNfe(entrada, opcoes) {
3203
3208
  };
3204
3209
  }
3205
3210
  let supl;
3206
- if (nfce) {
3211
+ if (comQr) {
3207
3212
  const tabela = urlsNfce(emitUf, opcoes.ambiente, diaBrasilia(agora));
3208
3213
  const urlQr = opcoes.urlQrCode ?? tabela.qrCode;
3209
3214
  const urlChave = opcoes.urlChave ?? tabela.urlChave;
@@ -3242,7 +3247,8 @@ async function montarNfe(entrada, opcoes) {
3242
3247
  ...supl === undefined ? {} : { nfce: supl },
3243
3248
  pl: pl.vigencia,
3244
3249
  infNFe: inf,
3245
- xml
3250
+ xml,
3251
+ ...aliquotasInformadas.length === 0 ? {} : { aliquotasInformadas }
3246
3252
  }
3247
3253
  };
3248
3254
  }
@@ -3266,7 +3272,7 @@ function comQrCode(nota, assinatura) {
3266
3272
  if (assinatura !== undefined) {
3267
3273
  const issues = conferirSupl(xml);
3268
3274
  if (issues.length > 0)
3269
- 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);
3270
3276
  }
3271
3277
  return xml;
3272
3278
  }
@@ -3274,18 +3280,18 @@ function inserirSupl(built, assinatura) {
3274
3280
  const s = built.nfce;
3275
3281
  if (s === undefined) {
3276
3282
  if (assinatura !== undefined)
3277
- 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");
3278
3284
  return built.xml;
3279
3285
  }
3280
3286
  if (s.assinar && assinatura === undefined) {
3281
- 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)");
3282
3288
  }
3283
3289
  if (!s.assinar && assinatura !== undefined) {
3284
3290
  throw new ErroDeConfiguracao2("este QR Code não leva assinatura (ZX02-330, rejeição 445)");
3285
3291
  }
3286
3292
  const fim = "</NFe>";
3287
3293
  if (!built.xml.endsWith(fim))
3288
- throw new ErroDeConfiguracao2("NFC-e montada fora da forma esperada");
3294
+ throw new ErroDeConfiguracao2("nota montada fora da forma esperada");
3289
3295
  const qrCode = `${s.base}${s.parametros}${assinatura === undefined ? "" : `|${assinatura}`}`;
3290
3296
  const supl = `<infNFeSupl><qrCode>${escapeXml(qrCode)}</qrCode><urlChave>${escapeXml(s.urlChave)}</urlChave></infNFeSupl>`;
3291
3297
  return built.xml.slice(0, -fim.length) + supl + fim;
@@ -3507,7 +3513,7 @@ import { completarRecusado } from "@sinete/rejeicoes";
3507
3513
  // packages/nfe/src/data/cstat.json
3508
3514
  var cstat_default = {
3509
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.",
3510
- 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)",
3511
3517
  atualizadoEm: "2026-09-26",
3512
3518
  autorizada: ["100", "150"],
3513
3519
  denegada: ["110", "301", "302", "303"],
@@ -3518,6 +3524,7 @@ var cstat_default = {
3518
3524
  loteNaoLocalizado: ["106"],
3519
3525
  servicoEmOperacao: ["107"],
3520
3526
  inutilizacaoHomologada: ["102"],
3527
+ inutilizacaoJaHomologada: ["563"],
3521
3528
  eventoRegistrado: ["135", "136", "155"],
3522
3529
  loteEventoProcessado: ["128"],
3523
3530
  cadastroEncontrado: ["111", "112"],
@@ -3866,6 +3873,11 @@ function autorDoEmitente(a, c) {
3866
3873
  return autor;
3867
3874
  }
3868
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
+ }
3869
3881
  function chaveDoDocumento(a) {
3870
3882
  const r = lerChaveAcesso2(a.id.slice(3), { caminho: "infNFe.Id", conferirEmitente: false });
3871
3883
  if (!r.ok)
@@ -3967,9 +3979,12 @@ function criarClienteNfe(opcoesDoCliente) {
3967
3979
  ...opcoesDoCliente.contingencia === undefined ? {} : { contingencia: opcoesDoCliente.contingencia }
3968
3980
  });
3969
3981
  };
3970
- const endpointDaChave = (servico, c, naUf = false) => {
3982
+ const endpointDaChave = (servico, c, naUf = false, semIe = opcoesDoCliente.contribuinteExclusivoIbsCbs === true) => {
3971
3983
  if (c.mod === "65")
3972
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" });
3973
3988
  const svc = naUf || c.tpEmis === undefined ? undefined : SVC_DO_TPEMIS[c.tpEmis];
3974
3989
  return nfeEndpoint({
3975
3990
  ambiente: opcoesDoCliente.ambiente,
@@ -3977,6 +3992,7 @@ function criarClienteNfe(opcoesDoCliente) {
3977
3992
  ...svc === undefined ? { uf: c.uf } : { autorizador: svc }
3978
3993
  });
3979
3994
  };
3995
+ const semIeOuOpcao = (a) => a === undefined ? opcoesDoCliente.contribuinteExclusivoIbsCbs === true : emitenteSemIe(a);
3980
3996
  const call = (ep, servico, mensagem, retorno, signal) => chamar({
3981
3997
  transport: opcoesDoCliente.transporte,
3982
3998
  endpoint: ep,
@@ -4002,7 +4018,7 @@ function criarClienteNfe(opcoesDoCliente) {
4002
4018
  throw new ErroDeConfiguracao4(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
4003
4019
  }
4004
4020
  const msg = envelope("consReciNFe", "4.00", [`<tpAmb>${tpAmb}</tpAmb><nRec>${nRec}</nRec>`]);
4005
- 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));
4006
4022
  const r = await call(ep, "NFeRetAutorizacao", msg, "retConsReciNFe", opcoes.signal);
4007
4023
  const v = decodificar(TRetConsReciNFe, r.ret, r.doc.texto).valor;
4008
4024
  if (v.nRec !== undefined && v.nRec !== nRec) {
@@ -4026,7 +4042,7 @@ function criarClienteNfe(opcoesDoCliente) {
4026
4042
  if (a && a.id !== `NFe${c.chave}`)
4027
4043
  throw new ErroDeConfiguracao4("a NF-e assinada não é a da chave consultada");
4028
4044
  const msg = serializarRaiz(consSitNFeElement, { versao: "4.00", tpAmb, xServ: "CONSULTAR", chNFe: c.chave });
4029
- const ep = endpointDaChave("NfeConsultaProtocolo", c);
4045
+ const ep = endpointDaChave("NfeConsultaProtocolo", c, false, semIeOuOpcao(a));
4030
4046
  const r = await call(ep, "NfeConsultaProtocolo", msg, "retConsSitNFe", opcoes?.signal);
4031
4047
  const v = decodificar(TRetConsSitNFe, r.ret, r.doc.texto).valor;
4032
4048
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
@@ -4144,7 +4160,7 @@ function criarClienteNfe(opcoesDoCliente) {
4144
4160
  `<idLote>${idLote()}</idLote><indSinc>${sincrono ? "1" : "0"}</indSinc>`,
4145
4161
  a.xml
4146
4162
  ]);
4147
- const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a));
4163
+ const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a), false, semIeOuOpcao(a));
4148
4164
  const r = await call(ep, "NFeAutorizacao", msg, "retEnviNFe", opcoes.signal);
4149
4165
  const v = decodificar(TRetEnviNFe, r.ret, r.doc.texto).valor;
4150
4166
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
@@ -4342,7 +4358,9 @@ function criarClienteNfe(opcoesDoCliente) {
4342
4358
  const v = decodificar(TRetInutNFe, r.ret, r.doc.texto).valor;
4343
4359
  const status = { cStat: v.infInut.cStat, xMotivo: v.infInut.xMotivo };
4344
4360
  logger.info("nfe.inutilizacao", { id, cStat: status.cStat });
4345
- 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)
4346
4364
  return rejeitado(status);
4347
4365
  const r0 = v.infInut;
4348
4366
  const n = (x) => x === undefined ? undefined : String(Number(x));
@@ -4360,6 +4378,9 @@ function criarClienteNfe(opcoesDoCliente) {
4360
4378
  detalhes: Object.fromEntries(fora.map(([k, v]) => [k, v]))
4361
4379
  });
4362
4380
  }
4381
+ if (anterior !== undefined) {
4382
+ return { ...rejeitado(status), anterior: { nProt: anterior, retInutNFe: avulso(r.doc, r.ret) } };
4383
+ }
4363
4384
  return criarAutorizado(status, {
4364
4385
  dhRecbto: v.infInut.dhRecbto,
4365
4386
  retInutNFe: avulso(r.doc, r.ret),
@@ -4574,5 +4595,5 @@ export {
4574
4595
  urlsNfce
4575
4596
  };
4576
4597
 
4577
- //# debugId=9351F0AE81B9EE1064756E2164756E21
4598
+ //# debugId=ED0E3E2F03183E8464756E2164756E21
4578
4599
  //# sourceMappingURL=index.js.map