using System.Reflection; using System.Text; using Unimake.Business.DFe.Xml.NFe; using System.Data; using Emit = Unimake.Business.DFe.Xml.NFe.Emit; using System.Xml; using Unimake.Business.DFe.Validator.NFe; class Program { static readonly string agora = DateTime.Now.AddMonths(-1).ToString("yyMM"); static async Task Main() { string pasta = @"X:\Back\Controle NFs\NFs"; List arquivosXML = Directory.GetFiles(pasta, "*.Xml").Select(x => new Arquivo(x)).Where(y => y.processar).ToList(); foreach (var pdf in Directory.GetFiles(pasta, "*.pdf")) { if (arquivosXML.Any(x => x.Referencia == Path.GetFileName(pdf).Split(" - ").First())) { arquivosXML.First(x => x.Referencia == Path.GetFileName(pdf).Split(" - ").First())?.CaminhoPdf.Add(pdf); } } var arquivos = arquivosXML.OrderBy(x => x.DataDeCriacao); var tarefas = new List>(); var linhas = new List(); //Processar arquivosXML em paralelo foreach (var arquivo in arquivos) { tarefas.Add(ProcessarXMLAsync(arquivo)); //linhas.Add(await ProcessarXMLAsync(arquivo)); } linhas.AddRange(await Task.WhenAll(tarefas)); // Gerar CSV StringBuilder csv = new(); foreach (string linha in linhas) { csv.AppendLine(linha); } // Escrever CSV no StdOut (VBA vai capturar) Console.OutputEncoding = Encoding.Latin1; Console.Write(csv.ToString()); //dados.Dispose(); } public class Arquivo { public string CaminhoArquivo { get; set; } public List CaminhoPdf { get; set; } = []; public string NomeArquivo { get; set; } public string TipoArquivo { get; set; } public string Referencia { get; set; } public DateTime DataDeCriacao { get; } public NF NF; public bool processar = true; public Arquivo(string caminhoArquivo) { //Console.WriteLine($"Lendo {caminhoArquivo}"); if (caminhoArquivo == "X:\\Back\\Controle NFs\\NFs\\173420 - DANFE 000173420 (1).xml") { Thread.Sleep(10); // Simula atraso para testes } CaminhoArquivo = caminhoArquivo; NomeArquivo = Path.GetFileName(caminhoArquivo); TipoArquivo = Path.GetExtension(caminhoArquivo).TrimStart('.'); Referencia = NomeArquivo.Split(" - ").FirstOrDefault() ?? ""; DataDeCriacao = File.GetCreationTime(caminhoArquivo); if (TipoArquivo.Equals("xml", StringComparison.CurrentCultureIgnoreCase)) { try { NF = new NF(caminhoArquivo); } catch { processar = false; } } } } static async Task ProcessarXMLAsync(Arquivo arquivo) { NFresponse response = new(); string status = ""; try { if (arquivo.TipoArquivo.Equals("xml", StringComparison.CurrentCultureIgnoreCase)) { //if (arquivo == @"X:\Back\Controle NFs\NFs\345425911,145611 - NFe35250603984862000194550010001466521382788552-procNFe.xml") //{ // Thread.Sleep(1000); //} NF Current_NF = new(arquivo.CaminhoArquivo); InfNFe infNFe = new NfeProc().LoadFromFile(arquivo.CaminhoArquivo).NFe.InfNFe.First(); Dest Comprador = infNFe.Dest; Emit Vendedor = infNFe.Emit; List Produtos = infNFe.Det; float soma1 = Produtos.Sum(prod => (float?)prod.Prod.QCom ?? 0); decimal soma2 = Produtos.Sum(prod => ( ( prod.Prod.UCom == "KWH" ? prod.Prod.QCom / 1000M : prod.Prod.QCom ) ) * ( ( prod.Prod.UCom == "KWH" ? prod.Prod.VUnCom * 1000M : prod.Prod.VUnCom ) )); if (Current_NF.CNPJ_Vendedor == "06981176000158" || Current_NF.CNPJ_Vendedor == "06981176002100" || Current_NF.CNPJ_Vendedor == "17155730000164") { soma1 /= 1000; } if (soma1 != 0) { decimal Valor_unitário = soma2 / (decimal)soma1; } response.CNPJ_Comprador = Current_NF.CNPJ_Comprador; response.CNPJ_Vendedor = Current_NF.CNPJ_Vendedor; response.Montante_operação = Current_NF.Montante_operação; response.Valor_unitário = Current_NF.Valor_unitário; response.Valor_final_c_impostos = Current_NF.Valor_final_c_impostos; response.RS_Comprador = Current_NF.RS_Comprador ?? ""; response.RS_Vendedor = Current_NF.RS_Vendedor ?? ""; response.Numero_NF = Current_NF.Numero_NF ?? 0; response.ICMS_NF = Current_NF.ICMS_NF; status = Current_NF.UF_NF ?? ""; response.Month = Current_NF.Month ?? agora; } } catch (Exception) { status = "XML vazio"; } return await Task.Run(() => { return $"\"{arquivo.CaminhoArquivo}\";\"{arquivo.NomeArquivo}\";\"{arquivo.TipoArquivo}\";\"{arquivo.Referencia}\";\"{response.CNPJ_Comprador}\";\"{response.CNPJ_Vendedor}\";\"{response.Montante_operação.ToString()?.Replace(',', '.')}\";\"{response.Valor_unitário.ToString()?.Replace(',', '.')}\";\"{response.Valor_final_c_impostos.ToString()?.Replace(',', '.')}\";\"{response.RS_Comprador}\";\"{response.RS_Vendedor}\";\"{response.Numero_NF}\";\"{response.ICMS_NF.ToString()?.Replace(',', '.')}\";\"{status}\";\"{arquivo.CaminhoPdf.Join("***")}\";\"{response.Month}\""; }); } public static double GetICMS(ICMS icms) { var propICMS = icms.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) // Opcional: filtrar apenas pelas que começam com "ICMS" .Where(p => p.Name.StartsWith("ICMS")) .ToList(); var primeiraProp = propICMS .Select(p => new { Prop = p, Valor = p.GetValue(icms) }) .FirstOrDefault(x => x.Valor != null); if (primeiraProp == null) { return 0; } if (primeiraProp.Valor == null) { return 0; } var tipo = primeiraProp.Valor.GetType(); var valor = Convert.ChangeType(primeiraProp.Valor, tipo); var ListICMSReal = valor.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(p => p.Name.StartsWith("PICMS")) .Select(p => p.GetValue(valor)) .FirstOrDefault(); double ICMSReal = 0; if (ListICMSReal != null && double.TryParse(ListICMSReal.ToString(), out ICMSReal)) { ICMSReal /= 100d; // Convert percentage to decimal } return ICMSReal; } public class NFresponse { public string CNPJ_Comprador { get; set; } = ""; public string CNPJ_Vendedor { get; set; } = ""; public decimal Montante_operação { get; set; } = 0; public decimal Valor_unitário { get; set; } = 0; public double Valor_final_c_impostos { get; set; } = 0; public string RS_Comprador { get; set; } = ""; public string RS_Vendedor { get; set; } = ""; public int Numero_NF { get; set; } = 0; public double ICMS_NF { get; set; } = 0; public string Month { get; set; } = ""; } public class NF { public NF(string caminhoArquivo) { nfeProc = new NfeProc().LoadFromFile(caminhoArquivo); nfe = nfeProc.NFe; infNFe = nfe.InfNFe.FirstOrDefault() ?? throw new InvalidOperationException("InfNFe is null or empty."); Comprador = infNFe.Dest; Vendedor = infNFe.Emit; Detalhes = infNFe.Det.First(); Produtos = infNFe.Det; Impostos = Detalhes.Imposto; NomeArquivo = Path.GetFileName(caminhoArquivo); TipoArquivo = Path.GetExtension(caminhoArquivo).TrimStart('.'); Referencia = NF.NomeArquivo.Split(" - ").FirstOrDefault() ?? ""; CNPJ_Comprador = Convert.ToInt64(Comprador.CNPJ ?? Comprador.CPF).ToString(@"00000000000000"); CNPJ_Vendedor = Convert.ToInt64(Vendedor.CNPJ).ToString(@"00000000000000"); Soma2 = Produtos.Sum(prod => ( ( prod.Prod.UCom == "KWH" ? prod.Prod.QCom / 1000M : prod.Prod.QCom ) ) * ( ( prod.Prod.UCom == "KWH" ? prod.Prod.VUnCom * 1000M : prod.Prod.VUnCom ) )); Montante_operação = Produtos.Sum(prod => ( prod.Prod.UCom == "KWH" ? prod.Prod.QCom / 1000M : prod.Prod.QCom ) ); Valor_unitário = ( Comprador.EnderDest.UF.ToString() == "SP" && Vendedor.EnderEmit.UF.ToString() == "SP" ) ? ( Montante_operação == 0 ? 0 : (Soma2 / Montante_operação) * (1 - (decimal)ICMS_NF)) : ( Montante_operação == 0 ? 0 : (Soma2 / Montante_operação) ); Valor_final_c_impostos = (infNFe.Pag.DetPag.Sum(pag => (pag.VPag)) != 0 ? infNFe.Pag.DetPag.Sum(pag => (pag.VPag)) : ((infNFe.Cobr == null ? infNFe.Total.ICMSTot.VNF : infNFe.Cobr.Fat.VLiq))); RS_Comprador = Comprador.XNome.Replace("&", "&").Replace("&", "&"); RS_Vendedor = Vendedor.XNome.Replace("&", "&").Replace("&", "&"); Numero_NF = infNFe.Ide.NNF; ICMS_NF = (GetICMS(Impostos.ICMS) == 0 && Valor_final_c_impostos != 0) ? 1 - ((double)Soma2 / Valor_final_c_impostos) : GetICMS(Impostos.ICMS); UF_NF = Comprador.EnderDest.UF.ToString(); UF_Vend = Vendedor.EnderEmit.UF.ToString(); Month = infNFe.Ide.DhEmi.AddMonths(-1).ToString("yyMM"); } static NfeProc nfeProc; static NFe nfe; static InfNFe infNFe; static Dest Comprador; static Emit Vendedor; static Det Detalhes; static List Produtos; static Imposto Impostos; public static string NomeArquivo; public static string? TipoArquivo; public string? Referencia; public string CNPJ_Comprador; public string CNPJ_Vendedor; public decimal Soma2; public decimal Montante_operação; public decimal Valor_unitário; public double Valor_final_c_impostos; public string? RS_Comprador; public string? RS_Vendedor; public int? Numero_NF; public double ICMS_NF; public string? UF_NF; public string? UF_Vend; public string? Month; } }