diff --git a/DFe.Testes/DFe.Testes.csproj b/DFe.Testes/DFe.Testes.csproj
index e1974af04..225cd4bb7 100644
--- a/DFe.Testes/DFe.Testes.csproj
+++ b/DFe.Testes/DFe.Testes.csproj
@@ -17,8 +17,10 @@
+
+
diff --git a/DFe.Testes/Gerais/ChaveFiscalTestes.cs b/DFe.Testes/Gerais/ChaveFiscalTestes.cs
new file mode 100644
index 000000000..4d761043b
--- /dev/null
+++ b/DFe.Testes/Gerais/ChaveFiscalTestes.cs
@@ -0,0 +1,261 @@
+using System;
+using DFe.Classes.Entidades;
+using DFe.Classes.Flags;
+using DFe.Utils;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace DFe.Testes.Gerais
+{
+ ///
+ /// Testes da chave de acesso do DF-e cobrindo o fluxo antigo (CNPJ 100% numérico)
+ /// e o novo fluxo com CNPJ alfanumérico da NT Conjunta 2025.001
+ ///
+ [TestClass]
+ public class ChaveFiscalTestes
+ {
+ //Chave real de NFC-e homologação (CNPJ numérico) usada como âncora de regressão do fluxo antigo
+ private const string ChaveNumericaReal = "23190811820016000167650010000000221100000227";
+
+ //Vetor ouro da NT: NFe de GO, emitida em 07/2025 pelo CNPJ alfanumérico de teste da Receita PC3D315K000193
+ private const string ChaveAlfanumericaOuro = "522507PC3D315K000193550010000000011000000018";
+
+ #region Fluxo novo - CNPJ alfanumérico
+
+ [TestMethod]
+ public void ObterChave_ComCnpjAlfanumerico_GeraAChaveDoVetorOuro()
+ {
+ // Arrange
+ var dataEmissao = new DateTimeOffset(2025, 7, 15, 10, 0, 0, TimeSpan.FromHours(-3));
+
+ // Act
+ var dados = ChaveFiscal.ObterChave(Estado.GO, dataEmissao, "PC3D315K000193", ModeloDocumento.NFe, 1, 1, 1, 1);
+
+ // Assert
+ Assert.AreEqual(ChaveAlfanumericaOuro, dados.Chave);
+ Assert.AreEqual((byte)8, dados.DigitoVerificador);
+ }
+
+ [TestMethod]
+ public void ObterChave_ComCnpjAlfanumerico_ChaveTemLayoutCorreto()
+ {
+ var dados = ChaveFiscal.ObterChave(Estado.GO, new DateTime(2025, 7, 15), "PC3D315K000193", ModeloDocumento.NFe, 1, 1, 1, 1);
+
+ Assert.AreEqual(44, dados.Chave.Length);
+ Assert.AreEqual("52", dados.Chave.Substring(0, 2), "cUF");
+ Assert.AreEqual("2507", dados.Chave.Substring(2, 4), "AAMM");
+ Assert.AreEqual("PC3D315K000193", dados.Chave.Substring(6, 14), "CNPJ");
+ Assert.AreEqual("55", dados.Chave.Substring(20, 2), "modelo");
+ }
+
+ [TestMethod]
+ public void ChaveValida_ComChaveAlfanumericaDoVetorOuro_RetornaVerdadeiro()
+ {
+ Assert.IsTrue(ChaveFiscal.ChaveValida(ChaveAlfanumericaOuro));
+ }
+
+ [TestMethod]
+ [DataRow("0")]
+ [DataRow("1")]
+ [DataRow("5")]
+ [DataRow("9")]
+ public void ChaveValida_ComChaveAlfanumericaComDvErrado_RetornaFalso(string dvErrado)
+ {
+ var chaveComDvErrado = ChaveAlfanumericaOuro.Substring(0, 43) + dvErrado;
+
+ Assert.IsFalse(ChaveFiscal.ChaveValida(chaveComDvErrado));
+ }
+
+ [TestMethod]
+ public void ObterChave_ComVariosCnpjsAlfanumericos_DvIgualAoDaImplementacaoDeReferenciaDaNT()
+ {
+ // Arrange - bases alfanuméricas com DVs calculados pela regra oficial de CNPJ
+ var basesCnpj = new[] { "12ABC34501DE", "PC3D315K0001", "A1B2C3D4E5F6", "ZZZZZZZZZZZZ", "0000000000AB", "H9J8K7L6M5N4" };
+ var ufs = new[] { Estado.GO, Estado.SP, Estado.CE, Estado.RS, Estado.AM, Estado.DF };
+ var modelos = new[] { ModeloDocumento.NFe, ModeloDocumento.NFCe };
+
+ for (var i = 0; i < basesCnpj.Length; i++)
+ {
+ var cnpj = basesCnpj[i] + CnpjFiscal.ObterDigitosVerificadores(basesCnpj[i]);
+
+ foreach (var modelo in modelos)
+ {
+ // Act
+ var dados = ChaveFiscal.ObterChave(ufs[i], new DateTime(2026, 7, 1), cnpj, modelo, i + 1, 1000 + i, 1, 77000 + i);
+
+ // Assert
+ var dvReferencia = CalcularDvReferenciaNt(dados.Chave.Substring(0, 43));
+ Assert.AreEqual(dvReferencia, (int)dados.DigitoVerificador, "CNPJ {0}, modelo {1}", cnpj, modelo);
+ Assert.IsTrue(ChaveFiscal.ChaveValida(dados.Chave), "ChaveValida deveria aceitar {0}", dados.Chave);
+ }
+ }
+ }
+
+ [TestMethod]
+ public void ObterChave_ComCnpjAlfanumericoMinusculo_LancaArgumentException()
+ {
+ Assert.ThrowsException(() =>
+ ChaveFiscal.ObterChave(Estado.GO, new DateTime(2025, 7, 15), "pc3d315k000193", ModeloDocumento.NFe, 1, 1, 1, 1));
+ }
+
+ [TestMethod]
+ [DataRow(':')]
+ [DataRow(';')]
+ [DataRow('<')]
+ [DataRow('=')]
+ [DataRow('>')]
+ [DataRow('?')]
+ [DataRow('@')]
+ public void ObterChave_ComCaractereEntreDigitosELetras_LancaArgumentException(char caractereInvalido)
+ {
+ //os caracteres ASCII 58 a 64 ficam entre '9' e 'A' e produziriam DV errado sem erro se aceitos
+ var cnpjInvalido = "PC3D315K0001" + caractereInvalido + "3";
+
+ Assert.ThrowsException(() =>
+ ChaveFiscal.ObterChave(Estado.GO, new DateTime(2025, 7, 15), cnpjInvalido, ModeloDocumento.NFe, 1, 1, 1, 1));
+ }
+
+ [TestMethod]
+ public void ChaveValida_ComLetraMinusculaNaChave_LancaArgumentException()
+ {
+ var chaveComMinuscula = "522507pC3D315K000193550010000000011000000018";
+
+ Assert.ThrowsException(() => ChaveFiscal.ChaveValida(chaveComMinuscula));
+ }
+
+ #endregion
+
+ #region Fluxo antigo - CNPJ numérico (regressão)
+
+ [TestMethod]
+ public void ObterChave_ComCnpjNumerico_GeraChaveRealConhecida()
+ {
+ // Arrange - componentes da chave real de homologação (NFC-e do CE, 08/2019)
+ var dataEmissao = new DateTimeOffset(2019, 8, 10, 12, 0, 0, TimeSpan.FromHours(-3));
+
+ // Act
+ var dados = ChaveFiscal.ObterChave(Estado.CE, dataEmissao, "11820016000167", ModeloDocumento.NFCe, 1, 22, 1, 10000022);
+
+ // Assert
+ Assert.AreEqual(ChaveNumericaReal, dados.Chave);
+ Assert.AreEqual((byte)7, dados.DigitoVerificador);
+ }
+
+ [TestMethod]
+ public void ChaveValida_ComChaveNumericaRealConhecida_RetornaVerdadeiro()
+ {
+ Assert.IsTrue(ChaveFiscal.ChaveValida(ChaveNumericaReal));
+ }
+
+ [TestMethod]
+ public void ChaveValida_ComChaveNumericaComDvErrado_RetornaFalso()
+ {
+ var chaveComDvErrado = ChaveNumericaReal.Substring(0, 43) + "9";
+
+ Assert.IsFalse(ChaveFiscal.ChaveValida(chaveComDvErrado));
+ }
+
+ [TestMethod]
+ public void ObterChave_ComVariosCnpjsNumericos_DvIdenticoAoAlgoritmoLegado()
+ {
+ // Arrange - regressão: para chave 100% numérica o DV novo deve ser idêntico ao da implementação antiga
+ var cnpjs = new[] { "11222333000181", "00000000000191", "11444777000161", "99999999999999", "00000000000000", "12345678000195" };
+ var ufs = new[] { Estado.SP, Estado.GO, Estado.CE, Estado.RS, Estado.MG, Estado.BA };
+
+ for (var i = 0; i < cnpjs.Length; i++)
+ {
+ foreach (var modelo in new[] { ModeloDocumento.NFe, ModeloDocumento.NFCe })
+ {
+ // Act
+ var dados = ChaveFiscal.ObterChave(ufs[i], new DateTime(2024, 12, 31), cnpjs[i], modelo, 883 + i, 999999990 + i, 2, 10000000 - i);
+
+ // Assert
+ var dvLegado = CalcularDvAlgoritmoLegado(dados.Chave.Substring(0, 43));
+ Assert.AreEqual(dvLegado, dados.DigitoVerificador.ToString(), "CNPJ {0}, modelo {1}", cnpjs[i], modelo);
+ Assert.IsTrue(ChaveFiscal.ChaveValida(dados.Chave));
+ }
+ }
+ }
+
+ [TestMethod]
+ public void ObterChave_ComCpfDe11Posicoes_PreencheComZerosAEsquerda()
+ {
+ // Act
+ var dados = ChaveFiscal.ObterChave(Estado.SP, new DateTime(2026, 7, 1), "12345678901", ModeloDocumento.NFe, 1, 123, 1, 55555);
+
+ // Assert
+ Assert.AreEqual(44, dados.Chave.Length);
+ Assert.AreEqual("00012345678901", dados.Chave.Substring(6, 14));
+ Assert.IsTrue(ChaveFiscal.ChaveValida(dados.Chave));
+ }
+
+ #endregion
+
+ #region Validação do documento do emitente
+
+ [TestMethod]
+ [DataRow("PC3D315K0001", DisplayName = "12 posições - base de CNPJ truncada")]
+ [DataRow("1122233300018", DisplayName = "13 posições")]
+ [DataRow("112223330001811", DisplayName = "15 posições")]
+ [DataRow("1234567890", DisplayName = "10 posições")]
+ public void ObterChave_ComDocumentoDeComprimentoInvalido_LancaArgumentException(string documento)
+ {
+ //um CNPJ truncado não pode virar silenciosamente uma chave bem-formada porém errada
+ Assert.ThrowsException(() =>
+ ChaveFiscal.ObterChave(Estado.GO, new DateTime(2026, 7, 1), documento, ModeloDocumento.NFe, 1, 1, 1, 1));
+ }
+
+ [TestMethod]
+ public void ObterChave_ComDocumentoVazio_LancaArgumentException()
+ {
+ Assert.ThrowsException(() =>
+ ChaveFiscal.ObterChave(Estado.GO, new DateTime(2026, 7, 1), "", ModeloDocumento.NFe, 1, 1, 1, 1));
+ }
+
+ [TestMethod]
+ public void ObterChave_ComDocumentoNulo_LancaArgumentException()
+ {
+ Assert.ThrowsException(() =>
+ ChaveFiscal.ObterChave(Estado.GO, new DateTime(2026, 7, 1), null, ModeloDocumento.NFe, 1, 1, 1, 1));
+ }
+
+ #endregion
+
+ ///
+ /// Implementação de referência do Anexo II da NT Conjunta 2025.001, portada para C#
+ ///
+ private static int CalcularDvReferenciaNt(string chave43)
+ {
+ var soma = 0;
+ var peso = 2;
+ for (var i = chave43.Length - 1; i >= 0; i--)
+ {
+ soma += (chave43[i] - '0') * peso;
+ peso = peso == 9 ? 2 : peso + 1;
+ }
+ var dv = 11 - soma % 11;
+ return dv >= 10 ? 0 : dv;
+ }
+
+ ///
+ /// Algoritmo do DV como era antes da correção (só funciona com dígitos),
+ /// usado para garantir que chaves numéricas não sofreram regressão
+ ///
+ private static string CalcularDvAlgoritmoLegado(string chave43)
+ {
+ var soma = 0;
+ var peso = 2;
+ for (var i = chave43.Length - 1; i != -1; i--)
+ {
+ var ch = Convert.ToInt32(chave43[i].ToString());
+ soma += ch * peso;
+ if (peso < 9)
+ peso += 1;
+ else
+ peso = 2;
+ }
+ var mod = soma % 11;
+ var dv = mod == 0 || mod == 1 ? 0 : 11 - mod;
+ return dv.ToString();
+ }
+ }
+}
diff --git a/DFe.Testes/Gerais/CnpjFiscalTestes.cs b/DFe.Testes/Gerais/CnpjFiscalTestes.cs
new file mode 100644
index 000000000..a91b7240c
--- /dev/null
+++ b/DFe.Testes/Gerais/CnpjFiscalTestes.cs
@@ -0,0 +1,128 @@
+using System;
+using DFe.Utils;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace DFe.Testes.Gerais
+{
+ ///
+ /// Testes do cálculo de dígitos verificadores e validação de CNPJ,
+ /// cobrindo CNPJs numéricos (fluxo antigo) e alfanuméricos (NT Conjunta 2025.001)
+ ///
+ [TestClass]
+ public class CnpjFiscalTestes
+ {
+ #region ObterDigitosVerificadores - vetores ouro
+
+ [TestMethod]
+ [DataRow("112223330001", "81", DisplayName = "Base numérica")]
+ [DataRow("12ABC34501DE", "35", DisplayName = "Exemplo da NT Conjunta 2025.001")]
+ [DataRow("PC3D315K0001", "93", DisplayName = "CNPJ de teste da Receita Federal")]
+ [DataRow("000000000000", "00", DisplayName = "Base zerada - o DV confere, o bloqueio é do Valido")]
+ public void ObterDigitosVerificadores_ComBaseDe12Posicoes_RetornaDvsEsperados(string baseCnpj, string dvsEsperados)
+ {
+ Assert.AreEqual(dvsEsperados, CnpjFiscal.ObterDigitosVerificadores(baseCnpj));
+ }
+
+ [TestMethod]
+ [DataRow("000000000001", "91", DisplayName = "Banco do Brasil")]
+ [DataRow("114447770001", "61", DisplayName = "CNPJ numérico clássico de testes")]
+ [DataRow("123456780001", "95", DisplayName = "CNPJ numérico sequencial")]
+ public void ObterDigitosVerificadores_ComBasesNumericasHistoricas_MantemComportamentoAntigo(string baseCnpj, string dvsEsperados)
+ {
+ Assert.AreEqual(dvsEsperados, CnpjFiscal.ObterDigitosVerificadores(baseCnpj));
+ }
+
+ #endregion
+
+ #region ObterDigitosVerificadores - entradas inválidas
+
+ [TestMethod]
+ [DataRow("pc3d315k0001", DisplayName = "Minúsculas")]
+ [DataRow("12ABC34501D", DisplayName = "11 posições")]
+ [DataRow("12ABC34501DEF", DisplayName = "13 posições")]
+ [DataRow("12ABC34501D@", DisplayName = "Caractere @ (ASCII 64)")]
+ [DataRow("12ABC34501D:", DisplayName = "Caractere : (ASCII 58)")]
+ [DataRow("12.ABC.345/01", DisplayName = "Com máscara")]
+ [DataRow("", DisplayName = "Vazia")]
+ public void ObterDigitosVerificadores_ComBaseInvalida_LancaArgumentException(string baseCnpj)
+ {
+ Assert.ThrowsException(() => CnpjFiscal.ObterDigitosVerificadores(baseCnpj));
+ }
+
+ [TestMethod]
+ public void ObterDigitosVerificadores_ComBaseNula_LancaArgumentNullException()
+ {
+ Assert.ThrowsException(() => CnpjFiscal.ObterDigitosVerificadores(null));
+ }
+
+ #endregion
+
+ #region Valido - CNPJs aceitos
+
+ [TestMethod]
+ [DataRow("11222333000181", DisplayName = "Numérico do vetor ouro")]
+ [DataRow("12ABC34501DE35", DisplayName = "Alfanumérico do exemplo da NT")]
+ [DataRow("PC3D315K000193", DisplayName = "Alfanumérico de teste da Receita")]
+ [DataRow("00000000000191", DisplayName = "Numérico clássico - Banco do Brasil")]
+ [DataRow("11444777000161", DisplayName = "Numérico clássico de testes")]
+ public void Valido_ComCnpjCorreto_RetornaVerdadeiro(string cnpj)
+ {
+ Assert.IsTrue(CnpjFiscal.Valido(cnpj));
+ }
+
+ #endregion
+
+ #region Valido - CNPJs rejeitados
+
+ [TestMethod]
+ public void Valido_ComCnpjZerado_RetornaFalso()
+ {
+ //o DV do CNPJ zerado confere, mas a NT veda o seu uso
+ Assert.IsFalse(CnpjFiscal.Valido("00000000000000"));
+ }
+
+ [TestMethod]
+ [DataRow("11222333000182", DisplayName = "Numérico com DV errado")]
+ [DataRow("12ABC34501DE36", DisplayName = "Alfanumérico com segundo DV errado")]
+ [DataRow("12ABC34501DE45", DisplayName = "Alfanumérico com primeiro DV errado")]
+ [DataRow("PC3D315K000139", DisplayName = "Alfanumérico com DVs trocados")]
+ public void Valido_ComDvIncorreto_RetornaFalso(string cnpj)
+ {
+ Assert.IsFalse(CnpjFiscal.Valido(cnpj));
+ }
+
+ [TestMethod]
+ [DataRow("pc3d315k000193", DisplayName = "Minúsculas")]
+ [DataRow("PC3D315K00019", DisplayName = "13 posições")]
+ [DataRow("PC3D315K0001935", DisplayName = "15 posições")]
+ [DataRow("12ABC34501DEA5", DisplayName = "Letra na posição dos DVs")]
+ [DataRow("12ABC34501D:93", DisplayName = "Caractere : (ASCII 58)")]
+ [DataRow("12ABC34501D@93", DisplayName = "Caractere @ (ASCII 64)")]
+ [DataRow("11.222.333/0001-81", DisplayName = "Com máscara")]
+ [DataRow("", DisplayName = "Vazio")]
+ [DataRow(null, DisplayName = "Nulo")]
+ public void Valido_ComFormatoInvalido_RetornaFalso(string cnpj)
+ {
+ Assert.IsFalse(CnpjFiscal.Valido(cnpj));
+ }
+
+ #endregion
+
+ #region Coerência entre ObterDigitosVerificadores e Valido
+
+ [TestMethod]
+ public void Valido_ComDvsCalculadosPelaPropriaClasse_RetornaVerdadeiro()
+ {
+ var bases = new[] { "112223330001", "12ABC34501DE", "PC3D315K0001", "A1B2C3D4E5F6", "ZZZZZZZZZZZZ", "0000000000AB", "999999999999" };
+
+ foreach (var baseCnpj in bases)
+ {
+ var cnpj = baseCnpj + CnpjFiscal.ObterDigitosVerificadores(baseCnpj);
+
+ Assert.IsTrue(CnpjFiscal.Valido(cnpj), "O CNPJ {0} deveria ser válido", cnpj);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/DFe.Testes/Gerais/Code128HibridoTestes.cs b/DFe.Testes/Gerais/Code128HibridoTestes.cs
new file mode 100644
index 000000000..9696207ba
--- /dev/null
+++ b/DFe.Testes/Gerais/Code128HibridoTestes.cs
@@ -0,0 +1,252 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NFe.Danfe.PdfClown.Tools;
+
+namespace DFe.Testes.Gerais
+{
+ ///
+ /// Testes do codificador CODE-128 híbrido (subconjuntos C e A) da seção 6 da NT Conjunta 2025.001,
+ /// usado no código de barras da chave de acesso do DANFE
+ ///
+ [TestClass]
+ public class Code128HibridoTestes
+ {
+ private const byte StartC = 105;
+ private const byte TrocaParaCodeA = 101;
+ private const byte TrocaParaCodeC = 99;
+ private const byte Stop = 106;
+
+ #region Exemplos literais da NT Conjunta 2025.001 - seção 6
+
+ [TestMethod]
+ public void ObterSimbolos_ExemploLiteralDaNT_5225AB83()
+ {
+ // Arrange - sequência completa dada pela NT: start, dados, DV 30 e stop
+ var esperado = new byte[] { 105, 52, 25, 101, 33, 34, 99, 83, 30, 106 };
+
+ // Act
+ var simbolos = Code128Hibrido.ObterSimbolos("5225AB83");
+
+ // Assert
+ CollectionAssert.AreEqual(esperado, simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_ExemploLiteralDaNT_123A()
+ {
+ // Arrange - "12" em Code C, troca para o Code A (101), '3' (19) e 'A' (33) no Code A
+ var dadosEsperados = new byte[] { 105, 12, 101, 19, 33 };
+
+ // Act
+ var simbolos = Code128Hibrido.ObterSimbolos("123A");
+
+ // Assert
+ CollectionAssert.AreEqual(dadosEsperados, simbolos.Take(5).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ #endregion
+
+ #region Chave de acesso com CNPJ alfanumérico
+
+ [TestMethod]
+ public void ObterSimbolos_ChaveDeAcessoAlfanumericaDoVetorOuro_CodificaConformeAsRegrasDaNT()
+ {
+ // Arrange
+ //6 dígitos iniciais em Code C (3 pares); letras e corridas curtas do CNPJ no Code A;
+ //corrida final de 30 dígitos de volta ao Code C (15 pares)
+ var dadosEsperados = new byte[]
+ {
+ 105, //Start C
+ 52, 25, 7, //"522507"
+ 101, //troca para Code A
+ 48, 35, //'P' 'C'
+ 19, //'3' (corrida de 1 dígito fica no Code A)
+ 36, //'D'
+ 19, 17, 21, //'3' '1' '5' (corrida de 3 dígitos fica no Code A)
+ 43, //'K'
+ 99, //volta ao Code C (corrida final par)
+ 0, 1, 93, 55, 0, 10, 0, 0, 0, 1, 10, 0, 0, 0, 18
+ };
+
+ // Act
+ var simbolos = Code128Hibrido.ObterSimbolos("522507PC3D315K000193550010000000011000000018");
+
+ // Assert
+ CollectionAssert.AreEqual(dadosEsperados, simbolos.Take(dadosEsperados.Length).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ #endregion
+
+ #region Regressão - conteúdo 100% numérico deve gerar exatamente o CODE-128 C puro
+
+ [TestMethod]
+ public void ObterSimbolos_ComChavesNumericas_IdenticoAoCode128CPuroDaImplementacaoAntiga()
+ {
+ var chavesNumericas = new[]
+ {
+ "23190811820016000167650010000000221100000227",
+ "11222333000181112223330001811122233300018111",
+ "00000000000000000000000000000000000000000000",
+ "99999999999999999999999999999999999999999999",
+ "35150300822602000124550010009923461099234656"
+ };
+
+ foreach (var chave in chavesNumericas)
+ {
+ // Act
+ var simbolos = Code128Hibrido.ObterSimbolos(chave);
+
+ // Assert
+ CollectionAssert.AreEqual(CodificarCode128CPuroLegado(chave), simbolos, "Divergência na chave {0}", chave);
+ }
+ }
+
+ #endregion
+
+ #region Regras de troca de subconjunto
+
+ [TestMethod]
+ public void ObterSimbolos_ComLetraInicial_TrocaParaCodeAAposOStartC()
+ {
+ var simbolos = Code128Hibrido.ObterSimbolos("A");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33 }, simbolos.Take(3).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_CorridaDe4DigitosEntreLetras_VoltaAoCodeC()
+ {
+ //"AB" no Code A, "1234" volta ao Code C (2 pares), "CD" troca novamente para o Code A
+ var simbolos = Code128Hibrido.ObterSimbolos("AB1234CD");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, TrocaParaCodeC, 12, 34, TrocaParaCodeA, 35, 36 }, simbolos.Take(10).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_CorridaDe3DigitosEntreLetras_PermaneceNoCodeA()
+ {
+ //corrida curta (menos de 4 dígitos) não justifica a troca
+ var simbolos = Code128Hibrido.ObterSimbolos("AB123C");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, 17, 18, 19, 35 }, simbolos.Take(8).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_CorridaImparDe5DigitosAntesDeLetra_UltimoDigitoFicaNoCodeA()
+ {
+ //"12345" antes de letra: pares "12" "34" no Code C e o dígito ímpar '5' fica no Code A
+ var simbolos = Code128Hibrido.ObterSimbolos("AB12345C");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, TrocaParaCodeC, 12, 34, TrocaParaCodeA, 21, 35 }, simbolos.Take(10).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_CorridaFinalParDe2Digitos_VoltaAoCodeC()
+ {
+ //final com quantidade par de dígitos volta ao Code C, como no exemplo 5225AB83 da NT
+ var simbolos = Code128Hibrido.ObterSimbolos("AB12");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, TrocaParaCodeC, 12 }, simbolos.Take(6).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_CorridaFinalImparDe3Digitos_PermaneceNoCodeA()
+ {
+ var simbolos = Code128Hibrido.ObterSimbolos("AB123");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, 17, 18, 19 }, simbolos.Take(7).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_CorridaFinalImparDe5Digitos_PrimeiroDigitoNoCodeAEDemaisNoCodeC()
+ {
+ //corrida final ímpar de 4+ dígitos: um dígito fica no Code A para a parte restante ser par
+ var simbolos = Code128Hibrido.ObterSimbolos("AB12345");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, TrocaParaCodeA, 33, 34, 17, TrocaParaCodeC, 23, 45 }, simbolos.Take(8).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ [TestMethod]
+ public void ObterSimbolos_NumericoImpar_ParesNoCodeCEUltimoDigitoNoCodeA()
+ {
+ var simbolos = Code128Hibrido.ObterSimbolos("123");
+
+ CollectionAssert.AreEqual(new byte[] { StartC, 12, TrocaParaCodeA, 19 }, simbolos.Take(4).ToArray());
+ AssertDigitoVerificadorEStop(simbolos);
+ }
+
+ #endregion
+
+ #region Entradas inválidas
+
+ [TestMethod]
+ [DataRow("")]
+ [DataRow(null)]
+ public void ObterSimbolos_ComCodigoVazioOuNulo_LancaArgumentException(string codigo)
+ {
+ Assert.ThrowsException(() => Code128Hibrido.ObterSimbolos(codigo));
+ }
+
+ [TestMethod]
+ [DataRow("12a4", DisplayName = "Letra minúscula")]
+ [DataRow("12-4", DisplayName = "Hífen")]
+ [DataRow("12 34", DisplayName = "Espaço")]
+ [DataRow("12@34", DisplayName = "Caractere @")]
+ public void ObterSimbolos_ComCaractereForaDeDigitosELetrasMaiusculas_LancaArgumentException(string codigo)
+ {
+ Assert.ThrowsException(() => Code128Hibrido.ObterSimbolos(codigo));
+ }
+
+ #endregion
+
+ ///
+ /// Confere as duas últimas posições da sequência: o DV módulo 103
+ /// (soma ponderada com o start valendo peso 1) e o símbolo de Stop (106)
+ ///
+ private static void AssertDigitoVerificadorEStop(byte[] simbolos)
+ {
+ Assert.AreEqual(Stop, simbolos[simbolos.Length - 1], "O último símbolo deve ser o Stop (106)");
+
+ var soma = (int)simbolos[0];
+ for (var i = 1; i < simbolos.Length - 2; i++)
+ soma += i * simbolos[i];
+
+ Assert.AreEqual((byte)(soma % 103), simbolos[simbolos.Length - 2], "Dígito verificador módulo 103 incorreto");
+ }
+
+ ///
+ /// Comportamento da implementação antiga (Barcode128C do DANFE PdfClown): Start C,
+ /// dados aos pares, DV módulo 103 e Stop - referência de regressão para conteúdo numérico
+ ///
+ private static byte[] CodificarCode128CPuroLegado(string codigo)
+ {
+ var codeBytes = new List { 105 };
+
+ for (var i = 0; i < codigo.Length; i += 2)
+ codeBytes.Add(byte.Parse(codigo.Substring(i, 2)));
+
+ var cd = 105;
+ for (var i = 1; i < codeBytes.Count; i++)
+ {
+ cd += i * codeBytes[i];
+ cd %= 103;
+ }
+
+ codeBytes.Add((byte)cd);
+ codeBytes.Add(106);
+
+ return codeBytes.ToArray();
+ }
+ }
+}
diff --git a/DFe.Testes/Gerais/DanfePdfClownChaveAlfanumericaTestes.cs b/DFe.Testes/Gerais/DanfePdfClownChaveAlfanumericaTestes.cs
new file mode 100644
index 000000000..1599753fa
--- /dev/null
+++ b/DFe.Testes/Gerais/DanfePdfClownChaveAlfanumericaTestes.cs
@@ -0,0 +1,76 @@
+using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NFe.Danfe.PdfClown;
+using NFe.Danfe.PdfClown.Modelo;
+
+namespace DFe.Testes.Gerais
+{
+ ///
+ /// Smoke test do DANFE PdfClown: o PDF deve ser gerado com o código de barras CODE-128 híbrido
+ /// tanto para chave 100% numérica (fluxo antigo) quanto para chave com CNPJ alfanumérico
+ ///
+ [TestClass]
+ public class DanfePdfClownChaveAlfanumericaTestes
+ {
+ private static DanfeViewModel CriarViewModelMinimo(string chaveAcesso)
+ {
+ var model = new DanfeViewModel
+ {
+ ChaveAcesso = chaveAcesso,
+ NfNumero = 1,
+ NfSerie = 1,
+ TipoNF = 1,
+ TipoAmbiente = 2,
+ DataHoraEmissao = new DateTime(2025, 7, 15),
+ NaturezaOperacao = "VENDA",
+ ProtocoloAutorizacao = "352250000000001 15/07/2025 10:00:00"
+ };
+
+ model.Emitente.RazaoSocial = "EMITENTE DE TESTE LTDA";
+ model.Emitente.CnpjCpf = chaveAcesso.Substring(6, 14);
+ model.Emitente.EnderecoLogadrouro = "RUA DE TESTE";
+ model.Emitente.EnderecoNumero = "1";
+ model.Emitente.EnderecoBairro = "CENTRO";
+ model.Emitente.Municipio = "GOIANIA";
+ model.Emitente.EnderecoUf = "GO";
+ model.Emitente.EnderecoCep = "74000000";
+
+ model.Destinatario.RazaoSocial = "DESTINATARIO DE TESTE";
+ model.Destinatario.CnpjCpf = "11222333000181";
+ model.Destinatario.EnderecoLogadrouro = "AVENIDA DE TESTE";
+ model.Destinatario.EnderecoNumero = "2";
+ model.Destinatario.EnderecoBairro = "CENTRO";
+ model.Destinatario.Municipio = "GOIANIA";
+ model.Destinatario.EnderecoUf = "GO";
+ model.Destinatario.EnderecoCep = "74000001";
+
+ return model;
+ }
+
+ [TestMethod]
+ [DataRow("522507PC3D315K000193550010000000011000000018", DisplayName = "Chave com CNPJ alfanumérico")]
+ [DataRow("23190811820016000167650010000000221100000227", DisplayName = "Chave numérica (regressão)")]
+ public void Gerar_DanfeComChave_ProduzPdf(string chaveAcesso)
+ {
+ // Arrange
+ var model = CriarViewModelMinimo(chaveAcesso);
+
+ using (var danfe = new DanfeDoc(model))
+ {
+ // Act
+ danfe.Gerar();
+
+ using (var ms = new MemoryStream())
+ {
+ danfe.Salvar(ms);
+
+ // Assert - PDF gerado, não vazio e com o cabeçalho %PDF
+ var bytes = ms.ToArray();
+ Assert.IsTrue(bytes.Length > 1000, "O PDF gerado está vazio ou pequeno demais ({0} bytes)", bytes.Length);
+ Assert.AreEqual("%PDF", System.Text.Encoding.ASCII.GetString(bytes, 0, 4));
+ }
+ }
+ }
+ }
+}
diff --git a/DFe.Testes/Gerais/FormatadorDanfeTestes.cs b/DFe.Testes/Gerais/FormatadorDanfeTestes.cs
new file mode 100644
index 000000000..f98d60239
--- /dev/null
+++ b/DFe.Testes/Gerais/FormatadorDanfeTestes.cs
@@ -0,0 +1,77 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using NFe.Danfe.PdfClown.Tools;
+
+namespace DFe.Testes.Gerais
+{
+ ///
+ /// Testes da formatação de CNPJ, CPF e chave de acesso do DANFE (PdfClown),
+ /// cobrindo documentos numéricos (fluxo antigo) e o CNPJ alfanumérico da NT Conjunta 2025.001
+ ///
+ [TestClass]
+ public class FormatadorDanfeTestes
+ {
+ #region FormatarCnpj
+
+ [TestMethod]
+ [DataRow("11222333000181", "11.222.333/0001-81", DisplayName = "CNPJ numérico")]
+ [DataRow("00000000000191", "00.000.000/0001-91", DisplayName = "CNPJ numérico com zeros")]
+ [DataRow("12ABC34501DE35", "12.ABC.345/01DE-35", DisplayName = "CNPJ alfanumérico da NT")]
+ [DataRow("PC3D315K000193", "PC.3D3.15K/0001-93", DisplayName = "CNPJ alfanumérico de teste da Receita")]
+ public void FormatarCnpj_ComCnpjSemMascara_AplicaAMascaraPosicional(string cnpj, string esperado)
+ {
+ Assert.AreEqual(esperado, Formatador.FormatarCnpj(cnpj));
+ }
+
+ [TestMethod]
+ [DataRow("11.222.333/0001-81", "11.222.333/0001-81", DisplayName = "Numérico já com máscara")]
+ [DataRow("12.ABC.345/01DE-35", "12.ABC.345/01DE-35", DisplayName = "Alfanumérico já com máscara")]
+ public void FormatarCnpj_ComCnpjJaFormatado_MantemAMascara(string cnpj, string esperado)
+ {
+ Assert.AreEqual(esperado, Formatador.FormatarCnpj(cnpj));
+ }
+
+ [TestMethod]
+ [DataRow("12abc34501de35", DisplayName = "Minúsculas não formatam")]
+ [DataRow("12ABC34501DEA5", DisplayName = "Letra nos DVs não formata")]
+ [DataRow("123", DisplayName = "Curto demais não formata")]
+ public void FormatarCnpj_ComConteudoForaDoPadrao_DevolveOTextoOriginal(string cnpj)
+ {
+ Assert.AreEqual(cnpj, Formatador.FormatarCnpj(cnpj));
+ }
+
+ #endregion
+
+ #region FormatarCpfCnpj
+
+ [TestMethod]
+ [DataRow("12345678901", "123.456.789-01", DisplayName = "CPF continua com máscara de CPF")]
+ [DataRow("11222333000181", "11.222.333/0001-81", DisplayName = "CNPJ numérico")]
+ [DataRow("12ABC34501DE35", "12.ABC.345/01DE-35", DisplayName = "CNPJ alfanumérico")]
+ public void FormatarCpfCnpj_EscolheAMascaraCorreta(string documento, string esperado)
+ {
+ Assert.AreEqual(esperado, Formatador.FormatarCpfCnpj(documento));
+ }
+
+ #endregion
+
+ #region FormatarChaveAcesso
+
+ [TestMethod]
+ public void FormatarChaveAcesso_ComChaveAlfanumerica_AgrupaDeQuatroEmQuatro()
+ {
+ var formatada = Formatador.FormatarChaveAcesso("522507PC3D315K000193550010000000011000000018");
+
+ Assert.AreEqual("5225 07PC 3D31 5K00 0193 5500 1000 0000 0110 0000 0018", formatada);
+ }
+
+ [TestMethod]
+ public void FormatarChaveAcesso_ComChaveNumerica_AgrupaDeQuatroEmQuatro()
+ {
+ var formatada = Formatador.FormatarChaveAcesso("23190811820016000167650010000000221100000227");
+
+ Assert.AreEqual("2319 0811 8200 1600 0167 6500 1000 0000 2211 0000 0227", formatada);
+ }
+
+ #endregion
+ }
+}
diff --git a/DFe.Utils/ChaveFiscal.cs b/DFe.Utils/ChaveFiscal.cs
index f8a200231..e5ef555fa 100644
--- a/DFe.Utils/ChaveFiscal.cs
+++ b/DFe.Utils/ChaveFiscal.cs
@@ -24,11 +24,24 @@ public class ChaveFiscal
/// Retorna um objeto com os dados da chave de acesso
public static DadosChaveFiscal ObterChave(Estado ufEmitente, DateTimeOffset dataEmissao, string cnpjEmitente, ModeloDocumento modelo, int serie, long numero, int tipoEmissao, int cNf)
{
+ if (string.IsNullOrEmpty(cnpjEmitente))
+ throw new ArgumentException("O CNPJ/CPF do emitente deve ser informado.", "cnpjEmitente");
+
+ // NT Conjunta 2025.001: o CNPJ pode ser alfanumérico ([A-Z0-9]{12}[0-9]{2}) e ocupa 14 posições na chave.
+ // Somente CPF (11 posições) é completado com zeros à esquerda; qualquer outro comprimento seria um
+ // documento truncado e geraria uma chave bem-formada porém errada.
+ var documentoEmitente = cnpjEmitente.Length == 11 ? cnpjEmitente.PadLeft(14, '0') : cnpjEmitente;
+
+ if (documentoEmitente.Length != 14)
+ throw new ArgumentException(
+ string.Format("O documento do emitente deve ter 14 posições (CNPJ) ou 11 posições (CPF); o valor informado \"{0}\" tem {1}.", cnpjEmitente, cnpjEmitente.Length),
+ "cnpjEmitente");
+
var chave = new StringBuilder();
chave.Append(((int)ufEmitente).ToString("D2"))
.Append(dataEmissao.ToString("yyMM"))
- .Append(cnpjEmitente)
+ .Append(documentoEmitente)
.Append(((int)modelo).ToString("D2"))
.Append(serie.ToString("D3"))
.Append(numero.ToString("D9"))
@@ -57,7 +70,7 @@ private static string ObterDigitoVerificador(string chave)
//percorrendo cada caractere da chave da direita para esquerda para fazer os cálculos com o peso
for (var i = chave.Length - 1; i != -1; i--)
{
- var ch = Convert.ToInt32(chave[i].ToString());
+ var ch = ObterValorDoCaractere(chave[i]);
soma += ch*peso;
//sempre que for 9 voltamos o peso a 2
if (peso < 9)
@@ -77,6 +90,21 @@ private static string ObterDigitoVerificador(string chave)
return dv.ToString();
}
+ ///
+ /// Obtém o valor numérico de um caractere da chave para o cálculo do dígito verificador,
+ /// conforme a NT Conjunta 2025.001: valor = código ASCII - 48 ('0'-'9' => 0 a 9; 'A'-'Z' => 17 a 42)
+ ///
+ private static int ObterValorDoCaractere(char caractere)
+ {
+ // A chave admite somente dígitos e letras maiúsculas; qualquer outro caractere
+ // (minúsculas, símbolos, ASCII 58-64) produziria um DV errado sem nenhum erro.
+ if ((caractere < '0' || caractere > '9') && (caractere < 'A' || caractere > 'Z'))
+ throw new ArgumentException(
+ string.Format("Caractere inválido na chave do DF-e: '{0}'. São aceitos somente dígitos (0-9) e letras maiúsculas (A-Z).", caractere));
+
+ return caractere - '0';
+ }
+
///
/// Informa se a chave de um DF-e é válida
///
diff --git a/DFe.Utils/CnpjFiscal.cs b/DFe.Utils/CnpjFiscal.cs
new file mode 100644
index 000000000..27bbd6b5a
--- /dev/null
+++ b/DFe.Utils/CnpjFiscal.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Linq;
+using System.Text.RegularExpressions;
+
+namespace DFe.Utils
+{
+ ///
+ /// Classe com métodos para tratamento do CNPJ, incluindo o CNPJ alfanumérico da NT Conjunta 2025.001
+ /// (12 posições [A-Z0-9] + 2 dígitos verificadores numéricos)
+ ///
+ public static class CnpjFiscal
+ {
+ private static readonly Regex FormatoCnpj = new Regex("^[A-Z0-9]{12}[0-9]{2}$", RegexOptions.Compiled);
+ private static readonly Regex FormatoBaseCnpj = new Regex("^[A-Z0-9]{12}$", RegexOptions.Compiled);
+
+ ///
+ /// Calcula os dois dígitos verificadores para as 12 primeiras posições de um CNPJ,
+ /// conforme a NT Conjunta 2025.001: módulo 11 sobre o valor de cada caractere (código ASCII - 48),
+ /// com pesos de 2 a 9 aplicados da direita para a esquerda
+ ///
+ /// 12 primeiras posições do CNPJ ([A-Z0-9]{12})
+ /// Os dois dígitos verificadores, ex.: "93"
+ public static string ObterDigitosVerificadores(string cnpjBase)
+ {
+ if (cnpjBase == null)
+ throw new ArgumentNullException("cnpjBase");
+
+ if (!FormatoBaseCnpj.IsMatch(cnpjBase))
+ throw new ArgumentException(
+ string.Format("A base do CNPJ deve ter 12 posições contendo somente dígitos e letras maiúsculas; valor informado: \"{0}\".", cnpjBase),
+ "cnpjBase");
+
+ var dv1 = CalcularDigito(cnpjBase);
+ var dv2 = CalcularDigito(cnpjBase + dv1);
+
+ return string.Concat(dv1, dv2);
+ }
+
+ ///
+ /// Informa se um CNPJ de 14 posições é válido: formato [A-Z0-9]{12}[0-9]{2},
+ /// dígitos verificadores corretos e diferente do CNPJ zerado (vedado pela NT Conjunta 2025.001)
+ ///
+ /// CNPJ com 14 posições, sem máscara
+ public static bool Valido(string cnpj)
+ {
+ if (string.IsNullOrEmpty(cnpj) || !FormatoCnpj.IsMatch(cnpj))
+ return false;
+
+ //CNPJ zerado tem dígitos verificadores que conferem, mas é vedado
+ if (cnpj.All(c => c == '0'))
+ return false;
+
+ return cnpj.Substring(12, 2) == ObterDigitosVerificadores(cnpj.Substring(0, 12));
+ }
+
+ private static int CalcularDigito(string valor)
+ {
+ var soma = 0;
+ var peso = 2;
+
+ //pesos de 2 a 9, aplicados da direita para a esquerda
+ for (var i = valor.Length - 1; i != -1; i--)
+ {
+ //NT Conjunta 2025.001: valor do caractere = código ASCII - 48 ('0'-'9' => 0 a 9; 'A'-'Z' => 17 a 42)
+ soma += (valor[i] - '0') * peso;
+ peso = peso == 9 ? 2 : peso + 1;
+ }
+
+ var resto = soma % 11;
+ return resto < 2 ? 0 : 11 - resto;
+ }
+ }
+}
diff --git a/NFe.AppTeste/MainWindow.xaml.cs b/NFe.AppTeste/MainWindow.xaml.cs
index 8c8204798..00dcd25e4 100644
--- a/NFe.AppTeste/MainWindow.xaml.cs
+++ b/NFe.AppTeste/MainWindow.xaml.cs
@@ -1973,14 +1973,11 @@ private void BtnAdminCsc_Click(object sender, RoutedEventArgs e)
throw new Exception("O Identificador do tipo de operação deve ser um número inteiro entre 1 e 3!");
//raizCnpj
- var raizCnpj = Funcoes.InpuBox(this, "Administração do CSC", "Raiz do CNPJ do contribuinte que está efetuando a consulta (oito primeiros dígitos do CNPJ):");
+ var raizCnpj = Funcoes.InpuBox(this, "Administração do CSC", "Raiz do CNPJ do contribuinte que está efetuando a consulta (oito primeiras posições do CNPJ):");
if (string.IsNullOrEmpty(raizCnpj)) throw new Exception("A Raiz do CNPJ do contribuinte deve ser informada!");
- long l;
- var longo = long.TryParse(raizCnpj, out l);
- if (!longo)
- throw new Exception("A Raiz do CNPJ do contribuinte deve conter apenas números!");
- if (raizCnpj.Length != 8)
- throw new Exception("A Raiz do CNPJ do contribuinte deve conter 8 caracteres!");
+ //NT Conjunta 2025.001: o CNPJ pode ser alfanumérico nas 12 primeiras posições
+ if (!System.Text.RegularExpressions.Regex.IsMatch(raizCnpj, "^[0-9A-Z]{8}$"))
+ throw new Exception("A Raiz do CNPJ do contribuinte deve conter 8 caracteres, apenas números e letras maiúsculas!");
var idCsc = "";
var codigoCsc = "";
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/eventoEPEC_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/eventoEPEC_v1.00.xsd
index 3562cc9eb..5524009ff 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/eventoEPEC_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/eventoEPEC_v1.00.xsd
@@ -213,7 +213,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteCCe_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteCCe_v1.00.xsd
index 4cd45988d..beff945c0 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteCCe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteCCe_v1.00.xsd
@@ -151,7 +151,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteConfRecebto_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteConfRecebto_v1.00.xsd
index 44581e874..3a610a676 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteConfRecebto_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteConfRecebto_v1.00.xsd
@@ -138,7 +138,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteConsSitNFe_v4.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteConsSitNFe_v4.00.xsd
index a56621542..8672a6761 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteConsSitNFe_v4.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteConsSitNFe_v4.00.xsd
@@ -316,7 +316,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEPEC_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEPEC_v1.00.xsd
index 132be27b9..746689377 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEPEC_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEPEC_v1.00.xsd
@@ -139,7 +139,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoAtorInteressado_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoAtorInteressado_v1.00.xsd
index 6eeb536ed..8b2ccfa2d 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoAtorInteressado_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoAtorInteressado_v1.00.xsd
@@ -173,7 +173,7 @@ Outros valores: 1=Empresa Emitente, 2=Empresa destinatária; 3=Empresa; 5=Fisco;
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEConf_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEConf_v1.00.xsd
index 710d25def..47e963bca 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEConf_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEConf_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEntregaNFe_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEntregaNFe_v1.00.xsd
index 17a5396c5..c3b05d07a 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEntregaNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancEntregaNFe_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancInsucessoNFe_v1.00.xsd
index 0bde4345e..cfbf265f3 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancInsucessoNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancInsucessoNFe_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancNFe_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancNFe_v1.00.xsd
index bf0d09a8b..719fdeaab 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancNFe_v1.00.xsd
@@ -127,7 +127,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancSubst_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancSubst_v1.00.xsd
index ce7b2c3db..b41416032 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancSubst_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoCancSubst_v1.00.xsd
@@ -155,7 +155,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEConf_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEConf_v1.00.xsd
index fe9d449d5..530897c85 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEConf_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEConf_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEntregaNFe_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEntregaNFe_v1.00.xsd
index a7d70d798..be38d6aa2 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEntregaNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoEntregaNFe_v1.00.xsd
@@ -90,7 +90,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoInsucessoNFe_v1.00.xsd
index 9ab61fe47..3b7915676 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoInsucessoNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEventoInsucessoNFe_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEvento_v1.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEvento_v1.00.xsd
index f1e023fed..e02813f96 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteEvento_v1.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteEvento_v1.00.xsd
@@ -99,7 +99,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/leiauteInutNFe_v4.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/leiauteInutNFe_v4.00.xsd
index 819597c1a..886e05d0f 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/leiauteInutNFe_v4.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/leiauteInutNFe_v4.00.xsd
@@ -76,7 +76,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03.xsd b/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03.xsd
index c967c195b..06f4c6147 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03.xsd
@@ -58,7 +58,7 @@
-
+
@@ -94,7 +94,7 @@
-
+
@@ -103,7 +103,7 @@
-
+
@@ -113,7 +113,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03_OPENSSL.xsd b/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03_OPENSSL.xsd
index 851a822ba..142dd55b2 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03_OPENSSL.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v1.03_OPENSSL.xsd
@@ -59,7 +59,7 @@
-
+
@@ -95,7 +95,7 @@
-
+
@@ -104,7 +104,7 @@
-
+
@@ -114,7 +114,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v4.00.xsd b/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v4.00.xsd
index dfabc3366..4ead3c532 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v4.00.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/tiposBasico_v4.00.xsd
@@ -52,7 +52,7 @@
-
+
@@ -92,7 +92,7 @@
-
+
@@ -102,7 +102,7 @@
-
+
@@ -112,7 +112,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas-sem-vIBS/tiposDistDFe_v1.01.xsd b/NFe.AppTeste/Schemas-sem-vIBS/tiposDistDFe_v1.01.xsd
index 8b0d8a135..1aa75ec7d 100644
--- a/NFe.AppTeste/Schemas-sem-vIBS/tiposDistDFe_v1.01.xsd
+++ b/NFe.AppTeste/Schemas-sem-vIBS/tiposDistDFe_v1.01.xsd
@@ -116,7 +116,7 @@
-
+
@@ -173,7 +173,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd b/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd
index a5051dd02..d204e4061 100644
--- a/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/DFeTiposBasicos_v1.00.xsd
@@ -1,6 +1,16 @@
+
+
+ Tipo Chave de Documento Fiscal Eletrônico
+
+
+
+
+
+
+
Tipo string genérico
@@ -55,6 +65,24 @@
+
+
+ Tipo CNPJ Base
+
+
+
+
+
+
+
+
+ Tipo CNPJ
+
+
+
+
+
+
Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais
@@ -81,6 +109,23 @@
+
+
+
+
+
+
+ Tipo de Receita Bruta do SN
+
+
+
+
+
+
+
+
+
+
@@ -93,6 +138,8 @@
+
+
@@ -115,6 +162,14 @@
+
+
+ Ano e mês referência do período de apuração (AAAA-MM)
+
+
+
+
+
Grupo de informações da Tributação da NFCom
@@ -163,6 +218,26 @@
+
+
+ Grupo de informações da Tributação da NFGas
+
+
+
+
+ Código Situação Tributária do IBS/CBS
+
+
+
+
+
+
+
+ Informado conforme indicador no cClassTrib
+
+
+
+
Grupo de informações da Tributação da NFAg
@@ -240,7 +315,7 @@
-
+
@@ -262,7 +337,7 @@
-
+
Informar essa opção da Choice para Monofasia (CST 620)
@@ -298,33 +373,6 @@
-
-
- Grupo de informações da Tributação da NFGas
-
-
-
-
- Código Situação Tributária do IBS/CBS
-
-
-
-
-
-
-
-
- Informar essa opção da Choice para Monofasia
-
-
-
-
-
- Informado conforme indicador no cClassTrib
-
-
-
-
Grupo de informações do Imposto Seletivo
@@ -347,7 +395,7 @@
Alíquota do Imposto Seletivo (percentual)
-
+
Alíquota do Imposto Seletivo (por valor)
@@ -949,6 +997,152 @@
Grupo de campos da redução de aliquota
+
+
+ Grupo de operações em áreas incentivadas (ALC/ZFM) - CBS (alíquota zero)
+ Grupo de informações para identificação de operações em áreas incentivadas (ALC/ZFM) com alíquota zero da CBS, conforme arts. 451 e 466 da LC 214/2025, quando fornecedor e destinatário estiverem nessas áreas, distinguindo a existência de processo aprovado na Suframa.
+
+
+
+
+ Valor da CBS
+
+
+
+
+
+
+
+ Grupo de informações da Tributação Regular. Informar como seria a tributação caso não cumprida a condição resolutória/suspensiva. Exemplo 1: Art. 442, §4. Operações com ZFM e ALC. Exemplo 2: Operações com suspensão do tributo.
+
+
+
+
+ Grupo de informações da composição do valor do IBS e da CBS em compras governamental
+
+
+
+
+
+
+ Tipo CBS IBS Completo NFe
+
+
+
+ IBS / CBS
+
+
+
+ Valor do BC
+
+
+
+
+
+ Grupo de informações do IBS na UF
+
+
+
+
+
+ Aliquota do IBS de competência das UF (em percentual)
+
+
+
+
+ Grupo de campos do Diferimento
+
+
+
+
+ Grupo de Informações da devolução de tributos
+
+
+
+
+ Grupo de campos da redução de aliquota
+
+
+
+
+ Valor do IBS de competência das UF
+
+
+
+
+
+
+
+ Grupo de Informações do IBS no Município
+
+
+
+
+
+ Aliquota do IBS Municipal (em percentual)
+
+
+
+
+ Grupo de campos do Diferimento
+
+
+
+
+ Grupo de Informações da devolução de tributos
+
+
+
+
+ Grupo de campos da redução de aliquota
+
+
+
+
+ Valor do IBS Municipal
+
+
+
+
+
+
+
+ Valor do IBS
+
+
+
+
+
+ Grupo de Tributação da CBS
+
+
+
+
+
+ Aliquota da CBS (em percentual)
+
+
+
+
+ Grupo de campos do Diferimento
+
+
+
+
+ Grupo de Informações da devolução de tributos
+
+
+
+
+ Grupo de campos da redução de aliquota
+
+
+
+
+ Grupo de operações em áreas incentivadas (ALC/ZFM) - CBS (alíquota zero)
+ Grupo de informações para identificação de operações em áreas incentivadas (ALC/ZFM) com alíquota zero da CBS, conforme arts. 451 e 466 da LC 214/2025, quando fornecedor e destinatário estiverem nessas áreas, distinguindo a existência de processo aprovado na Suframa.
+
+
Valor da CBS
@@ -1032,10 +1226,14 @@
Tipo Devolução Tributo
+
+
+ Percentual de devolução do tributo, conforme LC 214/25 art. 118.
+
+
- Valor do tributo devolvido. No fornecimento de energia elétrica, água, esgoto e
-gás natural e em outras hipóteses definidas no regulamento
+ Valor do tributo devolvido ("cashback" de desconto na própria Nota Fiscal / Fatura)
@@ -1131,7 +1329,9 @@ gás natural e em outras hipóteses definidas no regulamento
1=União
2=Estados
3=Distrito Federal
-4=Municípios
+4=Municípios
+5=Consórcio Público
+6=Comitê Gestor do IBS
@@ -1139,6 +1339,29 @@ gás natural e em outras hipóteses definidas no regulamento
Percentual de redução de aliquota em compra governamental
+
+
+ Tipo da operação com ente governamental:
+1 – Fornecimento com pagamento posterior;
+
+2 - Recebimento do pagamento com fornecimento já realizado;
+
+3 – Fornecimento com pagamento já realizado;
+
+4 – Recebimento do pagamento com fornecimento posterior;
+
+
+
+
+ Chave de acesso do documento fiscal anterior.
+
+Deverá ser informado para tpOperGov 2 e 3 e vedado para os tipos 1 e 4.
+
+No caso do tpOperGov 2 aceitará apenas uma chave referenciada, no tipo 3 poderá aceitar múltiplas chaves
+
+Obs: a chave de acesso deverá ser de um emitente com o mesmo CNPJ base
+
+
@@ -1153,19 +1376,49 @@ gás natural e em outras hipóteses definidas no regulamento
1=União
2=Estados
3=Distrito Federal
-4=Municípios
+4=Municípios
+5=Consórcio Público
+6=Comitê Gestor do IBS
- Percentual de redução de aliquota em compra governamental
+ Percentual de redução de alíquota em compra governamental
Tipo da operação com ente governamental:
-1 - Fornecimento
-2 - Recebimento do Pagamento
+1 – Fornecimento com pagamento posterior;
+2 - Recebimento do pagamento com fornecimento já realizado;
+3 – Fornecimento com pagamento já realizado;
+4 – Recebimento do pagamento com fornecimento posterior;
+
+
+
+
+ Chave de acesso do documento fiscal anterior.
+
+Deverá ser informado para tpOperGov 2 e 3 e vedado para os tipos 1 e 4.
+
+No caso do tpOperGov 2 aceitará apenas uma chave referenciada, no tipo 3 poderá aceitar múltiplas chaves
+
+Obs: a chave de acesso deverá ser de um emitente com o mesmo CNPJ base
+
+
+
+
+
+
+ Tipo Pagamento que ocorre em DFe emitdo anteriormente
+ Informado para abater as parcelas de antecipação de pagamento, conforme art. 10 §4
+
+
+
+
+ Chave de acesso do documento fiscal de antecipação de pagamento
+
+Obs: esse DFe deverá ter o indAntecipacaoPgto marcado no grupo ide
@@ -1187,6 +1440,68 @@ gás natural e em outras hipóteses definidas no regulamento
+
+
+ Tipo Operações em areas incentivadas com CBS Zero
+
+
+
+
+ Percentual efetivo sem a redução
+ Alíquota efetiva de referência da CBS aplicável à operação fora de áreas ou regimes incentivados.
+
+
+
+
+ Valor efetivo sem a redução
+ Valor da CBS calculado para a operação fora de áreas ou regimes incentivado
+
+
+
+
+
+
+ Tipo Operações em áreas incentivadas (ALC/ZFM) - CBS (alíquota zero)
+
+
+
+
+ Tipo de aplicação da alíquota zero da CBS.
+
+
+
+
+
+
+
+
+
+
+
+ Número do processo na Suframa para o item
+comercializado.
+
+
+
+
+
+
+
+
+
+
+ Percentual efetivo sem a redução
+ Alíquota efetiva de referência da CBS aplicável à operação fora de áreas ou regimes incentivados.
+
+
+
+
+ Valor efetivo sem a redução
+ Valor da CBS calculado para a operação fora de áreas ou regimes incentivado
+
+
+
+
Tipo Estorno de Crédito
@@ -1204,14 +1519,6 @@ gás natural e em outras hipóteses definidas no regulamento
-
-
- Ano e mês referência do período de apuração (AAAA-MM)
-
-
-
-
-
Tipo Ajuste de Competência
diff --git a/NFe.AppTeste/Schemas/distDFeInt_v1.01.xsd b/NFe.AppTeste/Schemas/distDFeInt_v1.01.xsd
index d66807e9c..89a68ae75 100644
--- a/NFe.AppTeste/Schemas/distDFeInt_v1.01.xsd
+++ b/NFe.AppTeste/Schemas/distDFeInt_v1.01.xsd
@@ -1,84 +1,83 @@
-
-
-
-
-
- Schema de pedido de distribuição de DF-e de interesse
-
-
-
-
-
-
+
+
+
+
+ Schema de pedido de distribuição de DF-e de interesse
+
+
+
+
+
+
Identificação do Ambiente:
1 - Produção
2 - Homologação
-
-
-
-
-
- Código da UF do Autor
-
-
-
-
-
- CNPJ do interessado no DF-e
-
-
-
-
- CPF do interessado no DF-e
-
-
-
-
-
-
- Grupo para distribuir DF-e de interesse
-
-
-
-
-
- Último NSU recebido pelo ator. Caso seja informado com zero, ou com um NSU muito antigo, a consulta retornará unicamente as informações resumidas e documentos fiscais eletrônicos que tenham sido recepcionados pelo Ambiente Nacional nos últimos 3 meses.
-
-
-
-
-
-
-
- Grupo para consultar um DF-e a partir de um NSU específico
-
-
-
-
-
- Número Sequencial Único. Geralmente esta consulta será utilizada quando identificado pelo interessado um NSU faltante. O Web Service retornará o documento ou informará que o NSU não existe no Ambiente Nacional. Assim, esta consulta fechará a lacuna do NSU identificado como faltante.
-
-
-
-
-
-
-
- Grupo para consultar uma NF-e a partir da chave de acesso
-
-
-
-
-
- Chave de acesso da NF-e a ser consultada
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+ Código da UF do Autor
+
+
+
+
+
+ CNPJ do interessado no DF-e
+
+
+
+
+ CPF do interessado no DF-e
+
+
+
+
+
+
+ Grupo para distribuir DF-e de interesse
+
+
+
+
+
+ Último NSU recebido pelo ator. Caso seja informado com zero, ou com um NSU muito antigo, a consulta retornará unicamente as informações resumidas e documentos fiscais eletrônicos que tenham sido recepcionados pelo Ambiente Nacional nos últimos 3 meses.
+
+
+
+
+
+
+
+ Grupo para consultar um DF-e a partir de um NSU específico
+
+
+
+
+
+ Número Sequencial Único. Geralmente esta consulta será utilizada quando identificado pelo interessado um NSU faltante. O Web Service retornará o documento ou informará que o NSU não existe no Ambiente Nacional. Assim, esta consulta fechará a lacuna do NSU identificado como faltante.
+
+
+
+
+
+
+
+ Grupo para consultar uma NF-e a partir da chave de acesso
+
+
+
+
+
+ Chave de acesso da NF-e a ser consultada
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/eventoEPEC_v1.00.xsd b/NFe.AppTeste/Schemas/eventoEPEC_v1.00.xsd
index 3562cc9eb..5524009ff 100644
--- a/NFe.AppTeste/Schemas/eventoEPEC_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/eventoEPEC_v1.00.xsd
@@ -213,7 +213,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteCCe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteCCe_v1.00.xsd
index 4cd45988d..beff945c0 100644
--- a/NFe.AppTeste/Schemas/leiauteCCe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteCCe_v1.00.xsd
@@ -151,7 +151,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteConfRecebto_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteConfRecebto_v1.00.xsd
index 44581e874..3a610a676 100644
--- a/NFe.AppTeste/Schemas/leiauteConfRecebto_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteConfRecebto_v1.00.xsd
@@ -138,7 +138,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEPEC_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEPEC_v1.00.xsd
index 132be27b9..746689377 100644
--- a/NFe.AppTeste/Schemas/leiauteEPEC_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEPEC_v1.00.xsd
@@ -139,7 +139,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoAtorInteressado_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoAtorInteressado_v1.00.xsd
index 6eeb536ed..8b2ccfa2d 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoAtorInteressado_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoAtorInteressado_v1.00.xsd
@@ -173,7 +173,7 @@ Outros valores: 1=Empresa Emitente, 2=Empresa destinatária; 3=Empresa; 5=Fisco;
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoCancEConf_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoCancEConf_v1.00.xsd
index 710d25def..47e963bca 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoCancEConf_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoCancEConf_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoCancEntregaNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoCancEntregaNFe_v1.00.xsd
index 17a5396c5..c3b05d07a 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoCancEntregaNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoCancEntregaNFe_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd
index 0bde4345e..cfbf265f3 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoCancInsucessoNFe_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoCancNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoCancNFe_v1.00.xsd
index bf0d09a8b..719fdeaab 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoCancNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoCancNFe_v1.00.xsd
@@ -127,7 +127,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoCancSubst_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoCancSubst_v1.00.xsd
index ce7b2c3db..b41416032 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoCancSubst_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoCancSubst_v1.00.xsd
@@ -155,7 +155,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoEConf_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoEConf_v1.00.xsd
index fe9d449d5..530897c85 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoEConf_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoEConf_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoEntregaNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoEntregaNFe_v1.00.xsd
index a7d70d798..be38d6aa2 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoEntregaNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoEntregaNFe_v1.00.xsd
@@ -90,7 +90,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd
index 9ab61fe47..3b7915676 100644
--- a/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEventoInsucessoNFe_v1.00.xsd
@@ -91,7 +91,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd b/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd
index f1e023fed..1f23ffac0 100644
--- a/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteEvento_v1.00.xsd
@@ -1,4 +1,4 @@
-
+
@@ -91,6 +91,40 @@
+
+
+ Grupo de Informação do Provedor de Assinatura e Autorização
+
+
+
+
+
+ CNPJ do Provedor de Assinatura e Autorização
+
+
+
+
+ Assinatura RSA do Emitente para DFe gerados por PAA
+
+
+
+
+
+ Assinatura digital padrão RSA
+ Converter o atributo Id do DFe para array de bytes e assinar com a chave privada do RSA com algoritmo SHA1 gerando um valor no formato base64.
+
+
+
+
+ Chave Publica no padrão XML RSA Key
+
+
+
+
+
+
+
+
@@ -99,7 +133,7 @@
-
+
diff --git a/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd b/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd
index 9409ba120..e27ed6a87 100644
--- a/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd
+++ b/NFe.AppTeste/Schemas/leiauteNFe_v4.00.xsd
@@ -1,23 +1,5 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -73,10 +55,7 @@
- Série do Documento Fiscal
-série normal 0-889
-Avulsa Fisco 890-899
-SCAN 900-999
+ Série do Documento Fiscal
@@ -132,13 +111,19 @@ SCAN 900-999
Informar o município de ocorrência do fato gerador do fato gerador do IBS / CBS.
-Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do estabelecimento) ”, e não tiver endereço do destinatário (Grupo: E05) ou local de entrega (Grupo: G01).
+Campo preenchido somente quando "indPres = 5 (Operação presencial, fora do estabelecimento)", e não estiver preenchido o endereço do destinatário (grupo: E05) nem o local de entrega (grupo: G01).
- Formato de impressão do DANFE (0-sem DANFE;1-DANFe Retrato; 2-DANFe Paisagem;3-DANFe Simplificado;
- 4-DANFe NFC-e;5-DANFe NFC-e em mensagem eletrônica)
+ Formato de impressão do DANFE:
+0 - Sem DANFE;
+1 - DANFE Retrato;
+2 - DANFE Paisagem;
+3 - DANFE Simplificado;
+4 - DANFE NFC-e;
+5 - DANFE NFC-e em mensagem eletrônica;
+6 - DANFE Simplificado Tipo 2 (nas condições do Ajuste SINIEF 13/26).
@@ -149,20 +134,21 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e
+
- Forma de emissão da NF-e
+ Forma de emissão da NF-e:
1 - Normal;
-2 - Contingência FS
-3 - Regime Especial NFF (NT 2021.002)
-4 - Contingência DPEC
-5 - Contingência FSDA
-6 - Contingência SVC - AN
-7 - Contingência SVC - RS
-9 - Contingência off-line NFC-e
+2 - Contingência FS;
+3 - Regime Especial NFF (NT 2021.002);
+4 - Contingência DPEC;
+5 - Contingência FSDA;
+6 - Contingência SVC - AN;
+7 - Contingência SVC - RS;
+9 - Contingência off-line da NFC-e e da NF-e com DANFE Simplificado Tipo 2.
@@ -209,13 +195,7 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e
- Tipo de Nota de Débito:
-01=Transferência de créditos para Cooperativas;
-02=Anulação de Crédito por Saídas Imunes/Isentas;
-03=Débitos de notas fiscais não processadas na apuração;
-04=Multa e juros;
-05=Transferência de crédito de sucessão.
-
+ Tipo de Nota de Débito
@@ -237,8 +217,14 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e
- Indicador de presença do comprador no estabelecimento comercial no momento da oepração
- (0-Não se aplica (ex.: Nota Fiscal complementar ou de ajuste;1-Operação presencial;2-Não presencial, internet;3-Não presencial, teleatendimento;4-NFC-e entrega em domicílio;5-Operação presencial, fora do estabelecimento;9-Não presencial, outros)
+ Indicador de presença do comprador no estabelecimento comercial no momento da oepração:
+0 - Não se aplica (ex.: Nota Fiscal complementar ou de ajuste);
+1 - Operação presencial;
+2 - Operação não presencial, internet;
+3 - Operação não presencial, teleatendimento;
+4 - Operação não presencial com NFC-e e NFe com DANFE Simplificado Tipo 2 (com entrega);
+5 - Operação presencial, fora do estabelecimento;
+9 - Operação não presencial, outros.
@@ -267,6 +253,17 @@ Campo preenchido somente quando “indPres = 5 (Operação presencial, fora do e
+
+
+ Código indicador do local da operação de fornecimento
+
+
+
+
+
+
+
+
Processo de emissão utilizado com a seguinte codificação:
@@ -620,6 +617,17 @@ Este campo será obrigatoriamente preenchido com:
+
+
+ Inscrição do emitente na Suframa
+
+
+
+
+
+
+
+
@@ -6654,7 +6662,7 @@ tipo de ato concessório:
-
+
@@ -6728,7 +6736,7 @@ tipo de ato concessório:
Descrição literal do status do serviço solicitado.
-
+
Código da Mensagem.
@@ -6747,7 +6755,7 @@ tipo de ato concessório:
-
+
@@ -7483,7 +7491,7 @@ alterado para tamanho variavel 1-4. (NT2011/004)
04=Multa e juros;
05=Transferência de crédito na sucessão;
06=Pagamento antecipado;
- 07=Perda em estoque;
+ 07=Perda em estoque (Perecimento, Perda, Furto, Roubo);
08=Desenquadramento do SN;
@@ -7506,6 +7514,7 @@ alterado para tamanho variavel 1-4. (NT2011/004)
03=Retorno por recusa na entrega ou por não localização do destinatário na tentativa de entrega;
04=Redução de valores;
05=Transferência de crédito na sucessão;
+ 06=Retorno por recusa parcial na entrega;
@@ -7515,6 +7524,7 @@ alterado para tamanho variavel 1-4. (NT2011/004)
+
diff --git a/NFe.AppTeste/Schemas/resEvento_v1.01.xsd b/NFe.AppTeste/Schemas/resEvento_v1.01.xsd
index 3ac45a4d8..40113c758 100644
--- a/NFe.AppTeste/Schemas/resEvento_v1.01.xsd
+++ b/NFe.AppTeste/Schemas/resEvento_v1.01.xsd
@@ -1,94 +1,94 @@
-
-
-
-
-
-
- Schema da estrutura XML gerada pelo Ambiente Nacional com o conjunto de informações resumidas de um evento de NF-e
-
-
-
-
-
- Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE extendida, utilizar 91 para identificar o Ambiente Nacional
-
-
-
-
-
- CNPJ do Emitente
-
-
-
-
- CPF do Emitente
-
-
-
-
-
- Chave de acesso da NF-e
-
-
-
-
- Data e Hora do Evento, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD = +hh:mm ou -hh:mm)
-
-
-
-
- Tipo do Evento
-
-
-
-
-
-
-
-
-
-
- Seqüencial do evento para o mesmo tipo de evento. Para maioria dos eventos será 1, nos casos em que possa existir mais de um evento, como é o caso da carta de correção, o autor do evento deve numerar de forma seqüencial
-
-
-
-
-
-
-
-
-
-
- Descrição do Evento
-
-
-
-
-
-
-
-
-
-
- Data e hora de autorização do evento no formato AAAA-MM-DDTHH:MM:SSTZD
-
-
-
-
- Número do Protocolo do evento. 1 posição (1 – Secretaria de Fazenda Estadual 2 – Receita Federal); 2 - códiga da UF - 2 posições ano; 10 seqüencial no ano
-
-
-
-
-
-
-
-
- Tipo Versão do leiate resNFe
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+ Schema da estrutura XML gerada pelo Ambiente Nacional com o conjunto de informações resumidas de um evento de NF-e
+
+
+
+
+
+ Código do órgão de recepção do Evento. Utilizar a Tabela do IBGE extendida, utilizar 91 para identificar o Ambiente Nacional
+
+
+
+
+
+
+CNPJ do Emitente
+
+
+
+
+ CPF do Emitente
+
+
+
+
+
+ Chave de acesso da NF-e
+
+
+
+
+ Data e Hora do Evento, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD = +hh:mm ou -hh:mm)
+
+
+
+
+ Tipo do Evento
+
+
+
+
+
+
+
+
+
+
+ Seqüencial do evento para o mesmo tipo de evento. Para maioria dos eventos será 1, nos casos em que possa existir mais de um evento, como é o caso da carta de correção, o autor do evento deve numerar de forma seqüencial
+
+
+
+
+
+
+
+
+
+
+ Descrição do Evento
+
+
+
+
+
+
+
+
+
+
+ Data e hora de autorização do evento no formato AAAA-MM-DDTHH:MM:SSTZD
+
+
+
+
+ Número do Protocolo do evento. 1 posição (1 – Secretaria de Fazenda Estadual 2 – Receita Federal); 2 - códiga da UF - 2 posições ano; 10 seqüencial no ano
+
+
+
+
+
+
+
+
+ Tipo Versão do leiate resNFe
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/resNFe_v1.01.xsd b/NFe.AppTeste/Schemas/resNFe_v1.01.xsd
index 91d83b0dd..91a9e9e46 100644
--- a/NFe.AppTeste/Schemas/resNFe_v1.01.xsd
+++ b/NFe.AppTeste/Schemas/resNFe_v1.01.xsd
@@ -1,111 +1,110 @@
-
-
-
-
-
-
- Schema da estrutura XML gerada pelo Ambiente Nacional com o conjunto de informações resumidas de uma NF-e
-
-
-
-
-
- Chave de acesso da NF-e
-
-
-
-
-
- CNPJ do Emitente
-
-
-
-
- CPF do Emitente
-
-
-
-
-
- Razão Social ou Nome do emitente
-
-
-
-
-
-
-
-
-
-
- Inscrição Estadual do Emitente
-
-
-
-
- Data e Hora de emissão do Documento Fiscal (AAAA-MM-DDThh:mm:ssTZD) ex.: 2012-09-01T13:00:00-03:00
-
-
-
-
- Tipo do Documento Fiscal (0 - entrada; 1 - saída)
-
-
-
-
-
-
-
-
-
-
-
- Valor Total da NF-e
-
-
-
-
- Digest Value da NF-e processada. Utilizado para conferir a integridade da NF-e original
-
-
-
-
- Data e hora de autorização da NF-e, no formato AAAA-MM-DDTHH:MM:SSTZD
-
-
-
-
- Número do Protocolo de Status da NF-e. 1 posição (1 – Secretaria de Fazenda Estadual 2 – Receita Federal); 2 - códiga da UF - 2 posições ano; 10 seqüencial no ano
-
-
-
-
-
+
+
+
+
+
+ Schema da estrutura XML gerada pelo Ambiente Nacional com o conjunto de informações resumidas de uma NF-e
+
+
+
+
+
+ Chave de acesso da NF-e
+
+
+
+
+
+ CNPJ do Emitente
+
+
+
+
+ CPF do Emitente
+
+
+
+
+
+ Razão Social ou Nome do emitente
+
+
+
+
+
+
+
+
+
+
+ Inscrição Estadual do Emitente
+
+
+
+
+ Data e Hora de emissão do Documento Fiscal (AAAA-MM-DDThh:mm:ssTZD) ex.: 2012-09-01T13:00:00-03:00
+
+
+
+
+ Tipo do Documento Fiscal (0 - entrada; 1 - saída)
+
+
+
+
+
+
+
+
+
+
+
+ Valor Total da NF-e
+
+
+
+
+ Digest Value da NF-e processada. Utilizado para conferir a integridade da NF-e original
+
+
+
+
+ Data e hora de autorização da NF-e, no formato AAAA-MM-DDTHH:MM:SSTZD
+
+
+
+
+ Número do Protocolo de Status da NF-e. 1 posição (1 – Secretaria de Fazenda Estadual 2 – Receita Federal); 2 - códiga da UF - 2 posições ano; 10 seqüencial no ano
+
+
+
+
+
Situação da NF-e
1-Uso autorizado no momento da consulta;
2-Uso denegado;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tipo Versão do leiate resNFe
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Versão do leiate resNFe
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/retDistDFeInt_v1.01.xsd b/NFe.AppTeste/Schemas/retDistDFeInt_v1.01.xsd
index 3c4b8fce6..638e08c18 100644
--- a/NFe.AppTeste/Schemas/retDistDFeInt_v1.01.xsd
+++ b/NFe.AppTeste/Schemas/retDistDFeInt_v1.01.xsd
@@ -1,83 +1,82 @@
-
-
-
-
-
- Schema do resultado do pedido de distribuição de DF-e de interesse
-
-
-
-
-
-
+
+
+
+
+ Schema do resultado do pedido de distribuição de DF-e de interesse
+
+
+
+
+
+
Identificação do Ambiente:
1 - Produção
2 - Homologação
-
-
-
-
-
- Versão do Web Service NFeDistribuicaoDFe
-
-
-
-
- Código do status de processamento da requisição
-
-
-
-
- Descrição literal do status do processamento da requisição
-
-
-
-
- Data e Hora de processamento da requisição no formato AAAA-MM-DDTHH:MM:SSTZD
-
-
-
-
- Último NSU pesquisado no Ambiente Nacional. Se for o caso, o solicitante pode continuar a consulta a partir deste NSU para obter novos resultados.
-
-
-
-
- Maior NSU existente no Ambiente Nacional para o CNPJ/CPF informado
-
-
-
-
- Conjunto de informações resumidas e documentos fiscais eletrônicos de interesse da pessoa ou empresa.
-
-
-
-
-
- Informação resumida ou documento fiscal eletrônico de interesse da pessoa ou empresa. O conteúdo desta tag estará compactado no padrão gZip. O tipo do campo é base64Binary.
-
-
-
-
-
-
- NSU do documento fiscal
-
-
-
-
- Identificação do Schema XML que será utilizado para validar o XML existente no conteúdo da tag docZip. Vai identificar o tipo do documento e sua versão. Exemplos: resNFe_v1.00.xsd, procNFe_v3.10.xsd, resEvento_1.00.xsd, procEventoNFe_v1.00.xsd
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+
+ Versão do Web Service NFeDistribuicaoDFe
+
+
+
+
+ Código do status de processamento da requisição
+
+
+
+
+ Descrição literal do status do processamento da requisição
+
+
+
+
+ Data e Hora de processamento da requisição no formato AAAA-MM-DDTHH:MM:SSTZD
+
+
+
+
+ Último NSU pesquisado no Ambiente Nacional. Se for o caso, o solicitante pode continuar a consulta a partir deste NSU para obter novos resultados.
+
+
+
+
+ Maior NSU existente no Ambiente Nacional para o CNPJ/CPF informado
+
+
+
+
+ Conjunto de informações resumidas e documentos fiscais eletrônicos de interesse da pessoa ou empresa.
+
+
+
+
+
+ Informação resumida ou documento fiscal eletrônico de interesse da pessoa ou empresa. O conteúdo desta tag estará compactado no padrão gZip. O tipo do campo é base64Binary.
+
+
+
+
+
+
+ NSU do documento fiscal
+
+
+
+
+ Identificação do Schema XML que será utilizado para validar o XML existente no conteúdo da tag docZip. Vai identificar o tipo do documento e sua versão. Exemplos: resNFe_v1.00.xsd, procNFe_v3.10.xsd, resEvento_1.00.xsd, procEventoNFe_v1.00.xsd
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd b/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd
index 1f9c9904b..592056fcc 100644
--- a/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd
+++ b/NFe.AppTeste/Schemas/tiposBasico_v1.03.xsd
@@ -1,13 +1,4 @@
-
-
-
-
-
-
-
-
-
@@ -68,7 +59,7 @@
-
+
@@ -95,7 +86,8 @@
-
+
+
@@ -104,16 +96,16 @@
-
+
- Tipo Número do CNPJ tmanho varíavel (3-14)
+ Tipo Número do CNPJ
-
+
@@ -123,7 +115,7 @@
-
+
@@ -903,4 +895,13 @@ acrescentado:
+
+
+ Tipo que representa uma chave publica padrão RSA
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/tiposBasico_v1.03_OPENSSL.xsd b/NFe.AppTeste/Schemas/tiposBasico_v1.03_OPENSSL.xsd
index 851a822ba..dd9796056 100644
--- a/NFe.AppTeste/Schemas/tiposBasico_v1.03_OPENSSL.xsd
+++ b/NFe.AppTeste/Schemas/tiposBasico_v1.03_OPENSSL.xsd
@@ -59,7 +59,7 @@
-
+
@@ -95,7 +95,7 @@
-
+
@@ -104,7 +104,7 @@
-
+
@@ -114,7 +114,7 @@
-
+
@@ -813,4 +813,13 @@ acrescentado:
+
+
+ Tipo que representa uma chave publica padrão RSA
+
+
+
+
+
+
diff --git a/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd b/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd
index 4445319c9..5fe029e97 100644
--- a/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd
+++ b/NFe.AppTeste/Schemas/tiposBasico_v4.00.xsd
@@ -98,7 +98,7 @@
- Tipo Número do CNPJ tmanho varíavel (3-14)
+ Tipo Número do CNPJ
diff --git a/NFe.AppTeste/Schemas/tiposDistDFe_v1.01.xsd b/NFe.AppTeste/Schemas/tiposDistDFe_v1.01.xsd
index 8b0d8a135..12c0015f1 100644
--- a/NFe.AppTeste/Schemas/tiposDistDFe_v1.01.xsd
+++ b/NFe.AppTeste/Schemas/tiposDistDFe_v1.01.xsd
@@ -1,217 +1,216 @@
-
-
-
-
- Tipo número sequencial único
-
-
-
-
-
-
-
- Tipo quantidade de NSU
-
-
-
-
-
-
-
-
- Tipo Versão dos leiautes do Web Service NFeDistribuicaoDFe
-
-
-
-
-
-
-
-
- Tipo Ambiente
-
-
-
-
-
-
-
-
-
- Tipo Código da UF da tabela do IBGE
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tipo Código de orgão (UF da tabela do IBGE + 90 RFB)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Tipo Número do CNPJ
-
-
-
-
-
-
-
-
-
- Tipo Número do CPF
-
-
-
-
-
-
-
-
-
- Tipo Versão do Aplicativo
-
-
-
-
-
-
-
-
- Tipo Código da Mensagem enviada
-
-
-
-
-
-
-
-
-
- Tipo Motivo
-
-
-
-
-
-
-
-
- Tipo string genérico
-
-
-
-
-
-
-
-
- Tipo Chave da Nota Fiscal Eletrônica
-
-
-
-
-
-
-
-
-
- Tipo Número do Protocolo de Status
-
-
-
-
-
-
-
-
-
- Data e Hora, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD = +hh:mm ou -hh:mm)
-
-
-
-
-
-
-
-
- Tipo Inscrição Estadual do Emitente // alterado EM 24/10/08 para aceitar ISENTO
-
-
-
-
-
-
-
-
-
- Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais
-
-
-
-
-
-
-
\ No newline at end of file
+
+
+
+ Tipo número sequencial único
+
+
+
+
+
+
+
+ Tipo quantidade de NSU
+
+
+
+
+
+
+
+
+ Tipo Versão dos leiautes do Web Service NFeDistribuicaoDFe
+
+
+
+
+
+
+
+
+ Tipo Ambiente
+
+
+
+
+
+
+
+
+
+ Tipo Código da UF da tabela do IBGE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Código de orgão (UF da tabela do IBGE + 90 RFB)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Tipo Número do CNPJ
+
+
+
+
+
+
+
+
+
+ Tipo Número do CPF
+
+
+
+
+
+
+
+
+
+ Tipo Versão do Aplicativo
+
+
+
+
+
+
+
+
+ Tipo Código da Mensagem enviada
+
+
+
+
+
+
+
+
+
+ Tipo Motivo
+
+
+
+
+
+
+
+
+ Tipo string genérico
+
+
+
+
+
+
+
+
+ Tipo Chave da Nota Fiscal Eletrônica
+
+
+
+
+
+
+
+
+
+ Tipo Número do Protocolo de Status
+
+
+
+
+
+
+
+
+
+ Data e Hora, formato UTC (AAAA-MM-DDThh:mm:ssTZD, onde TZD = +hh:mm ou -hh:mm)
+
+
+
+
+
+
+
+
+ Tipo Inscrição Estadual do Emitente // alterado EM 24/10/08 para aceitar ISENTO
+
+
+
+
+
+
+
+
+
+ Tipo Decimal com 15 dígitos, sendo 13 de corpo e 2 decimais
+
+
+
+
+
+
+
diff --git a/NFe.Danfe.PdfClown/Elementos/Barcode128C.cs b/NFe.Danfe.PdfClown/Elementos/Barcode128C.cs
index 524688bad..6ab3d5132 100644
--- a/NFe.Danfe.PdfClown/Elementos/Barcode128C.cs
+++ b/NFe.Danfe.PdfClown/Elementos/Barcode128C.cs
@@ -1,6 +1,7 @@
using System.Drawing;
using System.Text.RegularExpressions;
using NFe.Danfe.PdfClown.Graphics;
+using NFe.Danfe.PdfClown.Tools;
namespace NFe.Danfe.PdfClown.Elementos
{
@@ -144,12 +145,13 @@ public Barcode128C(string code, Estilo estilo, float largura = 75F) : base(estil
throw new ArgumentException("O código não pode ser vazio.", "code");
}
- if (!Regex.IsMatch(code, @"^\d+$"))
+ // NT Conjunta 2025.001: a chave de acesso pode conter letras maiúsculas nas posições do CNPJ
+ if (!Regex.IsMatch(code, "^[0-9A-Z]+$"))
{
- throw new ArgumentException("O código deve apenas conter digítos numéricos.", "code");
+ throw new ArgumentException("O código deve apenas conter digítos numéricos e letras maiúsculas.", "code");
}
- if (code.Length % 2 != 0)
+ if (Regex.IsMatch(code, @"^\d+$") && code.Length % 2 != 0)
{
Code = "0" + code;
}
@@ -163,35 +165,14 @@ public Barcode128C(string code, Estilo estilo, float largura = 75F) : base(estil
private void DrawBarcode(RectangleF rect, Gfx gfx)
{
+ byte[] codeBytes = Code128Hibrido.ObterSimbolos(this.Code);
- List codeBytes = new List();
-
- codeBytes.Add(105);
-
- for (int i = 0; i < this.Code.Length; i += 2)
- {
- byte b = byte.Parse(this.Code.Substring(i, 2));
- codeBytes.Add(b);
- }
-
- // Calcular dígito verificador
- int cd = 105;
-
- for (int i = 1; i < codeBytes.Count; i++)
- {
- cd += i * codeBytes[i];
- cd %= 103;
- }
-
- codeBytes.Add((byte)cd);
- codeBytes.Add(106);
-
- float n = codeBytes.Count * 11 + 2;
+ float n = codeBytes.Length * 11 + 2;
float w = rect.Width / n;
float x = 0;
- for (int i = 0; i < codeBytes.Count; i++)
+ for (int i = 0; i < codeBytes.Length; i++)
{
byte[] pt = Barcode128C.Dic[codeBytes[i]];
diff --git a/NFe.Danfe.PdfClown/Tools/Code128Hibrido.cs b/NFe.Danfe.PdfClown/Tools/Code128Hibrido.cs
new file mode 100644
index 000000000..e48f23d6f
--- /dev/null
+++ b/NFe.Danfe.PdfClown/Tools/Code128Hibrido.cs
@@ -0,0 +1,149 @@
+using System.Text.RegularExpressions;
+
+namespace NFe.Danfe.PdfClown.Tools
+{
+ ///
+ /// Codificador CODE-128 híbrido (subconjuntos C e A) conforme a seção 6 da NT Conjunta 2025.001,
+ /// para o código de barras da chave de acesso com CNPJ alfanumérico.
+ /// Regras: inicia com Start C (105); alterna para o Code A (código 101) nos caracteres não numéricos;
+ /// retorna ao Code C (código 99) em corridas de 4 ou mais dígitos ou em corrida final com quantidade
+ /// par de dígitos; dígito ímpar remanescente antes de uma letra fica no Code A.
+ /// Conteúdo 100% numérico produz exatamente a sequência do CODE-128 C puro.
+ ///
+ public static class Code128Hibrido
+ {
+ private const byte StartC = 105;
+ private const byte TrocaParaCodeA = 101;
+ private const byte TrocaParaCodeC = 99;
+ private const byte Stop = 106;
+
+ ///
+ /// Obtém a sequência completa de símbolos CODE-128 (Start C, dados com as trocas de subconjunto,
+ /// dígito verificador módulo 103 e Stop) para um conteúdo composto por dígitos e letras maiúsculas.
+ ///
+ /// Conteúdo a codificar ([0-9A-Z]+), ex.: chave de acesso de 44 posições
+ /// Símbolos CODE-128, um valor (0-106) por posição
+ public static byte[] ObterSimbolos(string codigo)
+ {
+ if (string.IsNullOrEmpty(codigo))
+ throw new ArgumentException("O código não pode ser vazio.", nameof(codigo));
+
+ if (!Regex.IsMatch(codigo, "^[0-9A-Z]+$"))
+ throw new ArgumentException("O código deve conter somente dígitos (0-9) e letras maiúsculas (A-Z).", nameof(codigo));
+
+ var simbolos = new List { StartC };
+ var emCodeC = true;
+ var i = 0;
+
+ while (i < codigo.Length)
+ {
+ var corrida = TamanhoCorridaDeDigitos(codigo, i);
+
+ if (corrida == 0)
+ {
+ //caractere não numérico: garante o Code A e codifica a letra
+ if (emCodeC)
+ {
+ simbolos.Add(TrocaParaCodeA);
+ emCodeC = false;
+ }
+
+ simbolos.Add(ValorCodeA(codigo[i]));
+ i++;
+ continue;
+ }
+
+ var corridaFinal = i + corrida == codigo.Length;
+
+ if (emCodeC)
+ {
+ //em Code C codifica os dígitos aos pares; o dígito ímpar remanescente fica no Code A
+ for (var p = 0; p < corrida / 2; p++)
+ {
+ simbolos.Add(ValorCodeC(codigo, i));
+ i += 2;
+ }
+
+ if (corrida % 2 == 1)
+ {
+ simbolos.Add(TrocaParaCodeA);
+ emCodeC = false;
+ simbolos.Add(ValorCodeA(codigo[i]));
+ i++;
+ }
+ }
+ else if (corrida >= 4 || (corridaFinal && corrida % 2 == 0))
+ {
+ //retorna ao Code C para a parte com quantidade par de dígitos
+ if (corrida % 2 == 1 && corridaFinal)
+ {
+ //corrida final ímpar de 4+ dígitos: o primeiro dígito fica no Code A para a parte restante ser par
+ simbolos.Add(ValorCodeA(codigo[i]));
+ i++;
+ corrida--;
+ }
+
+ simbolos.Add(TrocaParaCodeC);
+ emCodeC = true;
+
+ for (var p = 0; p < corrida / 2; p++)
+ {
+ simbolos.Add(ValorCodeC(codigo, i));
+ i += 2;
+ }
+
+ //corrida ímpar antes de letra: o dígito remanescente é codificado no Code A na próxima iteração
+ }
+ else
+ {
+ //corrida curta (1 a 3 dígitos) que não justifica a troca: codifica os dígitos no próprio Code A
+ for (var d = 0; d < corrida; d++)
+ {
+ simbolos.Add(ValorCodeA(codigo[i]));
+ i++;
+ }
+ }
+ }
+
+ simbolos.Add(ObterDigitoVerificador(simbolos));
+ simbolos.Add(Stop);
+
+ return simbolos.ToArray();
+ }
+
+ ///
+ /// Dígito verificador módulo 103: soma ponderada dos símbolos, com o start valendo peso 1
+ /// e cada símbolo de dados o peso da sua posição
+ ///
+ private static byte ObterDigitoVerificador(List simbolos)
+ {
+ var soma = (int)simbolos[0];
+
+ for (var i = 1; i < simbolos.Count; i++)
+ soma += i * simbolos[i];
+
+ return (byte)(soma % 103);
+ }
+
+ private static int TamanhoCorridaDeDigitos(string codigo, int inicio)
+ {
+ var fim = inicio;
+
+ while (fim < codigo.Length && codigo[fim] >= '0' && codigo[fim] <= '9')
+ fim++;
+
+ return fim - inicio;
+ }
+
+ private static byte ValorCodeC(string codigo, int posicao)
+ {
+ return (byte)((codigo[posicao] - '0') * 10 + (codigo[posicao + 1] - '0'));
+ }
+
+ private static byte ValorCodeA(char caractere)
+ {
+ //no Code A os caracteres ASCII 32-95 valem ASCII - 32 ('0'-'9' => 16-25; 'A'-'Z' => 33-58)
+ return (byte)(caractere - 32);
+ }
+ }
+}
diff --git a/NFe.Danfe.PdfClown/Tools/Formatador.cs b/NFe.Danfe.PdfClown/Tools/Formatador.cs
index 20b01c532..4b1069b61 100644
--- a/NFe.Danfe.PdfClown/Tools/Formatador.cs
+++ b/NFe.Danfe.PdfClown/Tools/Formatador.cs
@@ -22,7 +22,8 @@ static Formatador()
public const string FormatoNumeroNF = @"000\.000\.000";
public const string CEP = @"^(\d{5})\-?(\d{3})$";
- public const string CNPJ = @"^(\d{2})\.?(\d{3})\.?(\d{3})\/?(\d{4})\-?(\d{2})$";
+ //NT Conjunta 2025.001: CNPJ alfanumérico - 12 posições [A-Z0-9] e 2 dígitos verificadores numéricos, com a mesma máscara posicional
+ public const string CNPJ = @"^([A-Z\d]{2})\.?([A-Z\d]{3})\.?([A-Z\d]{3})\/?([A-Z\d]{4})\-?(\d{2})$";
public const string CPF = @"^(\d{3})\.?(\d{3})\.?(\d{3})\-?(\d{2})$";
public const string Telefone = @"^\(?(\d{2})\)?\s*(\d{4,5})\s*\-?\s*(\d{4})$";
diff --git a/NFe.Utils.Testes/ExtinfNFeSuplChaveAlfanumericaTestes.cs b/NFe.Utils.Testes/ExtinfNFeSuplChaveAlfanumericaTestes.cs
new file mode 100644
index 000000000..f4b3fda9e
--- /dev/null
+++ b/NFe.Utils.Testes/ExtinfNFeSuplChaveAlfanumericaTestes.cs
@@ -0,0 +1,82 @@
+using System;
+using DFe.Classes.Entidades;
+using DFe.Classes.Flags;
+using NFe.Classes;
+using NFe.Classes.Informacoes;
+using NFe.Classes.Informacoes.Identificacao;
+using NFe.Classes.Informacoes.Identificacao.Tipos;
+using NFe.Classes.Informacoes.Total;
+using NFe.Utils.InformacoesSuplementares;
+using Xunit;
+
+namespace NFe.Utils.Testes
+{
+ ///
+ /// Testes do QR-Code da NFC-e com chave de acesso contendo CNPJ alfanumérico (NT Conjunta 2025.001)
+ ///
+ public class ExtinfNFeSuplChaveAlfanumericaTestes
+ {
+ //NFC-e de GO com o CNPJ alfanumérico de teste da Receita (PC3D315K000193); DV da chave = 0
+ private const string ChaveAlfanumerica = "522507PC3D315K000193650010000000011000000010";
+
+ private static Classes.NFe CriarNfce(string chave)
+ {
+ return new Classes.NFe
+ {
+ infNFe = new infNFe
+ {
+ Id = "NFe" + chave,
+ versao = "4.00",
+ ide = new ide
+ {
+ tpAmb = TipoAmbiente.Homologacao,
+ cUF = Estado.GO,
+ tpEmis = TipoEmissao.teNormal,
+ dhEmi = new DateTimeOffset(2025, 7, 15, 10, 0, 0, TimeSpan.FromHours(-3))
+ },
+ total = new total
+ {
+ ICMSTot = new ICMSTot { vNF = 10.50m }
+ }
+ }
+ };
+ }
+
+ [Fact]
+ public void ObterUrlQrCode2_ComChaveAlfanumerica_MontaAUrlComAChaveSemConversaoNumerica()
+ {
+ // Arrange
+ var nfce = CriarNfce(ChaveAlfanumerica);
+
+ // Act
+ var url = new infNFeSupl().ObterUrlQrCode(nfce, VersaoQrCode.QrCodeVersao2, "000001", "CSC-DE-TESTE");
+
+ // Assert
+ Assert.Contains(ChaveAlfanumerica, url);
+
+ //formato dos parâmetros: chave|versão do QR-Code|ambiente|idCsc|hash SHA-1
+ var parametros = url.Substring(url.IndexOf("p=", StringComparison.Ordinal) + 2).Split('|');
+ Assert.Equal(5, parametros.Length);
+ Assert.Equal(ChaveAlfanumerica, parametros[0]);
+ Assert.Equal("2", parametros[1]);
+ Assert.Equal("2", parametros[2]);
+ Assert.Equal("1", parametros[3]);
+ Assert.Equal(40, parametros[4].Trim().Length);
+ }
+
+ [Fact]
+ public void ObterUrlQrCode2_ComChaveNumerica_MantemComportamentoAntigo()
+ {
+ // Arrange
+ var nfce = CriarNfce("23190811820016000167650010000000221100000227");
+
+ // Act
+ var url = new infNFeSupl().ObterUrlQrCode(nfce, VersaoQrCode.QrCodeVersao2, "000001", "CSC-DE-TESTE");
+
+ // Assert
+ var parametros = url.Substring(url.IndexOf("p=", StringComparison.Ordinal) + 2).Split('|');
+ Assert.Equal("23190811820016000167650010000000221100000227", parametros[0]);
+ Assert.Equal(40, parametros[4].Trim().Length);
+ }
+ }
+}