@sinete/nfe 0.4.0 → 0.6.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.6.0";
598
598
 
599
599
  // packages/nfe/src/build/destinatario.ts
600
600
  import { ufPorSigla } from "@sinete/core";
@@ -1627,11 +1627,13 @@ var TPAG_VEDADOS = {
1627
1627
  "99": "tPag 99 (outros) não é aceito na NFC-e (YA02-50, rejeição 436, NT 2020.006)"
1628
1628
  };
1629
1629
  function conferirNfce(input, ide, issues) {
1630
- const vedado = (path, msg) => issues.add(path, "grupo_vedado", `NFC-e ${msg}`);
1631
- const invalido = (path, msg) => issues.add(path, "campo_invalido", `NFC-e ${msg}`);
1630
+ const soNfce = ide.mod === "65";
1631
+ const doc = soNfce ? "NFC-e" : "NF-e com DANFE Simplificado Tipo 2";
1632
+ const vedado = (path, msg) => issues.add(path, "grupo_vedado", `${doc} ${msg}`);
1633
+ const invalido = (path, msg) => issues.add(path, "campo_invalido", `${doc} ${msg}`);
1632
1634
  if (input.dhSaiEnt !== undefined)
1633
1635
  vedado("dhSaiEnt", "sem data de entrada ou saída (B10-10, rejeição 705)");
1634
- if (input.dPrevEntrega !== undefined) {
1636
+ if (soNfce && input.dPrevEntrega !== undefined) {
1635
1637
  vedado("dPrevEntrega", "sem data de previsão de entrega (NT 2025.002, B10a-10, rejeição 1153)");
1636
1638
  }
1637
1639
  if (ide.tpNF !== "1")
@@ -1639,7 +1641,7 @@ function conferirNfce(input, ide, issues) {
1639
1641
  if (ide.idDest !== "1") {
1640
1642
  invalido("idDest", "só em operação interna, idDest 1 (B11a-10, rejeição 707)");
1641
1643
  }
1642
- if (ide.tpImp !== "4" && ide.tpImp !== "5") {
1644
+ if (soNfce && ide.tpImp !== "4" && ide.tpImp !== "5") {
1643
1645
  invalido("tpImp", "com DANFC-e: tpImp 4 (impresso) ou 5 (mensagem eletrônica) (B21-10, rejeição 709)");
1644
1646
  }
1645
1647
  if (ide.finNFe !== "1")
@@ -1649,27 +1651,29 @@ function conferirNfce(input, ide, issues) {
1649
1651
  if (!["1", "4", "5"].includes(ide.indPres)) {
1650
1652
  invalido("indPres", "só presencial: indPres 1, 4 (entrega a domicílio) ou 5 (NT 2025.002, B25b-20, rejeição 717)");
1651
1653
  }
1652
- if (input.cMunFGIBS !== undefined && ide.indPres !== "5") {
1654
+ if (soNfce && input.cMunFGIBS !== undefined && ide.indPres !== "5") {
1653
1655
  invalido("cMunFGIBS", "com cMunFGIBS só em operação presencial fora do estabelecimento, indPres 5 (NT 2025.002, B25b-60, rejeição 1000)");
1654
1656
  }
1655
- if (input.cMunFGIBS === undefined && ide.indPres === "5") {
1657
+ if (soNfce && input.cMunFGIBS === undefined && ide.indPres === "5") {
1656
1658
  issues.add("cMunFGIBS", "campo_obrigatorio", "NFC-e presencial fora do estabelecimento (indPres 5) informa cMunFGIBS (NT 2025.002, B25b-70, rejeição 1005)");
1657
1659
  }
1658
1660
  if (input.referenciadas !== undefined && input.referenciadas.length > 0) {
1659
1661
  vedado("referenciadas", "não referencia documento fiscal (BA01-10, rejeição 708)");
1660
1662
  }
1661
- if (input.gCompraGov !== undefined)
1663
+ if (soNfce && input.gCompraGov !== undefined)
1662
1664
  vedado("gCompraGov", "sem compra governamental (NT 2025.002, BB01-10, rejeição 1006)");
1663
1665
  if (input.emitente.IEST !== undefined)
1664
1666
  vedado("emitente.IEST", "sem IE de substituto tributário (C18-10, rejeição 718)");
1665
1667
  const d = input.destinatario;
1666
1668
  if (ide.indPres === "4" && d === undefined) {
1667
- issues.add("destinatario", "campo_obrigatorio", "NFC-e com entrega a domicílio identifica o destinatário (E01-20, rejeição 787)");
1669
+ issues.add("destinatario", "campo_obrigatorio", `${doc} com entrega a domicílio identifica o destinatário (E01-20, rejeição 787)`);
1668
1670
  }
1669
- if (ide.indPres === "4" && d !== undefined && d.endereco === undefined) {
1671
+ if (input.retirada !== undefined)
1672
+ vedado("retirada", "sem local de retirada (F01-10, rejeição 669)");
1673
+ if (soNfce && ide.indPres === "4" && d !== undefined && d.endereco === undefined) {
1670
1674
  issues.add("destinatario.endereco", "campo_obrigatorio", "NFC-e com entrega a domicílio informa o endereço do destinatário (E05-20, rejeição 788)");
1671
1675
  }
1672
- if (d !== undefined) {
1676
+ if (soNfce && d !== undefined) {
1673
1677
  if (d.CNPJ !== undefined && input.emitente.CNPJ !== undefined && digitos2(d.CNPJ) === digitos2(input.emitente.CNPJ)) {
1674
1678
  invalido("destinatario.CNPJ", "com destinatário igual ao emitente (E02-20, rejeição 220)");
1675
1679
  }
@@ -1688,15 +1692,18 @@ function conferirNfce(input, ide, issues) {
1688
1692
  vedado(`${p}.produto.especifico.arma`, "sem armamento (L01-10, rejeição 738)");
1689
1693
  if (esp.nRECOPI !== undefined)
1690
1694
  vedado(`${p}.produto.especifico.nRECOPI`, "sem papel imune RECOPI (LB01-10, rejeição 348)");
1691
- if (it.produto.tpCredPresIBSZFM !== undefined) {
1695
+ if (it.produto.indTot === "0") {
1696
+ invalido(`${p}.produto.indTot`, "sem item fora do total, indTot 1 (I17b-10, rejeição 774)");
1697
+ }
1698
+ if (soNfce && it.produto.tpCredPresIBSZFM !== undefined) {
1692
1699
  vedado(`${p}.produto.tpCredPresIBSZFM`, "sem classificação para subapuração do IBS na ZFM (NT 2025.002, I05k-10, rejeição 1165)");
1693
1700
  }
1694
1701
  const cfop = it.produto.CFOP.replace(/\D/g, "");
1695
1702
  const imp = it.impostos;
1696
- if (cfop === CFOP_ISSQN && imp.issqn === undefined) {
1703
+ if (soNfce && cfop === CFOP_ISSQN && imp.issqn === undefined) {
1697
1704
  issues.add(`${p}.impostos.issqn`, "combinacao_invalida", "NFC-e com CFOP 5.933 tem o grupo do ISSQN (I08-160, rejeição 374)");
1698
1705
  }
1699
- if (cfop !== CFOP_ISSQN && imp.issqn !== undefined) {
1706
+ if (soNfce && cfop !== CFOP_ISSQN && imp.issqn !== undefined) {
1700
1707
  issues.add(`${p}.produto.CFOP`, "combinacao_invalida", "NFC-e com ISSQN usa o CFOP 5.933 (I08-170, rejeição 374)");
1701
1708
  }
1702
1709
  const icms = imp.icms;
@@ -1725,10 +1732,10 @@ function conferirNfce(input, ide, issues) {
1725
1732
  if (tr !== undefined && tr.modFrete !== "9" && !entrega) {
1726
1733
  invalido("transporte.modFrete", "sem frete fora da entrega a domicílio: modFrete 9 (X02-10, rejeição 753)");
1727
1734
  }
1728
- if (tr?.transportador !== undefined && !entrega) {
1735
+ if (soNfce && tr?.transportador !== undefined && !entrega) {
1729
1736
  vedado("transporte.transportador", "só tem transportador na entrega a domicílio (X03-10, rejeição 754)");
1730
1737
  }
1731
- if (entrega && tr?.transportador === undefined) {
1738
+ if (soNfce && entrega && tr?.transportador === undefined) {
1732
1739
  issues.add("transporte.transportador", "campo_obrigatorio", "NFC-e com entrega a domicílio identifica o transportador (X03-20, rejeição 786)");
1733
1740
  }
1734
1741
  if (tr?.retTransp !== undefined)
@@ -1739,6 +1746,16 @@ function conferirNfce(input, ide, issues) {
1739
1746
  vedado("transporte.reboque", "sem reboque (X22-10, rejeição 757)");
1740
1747
  if (input.cobranca !== undefined)
1741
1748
  vedado("cobranca", "sem fatura nem duplicata (Y01-10, rejeição 760)");
1749
+ if (soNfce)
1750
+ conferirPagamentoNfce(input, issues);
1751
+ if (soNfce && input.exporta !== undefined)
1752
+ vedado("exporta", "sem comércio exterior (ZA01-30, rejeição 814)");
1753
+ if (input.compra !== undefined)
1754
+ vedado("compra", "sem dados de compra (ZB01-10, rejeição 762)");
1755
+ if (input.cana !== undefined)
1756
+ vedado("cana", "sem aquisição de cana (ZC01-10, rejeição 763)");
1757
+ }
1758
+ function conferirPagamentoNfce(input, issues) {
1742
1759
  if (input.pagamento === undefined || input.pagamento.detPag.length === 0) {
1743
1760
  issues.add("pagamento", "campo_obrigatorio", "a NFC-e informa o pagamento: tPag 90 (sem pagamento) é recusado (YA02-40, rejeição 899)");
1744
1761
  } else {
@@ -1751,12 +1768,6 @@ function conferirNfce(input, ide, issues) {
1751
1768
  }
1752
1769
  });
1753
1770
  }
1754
- if (input.exporta !== undefined)
1755
- vedado("exporta", "sem comércio exterior (ZA01-30, rejeição 814)");
1756
- if (input.compra !== undefined)
1757
- vedado("compra", "sem dados de compra (ZB01-10, rejeição 762)");
1758
- if (input.cana !== undefined)
1759
- vedado("cana", "sem aquisição de cana (ZC01-10, rejeição 763)");
1760
1771
  }
1761
1772
  function pagamentoNfce(pag, vNF, issues) {
1762
1773
  const total = pag.detPag.reduce((a, p) => a.plus(Decimal.of(p.vPag)), Decimal.ZERO);
@@ -1859,6 +1870,7 @@ function camposForaDoPl(ct, value, path, pl, issues) {
1859
1870
  }
1860
1871
 
1861
1872
  // packages/nfe/src/build/rejeicoes.ts
1873
+ import { indicadoresCfop } from "@sinete/validators";
1862
1874
  var CFOP_CST50_ISENTO = new Set([
1863
1875
  "1915",
1864
1876
  "1916",
@@ -1934,18 +1946,120 @@ function conferirEmitenteDoCertificado(nfe, titular) {
1934
1946
  }
1935
1947
  return [];
1936
1948
  }
1949
+ var NFCE_SEM_IE_ATE = "2033-01-01";
1950
+ function exclusivoIbsCbs(input, contexto, issues) {
1951
+ const e = input.emitente;
1952
+ if (e.IE !== undefined)
1953
+ return;
1954
+ if (contexto.nfce) {
1955
+ const datas = [
1956
+ contexto.dhEmi.slice(0, 10),
1957
+ ...contexto.instantes.flatMap((i) => [dataNoFuso(i, OFFSET_BRASILIA), dataNoFuso(i, 0)])
1958
+ ];
1959
+ if (datas.every((d) => d < NFCE_SEM_IE_ATE)) {
1960
+ 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)");
1961
+ }
1962
+ return;
1963
+ }
1964
+ if (e.CNPJ === undefined) {
1965
+ 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)");
1966
+ }
1967
+ if (e.IEST !== undefined) {
1968
+ 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)");
1969
+ }
1970
+ const icmsLiberado = (input.finNFe ?? "1") === "4" || input.tpNFCredito === "03";
1971
+ input.itens.forEach((it, n) => {
1972
+ if (!icmsLiberado) {
1973
+ for (const [campo, grupo] of [
1974
+ ["icms", it.impostos.icms],
1975
+ ["icmsUfDest", it.impostos.icmsUfDest]
1976
+ ]) {
1977
+ if (grupo === undefined)
1978
+ continue;
1979
+ 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)");
1980
+ }
1981
+ }
1982
+ if (it.impostos.ibsCbs === undefined) {
1983
+ 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)");
1984
+ }
1985
+ });
1986
+ }
1987
+ var CREDITO_COM_DEVOLUCAO = new Set(["03", "04", "06"]);
1988
+ function cfopDeDevolucao(input, issues) {
1989
+ const fin = input.finNFe ?? "1";
1990
+ if (fin === "2" || fin === "4")
1991
+ return;
1992
+ if (fin === "5" && input.tpNFCredito !== undefined && CREDITO_COM_DEVOLUCAO.has(input.tpNFCredito))
1993
+ return;
1994
+ input.itens.forEach((it, n) => {
1995
+ if (indicadoresCfop(it.produto.CFOP.replace(/\D/g, ""))?.indDevol !== true)
1996
+ return;
1997
+ 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)`);
1998
+ });
1999
+ }
2000
+ var CST_NAO_CONTRIBUINTE = new Set(["00", "20", "40", "41", "60", "61"]);
2001
+ var ANP_FORA_DA_EXCECAO_5 = new Set([
2002
+ "820101001",
2003
+ "820101010",
2004
+ "810102001",
2005
+ "810102004",
2006
+ "810102002",
2007
+ "810102003",
2008
+ "810101002",
2009
+ "810101001",
2010
+ "810101003",
2011
+ "220101003",
2012
+ "220101004",
2013
+ "220101002",
2014
+ "220101001",
2015
+ "220101005",
2016
+ "220101006",
2017
+ "560101001"
2018
+ ]);
2019
+ var CFOP_CST51 = new Set(["5123", "5922", "6123", "6922"]);
2020
+ function cstComNaoContribuinte(input, contexto, issues) {
2021
+ if (input.destinatario?.indIEDest !== "9" || input.tpNF === "0")
2022
+ return;
2023
+ if (input.itens.some((it) => it.produto.especifico !== undefined && ("veicProd" in it.produto.especifico)))
2024
+ return;
2025
+ const fin = input.finNFe ?? "1";
2026
+ const interna = contexto.idDest === "1";
2027
+ const interestadual = contexto.idDest === "2";
2028
+ input.itens.forEach((it, n) => {
2029
+ const icms = it.impostos.icms;
2030
+ if (icms === undefined || !("CST" in icms))
2031
+ return;
2032
+ const cst = icms.CST;
2033
+ if (CST_NAO_CONTRIBUINTE.has(cst))
2034
+ return;
2035
+ const cfop = it.produto.CFOP.replace(/\D/g, "");
2036
+ const esp = it.produto.especifico;
2037
+ if ((cst === "50" || cst === "51") && fin === "4")
2038
+ return;
2039
+ if (cst === "50") {
2040
+ const ind = indicadoresCfop(cfop);
2041
+ if (ind === undefined || ind.indRetor || ind.indRemes || cfop === "5949" || cfop === "6949")
2042
+ return;
2043
+ }
2044
+ if (cst === "51" && (CFOP_CST51.has(cfop) || interna))
2045
+ return;
2046
+ if ((cst === "10" || cst === "02") && interna)
2047
+ return;
2048
+ if (cst === "30" && interestadual) {
2049
+ if (esp !== undefined && "comb" in esp && !ANP_FORA_DA_EXCECAO_5.has(esp.comb.cProdANP))
2050
+ return;
2051
+ if (it.produto.NCM.replace(/\D/g, "") === "27160000")
2052
+ return;
2053
+ }
2054
+ if (cst === "90" && contexto.uf === "CE" && (cfop === "5403" || cfop === "5405"))
2055
+ return;
2056
+ 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)`);
2057
+ });
2058
+ }
1937
2059
 
1938
2060
  // 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
- }
2061
+ import { conferirTextos } from "@sinete/schemas";
2062
+ import { textoXmlValido } from "@sinete/schemas";
1949
2063
  var CAMPOS = [
1950
2064
  ["natOp", "ide.natOp"],
1951
2065
  ["emitente.xNome", "emit.xNome"],
@@ -1987,138 +2101,10 @@ var CAMPOS = [
1987
2101
  ["compra.xPed", "compra.xPed"],
1988
2102
  ["compra.xCont", "compra.xCont"]
1989
2103
  ];
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
2104
  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
- }
2105
+ const pular = new Set([...issues.list.map((i) => i.caminho), ...substituidos]);
2106
+ for (const t of conferirTextos(entrada, infNFe, CAMPOS, pular))
2107
+ issues.add(t.caminho, "campo_invalido", t.mensagem);
2122
2108
  }
2123
2109
 
2124
2110
  // packages/nfe/src/build/tributos.ts
@@ -2425,19 +2411,19 @@ function referencia(ref, path, issues) {
2425
2411
  }
2426
2412
  };
2427
2413
  }
2428
- function textosForaDoXml2(value, path, issues) {
2414
+ function textosForaDoXml(value, path, issues) {
2429
2415
  if (typeof value === "string") {
2430
2416
  if (!textoXmlValido(value))
2431
2417
  issues.montagem(path, "campo_invalido", "texto com caractere não permitido em XML");
2432
2418
  } else if (Array.isArray(value)) {
2433
2419
  for (const [n, v] of value.entries())
2434
- textosForaDoXml2(v, `${path}[${n}]`, issues);
2420
+ textosForaDoXml(v, `${path}[${n}]`, issues);
2435
2421
  } else if (typeof value === "object" && value !== null) {
2436
2422
  for (const [k, v] of Object.entries(value))
2437
- textosForaDoXml2(v, `${path}.${k}`, issues);
2423
+ textosForaDoXml(v, `${path}.${k}`, issues);
2438
2424
  }
2439
2425
  }
2440
- function montarItem(ctx, item, n, normal) {
2426
+ function montarItem(ctx, item, n, normal, semIe) {
2441
2427
  const path = `itens[${n}]`;
2442
2428
  const p = item.produto;
2443
2429
  const pp = `${path}.produto`;
@@ -2552,7 +2538,7 @@ function montarItem(ctx, item, n, normal) {
2552
2538
  const r = buildIcms(ctx, imp.icms, { vOp, vIPI: v.vIPI }, `${ip}.icms`);
2553
2539
  imposto.ICMS = r.grupo;
2554
2540
  icms = r.totais;
2555
- } else if (imp.issqn === undefined && imp.ibsCbs === undefined) {
2541
+ } else if (imp.issqn === undefined && imp.ibsCbs === undefined && !semIe) {
2556
2542
  ctx.issues.add(`${ip}.icms`, "campo_obrigatorio", "o item precisa de ICMS (ou ISSQN, na NF-e conjugada)");
2557
2543
  }
2558
2544
  if (imp.ii !== undefined) {
@@ -2653,7 +2639,8 @@ async function montarNfe(entrada, opcoes) {
2653
2639
  return { ok: false, ocorrencias: issues.classificadas };
2654
2640
  }
2655
2641
  const nfce = mod === "65";
2656
- const indPres = entrada.indPres ?? (nfce ? "1" : finNFeIn === "2" || finNFeIn === "3" ? "0" : "9");
2642
+ const tipo2 = !nfce && entrada.tpImp === "6";
2643
+ const indPres = entrada.indPres ?? (nfce || tipo2 ? "1" : finNFeIn === "2" || finNFeIn === "3" ? "0" : "9");
2657
2644
  const indFinal = entrada.indFinal ?? (nfce || entrada.destinatario?.indIEDest === "9" ? "1" : "0");
2658
2645
  const ctx = new Ctx(issues, { ...MODES, ...opcoes.arredondamento }, finNFeIn !== "2" && finNFeIn !== "3");
2659
2646
  const pRedutorGov = entrada.gCompraGov && ctx.req(entrada.gCompraGov.pRedutor, "gCompraGov.pRedutor", D0302A04);
@@ -2745,14 +2732,14 @@ async function montarNfe(entrada, opcoes) {
2745
2732
  if (cont.dhCont.getTime() > agora.getTime()) {
2746
2733
  issues.add("contingencia.dhCont", "contingencia_invalida", "entrada em contingência posterior à emissão");
2747
2734
  }
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)");
2735
+ if (!nfce && tpEmis === "9" && (entrada.tpImp ?? "1") !== "6") {
2736
+ 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
2737
  }
2751
2738
  if (nfce && (tpEmis === "6" || tpEmis === "7")) {
2752
2739
  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)");
2753
2740
  }
2754
2741
  }
2755
- const idDest = entrada.idDest ?? (nfce ? "1" : destUf === "EX" ? "3" : destUf !== undefined && destUf !== emitUf ? "2" : "1");
2742
+ const idDest = entrada.idDest ?? (nfce || tipo2 ? "1" : destUf === "EX" ? "3" : destUf !== undefined && destUf !== emitUf ? "2" : "1");
2756
2743
  const tpImp = entrada.tpImp ?? (nfce ? "4" : "1");
2757
2744
  conferirDestinatario(entrada, {
2758
2745
  mod,
@@ -2762,8 +2749,9 @@ async function montarNfe(entrada, opcoes) {
2762
2749
  indFinal,
2763
2750
  producao: opcoes.ambiente === "producao"
2764
2751
  }, issues);
2765
- if (nfce) {
2752
+ if (nfce || tipo2) {
2766
2753
  conferirNfce(entrada, {
2754
+ mod: nfce ? "65" : "55",
2767
2755
  tpNF: entrada.tpNF,
2768
2756
  idDest,
2769
2757
  tpImp,
@@ -2774,7 +2762,11 @@ async function montarNfe(entrada, opcoes) {
2774
2762
  } else if (tpImp === "4" || tpImp === "5") {
2775
2763
  issues.add("tpImp", "campo_invalido", "tpImp 4 e 5 (DANFC-e) são da NFC-e (B21-20, rejeição 710)");
2776
2764
  }
2765
+ const comQr = nfce || tpImp === "6";
2777
2766
  const qr = opcoes.qrCode ?? { versao: "3" };
2767
+ if (!nfce && comQr && qr.versao === "2") {
2768
+ 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)");
2769
+ }
2778
2770
  if (nfce && qr.versao === "2") {
2779
2771
  if (!/^\d{1,6}$/.test(qr.idCSC) || Number(qr.idCSC) === 0) {
2780
2772
  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,9 +2787,10 @@ async function montarNfe(entrada, opcoes) {
2795
2787
  if (entrada.itens.length === 0 || entrada.itens.length > 990) {
2796
2788
  issues.add("itens", "itens_limite", "a NF-e tem de 1 a 990 itens");
2797
2789
  }
2798
- const itens = entrada.itens.map((it, n) => montarItem(ctx, it, n, finNFeIn === "1"));
2790
+ const semIe = !nfce && entrada.emitente.IE === undefined;
2791
+ const itens = entrada.itens.map((it, n) => montarItem(ctx, it, n, finNFeIn === "1", semIe));
2799
2792
  const primeiro = itens[0];
2800
- if (nfce && opcoes.ambiente === "homologacao" && primeiro !== undefined) {
2793
+ if ((nfce || tipo2) && opcoes.ambiente === "homologacao" && primeiro !== undefined) {
2801
2794
  primeiro.det.prod.xProd = XPROD_HOMOLOGACAO_NFCE;
2802
2795
  }
2803
2796
  const classificados = entrada.itens.map((it, n) => ({ it, n })).filter(({ it }) => it.impostos.ibsCbs?.classificacao !== undefined);
@@ -2896,8 +2889,9 @@ async function montarNfe(entrada, opcoes) {
2896
2889
  grupoInvalido(TISCt, "IS", imp.IS, is, issues);
2897
2890
  }
2898
2891
  });
2899
- const substituidos = opcoes.ambiente === "homologacao" ? ["destinatario.xNome", ...nfce ? ["itens[0].produto.xProd"] : []] : [];
2892
+ const substituidos = opcoes.ambiente === "homologacao" ? ["destinatario.xNome", ...nfce || tipo2 ? ["itens[0].produto.xProd"] : []] : [];
2900
2893
  conferirTextosDaEntrada(entrada, pl.infNFe, issues, new Set(substituidos));
2894
+ exclusivoIbsCbs(entrada, { nfce, dhEmi, instantes: [agora, fatoGerador] }, issues);
2901
2895
  if (!issues.empty)
2902
2896
  return { ok: false, ocorrencias: issues.classificadas };
2903
2897
  const gruposIbsCbs = itens.map((m) => m.det.imposto.IBSCBS).filter((g) => g !== undefined);
@@ -3192,9 +3186,13 @@ async function montarNfe(entrada, opcoes) {
3192
3186
  agropecuario: entrada.agropecuario
3193
3187
  });
3194
3188
  cstComIsento(entrada, idDest, issues);
3189
+ if (!nfce) {
3190
+ cfopDeDevolucao(entrada, issues);
3191
+ cstComNaoContribuinte(entrada, { idDest, uf: emitUf }, issues);
3192
+ }
3195
3193
  vencimentos(entrada, { dhEmi, instante: agora }, issues);
3196
3194
  camposForaDoPl(pl.infNFe, inf, "infNFe", pl.vigencia.pl, issues);
3197
- textosForaDoXml2(inf, "infNFe", issues);
3195
+ textosForaDoXml(inf, "infNFe", issues);
3198
3196
  if (!issues.empty)
3199
3197
  return { ok: false, ocorrencias: issues.classificadas };
3200
3198
  let xml;
@@ -3223,7 +3221,7 @@ async function montarNfe(entrada, opcoes) {
3223
3221
  };
3224
3222
  }
3225
3223
  let supl;
3226
- if (nfce) {
3224
+ if (comQr) {
3227
3225
  const tabela = urlsNfce(emitUf, opcoes.ambiente, diaBrasilia(agora));
3228
3226
  const urlQr = opcoes.urlQrCode ?? tabela.qrCode;
3229
3227
  const urlChave = opcoes.urlChave ?? tabela.urlChave;
@@ -3287,7 +3285,7 @@ function comQrCode(nota, assinatura) {
3287
3285
  if (assinatura !== undefined) {
3288
3286
  const issues = conferirSupl(xml);
3289
3287
  if (issues.length > 0)
3290
- throw new ErroDeValidacao("o QR Code da NFC-e não passou no schema", issues);
3288
+ throw new ErroDeValidacao("o QR Code não passou no schema", issues);
3291
3289
  }
3292
3290
  return xml;
3293
3291
  }
@@ -3295,18 +3293,18 @@ function inserirSupl(built, assinatura) {
3295
3293
  const s = built.nfce;
3296
3294
  if (s === undefined) {
3297
3295
  if (assinatura !== undefined)
3298
- throw new ErroDeConfiguracao2("a NF-e (modelo 55) não tem QR Code");
3296
+ throw new ErroDeConfiguracao2("esta NF-e não tem QR Code: só a NF-e com DANFE Simplificado Tipo 2 (tpImp 6) leva");
3299
3297
  return built.xml;
3300
3298
  }
3301
3299
  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)");
3300
+ throw new ErroDeConfiguracao2("contingência off-line com QR Code versão 3 precisa da assinatura (ZX02-334, rejeição 474)");
3303
3301
  }
3304
3302
  if (!s.assinar && assinatura !== undefined) {
3305
3303
  throw new ErroDeConfiguracao2("este QR Code não leva assinatura (ZX02-330, rejeição 445)");
3306
3304
  }
3307
3305
  const fim = "</NFe>";
3308
3306
  if (!built.xml.endsWith(fim))
3309
- throw new ErroDeConfiguracao2("NFC-e montada fora da forma esperada");
3307
+ throw new ErroDeConfiguracao2("nota montada fora da forma esperada");
3310
3308
  const qrCode = `${s.base}${s.parametros}${assinatura === undefined ? "" : `|${assinatura}`}`;
3311
3309
  const supl = `<infNFeSupl><qrCode>${escapeXml(qrCode)}</qrCode><urlChave>${escapeXml(s.urlChave)}</urlChave></infNFeSupl>`;
3312
3310
  return built.xml.slice(0, -fim.length) + supl + fim;
@@ -3528,7 +3526,7 @@ import { completarRecusado } from "@sinete/rejeicoes";
3528
3526
  // packages/nfe/src/data/cstat.json
3529
3527
  var cstat_default = {
3530
3528
  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)",
3529
+ 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
3530
  atualizadoEm: "2026-09-26",
3533
3531
  autorizada: ["100", "150"],
3534
3532
  denegada: ["110", "301", "302", "303"],
@@ -3539,6 +3537,7 @@ var cstat_default = {
3539
3537
  loteNaoLocalizado: ["106"],
3540
3538
  servicoEmOperacao: ["107"],
3541
3539
  inutilizacaoHomologada: ["102"],
3540
+ inutilizacaoJaHomologada: ["563"],
3542
3541
  eventoRegistrado: ["135", "136", "155"],
3543
3542
  loteEventoProcessado: ["128"],
3544
3543
  cadastroEncontrado: ["111", "112"],
@@ -3887,6 +3886,11 @@ function autorDoEmitente(a, c) {
3887
3886
  return autor;
3888
3887
  }
3889
3888
  var SVC_DO_TPEMIS = { "6": "SVC-AN", "7": "SVC-RS" };
3889
+ function emitenteSemIe(a) {
3890
+ const inf = primeiroFilho5(a.documento.raiz, "infNFe", NFE_NS4);
3891
+ const emit = inf === undefined ? undefined : primeiroFilho5(inf, "emit", NFE_NS4);
3892
+ return emit !== undefined && primeiroFilho5(emit, "IE", NFE_NS4) === undefined;
3893
+ }
3890
3894
  function chaveDoDocumento(a) {
3891
3895
  const r = lerChaveAcesso2(a.id.slice(3), { caminho: "infNFe.Id", conferirEmitente: false });
3892
3896
  if (!r.ok)
@@ -3988,9 +3992,12 @@ function criarClienteNfe(opcoesDoCliente) {
3988
3992
  ...opcoesDoCliente.contingencia === undefined ? {} : { contingencia: opcoesDoCliente.contingencia }
3989
3993
  });
3990
3994
  };
3991
- const endpointDaChave = (servico, c, naUf = false) => {
3995
+ const endpointDaChave = (servico, c, naUf = false, semIe = opcoesDoCliente.contribuinteExclusivoIbsCbs === true) => {
3992
3996
  if (c.mod === "65")
3993
3997
  return endpointNfce(servico, c.uf);
3998
+ const serie = Number(c.serie);
3999
+ if (semIe && !(servico === "RecepcaoEvento" && serie >= 890 && serie <= 919))
4000
+ return nfeEndpoint({ ambiente: opcoesDoCliente.ambiente, servico, autorizador: "SVRS" });
3994
4001
  const svc = naUf || c.tpEmis === undefined ? undefined : SVC_DO_TPEMIS[c.tpEmis];
3995
4002
  return nfeEndpoint({
3996
4003
  ambiente: opcoesDoCliente.ambiente,
@@ -3998,6 +4005,7 @@ function criarClienteNfe(opcoesDoCliente) {
3998
4005
  ...svc === undefined ? { uf: c.uf } : { autorizador: svc }
3999
4006
  });
4000
4007
  };
4008
+ const semIeOuOpcao = (a) => a === undefined ? opcoesDoCliente.contribuinteExclusivoIbsCbs === true : emitenteSemIe(a);
4001
4009
  const call = (ep, servico, mensagem, retorno, signal) => chamar({
4002
4010
  transport: opcoesDoCliente.transporte,
4003
4011
  endpoint: ep,
@@ -4023,7 +4031,7 @@ function criarClienteNfe(opcoesDoCliente) {
4023
4031
  throw new ErroDeConfiguracao4(`mod ${opcoes.mod} não é o da NF-e assinada (${c.mod})`);
4024
4032
  }
4025
4033
  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);
4034
+ 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
4035
  const r = await call(ep, "NFeRetAutorizacao", msg, "retConsReciNFe", opcoes.signal);
4028
4036
  const v = decodificar(TRetConsReciNFe, r.ret, r.doc.texto).valor;
4029
4037
  if (v.nRec !== undefined && v.nRec !== nRec) {
@@ -4047,7 +4055,7 @@ function criarClienteNfe(opcoesDoCliente) {
4047
4055
  if (a && a.id !== `NFe${c.chave}`)
4048
4056
  throw new ErroDeConfiguracao4("a NF-e assinada não é a da chave consultada");
4049
4057
  const msg = serializarRaiz(consSitNFeElement, { versao: "4.00", tpAmb, xServ: "CONSULTAR", chNFe: c.chave });
4050
- const ep = endpointDaChave("NfeConsultaProtocolo", c);
4058
+ const ep = endpointDaChave("NfeConsultaProtocolo", c, false, semIeOuOpcao(a));
4051
4059
  const r = await call(ep, "NfeConsultaProtocolo", msg, "retConsSitNFe", opcoes?.signal);
4052
4060
  const v = decodificar(TRetConsSitNFe, r.ret, r.doc.texto).valor;
4053
4061
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
@@ -4165,7 +4173,7 @@ function criarClienteNfe(opcoesDoCliente) {
4165
4173
  `<idLote>${idLote()}</idLote><indSinc>${sincrono ? "1" : "0"}</indSinc>`,
4166
4174
  a.xml
4167
4175
  ]);
4168
- const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a));
4176
+ const ep = endpointDaChave("NFeAutorizacao", chaveDoDocumento(a), false, semIeOuOpcao(a));
4169
4177
  const r = await call(ep, "NFeAutorizacao", msg, "retEnviNFe", opcoes.signal);
4170
4178
  const v = decodificar(TRetEnviNFe, r.ret, r.doc.texto).valor;
4171
4179
  const status = { cStat: v.cStat, xMotivo: v.xMotivo };
@@ -4363,7 +4371,9 @@ function criarClienteNfe(opcoesDoCliente) {
4363
4371
  const v = decodificar(TRetInutNFe, r.ret, r.doc.texto).valor;
4364
4372
  const status = { cStat: v.infInut.cStat, xMotivo: v.infInut.xMotivo };
4365
4373
  logger.info("nfe.inutilizacao", { id, cStat: status.cStat });
4366
- if (!cstatEm(status.cStat, "inutilizacaoHomologada"))
4374
+ const homologada = cstatEm(status.cStat, "inutilizacaoHomologada");
4375
+ const anterior = cstatEm(status.cStat, "inutilizacaoJaHomologada") ? v.infInut.nProt || undefined : undefined;
4376
+ if (!homologada && anterior === undefined)
4367
4377
  return rejeitado(status);
4368
4378
  const r0 = v.infInut;
4369
4379
  const n = (x) => x === undefined ? undefined : String(Number(x));
@@ -4381,6 +4391,9 @@ function criarClienteNfe(opcoesDoCliente) {
4381
4391
  detalhes: Object.fromEntries(fora.map(([k, v]) => [k, v]))
4382
4392
  });
4383
4393
  }
4394
+ if (anterior !== undefined) {
4395
+ return { ...rejeitado(status), anterior: { nProt: anterior, retInutNFe: avulso(r.doc, r.ret) } };
4396
+ }
4384
4397
  return criarAutorizado(status, {
4385
4398
  dhRecbto: v.infInut.dhRecbto,
4386
4399
  retInutNFe: avulso(r.doc, r.ret),
@@ -4595,5 +4608,5 @@ export {
4595
4608
  urlsNfce
4596
4609
  };
4597
4610
 
4598
- //# debugId=74A78D3EACEECD4D64756E2164756E21
4611
+ //# debugId=870986C8C708F67A64756E2164756E21
4599
4612
  //# sourceMappingURL=index.js.map