namespace Download_Faturas { using System.Data.OleDb; using System.Globalization; using System.Net.Http.Headers; using System.Reflection; using System.Reflection.Metadata.Ecma335; using System.Runtime.Intrinsics.X86; using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using iText.Kernel.Pdf; using iText.Kernel.Utils; public class Fatura { private const string Token = "UFY4VWzqcHYcGNd0gkBOMFL9G5ZThV6gXBQIJ79F5HSqITzavz4Fe7iXvAbJLvZJ"; private JsonElement faturaParsed; private string? id; private string? uc; private int? pagina; public Fatura(string id, string fatura_path, HttpClient httpClient) { // Utilizado para gerar novo token // this.token = Req_token(httpClient).ToString(); HttpResponseMessage fatura_response = this.GetStatus(httpClient, Token, id); if (fatura_response.IsSuccessStatusCode) { this.faturaParsed = JsonDocument.Parse(fatura_response.Content.ReadAsStringAsync().Result).RootElement; this.Agrupada = this.faturaParsed.TryGetProperty("multiple", out var _); this.Status = this.faturaParsed.GetProperty("status").GetString(); this.Arquivo = new FileInfo(fatura_path); this.id = id; if (this.faturaParsed.GetProperty("external").GetString() is not null) { this.pagina = JsonDocument.Parse(this.faturaParsed.GetProperty("external").GetString() !).RootElement.GetProperty("origin")[0].GetProperty("page").GetInt32(); } if (this.Agrupada) { this.Agrupada_children = this.faturaParsed.GetProperty("children").EnumerateArray(); } } } public Fatura(string id, JsonElement fatura_Parsed) { // Utilizado para gerar novo token // this.token = Req_token(httpClient).ToString(); this.faturaParsed = fatura_Parsed; this.Agrupada = false; this.id = id; } public string? Gestao { get; private set; } public string? Empresa { get; private set; } public string? Unidade { get; private set; } public int? Mes { get; private set; } public string? Status { get; private set; } public FileInfo? Arquivo { get; private set; } public DirectoryInfo? PastaTUSD { get; private set; } public bool Agrupada { get; private set; } public JsonElement.ArrayEnumerator Agrupada_children { get; private set; } public void Processar(OleDbConnection conn) { // Variavel para armazenar os dados a serem lancados para a TUSD no BD RecordSet dadosTusd = new (); // Resultado da fatura processada JsonElement a; if (!this.faturaParsed.TryGetProperty("result", out a)) { this.faturaParsed.TryGetProperty("json", out a); } Rootobject parsedResult = JsonSerializer.Deserialize(a)!; if (parsedResult.dates.reading.periodUntil == DateTime.MinValue) { return; } dadosTusd.Mes = int.Parse(parsedResult.dates.reading.periodUntil.AddDays(-15).ToString("yMM")); string uc = new Regex("^0+").Replace(parsedResult.locationNumber, string.Empty).Replace("/", string.Empty).Replace("-", string.Empty).Replace(".", string.Empty); // Vinculo da fatura com os dados cadastrais int? unidades; string sqlQuery = $"SELECT COUNT (Cod_Smart_unidade) FROM Dados_cadastrais WHERE Codigo_Instalacao = @uc AND unidade_gerenciada"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@uc", uc); unidades = (int?)cmd.ExecuteScalar(); if (unidades == 1) { sqlQuery = $"SELECT Cod_Smart_unidade, Gestao, Cliente, Unidade, PerfilCCEE, Submercado, Status_unidade, Grupo, Perfil, Distribuidora, ICMS_TUSD, Demanda_P, Demanda_FP, Caminho_NFs, Data_de_Migracao FROM Dados_cadastrais WHERE Codigo_Instalacao = @uc AND unidade_gerenciada"; } else { sqlQuery = $"SELECT Cod_Smart_unidade, Gestao, Cliente, Unidade, PerfilCCEE, Submercado, Status_unidade, Grupo, Perfil, Distribuidora, ICMS_TUSD, Demanda_P, Demanda_FP, Caminho_NFs, Data_de_Migracao FROM Dados_cadastrais WHERE (CNPJ_CPF LIKE @cnpj AND Codigo_Instalacao = @uc AND unidade_gerenciada) OR (Razao_Social LIKE @razao_social AND Codigo_Instalacao = @uc AND unidade_gerenciada)"; } } using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { if (unidades == 1) { cmd.Parameters.AddWithValue("@uc", uc); } else { cmd.Parameters.AddWithValue("@cnpj", parsedResult.customer.cnpj?[..8] != null ? parsedResult.customer.cnpj?[..8] + "%" : "NAN"); cmd.Parameters.AddWithValue("@uc", uc); cmd.Parameters.AddWithValue("@razao_social", parsedResult.customer.name); } using (OleDbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { // Dados cadastrais dadosTusd.Cod_Smart_unidade = long.Parse(reader["Cod_Smart_unidade"].ToString() !); dadosTusd.Perfil_CliqCCEE = reader["PerfilCCEE"].ToString(); dadosTusd.Submercado = reader["Submercado"].ToString(); DateTime dataMigração = DateTime.Parse(reader["Data_de_Migracao"].ToString() !); if (int.Parse(dataMigração.ToString("yMM")) <= dadosTusd.Mes) { dadosTusd.Ambiente = reader["Status_unidade"].ToString(); } else { dadosTusd.Ambiente = "Cativo"; } dadosTusd.Grupo = reader["Grupo"].ToString(); dadosTusd.Distribuidora = reader["Distribuidora"].ToString(); dadosTusd.ICMS = float.Parse(reader["ICMS_TUSD"].ToString() !); dadosTusd.Dem_Cont_P = float.Parse(reader["Demanda_P"].ToString() !); dadosTusd.Dem_Cont_FP = float.Parse(reader["Demanda_FP"].ToString() !); dadosTusd.Perfil = reader["Perfil"].ToString(); this.PastaTUSD = new DirectoryInfo(reader["Caminho_NFs"].ToString() !.Replace("\\NFe", string.Empty, StringComparison.OrdinalIgnoreCase) + "\\TUSD"); this.Gestao = reader["Gestao"].ToString(); this.Empresa = reader["Cliente"].ToString(); this.Unidade = reader["Unidade"].ToString(); } } } // Verifica se a fatura ja foi lançada bool tusdLanc; sqlQuery = $"SELECT Cod_TUSD FROM Dados_TUSD WHERE Cod_TUSD = ?"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { double cod_tusd = double.Parse(dadosTusd.Cod_Smart_unidade.ToString() + dadosTusd.Mes.ToString()); cmd.Parameters.AddWithValue("?", cod_tusd); using (OleDbDataReader reader = cmd.ExecuteReader()) { tusdLanc = reader.HasRows; } } if (dadosTusd.Cod_Smart_unidade == 0) { this.Status = "UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD"; this.uc = uc; this.Mes = dadosTusd.Mes; return; } else if (tusdLanc) { this.Status = "FATURA DUPLICADA NO BD"; this.uc = uc; this.Mes = dadosTusd.Mes; return; } // PIS e Cofins sqlQuery = $"SELECT Distribuidoras_PIS.PIS, Distribuidoras_PIS.COFINS FROM Distribuidoras_geral INNER JOIN Distribuidoras_PIS ON Distribuidoras_geral.ID_dist = Distribuidoras_PIS.ID_dist WHERE Distribuidoras_PIS.Mes = ? AND Distribuidoras_geral.Distribuidora = ?"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("?", dadosTusd.Mes.ToString()); cmd.Parameters.AddWithValue("?", dadosTusd.Distribuidora); using (OleDbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { // PIS e Cofins dadosTusd.PIS = float.Parse(reader["PIS"].ToString() !); dadosTusd.COFINS = float.Parse(reader["COFINS"].ToString() !); } } } // Dados da fatura processada dadosTusd.Cod_TUSD = long.Parse(dadosTusd.Cod_Smart_unidade.ToString() + dadosTusd.Mes.ToString()); switch (parsedResult.tariffModality, parsedResult.subgroup) { case ("blue", _): dadosTusd.Perfil = "AZUL"; break; case ("green", _): dadosTusd.Perfil = "VERDE"; break; case ("standart", _): dadosTusd.Perfil = "CONVENCIONAL"; break; case (_, "B3"): dadosTusd.Perfil = "CONVENCIONAL"; break; default: break; } dadosTusd.Valor = parsedResult.totalCharges; dadosTusd.Inicio_Leitura = parsedResult.dates.reading.periodFrom; dadosTusd.Fim_leitura = parsedResult.dates.reading.periodUntil; DateTime d = DateTime.Now; dadosTusd.Hora_TUSD = new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second); dadosTusd.Dem_Reativa_kvar = 0; dadosTusd.Multa = 0; dadosTusd.Credito = 0; dadosTusd.Bandeira_RS_MWh = 0; dadosTusd.FIC_DIC = 0; dadosTusd.Enc_conexao = 0; dadosTusd.Liminar_ICMS = 0; dadosTusd.Outros = 0; dadosTusd.Cred_livre = 0; dadosTusd.Tempo_TUSD = 0; dadosTusd.Lanc_aut = true; dadosTusd.Rev_atual = true; dadosTusd.Revisao = 0; // Loop entre os dados faturados na fatura int j = 0; float? dem_Reg_P = null; float? dem_Reg_FP = null; float? consumo_Reg_FP = 0; string? kind_P = string.Empty; string? kind_FP = string.Empty; if (this.id == "2356193") { int i = 0; i++; } List<(string, float)> insertOthers = new List<(string, float)>(); foreach (Item item in parsedResult.items) { switch (item.type, item.period, item.kind) { // Energia Ponta case ("energy", "peak", "TUSD"): dadosTusd.Consumo_P += item.billed / 1000; break; // Energia Fora de Ponta case ("energy", _, "TUSD"): if (item.period == "off-peak" || item.period == "off-peak inductive" || item.period == "off-peak capacitive" || item.period == "reserved") { dadosTusd.Consumo_FP += item.billed / 1000; } else { insertOthers.Add((item.texts[0], item.charge)); } break; // Demanda case ("demand", _, _): if (item.contract != 0) { if (item.period == "peak") { dadosTusd.Dem_Reg_P = item.billed; dadosTusd.Dem_Cont_P = item.contract; } else if (item.period == "off-peak") { dadosTusd.Dem_Reg_FP = item.billed; dadosTusd.Dem_Cont_FP = item.contract; } if (dadosTusd.Perfil == "AZUL") { if (item.period == "peak") { sqlQuery = $"UPDATE Dados_cadastrais SET Demanda_P = @demanda WHERE Cod_Smart_unidade = @cod_smart_unidade"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } else if (item.period == "off-peak") { sqlQuery = $"UPDATE Dados_cadastrais SET Demanda_FP = @demanda WHERE Cod_Smart_unidade = @cod_smart_unidade"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } } else if (dadosTusd.Perfil == "VERDE") { sqlQuery = $"UPDATE Dados_cadastrais SET Demanda_P = @demanda, Demanda_FP = @demanda WHERE Cod_Smart_unidade = @cod_smart_unidade"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } } break; // Ilum. publica case ("publicLighting", _, _): dadosTusd.Ilum_Publica = item.charge; break; // Energia Reativa case ("excessReactiveEnergy", _, _): dadosTusd.En_Reativa_Mvarh += item.billed / 1000; break; // Demanda Reativa case ("excessReactiveDemand", _, _): dadosTusd.Dem_Reativa_kvar += item.billed; break; // Bandeira Tarifaria case ("flagSurcharge", _, _): dadosTusd.Bandeira_RS_MWh = item.charge; break; // Items não classificados case ("other", _, _): j++; // Exclui os items lançados anteriormente para a fatura e cria a instrução SQL para inserir os novos items if (j == 1) { sqlQuery = $"DELETE FROM Dados_TUSD_aux WHERE Cod_TUSD = @cod_tusd"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); cmd.ExecuteNonQuery(); } } insertOthers.Add((item.name, item.charge)); break; } } // Busca a demanda registrada nos itens medidos foreach (Measureditem measuredItem in parsedResult.measuredItems) { switch (measuredItem.type, measuredItem.period) { case ("demand", "peak"): dem_Reg_P = measuredItem.measured.Max(); break; case ("demand", "off-peak"): dem_Reg_FP = measuredItem.measured.Max(); break; case ("energy", "off-peak"): consumo_Reg_FP = consumo_Reg_FP.GetValueOrDefault() + measuredItem.measured.Sum(); break; case ("energy", "off-peak inductive"): consumo_Reg_FP = consumo_Reg_FP.GetValueOrDefault() + measuredItem.measured.Sum(); break; case ("energy", "off-peak capacitive"): consumo_Reg_FP = consumo_Reg_FP.GetValueOrDefault() + measuredItem.measured.Sum(); break; case ("energy", "off-peak capacitive green flag"): consumo_Reg_FP = consumo_Reg_FP.GetValueOrDefault() + measuredItem.measured.Sum(); break; case ("energy", "off-peak inductive green flag"): consumo_Reg_FP = consumo_Reg_FP.GetValueOrDefault() + measuredItem.measured.Sum(); break; case ("energy", "reserved"): consumo_Reg_FP = consumo_Reg_FP.GetValueOrDefault() + measuredItem.measured.Sum(); break; } } if (dem_Reg_P != null && (Math.Round((decimal)dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000) !, 2))) { dadosTusd.Dem_Reg_P = (float)(dem_Reg_P * 1.025); } else if (dem_Reg_P != null) { dadosTusd.Dem_Reg_P = (float)dem_Reg_P; } if (dem_Reg_FP != null && (Math.Round((decimal)dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000) !, 2))) { dadosTusd.Dem_Reg_FP = (float)(dem_Reg_FP * 1.025); } else if (dem_Reg_FP != null) { dadosTusd.Dem_Reg_FP = dem_Reg_FP ?? 0; } var dados = dadosTusd.GetType().GetProperties(); StringBuilder fields = new StringBuilder(); StringBuilder values = new StringBuilder(); // Verifica se já existe a fatura lançada | atualizar fatura ou nova fatura if (tusdLanc) { // Cria o comando para atualização da fatura sqlQuery = "UPDATE Dados_TUSD SET "; // Loop por todos os dados ja obtidos PropertyInfo[] propriedades = typeof(RecordSet).GetProperties(); foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; // Adicione a coluna à instrução SQL sqlQuery += $"{nomeColuna} = @{nomeColuna}, "; } // Remova a última vírgula e adicione a cláusula WHERE sqlQuery = sqlQuery.TrimEnd(',', ' ') + $" WHERE Cod_TUSD = @cod_tusd"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; object valorColuna = propriedade.GetValue(dadosTusd) ?? string.Empty; cmd.Parameters.AddWithValue($"@{nomeColuna}", valorColuna); } // Valor do código TUSD na cláusula WHERE cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); cmd.ExecuteNonQuery(); } // Inseri os itens classificados como "othes" após criar o registro da TUSD devido as relação entre as tabelas foreach ((string name, float valor) in insertOthers) { j++; sqlQuery = "INSERT INTO Dados_TUSD_aux (Cod_TUSD,Id,Nome,Valor,Cod_lanc) VALUES (@cod_tusd, @j, @name, @valor,0)"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); cmd.Parameters.AddWithValue("@j", j); cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@valor", valor); cmd.ExecuteNonQuery(); } } } else { // Cria o comando para lançar da fatura sqlQuery = "INSERT INTO Dados_TUSD ("; PropertyInfo[] propriedades = typeof(RecordSet).GetProperties(); /*int i = 0;*/ foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; // Adicione a coluna à instrução SQL sqlQuery += $"{nomeColuna}, "; } // Remova a última vírgula e adicione a cláusula VALUES sqlQuery = sqlQuery.TrimEnd(',', ' ') + ") VALUES ("; foreach (PropertyInfo propriedade in propriedades) { // Adicione os parâmetros à instrução SQL string nomeColuna = propriedade.Name; sqlQuery += $"@{nomeColuna}, "; } // Remova a última vírgula e feche a instrução SQL sqlQuery = sqlQuery.TrimEnd(',', ' ') + ")"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; object valorColuna = propriedade.GetValue(dadosTusd) ?? string.Empty; cmd.Parameters.AddWithValue($"@{nomeColuna}", valorColuna); } cmd.ExecuteNonQuery(); } // Inseri os itens classificados como "othes" após criar o registro da TUSD devido as relação entre as tabelas j = 0; foreach ((string name, float valor) in insertOthers) { j++; sqlQuery = "INSERT INTO Dados_TUSD_aux (Cod_TUSD,Id,Nome,Valor,Cod_lanc) VALUES (@cod_tusd, @j, @name, @valor, 0)"; using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) { cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); cmd.Parameters.AddWithValue("@j", j); cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@valor", valor); cmd.ExecuteNonQuery(); } } } this.Status = "FATURA INCLUIDA NO BD"; this.uc = uc; this.Mes = dadosTusd.Mes; } public void Mover(bool separar) { string destino = string.Empty; switch (this.Status, separar) { case ("UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD", _): destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\5 - {this.Status}\ID {this.id!} - Mês {this.Mes} - UC {this.uc}.pdf"; if (separar) { new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else { try { this.Arquivo!.MoveTo(destino); } catch { } } break; case ("FATURA DUPLICADA NO BD", _): destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\4 - {this.Status}\ID {this.id!} - Mês {this.Mes} - Empresa {this.Empresa} - Unidade {this.Unidade}.pdf"; if (separar) { new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else { try { this.Arquivo!.MoveTo(destino); } catch { } } break; case ("FATURA INCLUIDA NO BD", _): if (this.PastaTUSD!.Exists) { destino = this.PastaTUSD!.FullName + $@"\ID {this.id!} - Mês {this.Mes} - Empresa {this.Empresa} - Unidade {this.Unidade}.pdf"; } else { destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\6 - {this.Status}\ID {this.id!} - Mês {this.Mes} - Empresa {this.Empresa} - Unidade {this.Unidade}.pdf"; } if (separar) { new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else { try { this.Arquivo!.MoveTo(destino); } catch { } } break; case ("INVALID", _): destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\7 - ERRO\ID {this.id!} - {this.Arquivo?.Name}"; if (separar) { new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else { try { this.Arquivo!.MoveTo(destino); } catch { throw; } } break; case (_, true): destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\3 - PROCESSANDO\ID {this.id!} - {this.Arquivo?.Name}"; new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); break; } } private HttpResponseMessage GetStatus(HttpClient httpClient, string token, string id) { var request = new HttpRequestMessage(new HttpMethod("GET"), $"https://api.4docs.cloud/v2/request/status?id={id}"); request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); var response = httpClient.Send(request); return response; } private string Req_token(HttpClient httpClient) { var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.4docs.cloud/v2/oauth2/token"); var base64authorization = Convert.ToBase64String(Encoding.ASCII.GetBytes("smart:vnqtvmesikjzyipc")); request.Headers.TryAddWithoutValidation("Authorization", $"Basic {base64authorization}"); request.Content = new StringContent("grant_type=client_credentials"); request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/x-www-form-urlencoded"); var response = httpClient.Send(request); return JsonDocument.Parse(response.Content.ReadAsStringAsync().Result).RootElement.GetProperty("access_token").GetString() !; } } public class PDFSplitter { public PDFSplitter(int? pagina, string origem, string destino) { FileStream document = new FileStream(origem, FileMode.Open, FileAccess.Read, FileShare.Read); PdfDocument pdfDocument = new PdfDocument(new PdfReader(document)); var split = new CustomPdfSplitter(pdfDocument, pageRange => new PdfWriter(destino)); PdfDocument result = split.ExtractPageRange(new PageRange(pagina.ToString())); document.Close(); result.Close(); } } public class CustomPdfSplitter : PdfSplitter { private Func nextWriter; public CustomPdfSplitter(PdfDocument pdfDocument, Func nextWriter) : base(pdfDocument) { this.nextWriter = nextWriter; } protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) { return this.nextWriter.Invoke(documentPageRange); } } }