diff --git a/OldComplianceNFs.csproj b/OldComplianceNFs.csproj new file mode 100644 index 0000000..c86b8fa --- /dev/null +++ b/OldComplianceNFs.csproj @@ -0,0 +1,29 @@ + + + + Exe + net9.0-windows + enable + enable + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/OldComplianceNFs.sln b/OldComplianceNFs.sln new file mode 100644 index 0000000..03ace6e --- /dev/null +++ b/OldComplianceNFs.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35527.113 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OldComplianceNFs", "OldComplianceNFs.csproj", "{6497B886-8A32-4965-8CA0-3A241B98B81A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {6497B886-8A32-4965-8CA0-3A241B98B81A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6497B886-8A32-4965-8CA0-3A241B98B81A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6497B886-8A32-4965-8CA0-3A241B98B81A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6497B886-8A32-4965-8CA0-3A241B98B81A}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..8708bcf --- /dev/null +++ b/Program.cs @@ -0,0 +1,202 @@ +using System.Data; +using System.Data.OleDb; +using System.Text; +using System.Xml.Linq; +using static System.Net.Mime.MediaTypeNames; + +class Program +{ + static readonly DataTable dados = new(); + static void ObterDadosAccess(string connectionString, string query) + { + using OleDbConnection connection = new(connectionString); + OleDbCommand command = new(query, connection); + connection.Open(); + var reader = command.ExecuteReader(); + + dados.Load(reader); + + //reader.Close(); + //command.Dispose(); + //connection.Close(); + } + static async Task Main() + { + string pasta = @"X:\Back\Controle NFs\NFs"; + var arquivosXML = Directory.GetFiles(pasta, "*.xml"); + var arquivosPDF = Directory.GetFiles(pasta, "*.pdf"); + var arquivos = arquivosXML.Concat(arquivosPDF); + var tarefas = new List>(); + + // Obter dados do banco de dados Access + string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=X:/Middle/Informativo Setorial/Modelo Word/BD1_dados cadastrais e faturas.accdb;Jet OLEDB:Database Password=gds21"; + string query = "SELECT * FROM Dados_TE LEFT JOIN Dados_Cadastrais ON Dados_TE.Cod_smart_unidade = Dados_Cadastrais.Cod_smart_unidade"; + ObterDadosAccess(connectionString, query); + + // Processar arquivosXML em paralelo + foreach (string arquivo in arquivos) + { + tarefas.Add(ProcessarXMLAsync(arquivo)); + } + + var linhas = await Task.WhenAll(tarefas); + + // Gerar CSV + StringBuilder csv = new(); + + foreach (string linha in linhas) + { + csv.AppendLine(linha); + } + + //StringBuilder csv = new(); + + //foreach (string arquivo in arquivos) + //{ + // csv.AppendLine(await ProcessarXMLAsync(arquivo)); + //} + + // Escrever CSV no StdOut (VBA vai capturar) + //Console.OutputEncoding = Encoding.UTF8; + Console.Write(csv.ToString()); + //dados.Dispose(); + } + static string ProcessarArquivo(string caminhoArquivo) + { + string nomeArquivo = Path.GetFileName(caminhoArquivo); + string tipoArquivo = Path.GetExtension(caminhoArquivo).TrimStart('.'); + string referencia = nomeArquivo.Split(" - ").FirstOrDefault() ?? ""; + + // Formatar como CSV (com proteção contra vírgulas) + return $"\"{caminhoArquivo}\";\"{nomeArquivo}\";\"{tipoArquivo}\";\"{referencia}\""; + } + static async Task ProcessarXMLAsync(string caminhoArquivo) + { + string? CNPJ_Comprador = ""; + string? CNPJ_Vendedor = ""; + float? Montante_operação = null; + float? Valor_unitário = null; + float? Valor_final_c_impostos = null; + string? RS_Comprador = ""; + string? RS_Vendedor = ""; + int? Numero_NF = null; + float? ICMS_NF = null; + string? UF_NF = ""; + string? UF_Vend = ""; + string? Cod_TE = ""; + + if (Path.GetExtension(caminhoArquivo).Equals(".xml", StringComparison.CurrentCultureIgnoreCase)) + { + if (caminhoArquivo == "X:\\Back\\Controle NFs\\NFs\\581556552,910625 - NFE31250317155730000164550010000669361412505682.XML") { ICMS_NF = 0; } + XDocument xml = XDocument.Load(caminhoArquivo); + XNamespace ns = "http://www.portalfiscal.inf.br/nfe"; // Namespace do XML + + CNPJ_Comprador = xml.Descendants(ns + "dest").Elements(ns + "CNPJ").FirstOrDefault()?.Value ?? xml.Descendants(ns + "dest").Elements(ns + "CPF").FirstOrDefault()?.Value; + CNPJ_Comprador = Convert.ToInt64(CNPJ_Comprador).ToString(@"00000000000000"); + + CNPJ_Vendedor = xml.Descendants(ns + "emit").Elements(ns + "CNPJ").FirstOrDefault()?.Value; + CNPJ_Vendedor = Convert.ToInt64(CNPJ_Vendedor).ToString(@"00000000000000"); + + RS_Comprador = xml.Descendants(ns + "dest").Elements(ns + "xNome").FirstOrDefault()?.Value; + RS_Vendedor = xml.Descendants(ns + "emit").Elements(ns + "xNome").FirstOrDefault()?.Value; + + float soma1 = xml.Descendants(ns + "prod").Sum(prod => (float?)prod.Element(ns + "qCom") ?? 0); + float soma2 = xml.Descendants(ns + "prod").Sum(prod => ((float?)prod.Element(ns + "qCom") ?? 0) * ((float?)prod.Element(ns + "vUnCom") ?? 0)); + + if (CNPJ_Vendedor == "06981176000158" || CNPJ_Vendedor == "06981176002100" || CNPJ_Vendedor == "17155730000164") + { + soma1 /= 1000; + } + + Montante_operação = soma1; + if (soma1 != 0) + { + Valor_unitário = soma2 / soma1; + } + else + { + Valor_unitário = 0; + } + + Valor_final_c_impostos = float.TryParse(xml.Descendants(ns + "pag").Elements(ns + "detPag").Elements(ns + "vPag").FirstOrDefault()?.Value.Replace(".",","), out float valor) ? valor : 0; + + if (Valor_final_c_impostos == 0) + { + Valor_final_c_impostos = float.TryParse(xml.Descendants(ns + "cobr").Elements(ns + "fat").Elements(ns + "vLiq").FirstOrDefault()?.Value.Replace(".", ","), out float valor2) ? valor2 : 0; + } + + Numero_NF = int.Parse(xml.Descendants(ns + "ide").Elements(ns + "nNF").FirstOrDefault()?.Value ?? "0"); + + ICMS_NF = (float.TryParse(xml.Descendants(ns + "imposto").Elements(ns + "ICMS").Elements(ns + "ICMS00").Elements(ns + "pICMS").FirstOrDefault()?.Value.Replace(".", ","), out float valor1) ? valor1 : 0)/100; + + if (ICMS_NF == 0 && Valor_final_c_impostos != 0) { + ICMS_NF = 1 - (soma2 / Valor_final_c_impostos); + } + + UF_NF = xml.Descendants(ns + "dest").Elements(ns + "enderDest").Elements(ns + "UF").FirstOrDefault()?.Value; + UF_Vend = xml.Descendants(ns + "emit").Elements(ns + "enderEmit").Elements(ns + "UF").FirstOrDefault()?.Value; + + if (UF_NF == "SP" && UF_Vend == "SP") + { + Valor_unitário *= (1 - ICMS_NF); + } + + Cod_TE = Id_operacao(CNPJ_Comprador, CNPJ_Vendedor, Montante_operação ?? 0, Valor_unitário ?? 0, Valor_final_c_impostos ?? 0); + } + return await Task.Run(() => + { + // Formatar como CSV (com proteção contra vírgulas) + return $"{ProcessarArquivo(caminhoArquivo)};\"{ + CNPJ_Comprador}\";\"{ + CNPJ_Vendedor}\";\"{ + Montante_operação.ToString()?.Replace(',','.')}\";\"{ + Valor_unitário.ToString()?.Replace(',', '.')}\";\"{ + Valor_final_c_impostos.ToString()?.Replace(',','.')}\";\"{ + RS_Comprador}\";\"{ + RS_Vendedor}\";\"{ + Numero_NF}\";\"{ + ICMS_NF.ToString()?.Replace(',','.')}\";\"{ + UF_NF}\""; + //Cod_TE}\""; + + }); + } + static string Id_operacao(string CNPJ_Comprador, string CNPJ_Vendedor, float Montante_operação, float Valor_unitário, float Valor_final_c_impostos) + { + float tolerancia_montante = 0.01f; + float tolerancia_valor_unitario = 0.005f; + float tolerancia_valor_final = 0.01f; + + try + { + var selecao = dados.Select($"CNPJ_comp = {CNPJ_Comprador} AND CNPJ_vend = {CNPJ_Vendedor}", $"Mes DESC"); + + foreach (var row in selecao) + { + double mont_LO = row.Field("Mont_LO"); + double prec_LO = row.Field("Prec_LO"); + double NF_c_ICMS = row.Field("NF_c_ICMS"); + + bool montDentroDaTolerancia = Math.Abs(mont_LO - Montante_operação) / Montante_operação < tolerancia_montante; + bool unitDentroDaTolerancia = Math.Abs(prec_LO - Valor_unitário) / Valor_unitário < tolerancia_valor_unitario; + bool valorDentroDaTolerancia = Math.Abs(NF_c_ICMS - Valor_final_c_impostos) / Valor_final_c_impostos < tolerancia_valor_final; + + if (montDentroDaTolerancia && unitDentroDaTolerancia) + { + return row.Field("Cod_TE")!; + } + else if (valorDentroDaTolerancia) + { + return row.Field("Cod_TE")!; + } + } + } + catch (Exception) + { + return "NAO IDENTIFICADA"; + } + + return "NAO IDENTIFICADA"; + + } +} diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..14a874a --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// O código foi gerado por uma ferramenta. +// Versão de Tempo de Execução:4.0.30319.42000 +// +// As alterações ao arquivo poderão causar comportamento incorreto e serão perdidas se +// o código for gerado novamente. +// +//------------------------------------------------------------------------------ + +namespace OldComplianceNFs.Properties { + using System; + + + /// + /// Uma classe de recurso de tipo de alta segurança, para pesquisar cadeias de caracteres localizadas etc. + /// + // Essa classe foi gerada automaticamente pela classe StronglyTypedResourceBuilder + // através de uma ferramenta como ResGen ou Visual Studio. + // Para adicionar ou remover um associado, edite o arquivo .ResX e execute ResGen novamente + // com a opção /str, ou recrie o projeto do VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Retorna a instância de ResourceManager armazenada em cache usada por essa classe. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("OldComplianceNFs.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Substitui a propriedade CurrentUICulture do thread atual para todas as + /// pesquisas de recursos que usam essa classe de recurso de tipo de alta segurança. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..4fdb1b6 --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file