From ebfa907ad1781961c901c42e564004cca38d0f61 Mon Sep 17 00:00:00 2001 From: joaovictorjs Date: Tue, 24 Mar 2026 09:31:14 -0300 Subject: [PATCH 1/4] feat: adiciona suporte a caracteres alfanumericos --- DFe.Utils/ChaveFiscal.cs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/DFe.Utils/ChaveFiscal.cs b/DFe.Utils/ChaveFiscal.cs index 779a366a0..9a47f0385 100644 --- a/DFe.Utils/ChaveFiscal.cs +++ b/DFe.Utils/ChaveFiscal.cs @@ -95,8 +95,8 @@ 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()); - soma += ch*peso; + var valorCaractere = ObterValorDoCaractere(chave[i]); + soma += valorCaractere * peso; //sempre que for 9 voltamos o peso a 2 if (peso < 9) peso += 1; @@ -115,6 +115,18 @@ private static string ObterDigitoVerificador(string chave) return dv.ToString(); } + /// + /// Obtem o valor de um caractere + /// + /// + /// + private static int ObterValorDoCaractere(char caractere) + { + const int zeroASCII = 48; + var valor = caractere - zeroASCII; + return valor; + } + /// /// Informa se a chave de um DF-e é válida /// From 1f4e1f6f04ea0c42c808e1bfc1145145e7ec84e4 Mon Sep 17 00:00:00 2001 From: joaovictorjs Date: Tue, 24 Mar 2026 16:44:37 -0300 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20adiciona=20suporte=20ao=20CNPJ=20al?= =?UTF-8?q?fanum=C3=A9rico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NFe.Classes/Informacoes/Emitente/emit.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NFe.Classes/Informacoes/Emitente/emit.cs b/NFe.Classes/Informacoes/Emitente/emit.cs index 2b94d7ac0..238d8f5c4 100644 --- a/NFe.Classes/Informacoes/Emitente/emit.cs +++ b/NFe.Classes/Informacoes/Emitente/emit.cs @@ -52,7 +52,7 @@ public string CNPJ { if (string.IsNullOrEmpty(value)) return; if (string.IsNullOrEmpty(_cpf)) - _cnpj = Regex.Match(value, @"\d+").Value; + _cnpj = Regex.Match(value, @"[0-9A-Z]+").Value; else { From d3dcfc7844d3e0922d61b8b82b6dc70d802b8483 Mon Sep 17 00:00:00 2001 From: joaovictorjs Date: Tue, 24 Mar 2026 20:36:41 -0300 Subject: [PATCH 3/4] test: cria testes para ObterChave e ObterValorDoCaractere --- DFe.Utils/ChaveFiscal.cs | 2 +- DFe.Utils/Properties/AssemblyInfo.cs | 3 ++ NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs | 43 +++++++++++++++++ .../Dados/ChaveFiscalDadosDeTeste.cs | 47 +++++++++++++++++++ NFe.Utils.Testes/NFe.Utils.Testes.csproj | 1 + 5 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 DFe.Utils/Properties/AssemblyInfo.cs create mode 100644 NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs create mode 100644 NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs diff --git a/DFe.Utils/ChaveFiscal.cs b/DFe.Utils/ChaveFiscal.cs index 9a47f0385..30c7ed088 100644 --- a/DFe.Utils/ChaveFiscal.cs +++ b/DFe.Utils/ChaveFiscal.cs @@ -120,7 +120,7 @@ private static string ObterDigitoVerificador(string chave) /// /// /// - private static int ObterValorDoCaractere(char caractere) + internal static int ObterValorDoCaractere(char caractere) { const int zeroASCII = 48; var valor = caractere - zeroASCII; diff --git a/DFe.Utils/Properties/AssemblyInfo.cs b/DFe.Utils/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..9d397211c --- /dev/null +++ b/DFe.Utils/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("NFe.Utils.Testes")] diff --git a/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs b/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs new file mode 100644 index 000000000..3cd8914ad --- /dev/null +++ b/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs @@ -0,0 +1,43 @@ +using System; +using DFe.Utils; +using DFe.Classes.Entidades; +using DFe.Classes.Flags; +using NFe.Utils.Testes.Dados; +using Xunit; + +namespace NFe.Utils.Testes; + +public class ChaveFiscalTesteUnitario +{ + [Theory(DisplayName = "Dado cnpj alfanumérico, quando obter chave fiscal, então não deve lançar exceção.")] + [InlineData("T6J3XFX0IVDD47")] + [InlineData("t6j3xfx0ivdd47")] + public void DadoCnpjAlfanumericoQuandoObterChaveFiscalEntaoNaoDeveLancarExcecao(string cnpj) + { + // Arrange + var estado = Estado.SE; + var data = DateTime.Now; + var modelo = ModeloDocumento.NFe; + var serie = 100; + var numero = 12345; + var tipoEmissao = 1; + var cNf = 12345678; + + // Act + var excecaoCapturada = Record.Exception(() => ChaveFiscal.ObterChave(estado, data, cnpj, modelo, serie, numero, tipoEmissao, cNf)); + + // Assert + Assert.Null(excecaoCapturada); + } + + [Theory(DisplayName = "Dado caractere, quando obter valor do caractere, então deve retornar o valor esperado.")] + [MemberData(nameof(ChaveFiscalDadosDeTeste.ObterCaracteresEValores), MemberType = typeof(ChaveFiscalDadosDeTeste))] + public void DadoCaractereQuandoObterValorEntaoDeveRetornarValorEsperado(char caractere, int valorEsperado) + { + // Act + var valorObtido = ChaveFiscal.ObterValorDoCaractere(caractere); + + // Assert + Assert.Equal(valorEsperado, valorObtido); + } +} diff --git a/NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs b/NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs new file mode 100644 index 000000000..7bf54ebe1 --- /dev/null +++ b/NFe.Utils.Testes/Dados/ChaveFiscalDadosDeTeste.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; + +namespace NFe.Utils.Testes.Dados; + +public static class ChaveFiscalDadosDeTeste +{ + public static IEnumerable ObterCaracteresEValores() + { + yield return new object[] { '0', 0 }; + yield return new object[] { '1', 1 }; + yield return new object[] { '2', 2 }; + yield return new object[] { '3', 3 }; + yield return new object[] { '4', 4 }; + yield return new object[] { '5', 5 }; + yield return new object[] { '6', 6 }; + yield return new object[] { '7', 7 }; + yield return new object[] { '8', 8 }; + yield return new object[] { '9', 9 }; + + yield return new object[] { 'A', 17 }; + yield return new object[] { 'B', 18 }; + yield return new object[] { 'C', 19 }; + yield return new object[] { 'D', 20 }; + yield return new object[] { 'E', 21 }; + yield return new object[] { 'F', 22 }; + yield return new object[] { 'G', 23 }; + yield return new object[] { 'H', 24 }; + yield return new object[] { 'I', 25 }; + yield return new object[] { 'J', 26 }; + yield return new object[] { 'K', 27 }; + yield return new object[] { 'L', 28 }; + yield return new object[] { 'M', 29 }; + yield return new object[] { 'N', 30 }; + yield return new object[] { 'O', 31 }; + yield return new object[] { 'P', 32 }; + yield return new object[] { 'Q', 33 }; + yield return new object[] { 'R', 34 }; + yield return new object[] { 'S', 35 }; + yield return new object[] { 'T', 36 }; + yield return new object[] { 'U', 37 }; + yield return new object[] { 'V', 38 }; + yield return new object[] { 'W', 39 }; + yield return new object[] { 'X', 40 }; + yield return new object[] { 'Y', 41 }; + yield return new object[] { 'Z', 42 }; + } +} diff --git a/NFe.Utils.Testes/NFe.Utils.Testes.csproj b/NFe.Utils.Testes/NFe.Utils.Testes.csproj index c84a94097..d0365598d 100644 --- a/NFe.Utils.Testes/NFe.Utils.Testes.csproj +++ b/NFe.Utils.Testes/NFe.Utils.Testes.csproj @@ -19,6 +19,7 @@ + From 1fd0a72278e8c3a86f336ba5bbc7a2e0c5e94579 Mon Sep 17 00:00:00 2001 From: joaovictorjs Date: Wed, 25 Mar 2026 08:48:34 -0300 Subject: [PATCH 4/4] =?UTF-8?q?test:=20remove=20caso=20com=20cnpj=20alfanu?= =?UTF-8?q?m=C3=A9rico=20min=C3=BAsculo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs b/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs index 3cd8914ad..7d17f9955 100644 --- a/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs +++ b/NFe.Utils.Testes/ChaveFiscalTesteUnitario.cs @@ -11,7 +11,7 @@ public class ChaveFiscalTesteUnitario { [Theory(DisplayName = "Dado cnpj alfanumérico, quando obter chave fiscal, então não deve lançar exceção.")] [InlineData("T6J3XFX0IVDD47")] - [InlineData("t6j3xfx0ivdd47")] + [InlineData("W2MNK0KZ000190")] public void DadoCnpjAlfanumericoQuandoObterChaveFiscalEntaoNaoDeveLancarExcecao(string cnpj) { // Arrange