From 6b0a5d61d372e607e5c5488545ef336601bff4e8 Mon Sep 17 00:00:00 2001 From: Giuliano Paschoalino Date: Fri, 28 Nov 2025 11:21:22 -0300 Subject: [PATCH] =?UTF-8?q?Refatora=C3=A7=C3=A3o=20e=20melhorias=20gerais?= =?UTF-8?q?=20no=20processamento=20de=20faturas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Alterado namespace para `Download_Faturas.Tests` e adicionados cabeçalhos de copyright. - Refatoração para uso de recursos modernos do C# (ex.: inicializações simplificadas, métodos estáticos). - Adicionados comentários XML e arquivo `stylecop.json` para padronização. - Melhorias em testes de integração, incluindo ajustes na lógica de comparação e manipulação de CSV. - Refatoração das classes `Fatura` e `FaturaOld` para encapsulamento e redução de duplicação. - Adicionado suporte a conversores JSON personalizados (`DefaultDateTimeConverter`, `FloatArrayOrSingleConverter`). - Melhorias no arquivo `Program.cs` com novos métodos auxiliares e tratamento de erros. - Adicionadas classes auxiliares para manipulação de PDFs (`PDFSplitter`, `CustomPdfSplitter`). - Ajustes nos arquivos de projeto para geração de documentação XML e inclusão do `StyleCop.Analyzers`. - Correções em valores de consumo e demanda nos arquivos CSV. - Melhor tratamento de erros e mensagens de log para facilitar o diagnóstico. --- .../FaturaIntegrationTests.cs | 74 ++-- Download Faturas.Tests/GlobalSuppressions.cs | 10 + Download Faturas.Tests/divergencias.csv | 21 +- Download Faturas/CustomPdfSplitter.cs | 39 ++ Download Faturas/DefaultDateTimeConverter.cs | 30 +- Download Faturas/Download Faturas.csproj | 13 +- Download Faturas/Fatura.cs | 357 ++++++++++-------- Download Faturas/FaturaOld.cs | 285 ++++++++------ .../FloatArrayOrSingleConverter.cs | 27 +- Download Faturas/GlobalSuppressions.cs | 16 + Download Faturas/PDFSplitter.cs | 40 ++ Download Faturas/Program.cs | 67 ++-- Download Faturas/RecordSet.cs | 151 +++++++- Download Faturas/Rootobject.cs | 193 +++++++++- Download Faturas/stylecop.json | 8 + Upload Faturas/GlobalSuppressions.cs | 8 + Upload Faturas/Program.cs | 262 +++++++------ Upload Faturas/Upload Faturas.csproj | 1 + Webhook 4docs/GlobalSuppressions.cs | 11 + Webhook 4docs/ProcessedInvoices.cs | 15 +- Webhook 4docs/Program.cs | 8 +- Webhook 4docs/WebhookDbContext.cs | 9 +- 22 files changed, 1165 insertions(+), 480 deletions(-) create mode 100644 Download Faturas.Tests/GlobalSuppressions.cs create mode 100644 Download Faturas/CustomPdfSplitter.cs create mode 100644 Download Faturas/GlobalSuppressions.cs create mode 100644 Download Faturas/PDFSplitter.cs create mode 100644 Download Faturas/stylecop.json create mode 100644 Upload Faturas/GlobalSuppressions.cs create mode 100644 Webhook 4docs/GlobalSuppressions.cs diff --git a/Download Faturas.Tests/FaturaIntegrationTests.cs b/Download Faturas.Tests/FaturaIntegrationTests.cs index 0e472bf..c7380d2 100644 --- a/Download Faturas.Tests/FaturaIntegrationTests.cs +++ b/Download Faturas.Tests/FaturaIntegrationTests.cs @@ -3,28 +3,35 @@ using System.Numerics; using System.Text.Json; using Download_Faturas; -namespace Download_Faturas1.Tests +namespace Download_Faturas.Tests { public class FaturaIntegrationTests { private const string Token = "UFY4VWzqcHYcGNd0gkBOMFL9G5ZThV6gXBQIJ79F5HSqITzavz4Fe7iXvAbJLvZJ"; - private static readonly HttpClient httpClient = new HttpClient(); + private static readonly HttpClient httpClient = new (); [Fact] public async Task CompareFaturaWithFaturaOld_ShouldReportDifferences() { // Sample fatura IDs to test (replace with real IDs or fetch dynamically) var faturaIds = LoadCsvColumn("../../../../Download Faturas.Tests/4Docs_2025_07.csv", 0); - var differences = new List(); - differences.Add($"FaturaId\tDistribuidora\toldConsumo_P\tnewConsumo_P\toldConsumo_FP\tnewConsumo_FP\toldDem_Reg_P\tnewDem_Reg_P\toldDem_Reg_FP\tnewDem_Reg_FP\toldEn_Reativa_Mvarh\tnewEn_Reativa_Mvarh"); + var differences = new List + { + $"FaturaId\tDistribuidora\toldConsumo_P\tnewConsumo_P\toldConsumo_FP\tnewConsumo_FP\toldDem_Reg_P\tnewDem_Reg_P\toldDem_Reg_FP\tnewDem_Reg_FP\toldEn_Reativa_Mvarh\tnewEn_Reativa_Mvarh" + }; - using (OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=X:/Middle/Informativo Setorial/Modelo Word/BD1_Testes.accdb;Jet OLEDB:Database Password=gds21")) + using (OleDbConnection conn = new (@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=X:/Middle/Informativo Setorial/Modelo Word/BD1_Testes.accdb;Jet OLEDB:Database Password=gds21")) { // Open the connection to the test database conn.Open(); foreach (var faturaId in faturaIds) { + if (faturaId == "2640189") + { + int i = 0; + if (i == 0) continue; + } // Retrieve fatura JSON from 4Docs API var request = new HttpRequestMessage(HttpMethod.Get, $"https://api.4docs.cloud/v2/request/status?id={faturaId}"); request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {Token}"); @@ -32,7 +39,6 @@ namespace Download_Faturas1.Tests if (!response.IsSuccessStatusCode) continue; var json = await response.Content.ReadAsStringAsync(); var faturaParsed = JsonDocument.Parse(json).RootElement; - int? pagina; // Process with old logic (FaturaOld) var faturaOld = new FaturaOld(faturaId, faturaParsed); @@ -40,14 +46,14 @@ namespace Download_Faturas1.Tests var fatura = new Fatura(faturaId, faturaParsed); faturaOld.Processar(conn); // This will write to DB, but we want to compare without writing - var oldVal = GetDadosTusd(conn, faturaOld.cod_tusd); - DeleteTusdRecords(conn, faturaOld.cod_tusd); // Delete old TUSD records before processing + var oldVal = GetDadosTusd(conn, faturaOld.CodTusd); + DeleteTusdRecords(conn, faturaOld.CodTusd); // Delete old TUSD records before processing fatura.Processar(conn); // This will also write to DB, but we want to compare without writing - var newVal = GetDadosTusd(conn, fatura.cod_tusd); - DeleteTusdRecords(conn, fatura.cod_tusd); // Delete old TUSD records before processing + var newVal = GetDadosTusd(conn, fatura.CodTusd); + DeleteTusdRecords(conn, fatura.CodTusd); // Delete old TUSD records before processing - if (!string.Equals(newVal, oldVal)) + if (!Equals(newVal, oldVal)) { differences.Add($"{faturaId}\t{oldVal.Distribuidora}\t{oldVal.Consumo_P}\t{newVal.Consumo_P}\t{oldVal.Consumo_FP}\t{newVal.Consumo_FP}\t{oldVal.Dem_Reg_P}\t{newVal.Dem_Reg_P}\t{oldVal.Dem_Reg_FP}\t{newVal.Dem_Reg_FP}\t{oldVal.En_Reativa_Mvarh}\t{newVal.En_Reativa_Mvarh}"); } @@ -60,23 +66,23 @@ namespace Download_Faturas1.Tests Assert.True(differences.Count == 0, $"Differences found between Fatura and FaturaOld:\n{string.Join("\n", differences)}"); } - void DeleteTusdRecords(OleDbConnection conn, double codTusd) + static void DeleteTusdRecords(OleDbConnection conn, double codTusd) { // Deletes TUSD records based on cod_tusd string sqlQuery = "DELETE FROM Dados_TUSD WHERE Cod_TUSD = ?"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("?", codTusd); cmd.ExecuteNonQuery(); } } - RecordSet GetDadosTusd(OleDbConnection conn, double codTusd) + static RecordSet GetDadosTusd(OleDbConnection conn, double codTusd) { - RecordSet dadosTusd = new RecordSet(); + RecordSet dadosTusd = new (); // Retrieves TUSD records based on cod_tusd string sqlQuery = "SELECT * FROM Dados_TUSD WHERE Cod_TUSD = ?"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("?", codTusd); using (OleDbDataReader reader = cmd.ExecuteReader()) @@ -85,29 +91,29 @@ namespace Download_Faturas1.Tests { // Dados Tusd ; - dadosTusd.Cod_TUSD = double.Parse(reader["Cod_TUSD"].ToString()); - dadosTusd.Mes = int.Parse(reader["Mes"].ToString()); - dadosTusd.Distribuidora = reader["Distribuidora"].ToString(); - dadosTusd.Grupo = reader["Grupo"].ToString(); - dadosTusd.Perfil = reader["Perfil"].ToString(); - dadosTusd.Inicio_Leitura = DateTime.Parse(reader["Inicio_Leitura"].ToString()); - dadosTusd.Fim_leitura = DateTime.Parse(reader["Fim_leitura"].ToString()); - dadosTusd.Valor = float.Parse(reader["Valor"].ToString()); - dadosTusd.Consumo_P = float.Parse(reader["Consumo_P"].ToString()); - dadosTusd.Consumo_FP = float.Parse(reader["Consumo_FP"].ToString()); - dadosTusd.Dem_Reg_P = float.Parse(reader["Dem_Reg_P"].ToString()); - dadosTusd.Dem_Reg_FP = float.Parse(reader["Dem_Reg_FP"].ToString()); - dadosTusd.Dem_Cont_P = float.Parse(reader["Dem_Cont_P"].ToString()); - dadosTusd.Dem_Cont_FP = float.Parse(reader["Dem_Cont_FP"].ToString()); - dadosTusd.En_Reativa_Mvarh = float.Parse(reader["En_Reativa_Mvarh"].ToString()); - dadosTusd.Dem_Reativa_kvar = float.Parse(reader["Dem_Reativa_kvar"].ToString()); + dadosTusd.Cod_TUSD = double.Parse(reader["Cod_TUSD"].ToString()!); + dadosTusd.Mes = int.Parse(reader["Mes"].ToString()!); + dadosTusd.Distribuidora = reader["Distribuidora"].ToString()!; + dadosTusd.Grupo = reader["Grupo"].ToString()!; + dadosTusd.Perfil = reader["Perfil"].ToString()!; + dadosTusd.Inicio_Leitura = DateTime.Parse(reader["Inicio_Leitura"].ToString()!); + dadosTusd.Fim_leitura = DateTime.Parse(reader["Fim_leitura"].ToString()!); + dadosTusd.Valor = float.Parse(reader["Valor"].ToString()!); + dadosTusd.Consumo_P = float.Parse(reader["Consumo_P"].ToString()!); + dadosTusd.Consumo_FP = float.Parse(reader["Consumo_FP"].ToString()!); + dadosTusd.Dem_Reg_P = float.Parse(reader["Dem_Reg_P"].ToString()!); + dadosTusd.Dem_Reg_FP = float.Parse(reader["Dem_Reg_FP"].ToString()!); + dadosTusd.Dem_Cont_P = float.Parse(reader["Dem_Cont_P"].ToString()!); + dadosTusd.Dem_Cont_FP = float.Parse(reader["Dem_Cont_FP"].ToString()!); + dadosTusd.En_Reativa_Mvarh = float.Parse(reader["En_Reativa_Mvarh"].ToString()!); + dadosTusd.Dem_Reativa_kvar = float.Parse(reader["Dem_Reativa_kvar"].ToString()!); } } } return dadosTusd; } //load csv column - List LoadCsvColumn(string filePath, int columnIndex) + static List LoadCsvColumn(string filePath, int columnIndex) { var columnData = new List(); using (var reader = new StreamReader(filePath)) @@ -131,7 +137,7 @@ namespace Download_Faturas1.Tests } //write data to csv - void WriteCsv(string filePath, List data) + static void WriteCsv(string filePath, List data) { using (var writer = new StreamWriter(filePath)) { diff --git a/Download Faturas.Tests/GlobalSuppressions.cs b/Download Faturas.Tests/GlobalSuppressions.cs new file mode 100644 index 0000000..d825d20 --- /dev/null +++ b/Download Faturas.Tests/GlobalSuppressions.cs @@ -0,0 +1,10 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Tests.FaturaIntegrationTests.DeleteTusdRecords(System.Data.OleDb.OleDbConnection,System.Double)")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Tests.FaturaIntegrationTests.GetDadosTusd(System.Data.OleDb.OleDbConnection,System.Double)~Download_Faturas.RecordSet")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Tests.FaturaIntegrationTests.WriteCsv(System.String,System.Collections.Generic.List{System.String})")] diff --git a/Download Faturas.Tests/divergencias.csv b/Download Faturas.Tests/divergencias.csv index 0edd58f..457b24f 100644 --- a/Download Faturas.Tests/divergencias.csv +++ b/Download Faturas.Tests/divergencias.csv @@ -18,7 +18,7 @@ FaturaId Distribuidora oldConsumo_P newConsumo_P oldConsumo_FP newConsumo_FP old 2657251 ELETROPAULO 0 0 1,926 1,926 0 0 0 0 0 0 2657249 ELETROPAULO 0 0 2,427 2,427 0 0 0 0 0 0 2657247 ESCELSA 12,808945 12,808945 112,56336 112,56336 308,16 308,16 371,52 371,52 1,2908161 1,2908161 -2657245 CEMIG 2,045 2,045 0 42,366 74 74 116 116 3,7159998 3,7159998 +2657245 CEMIG 2,045 2,045 0 0 74 74 116 116 3,7159998 3,7159998 2657243 AMPLA 0,17639999 0,17639999 1,722 1,722 6,38 6,38 8,73 8,73 0,120288 0,120288 2657241 LIGHT 0 12,957 118,419 118,419 0 0 406 406 0,632 0,632 2651045 CEPISA 2,14103 2,14103 26,00794 26,00794 57,81 57,81 64,01125 64,01125 0,01244 0,01244 @@ -32,7 +32,7 @@ FaturaId Distribuidora oldConsumo_P newConsumo_P oldConsumo_FP newConsumo_FP old 2651029 CEPISA 6,52224 6,52224 61,94176 61,94176 139,6255 139,6255 144,35075 144,35075 1,37341 1,37341 2651027 0 0 0 0 0 0 0 0 0 0 2651025 LIGHT 0 2,916 155,358 155,358 0 0 1156 1156 5,676 5,676 -2651023 CEAL 2,33626 0 19,12764 0 52,808 51,52 65,6 64 0 0 +2651023 CEAL 2,33626 2,33626 19,12764 19,12764 52,808 52,808 65,6 65,6 0 0 2651021 0 0 0 0 0 0 0 0 0 0 2651019 LIGHT 0 9,416 101,152 101,152 0 0 226 226 0,148 0,148 2651017 ESCELSA 0 0 0 0 0 0 0 0 0 0 @@ -48,10 +48,10 @@ FaturaId Distribuidora oldConsumo_P newConsumo_P oldConsumo_FP newConsumo_FP old 2648777 ESCELSA 1,2243912 1,2243912 8,927733 8,927733 85,7064 85,7064 108,141594 108,141594 1,7908062 1,7908062 2648775 ESCELSA 0 0 0 0 0 0 0 0 0 0 2648773 EPB 3,2951698 3,2951698 31,32226 31,32226 98,4 98,4 121,16 121,16 2,2639399 2,2639399 -2648771 CEMIG 0,049 0,049 0 23,074 11 11 255 255 0,015 0,015 +2648771 CEMIG 0,049 0,049 0 0 11 11 255 255 0,015 0,015 2648769 ESCELSA 0,295176 0,295176 100,56077 100,56077 5,376 5,376 696,864 696,864 4,44696 4,44696 -2648767 CEMIG 2,68 2,68 0 28,158 147 147 175 175 0,187 0,187 -2648765 CEMIG 3,52 3,52 0 91,388 144 144 336 336 2,21 2,21 +2648767 CEMIG 2,68 2,68 0 0 147 147 175 175 0,187 0,187 +2648765 CEMIG 3,52 3,52 0 0 144 144 336 336 2,21 2,21 2648763 AMPLA 2,365083 2,365083 19,2213 19,2213 106,59 106,59 128,77 128,77 0,9909899 0,9909899 2647742 LIGHT 0 3,252 37,896 37,896 0 0 95 95 0 0 2647740 LIGHT 0 17,267 201,999 201,999 0 0 444 444 0 0 @@ -62,19 +62,18 @@ FaturaId Distribuidora oldConsumo_P newConsumo_P oldConsumo_FP newConsumo_FP old 2642379 0 0 0 0 0 0 0 0 0 0 2642377 0 0 0 0 0 0 0 0 0 0 2642375 0 0 0 0 0 0 0 0 0 0 -2642373 LIGHT 0 0 31,2 0 0 0 0 0 0 0 -2642371 LIGHT 0 0 28,2 0 0 0 0 0 0 0 +2642373 LIGHT 0 0 31,2 31,2 0 0 0 0 0 0 +2642371 LIGHT 0 0 28,2 28,2 0 0 0 0 0 0 2642369 0 0 0 0 0 0 0 0 0 0 -2642367 LIGHT 0 0 28,4 0 0 0 0 0 0 0 +2642367 LIGHT 0 0 28,4 28,4 0 0 0 0 0 0 2642365 0 0 0 0 0 0 0 0 0 0 2642363 0 0 0 0 0 0 0 0 0 0 2642361 0 0 0 0 0 0 0 0 0 0 2642359 CEMIG 21,919 21,919 203,795 203,795 406 406 454 454 0 0 2641859 ESCELSA 0,364392 0,364392 42,21798 42,21798 15,792 15,792 326,928 326,928 3,543792 3,543792 -2641857 CEAL 2,65737 0 21,834301 0 61,664 60,16 80,688 78,72 0 0 +2641857 CEAL 2,65737 2,65737 21,834301 21,834301 61,664 61,664 80,688 80,688 0 0 2641855 ESCELSA 1,2725999 1,2725999 81,32006 81,32006 67,2 67,2 491,904 491,904 0,027384 0,027384 -2640192 ENERGISA-MS 1,8795 0 31,0065 0 169,79 169,79 227,64 227,64 9,7923 9,7923 -2640189 CPFL PIRATININGA 91,2192 91,2192 638,16235 638,16235 1814,4 1814,4 2169,6 2169,6 0,014784001 0,014784001 +2640192 ENERGISA-MS 1,8795 1,8795 31,0065 31,0065 169,79 169,79 227,64 227,64 9,7923 9,7923 2640187 CPFL PIRATININGA 52,9044 52,9044 584,6424 584,6424 1670,4 1670,4 2400 2400 2,301805 2,301805 2640185 CPFL PIRATININGA 50,46 50,46 518,0424 518,0424 1699,2 1699,2 2347,2 2347,2 2,160003 2,160003 2640183 CPFL PIRATININGA 54,162 54,162 597,40436 597,40436 1612,8 1612,8 2592 2592 0,65190303 0,65190303 diff --git a/Download Faturas/CustomPdfSplitter.cs b/Download Faturas/CustomPdfSplitter.cs new file mode 100644 index 0000000..009b21f --- /dev/null +++ b/Download Faturas/CustomPdfSplitter.cs @@ -0,0 +1,39 @@ +// +// Copyright (c) Smart Energia. All rights reserved. +// + +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; + + /// + /// Custom PDF splitter that allows specifying a function to create the next PDF writer. + /// + /// + /// Initializes a new instance of the class. + /// + /// The PDF document to split. + /// A function that returns the next PdfWriter given a PageRange. + public class CustomPdfSplitter(PdfDocument pdfDocument, Func nextWriter) : PdfSplitter(pdfDocument) + { + /// + /// Gets the next PDF writer for the specified page range. + /// + /// The page range for which to get the next PDF writer. + /// The next PDF writer. + protected override PdfWriter GetNextPdfWriter(PageRange documentPageRange) + { + return nextWriter.Invoke(documentPageRange); + } + } +} \ No newline at end of file diff --git a/Download Faturas/DefaultDateTimeConverter.cs b/Download Faturas/DefaultDateTimeConverter.cs index 952db24..1a64cea 100644 --- a/Download Faturas/DefaultDateTimeConverter.cs +++ b/Download Faturas/DefaultDateTimeConverter.cs @@ -1,11 +1,24 @@ -using System; -using System.Text.Json; -using System.Text.Json.Serialization; - +// +// Copyright (c) Smart Energia. All rights reserved. +// namespace Download_Faturas { + using System; + using System.Text.Json; + using System.Text.Json.Serialization; + + /// + /// Custom JSON converter for DateTime to handle default values. + /// public class DefaultDateTimeConverter : JsonConverter { + /// + /// Reads and converts the JSON to DateTime, returning DateTime.MinValue for invalid or empty strings. + /// + /// The Utf8JsonReader instance to read JSON tokens from. + /// The target type to convert to (expected DateTime). + /// The serializer options that may affect parsing behavior. + /// The parsed DateTime value, or DateTime.MinValue when the input is null, empty, or invalid. public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.String) @@ -26,9 +39,16 @@ namespace Download_Faturas return DateTime.MinValue; } + /// + /// Writes the DateTime value as a string in JSON. + /// + /// The Utf8JsonWriter instance to write JSON tokens to. + /// The DateTime value to write. + /// The serializer options that may affect writing behavior. public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options) { - writer.WriteStringValue(value); + // Write DateTime in round-trip ISO 8601 format so JSON consumers can parse it reliably. + writer.WriteStringValue(value.ToString("o")); } } } diff --git a/Download Faturas/Download Faturas.csproj b/Download Faturas/Download Faturas.csproj index 9263a54..c09f137 100644 --- a/Download Faturas/Download Faturas.csproj +++ b/Download Faturas/Download Faturas.csproj @@ -1,4 +1,4 @@ - + Exe @@ -7,6 +7,7 @@ enable enable AnyCPU + true @@ -14,7 +15,15 @@ - + + + + + + + + + diff --git a/Download Faturas/Fatura.cs b/Download Faturas/Fatura.cs index 36731bd..5c1bb61 100644 --- a/Download Faturas/Fatura.cs +++ b/Download Faturas/Fatura.cs @@ -1,4 +1,8 @@ -namespace Download_Faturas +// +// Copyright (c) Smart Energia. All rights reserved. +// + +namespace Download_Faturas { using System.Data.OleDb; using System.Globalization; @@ -12,19 +16,34 @@ using iText.Kernel.Pdf; using iText.Kernel.Utils; + /// + /// Representa uma fatura eletrônica e fornece métodos para processá-la e movê-la. + /// public class Fatura { private const string Token = "UFY4VWzqcHYcGNd0gkBOMFL9G5ZThV6gXBQIJ79F5HSqITzavz4Fe7iXvAbJLvZJ"; - private JsonElement faturaParsed; - private string? id; - private string? uc; - private int? pagina; + /// + /// Gets or sets the data to be recorded for TUSD in the database. + /// + private readonly RecordSet dadosTusd = new (); + private readonly JsonElement faturaParsed; + private readonly string? id; + private readonly int? pagina; + private string? uc; + + /// + /// Initializes a new instance of the class. + /// Inicializa uma nova instância da classe . + /// + /// Identificador da fatura no serviço 4docs. + /// Caminho completo para o arquivo PDF da fatura local. + /// Instância de HttpClient usada para realizar chamadas HTTP à API. 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); + // this.token = Req_token(HttpClient).ToString(); + HttpResponseMessage fatura_response = GetStatus(httpClient, Token, id); if (fatura_response.IsSuccessStatusCode) { this.faturaParsed = JsonDocument.Parse(fatura_response.Content.ReadAsStringAsync().Result).RootElement; @@ -45,61 +64,97 @@ } } + /// + /// Initializes a new instance of the class. + /// Inicializa uma nova instância da classe para faturas já processadas. + /// + /// Identificador da fatura no serviço 4docs. + /// JsonElement contendo os dados da fatura já parseados. public Fatura(string id, JsonElement fatura_Parsed) { // Utilizado para gerar novo token - // this.token = Req_token(httpClient).ToString(); + // this.token = Req_token(HttpClient).ToString(); this.faturaParsed = fatura_Parsed; this.Agrupada = false; this.id = id; } + /// + /// Gets or sets the TUSD code for the invoice. + /// + public double CodTusd { get; set; } + + /// + /// Gets the consumer unit code associated with the invoice. + /// public string? Gestao { get; private set; } + /// + /// Gets the company name associated with the invoice. + /// public string? Empresa { get; private set; } + /// + /// Gets the unit name associated with the invoice. + /// public string? Unidade { get; private set; } + /// + /// Gets the month associated with the invoice. + /// public int? Mes { get; private set; } + /// + /// Gets the status of the invoice. + /// public string? Status { get; private set; } + /// + /// Gets the file information of the invoice PDF. + /// public FileInfo? Arquivo { get; private set; } + /// + /// Gets the directory information for the TUSD folder. + /// public DirectoryInfo? PastaTUSD { get; private set; } + /// + /// Gets a value indicating whether the invoice is grouped. + /// public bool Agrupada { get; private set; } + /// + /// Gets the children elements if the invoice is grouped. + /// public JsonElement.ArrayEnumerator Agrupada_children { get; private set; } - // Variavel para armazenar os dados a serem lancados para a TUSD no BD - public RecordSet dadosTusd = new (); - - public double cod_tusd; - + /// + /// Processes the invoice and records the TUSD data in the database. + /// + /// An open OleDbConnection to the database used to insert or update TUSD records. public void Processar(OleDbConnection conn) { // Resultado da fatura processada - JsonElement a; - if (!this.faturaParsed.TryGetProperty("result", out a)) + if (!this.faturaParsed.TryGetProperty("result", out JsonElement a)) { this.faturaParsed.TryGetProperty("json", out a); } - Rootobject parsedResult = JsonSerializer.Deserialize(a)!; + Rootobject parsedResult = JsonSerializer.Deserialize(a) !; if (parsedResult == null || parsedResult.dates == null || parsedResult.dates.reading == null || parsedResult.locationNumber == null || parsedResult.customer == null || parsedResult.items == null || parsedResult.dates.reading.periodUntil == DateTime.MinValue) { return; } - dadosTusd.Mes = int.Parse(parsedResult.dates.reading.periodUntil.AddDays(-15).ToString("yMM")); + this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@uc", uc); @@ -115,7 +170,7 @@ } } - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { if (unidades == 1) { @@ -133,26 +188,26 @@ 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) + this.dadosTusd.Cod_Smart_unidade = long.Parse(reader["Cod_Smart_unidade"].ToString() !); + this.dadosTusd.Perfil_CliqCCEE = reader["PerfilCCEE"].ToString(); + this.dadosTusd.Submercado = reader["Submercado"].ToString(); + DateTime dataMigração = DateTime.Parse(reader["Data_de_Migracao"].ToString() !); + if (int.Parse(dataMigração.ToString("yMM")) <= this.dadosTusd.Mes) { - dadosTusd.Ambiente = reader["Status_unidade"].ToString(); + this.dadosTusd.Ambiente = reader["Status_unidade"].ToString(); } else { - dadosTusd.Ambiente = "Cativo"; + this.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.dadosTusd.Grupo = reader["Grupo"].ToString(); + this.dadosTusd.Distribuidora = reader["Distribuidora"].ToString(); + this.dadosTusd.ICMS = float.Parse(reader["ICMS_TUSD"].ToString() !); + this.dadosTusd.Dem_Cont_P = float.Parse(reader["Demanda_P"].ToString() !); + this.dadosTusd.Dem_Cont_FP = float.Parse(reader["Demanda_FP"].ToString() !); + this.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(); @@ -164,10 +219,10 @@ bool tusdLanc; sqlQuery = $"SELECT Cod_TUSD FROM Dados_TUSD WHERE Cod_TUSD = ?"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cod_tusd = double.Parse(dadosTusd.Cod_Smart_unidade.ToString() + dadosTusd.Mes.ToString()); - cmd.Parameters.AddWithValue("?", cod_tusd); + this.CodTusd = double.Parse(this.dadosTusd.Cod_Smart_unidade.ToString() + this.dadosTusd.Mes.ToString()); + cmd.Parameters.AddWithValue("?", this.CodTusd); using (OleDbDataReader reader = cmd.ExecuteReader()) { @@ -175,82 +230,82 @@ } } - if (dadosTusd.Cod_Smart_unidade == 0) + if (this.dadosTusd.Cod_Smart_unidade == 0) { this.Status = "UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD"; this.uc = uc; - this.Mes = dadosTusd.Mes; + this.Mes = this.dadosTusd.Mes; return; } else if (tusdLanc) { this.Status = "FATURA DUPLICADA NO BD"; this.uc = uc; - this.Mes = dadosTusd.Mes; + this.Mes = this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("?", dadosTusd.Mes.ToString()); - cmd.Parameters.AddWithValue("?", dadosTusd.Distribuidora); + cmd.Parameters.AddWithValue("?", this.dadosTusd.Mes.ToString()); + cmd.Parameters.AddWithValue("?", this.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()!); + this.dadosTusd.PIS = float.Parse(reader["PIS"].ToString() !); + this.dadosTusd.COFINS = float.Parse(reader["COFINS"].ToString() !); } } } // Dados da fatura processada - dadosTusd.Cod_TUSD = long.Parse(dadosTusd.Cod_Smart_unidade.ToString() + dadosTusd.Mes.ToString()); + this.dadosTusd.Cod_TUSD = long.Parse(this.dadosTusd.Cod_Smart_unidade.ToString() + this.dadosTusd.Mes.ToString()); switch (parsedResult.tariffModality, parsedResult.subgroup) { case ("blue", _): - dadosTusd.Perfil = "AZUL"; + this.dadosTusd.Perfil = "AZUL"; break; case ("green", _): - dadosTusd.Perfil = "VERDE"; + this.dadosTusd.Perfil = "VERDE"; break; case ("standart", _): - dadosTusd.Perfil = "CONVENCIONAL"; + this.dadosTusd.Perfil = "CONVENCIONAL"; break; case (_, "B3"): - dadosTusd.Perfil = "CONVENCIONAL"; + this.dadosTusd.Perfil = "CONVENCIONAL"; break; default: break; } - dadosTusd.Valor = parsedResult.totalCharges; - dadosTusd.Inicio_Leitura = parsedResult.dates.reading.periodFrom; - dadosTusd.Fim_leitura = parsedResult.dates.reading.periodUntil; + this.dadosTusd.Valor = parsedResult.totalCharges; + this.dadosTusd.Inicio_Leitura = parsedResult.dates.reading.periodFrom; + this.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; + this.dadosTusd.Hora_TUSD = new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second); + this.dadosTusd.Dem_Reativa_kvar = 0; + this.dadosTusd.Multa = 0; + this.dadosTusd.Credito = 0; + this.dadosTusd.Bandeira_RS_MWh = 0; + this.dadosTusd.FIC_DIC = 0; + this.dadosTusd.Enc_conexao = 0; + this.dadosTusd.Liminar_ICMS = 0; + this.dadosTusd.Outros = 0; + this.dadosTusd.Cred_livre = 0; + this.dadosTusd.Tempo_TUSD = 0; + this.dadosTusd.Lanc_aut = true; + this.dadosTusd.Rev_atual = true; + this.dadosTusd.Revisao = 0; // Loop entre os dados faturados na fatura int j = 0; @@ -260,22 +315,44 @@ string? kind_P = string.Empty; string? kind_FP = string.Empty; - List<(string, float)> insertOthers = new List<(string, float)>(); + List<(string, float)> insertOthers = []; foreach (Item item in parsedResult.items) { - switch (item.type, item.period, item.kind) + switch (item.type, item.period) { // Energia Ponta - case ("energy", "peak", "TUSD"): - dadosTusd.Consumo_P += item.billed / 1000; + case ("energy", "peak"): + if (kind_P == string.Empty) + { + kind_P = item.kind; + } + + if (item.kind == kind_P || item.kind == "TUSD") + { + if ((item.billed / 1000) != this.dadosTusd.Consumo_P) + { + this.dadosTusd.Consumo_P += item.billed / 1000; + } + } break; // Energia Fora de Ponta - case ("energy", _, "TUSD"): + case ("energy", _): if (item.period == "off-peak" || item.period == "off-peak inductive" || item.period == "off-peak capacitive" || item.period == "reserved") { - dadosTusd.Consumo_FP += item.billed / 1000; + if (kind_FP == string.Empty) + { + kind_FP = item.kind; + } + + if (item.kind == kind_FP) + { + if ((item.billed / 1000) != this.dadosTusd.Consumo_FP) + { + this.dadosTusd.Consumo_FP += item.billed / 1000; + } + } } else { @@ -285,51 +362,51 @@ break; // Demanda - case ("demand", _, _): + case ("demand", _): if (item.contract != 0) { if (item.period == "peak") { - dadosTusd.Dem_Reg_P = item.billed; - dadosTusd.Dem_Cont_P = item.contract; + this.dadosTusd.Dem_Reg_P = item.billed; + this.dadosTusd.Dem_Cont_P = item.contract; } else if (item.period == "off-peak") { - dadosTusd.Dem_Reg_FP = item.billed; - dadosTusd.Dem_Cont_FP = item.contract; + this.dadosTusd.Dem_Reg_FP = item.billed; + this.dadosTusd.Dem_Cont_FP = item.contract; } - if (dadosTusd.Perfil == "AZUL") + if (this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); - cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); + cmd.Parameters.AddWithValue("@cod_smart_unidade", this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); - cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); + cmd.Parameters.AddWithValue("@cod_smart_unidade", this.dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } } - else if (dadosTusd.Perfil == "VERDE") + else if (this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); - cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); + cmd.Parameters.AddWithValue("@cod_smart_unidade", this.dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } @@ -338,36 +415,36 @@ break; // Ilum. publica - case ("publicLighting", _, _): - dadosTusd.Ilum_Publica = item.charge; + case ("publicLighting", _): + this.dadosTusd.Ilum_Publica = item.charge; break; // Energia Reativa - case ("excessReactiveEnergy", _, _): - dadosTusd.En_Reativa_Mvarh += item.billed / 1000; + case ("excessReactiveEnergy", _): + this.dadosTusd.En_Reativa_Mvarh += item.billed / 1000; break; // Demanda Reativa - case ("excessReactiveDemand", _, _): - dadosTusd.Dem_Reativa_kvar += item.billed; + case ("excessReactiveDemand", _): + this.dadosTusd.Dem_Reativa_kvar += item.billed; break; // Bandeira Tarifaria - case ("flagSurcharge", _, _): - dadosTusd.Bandeira_RS_MWh = item.charge; + case ("flagSurcharge", _): + this.dadosTusd.Bandeira_RS_MWh = item.charge; break; // Items não classificados - case ("other", _, _): + 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); + cmd.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.ExecuteNonQuery(); } } @@ -409,27 +486,27 @@ } } - if (dem_Reg_P != null && (Math.Round((decimal)dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000)!, 2))) + if (dem_Reg_P != null && (Math.Round((decimal)this.dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000) !, 2))) { - dadosTusd.Dem_Reg_P = (float)(dem_Reg_P * 1.025); + this.dadosTusd.Dem_Reg_P = (float)(dem_Reg_P * 1.025); } else if (dem_Reg_P != null) { - dadosTusd.Dem_Reg_P = (float)dem_Reg_P; + this.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))) + if (dem_Reg_FP != null && (Math.Round((decimal)this.dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000) !, 2))) { - dadosTusd.Dem_Reg_FP = (float)(dem_Reg_FP * 1.025); + this.dadosTusd.Dem_Reg_FP = (float)(dem_Reg_FP * 1.025); } else if (dem_Reg_FP != null) { - dadosTusd.Dem_Reg_FP = dem_Reg_FP ?? 0; + this.dadosTusd.Dem_Reg_FP = dem_Reg_FP ?? 0; } - var dados = dadosTusd.GetType().GetProperties(); - StringBuilder fields = new StringBuilder(); - StringBuilder values = new StringBuilder(); + // var dados = this.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) @@ -450,17 +527,17 @@ // 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; - object valorColuna = propriedade.GetValue(dadosTusd) ?? string.Empty; + object valorColuna = propriedade.GetValue(this.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.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.ExecuteNonQuery(); } @@ -470,9 +547,9 @@ { 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); + cmd.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.Parameters.AddWithValue("@j", j); cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@valor", valor); @@ -508,12 +585,12 @@ // Remova a última vírgula e feche a instrução SQL sqlQuery = sqlQuery.TrimEnd(',', ' ') + ")"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; - object valorColuna = propriedade.GetValue(dadosTusd) ?? string.Empty; + object valorColuna = propriedade.GetValue(this.dadosTusd) ?? string.Empty; cmd.Parameters.AddWithValue($"@{nomeColuna}", valorColuna); } @@ -526,9 +603,9 @@ { 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); + cmd.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.Parameters.AddWithValue("@j", j); cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@valor", valor); @@ -539,13 +616,16 @@ this.Status = "FATURA INCLUIDA NO BD"; this.uc = uc; - this.Mes = dadosTusd.Mes; - + this.Mes = this.dadosTusd.Mes; } + /// + /// Moves the invoice PDF to the appropriate directory based on its status. + /// + /// If true, split the PDF into the target page range before moving; if false, move the whole file. public void Mover(bool separar) { - string destino = string.Empty; + string destino; switch (this.Status, separar) { @@ -555,7 +635,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -577,7 +657,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -606,7 +686,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -628,7 +708,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -649,13 +729,13 @@ destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\3 - PROCESSANDO\ID {this.id!} - {this.Arquivo?.Name}"; - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); break; } } - private HttpResponseMessage GetStatus(HttpClient httpClient, string token, string id) + private static 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}"); @@ -663,7 +743,7 @@ return response; } - private string Req_token(HttpClient httpClient) + private static 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")); @@ -674,33 +754,4 @@ 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); - } - } } \ No newline at end of file diff --git a/Download Faturas/FaturaOld.cs b/Download Faturas/FaturaOld.cs index 7343178..558adc6 100644 --- a/Download Faturas/FaturaOld.cs +++ b/Download Faturas/FaturaOld.cs @@ -1,4 +1,8 @@ -namespace Download_Faturas +// +// Copyright (c) Smart Energia. All rights reserved. +// + +namespace Download_Faturas { using System.Data.OleDb; using System.Globalization; @@ -12,19 +16,29 @@ using iText.Kernel.Pdf; using iText.Kernel.Utils; + /// + /// Class representing the old invoice processing logic. + /// public class FaturaOld { private const string Token = "UFY4VWzqcHYcGNd0gkBOMFL9G5ZThV6gXBQIJ79F5HSqITzavz4Fe7iXvAbJLvZJ"; - private JsonElement faturaParsed; - private string? id; + private readonly JsonElement faturaParsed; + private readonly string? id; + private readonly int? pagina; + private readonly RecordSet dadosTusd = new (); private string? uc; - private int? pagina; + /// + /// Initializes a new instance of the class. + /// + /// The identifier of the invoice. + /// The file path of the invoice. + /// The HTTP client used for requests. public FaturaOld(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); + // this.token = Req_token(HttpClient).ToString(); + HttpResponseMessage fatura_response = GetStatus(httpClient, Token, id); if (fatura_response.IsSuccessStatusCode) { this.faturaParsed = JsonDocument.Parse(fatura_response.Content.ReadAsStringAsync().Result).RootElement; @@ -45,60 +59,96 @@ } } + /// + /// Initializes a new instance of the class. + /// + /// The identifier of the invoice. + /// The parsed JSON element of the invoice. public FaturaOld(string id, JsonElement fatura_Parsed) { // Utilizado para gerar novo token - // this.token = Req_token(httpClient).ToString(); + // this.token = Req_token(HttpClient).ToString(); this.faturaParsed = fatura_Parsed; this.Agrupada = false; this.id = id; } + /// + /// Gets or sets the TUSD code for the invoice. + /// + public double CodTusd { get; set; } + + /// + /// Gets the consumer managing group associated with the invoice. + /// public string? Gestao { get; private set; } + /// + /// Gets the company associated with the invoice. + /// public string? Empresa { get; private set; } + /// + /// Gets the unit associated with the invoice. + /// public string? Unidade { get; private set; } + /// + /// Gets the month associated with the invoice. + /// public int? Mes { get; private set; } + /// + /// Gets the status of the invoice. + /// public string? Status { get; private set; } + /// + /// Gets the file information associated with the invoice. + /// public FileInfo? Arquivo { get; private set; } + /// + /// Gets the directory information for TUSD associated with the invoice. + /// public DirectoryInfo? PastaTUSD { get; private set; } + /// + /// Gets a value indicating whether the invoice is grouped. + /// public bool Agrupada { get; private set; } + /// + /// Gets the children invoices if the invoice is grouped. + /// public JsonElement.ArrayEnumerator Agrupada_children { get; private set; } - // Variavel para armazenar os dados a serem lancados para a TUSD no BD - public RecordSet dadosTusd = new (); - - public double cod_tusd; + /// + /// Processes the invoice and writes data to the database. + /// + /// The database connection to use for processing. public void Processar(OleDbConnection conn) { // Resultado da fatura processada - JsonElement a; - if (!this.faturaParsed.TryGetProperty("result", out a)) + if (!this.faturaParsed.TryGetProperty("result", out JsonElement a)) { this.faturaParsed.TryGetProperty("json", out a); } - Rootobject parsedResult = JsonSerializer.Deserialize(a)!; + Rootobject parsedResult = JsonSerializer.Deserialize(a) !; if (parsedResult == null || parsedResult.dates == null || parsedResult.dates.reading == null || parsedResult.locationNumber == null || parsedResult.customer == null || parsedResult.items == null || parsedResult.dates.reading.periodUntil == DateTime.MinValue) { return; } - dadosTusd.Mes = int.Parse(parsedResult.dates.reading.periodUntil.AddDays(-15).ToString("yMM")); + this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@uc", uc); @@ -114,7 +164,7 @@ } } - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { if (unidades == 1) { @@ -132,26 +182,26 @@ 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) + this.dadosTusd.Cod_Smart_unidade = long.Parse(reader["Cod_Smart_unidade"].ToString() !); + this.dadosTusd.Perfil_CliqCCEE = reader["PerfilCCEE"].ToString(); + this.dadosTusd.Submercado = reader["Submercado"].ToString(); + DateTime dataMigração = DateTime.Parse(reader["Data_de_Migracao"].ToString() !); + if (int.Parse(dataMigração.ToString("yMM")) <= this.dadosTusd.Mes) { - dadosTusd.Ambiente = reader["Status_unidade"].ToString(); + this.dadosTusd.Ambiente = reader["Status_unidade"].ToString(); } else { - dadosTusd.Ambiente = "Cativo"; + this.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.dadosTusd.Grupo = reader["Grupo"].ToString(); + this.dadosTusd.Distribuidora = reader["Distribuidora"].ToString(); + this.dadosTusd.ICMS = float.Parse(reader["ICMS_TUSD"].ToString() !); + this.dadosTusd.Dem_Cont_P = float.Parse(reader["Demanda_P"].ToString() !); + this.dadosTusd.Dem_Cont_FP = float.Parse(reader["Demanda_FP"].ToString() !); + this.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(); @@ -163,10 +213,10 @@ bool tusdLanc; sqlQuery = $"SELECT Cod_TUSD FROM Dados_TUSD WHERE Cod_TUSD = ?"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cod_tusd = double.Parse(dadosTusd.Cod_Smart_unidade.ToString() + dadosTusd.Mes.ToString()); - cmd.Parameters.AddWithValue("?", cod_tusd); + this.CodTusd = double.Parse(this.dadosTusd.Cod_Smart_unidade.ToString() + this.dadosTusd.Mes.ToString()); + cmd.Parameters.AddWithValue("?", this.CodTusd); using (OleDbDataReader reader = cmd.ExecuteReader()) { @@ -174,82 +224,82 @@ } } - if (dadosTusd.Cod_Smart_unidade == 0) + if (this.dadosTusd.Cod_Smart_unidade == 0) { this.Status = "UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD"; this.uc = uc; - this.Mes = dadosTusd.Mes; + this.Mes = this.dadosTusd.Mes; return; } else if (tusdLanc) { this.Status = "FATURA DUPLICADA NO BD"; this.uc = uc; - this.Mes = dadosTusd.Mes; + this.Mes = this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("?", dadosTusd.Mes.ToString()); - cmd.Parameters.AddWithValue("?", dadosTusd.Distribuidora); + cmd.Parameters.AddWithValue("?", this.dadosTusd.Mes.ToString()); + cmd.Parameters.AddWithValue("?", this.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()!); + this.dadosTusd.PIS = float.Parse(reader["PIS"].ToString() !); + this.dadosTusd.COFINS = float.Parse(reader["COFINS"].ToString() !); } } } // Dados da fatura processada - dadosTusd.Cod_TUSD = long.Parse(dadosTusd.Cod_Smart_unidade.ToString() + dadosTusd.Mes.ToString()); + this.dadosTusd.Cod_TUSD = long.Parse(this.dadosTusd.Cod_Smart_unidade.ToString() + this.dadosTusd.Mes.ToString()); switch (parsedResult.tariffModality, parsedResult.subgroup) { case ("blue", _): - dadosTusd.Perfil = "AZUL"; + this.dadosTusd.Perfil = "AZUL"; break; case ("green", _): - dadosTusd.Perfil = "VERDE"; + this.dadosTusd.Perfil = "VERDE"; break; case ("standart", _): - dadosTusd.Perfil = "CONVENCIONAL"; + this.dadosTusd.Perfil = "CONVENCIONAL"; break; case (_, "B3"): - dadosTusd.Perfil = "CONVENCIONAL"; + this.dadosTusd.Perfil = "CONVENCIONAL"; break; default: break; } - dadosTusd.Valor = parsedResult.totalCharges; - dadosTusd.Inicio_Leitura = parsedResult.dates.reading.periodFrom; - dadosTusd.Fim_leitura = parsedResult.dates.reading.periodUntil; + this.dadosTusd.Valor = parsedResult.totalCharges; + this.dadosTusd.Inicio_Leitura = parsedResult.dates.reading.periodFrom; + this.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; + this.dadosTusd.Hora_TUSD = new DateTime(d.Year, d.Month, d.Day, d.Hour, d.Minute, d.Second); + this.dadosTusd.Dem_Reativa_kvar = 0; + this.dadosTusd.Multa = 0; + this.dadosTusd.Credito = 0; + this.dadosTusd.Bandeira_RS_MWh = 0; + this.dadosTusd.FIC_DIC = 0; + this.dadosTusd.Enc_conexao = 0; + this.dadosTusd.Liminar_ICMS = 0; + this.dadosTusd.Outros = 0; + this.dadosTusd.Cred_livre = 0; + this.dadosTusd.Tempo_TUSD = 0; + this.dadosTusd.Lanc_aut = true; + this.dadosTusd.Rev_atual = true; + this.dadosTusd.Revisao = 0; // Loop entre os dados faturados na fatura int j = 0; @@ -259,13 +309,7 @@ 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)>(); + List<(string, float)> insertOthers = []; foreach (Item item in parsedResult.items) { switch (item.type, item.period) @@ -279,7 +323,7 @@ if (item.kind == kind_P) { - dadosTusd.Consumo_P += item.billed / 1000; + this.dadosTusd.Consumo_P += item.billed / 1000; } break; @@ -295,7 +339,7 @@ if (item.kind == kind_FP) { - dadosTusd.Consumo_FP += item.billed / 1000; + this.dadosTusd.Consumo_FP += item.billed / 1000; } } else @@ -312,45 +356,45 @@ { if (item.period == "peak") { - dadosTusd.Dem_Reg_P = item.billed; - dadosTusd.Dem_Cont_P = item.contract; + this.dadosTusd.Dem_Reg_P = item.billed; + this.dadosTusd.Dem_Cont_P = item.contract; } else if (item.period == "off-peak") { - dadosTusd.Dem_Reg_FP = item.billed; - dadosTusd.Dem_Cont_FP = item.contract; + this.dadosTusd.Dem_Reg_FP = item.billed; + this.dadosTusd.Dem_Cont_FP = item.contract; } - if (dadosTusd.Perfil == "AZUL") + if (this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); - cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); + cmd.Parameters.AddWithValue("@cod_smart_unidade", this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); - cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); + cmd.Parameters.AddWithValue("@cod_smart_unidade", this.dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } } - else if (dadosTusd.Perfil == "VERDE") + else if (this.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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { cmd.Parameters.AddWithValue("@demanda", item.contract); - cmd.Parameters.AddWithValue("@cod_smart_unidade", dadosTusd.Cod_Smart_unidade); + cmd.Parameters.AddWithValue("@cod_smart_unidade", this.dadosTusd.Cod_Smart_unidade); cmd.ExecuteNonQuery(); } } @@ -360,22 +404,22 @@ // Ilum. publica case ("publicLighting", _): - dadosTusd.Ilum_Publica = item.charge; + this.dadosTusd.Ilum_Publica = item.charge; break; // Energia Reativa case ("excessReactiveEnergy", _): - dadosTusd.En_Reativa_Mvarh += item.billed / 1000; + this.dadosTusd.En_Reativa_Mvarh += item.billed / 1000; break; // Demanda Reativa case ("excessReactiveDemand", _): - dadosTusd.Dem_Reativa_kvar += item.billed; + this.dadosTusd.Dem_Reativa_kvar += item.billed; break; // Bandeira Tarifaria case ("flagSurcharge", _): - dadosTusd.Bandeira_RS_MWh = item.charge; + this.dadosTusd.Bandeira_RS_MWh = item.charge; break; // Items não classificados @@ -386,9 +430,9 @@ if (j == 1) { sqlQuery = $"DELETE FROM Dados_TUSD_aux WHERE Cod_TUSD = @cod_tusd"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); + cmd.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.ExecuteNonQuery(); } } @@ -430,27 +474,27 @@ } } - if (dem_Reg_P != null && (Math.Round((decimal)dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000)!, 2))) + if (dem_Reg_P != null && (Math.Round((decimal)this.dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000) !, 2))) { - dadosTusd.Dem_Reg_P = (float)(dem_Reg_P * 1.025); + this.dadosTusd.Dem_Reg_P = (float)(dem_Reg_P * 1.025); } else if (dem_Reg_P != null) { - dadosTusd.Dem_Reg_P = (float)dem_Reg_P; + this.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))) + if (dem_Reg_FP != null && (Math.Round((decimal)this.dadosTusd.Consumo_FP, 2) == Math.Round((decimal)(consumo_Reg_FP * 1.025 / 1000) !, 2))) { - dadosTusd.Dem_Reg_FP = (float)(dem_Reg_FP * 1.025); + this.dadosTusd.Dem_Reg_FP = (float)(dem_Reg_FP * 1.025); } else if (dem_Reg_FP != null) { - dadosTusd.Dem_Reg_FP = dem_Reg_FP ?? 0; + this.dadosTusd.Dem_Reg_FP = dem_Reg_FP ?? 0; } - var dados = dadosTusd.GetType().GetProperties(); - StringBuilder fields = new StringBuilder(); - StringBuilder values = new StringBuilder(); + // var dados = this.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) @@ -471,17 +515,17 @@ // 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; - object valorColuna = propriedade.GetValue(dadosTusd) ?? string.Empty; + object valorColuna = propriedade.GetValue(this.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.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.ExecuteNonQuery(); } @@ -491,9 +535,9 @@ { 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); + cmd.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.Parameters.AddWithValue("@j", j); cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@valor", valor); @@ -529,12 +573,12 @@ // Remova a última vírgula e feche a instrução SQL sqlQuery = sqlQuery.TrimEnd(',', ' ') + ")"; - using (OleDbCommand cmd = new OleDbCommand(sqlQuery, conn)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { foreach (PropertyInfo propriedade in propriedades) { string nomeColuna = propriedade.Name; - object valorColuna = propriedade.GetValue(dadosTusd) ?? string.Empty; + object valorColuna = propriedade.GetValue(this.dadosTusd) ?? string.Empty; cmd.Parameters.AddWithValue($"@{nomeColuna}", valorColuna); } @@ -547,9 +591,9 @@ { 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)) + using (OleDbCommand cmd = new (sqlQuery, conn)) { - cmd.Parameters.AddWithValue("@cod_tusd", dadosTusd.Cod_TUSD); + cmd.Parameters.AddWithValue("@cod_tusd", this.dadosTusd.Cod_TUSD); cmd.Parameters.AddWithValue("@j", j); cmd.Parameters.AddWithValue("@name", name); cmd.Parameters.AddWithValue("@valor", valor); @@ -560,13 +604,16 @@ this.Status = "FATURA INCLUIDA NO BD"; this.uc = uc; - this.Mes = dadosTusd.Mes; - + this.Mes = this.dadosTusd.Mes; } + /// + /// Moves the invoice file based on its status. + /// + /// Indicates whether to split the PDF before moving. public void Mover(bool separar) { - string destino = string.Empty; + string destino; switch (this.Status, separar) { @@ -576,7 +623,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -598,7 +645,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -627,7 +674,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -649,7 +696,7 @@ if (separar) { - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); } else @@ -670,13 +717,13 @@ destino = this.Arquivo?.Directory?.Parent?.FullName + $@"\3 - PROCESSANDO\ID {this.id!} - {this.Arquivo?.Name}"; - new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); + _ = new PDFSplitter(this.pagina, this.Arquivo!.ToString(), destino); this.Arquivo = new FileInfo(destino); break; } } - private HttpResponseMessage GetStatus(HttpClient httpClient, string token, string id) + private static 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}"); @@ -684,7 +731,7 @@ return response; } - private string Req_token(HttpClient httpClient) + private static 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")); diff --git a/Download Faturas/FloatArrayOrSingleConverter.cs b/Download Faturas/FloatArrayOrSingleConverter.cs index 41c31a6..2e5b26c 100644 --- a/Download Faturas/FloatArrayOrSingleConverter.cs +++ b/Download Faturas/FloatArrayOrSingleConverter.cs @@ -1,12 +1,27 @@ -namespace Download_Faturas +// +// Copyright (c) Smart Energia. All rights reserved. +// + +namespace Download_Faturas { using System; using System.Text.Json; using System.Text.Json.Serialization; + /// + /// Custom JSON converter to handle float arrays or single float values. + /// public class FloatArrayOrSingleConverter : JsonConverter { - public override float[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + /// + /// Reads and converts the JSON to either a float array or a single float value. + /// + /// The reader to read from. + /// The type to convert. + /// Serialization options. + /// The converted float array. + /// Thrown when the JSON token is not an array or a number. + public override float[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.StartArray) { @@ -16,7 +31,7 @@ else if (reader.TokenType == JsonTokenType.Number) { // Se for um único valor, cria um array com esse valor - return new float[] { reader.GetSingle() }; + return [reader.GetSingle()]; } else { @@ -24,6 +39,12 @@ } } + /// + /// Writes the float array or single float value to JSON. + /// + /// The writer to write to. + /// The float array value to write. + /// Serialization options. public override void Write(Utf8JsonWriter writer, float[] value, JsonSerializerOptions options) { if (value.Length == 1) diff --git a/Download Faturas/GlobalSuppressions.cs b/Download Faturas/GlobalSuppressions.cs new file mode 100644 index 0000000..a60ebd9 --- /dev/null +++ b/Download Faturas/GlobalSuppressions.cs @@ -0,0 +1,16 @@ +// +// Copyright (c) Smart Energia. All rights reserved. +// + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1010:Opening square brackets should be spaced correctly", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Fatura.Processar(System.Data.OleDb.OleDbConnection)")] +[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "", Scope = "member", Target = "~M:Download_Faturas.FloatArrayOrSingleConverter.Read(System.Text.Json.Utf8JsonReader@,System.Type,System.Text.Json.JsonSerializerOptions)~System.Single[]")] +[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1009:Closing parenthesis should be spaced correctly", Justification = "", Scope = "type", Target = "~T:Download_Faturas.CustomPdfSplitter")] +[assembly: SuppressMessage("Performance", "SYSLIB1045:Converter em 'GeneratedRegexAttribute'.", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Fatura.Processar(System.Data.OleDb.OleDbConnection)")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Fatura.Processar(System.Data.OleDb.OleDbConnection)")] +[assembly: SuppressMessage("Performance", "SYSLIB1045:Converter em 'GeneratedRegexAttribute'.", Justification = "", Scope = "member", Target = "~M:Download_Faturas.FaturaOld.Processar(System.Data.OleDb.OleDbConnection)")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.FaturaOld.Processar(System.Data.OleDb.OleDbConnection)")] +[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1010:Opening square brackets should be spaced correctly", Justification = "", Scope = "member", Target = "~M:Download_Faturas.FaturaOld.Processar(System.Data.OleDb.OleDbConnection)")] +[assembly: SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1010:Opening square brackets should be spaced correctly", Justification = "", Scope = "member", Target = "~M:Download_Faturas.FloatArrayOrSingleConverter.Read(System.Text.Json.Utf8JsonReader@,System.Type,System.Text.Json.JsonSerializerOptions)~System.Single[]")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Program.Main")] diff --git a/Download Faturas/PDFSplitter.cs b/Download Faturas/PDFSplitter.cs new file mode 100644 index 0000000..63df023 --- /dev/null +++ b/Download Faturas/PDFSplitter.cs @@ -0,0 +1,40 @@ +// +// Copyright (c) Smart Energia. All rights reserved. +// + +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; + + /// + /// Class for splitting PDF documents. + /// + public class PDFSplitter + { + /// + /// Initializes a new instance of the class. + /// + /// The 1-based page number to extract; if null, the whole document is used. + /// Full path to the source PDF file to read. + /// Full path to the destination PDF file to create containing the extracted pages. + public PDFSplitter(int? pagina, string origem, string destino) + { + FileStream document = new (origem, FileMode.Open, FileAccess.Read, FileShare.Read); + PdfDocument pdfDocument = new (new PdfReader(document)); + var split = new CustomPdfSplitter(pdfDocument, pageRange => new PdfWriter(destino)); + PdfDocument result = split.ExtractPageRange(new PageRange(pagina.ToString())); + document.Close(); + result.Close(); + } + } +} \ No newline at end of file diff --git a/Download Faturas/Program.cs b/Download Faturas/Program.cs index b1f7a78..3b2a899 100644 --- a/Download Faturas/Program.cs +++ b/Download Faturas/Program.cs @@ -1,4 +1,8 @@ -namespace Download_Faturas +// +// Copyright (c) Smart Energia. All rights reserved. +// + +namespace Download_Faturas { using System.Data.OleDb; using System.Globalization; @@ -7,53 +11,64 @@ using System.Text.Json; using System.Text.RegularExpressions; + /// + /// Main program class for processing invoices. + /// public class Program { #if DEBUG + /// + /// Path to the log file for invoices. + /// public const string LogFaturas = @"X:\Back\Carteira x.x\4Docs\import.txt"; + + /// + /// Path to the secondary log file for invoices. + /// public const string LogFaturas2 = @"X:\Back\Carteira x.x\4Docs\import2.txt"; #else public const String LogFaturas = "import.txt"; public const String LogFaturas2 = "import2.txt"; #endif + + /// + /// Path to the database file. + /// public const string CaminhoDB = "X:/Middle/Informativo Setorial/Modelo Word/BD1_dados cadastrais e faturas.accdb"; - private static HttpClient httpClient = new (); - private static StreamReader sr = new (LogFaturas); - private static StreamWriter sw = new (LogFaturas2); + private static readonly HttpClient HttpClient = new (); + private static readonly StreamReader Sr = new (LogFaturas); + private static readonly StreamWriter Sw = new (LogFaturas2); private static string? fatura; + /// + /// Main entry point of the program. + /// public static void Main() { // Abre a conexao com o banco de dados - using (OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) + using (OleDbConnection conn = new (@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) { conn.Open(); // Loop entre as faturas pendentes - while ((fatura = sr.ReadLine()) != null) + while ((fatura = Sr.ReadLine()) != null) { string fatura_ID = fatura.Split(",")[0]; string fatura_status = fatura.Split(",")[1]; string fatura_arquivo = fatura.Split(",")[2]; - if (fatura_ID == "1826871") - { - int i = 0; - i++; - } - // Verifica se a fatura foi processada e atualiza os valores para banco de dados if (fatura_status == "DELAYED" | fatura_status == "MULTACTIONABLE" | fatura_status == "ACTIONABLE" | fatura_status == string.Empty | fatura_status == "UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD" | fatura_status == "PREPROCESS") { if (fatura_status == "UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD" && !File.Exists(fatura_arquivo)) { - sw.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura_arquivo); + Sw.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura_arquivo); Console.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura_arquivo); } else { // Verifica se a fatura foi processada e atualiza os valores para o banco de dados - Fatura fatura = new Fatura(fatura_ID, fatura_arquivo, httpClient); + Fatura fatura = new (fatura_ID, fatura_arquivo, HttpClient); if (fatura.Status == "SUCCESS" & !fatura.Agrupada) { @@ -61,12 +76,12 @@ try { fatura.Mover(separar: false); - sw.WriteLine(fatura_ID + "," + fatura.Status + "," + fatura.Arquivo); + Sw.WriteLine(fatura_ID + "," + fatura.Status + "," + fatura.Arquivo); Console.WriteLine(fatura_ID + "," + fatura.Status + "," + fatura.Arquivo); } catch (FileNotFoundException) { - sw.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura.Arquivo); + Sw.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura.Arquivo); Console.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura.Arquivo); } } @@ -74,7 +89,7 @@ { foreach (JsonElement individual_ID in fatura.Agrupada_children) { - Fatura faturaIndividual = new (individual_ID.ToString(), fatura_arquivo, httpClient); + Fatura faturaIndividual = new (individual_ID.ToString(), fatura_arquivo, HttpClient); if (faturaIndividual.Status == "SUCCESS") { @@ -82,12 +97,12 @@ try { faturaIndividual.Mover(separar: true); - sw.WriteLine(individual_ID.ToString() + "," + faturaIndividual.Status + "," + faturaIndividual.Arquivo); + Sw.WriteLine(individual_ID.ToString() + "," + faturaIndividual.Status + "," + faturaIndividual.Arquivo); Console.WriteLine(individual_ID.ToString() + "," + faturaIndividual.Status + "," + faturaIndividual.Arquivo); } catch (FileNotFoundException) { - sw.WriteLine(individual_ID.ToString() + "," + "ARQUIVO NÃO LOCALIZADO" + "," + faturaIndividual.Arquivo); + Sw.WriteLine(individual_ID.ToString() + "," + "ARQUIVO NÃO LOCALIZADO" + "," + faturaIndividual.Arquivo); Console.WriteLine(individual_ID.ToString() + "," + "ARQUIVO NÃO LOCALIZADO" + "," + faturaIndividual.Arquivo); } } @@ -96,12 +111,12 @@ try { faturaIndividual.Mover(separar: true); - sw.WriteLine(individual_ID.ToString() + "," + faturaIndividual.Status + "," + faturaIndividual.Arquivo); + Sw.WriteLine(individual_ID.ToString() + "," + faturaIndividual.Status + "," + faturaIndividual.Arquivo); Console.WriteLine(individual_ID.ToString() + "," + faturaIndividual.Status + "," + faturaIndividual.Arquivo); } catch (FileNotFoundException) { - sw.WriteLine(individual_ID.ToString() + "," + "ARQUIVO NÃO LOCALIZADO" + "," + faturaIndividual.Arquivo); + Sw.WriteLine(individual_ID.ToString() + "," + "ARQUIVO NÃO LOCALIZADO" + "," + faturaIndividual.Arquivo); Console.WriteLine(individual_ID.ToString() + "," + "ARQUIVO NÃO LOCALIZADO" + "," + faturaIndividual.Arquivo); } } @@ -117,26 +132,26 @@ } catch (FileNotFoundException) { - sw.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura.Arquivo); + Sw.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura.Arquivo); Console.WriteLine(fatura_ID + "," + "ARQUIVO NÃO LOCALIZADO" + "," + fatura.Arquivo); } } else { - sw.WriteLine(fatura_ID + "," + fatura.Status + "," + fatura_arquivo); + Sw.WriteLine(fatura_ID + "," + fatura.Status + "," + fatura_arquivo); Console.WriteLine(fatura_ID + "," + fatura.Status + "," + fatura_arquivo); } } } else { - sw.WriteLine(fatura); + Sw.WriteLine(fatura); Console.WriteLine(fatura); } } - sr.Close(); - sw.Close(); + Sr.Close(); + Sw.Close(); File.Move(LogFaturas2, LogFaturas, true); } } diff --git a/Download Faturas/RecordSet.cs b/Download Faturas/RecordSet.cs index 1528487..743ab42 100644 --- a/Download Faturas/RecordSet.cs +++ b/Download Faturas/RecordSet.cs @@ -1,100 +1,249 @@ -namespace Download_Faturas +// +// Copyright (c) Smart Energia. All rights reserved. +// + +namespace Download_Faturas { + /// + /// Record set class representing invoice data. + /// public class RecordSet { + /// + /// Gets or sets the TUSD code. + /// public double Cod_TUSD { get; set; } + /// + /// Gets or sets the Smart unit code. + /// public double Cod_Smart_unidade { get; set; } + /// + /// Gets or sets the month. + /// public int Mes { get; set; } + /// + /// Gets or sets the revision. + /// public int Revisao { get; set; } + /// + /// Gets or sets a value indicating whether this is the current revision. + /// public bool Rev_atual { get; set; } + /// + /// Gets or sets the TUSD hour. + /// public DateTime Hora_TUSD { get; set; } + /// + /// Gets or sets the TUSD time. + /// public int Tempo_TUSD { get; set; } + /// + /// Gets or sets the CliqCCEE profile. + /// public string? Perfil_CliqCCEE { get; set; } + /// + /// Gets or sets the submarket. + /// public string? Submercado { get; set; } + /// + /// Gets or sets the environment. + /// public string? Ambiente { get; set; } + /// + /// Gets or sets the distributor. + /// public string? Distribuidora { get; set; } + /// + /// Gets or sets the group. + /// public string? Grupo { get; set; } + /// + /// Gets or sets the profile. + /// public string? Perfil { get; set; } + /// + /// Gets or sets the start of the reading period. + /// public DateTime Inicio_Leitura { get; set; } + /// + /// Gets or sets the end of the reading period. + /// public DateTime Fim_leitura { get; set; } + /// + /// Gets or sets the value. + /// public float Valor { get; set; } + /// + /// Gets or sets the P consumption. + /// public float Consumo_P { get; set; } + /// + /// Gets or sets the FP consumption. + /// public float Consumo_FP { get; set; } + /// + /// Gets or sets the registered P demand. + /// public float Dem_Reg_P { get; set; } + /// + /// Gets or sets the registered FP demand. + /// public float Dem_Reg_FP { get; set; } + /// + /// Gets or sets the contracted P demand. + /// public float Dem_Cont_P { get; set; } + /// + /// Gets or sets the contracted FP demand. + /// public float Dem_Cont_FP { get; set; } + /// + /// Gets or sets the PIS value. + /// public float PIS { get; set; } + /// + /// Gets or sets the COFINS value. + /// public float COFINS { get; set; } + /// + /// Gets or sets the ICMS value. + /// public float ICMS { get; set; } + /// + /// Gets or sets the public lighting value. + /// public float Ilum_Publica { get; set; } + /// + /// Gets or sets the fine value. + /// public float Multa { get; set; } + /// + /// Gets or sets the credit value. + /// public float Credito { get; set; } + /// + /// Gets or sets the other values. + /// public float Outros { get; set; } + /// + /// Gets or sets the reactive energy in Mvarh. + /// public float En_Reativa_Mvarh { get; set; } + /// + /// Gets or sets the reactive demand in kvar. + /// public float Dem_Reativa_kvar { get; set; } + /// + /// Gets or sets the Bandeira RS in MWh. + /// public float Bandeira_RS_MWh { get; set; } + /// + /// Gets or sets the Liminar ICMS value. + /// public float Liminar_ICMS { get; set; } + /// + /// Gets or sets the connection charge. + /// public float Enc_conexao { get; set; } + /// + /// Gets or sets the FIC DIC value. + /// public float FIC_DIC { get; set; } // public string Hora_compliance { get; set; } + + /// + /// Gets or sets the P billed demand. + /// public float Dem_Fat_P { get; set; } + /// + /// Gets or sets the FP billed demand. + /// public float Dem_Fat_FP { get; set; } + /// + /// Gets or sets the reactive real value. + /// public float Reativos_reais { get; set; } + /// + /// Gets or sets the reactive real value. + /// public float Ultrapassagem_reais { get; set; } + /// + /// Gets or sets the Bandeira real value. + /// public float Bandeira_reais { get; set; } + /// + /// Gets or sets the compliance calculation value. + /// public float Compliance_calc { get; set; } + /// + /// Gets or sets a value indicating whether the compliance is correct. + /// public bool Compliance_Correto { get; set; } + /// + /// Gets or sets a value indicating whether DEVEC is declared. + /// public bool Decl_DEVEC { get; set; } + /// + /// Gets or sets the free market credit value. + /// public float Cred_livre { get; set; } + /// + /// Gets or sets the internal comments. + /// public string? Coment_int { get; set; } + /// + /// Gets or sets the client comments. + /// public string? Coment_cli { get; set; } + /// + /// Gets or sets a value indicating whether the entry is automatic. + /// public bool Lanc_aut { get; set; } } } \ No newline at end of file diff --git a/Download Faturas/Rootobject.cs b/Download Faturas/Rootobject.cs index 50822ce..12af52d 100644 --- a/Download Faturas/Rootobject.cs +++ b/Download Faturas/Rootobject.cs @@ -1,142 +1,333 @@ -namespace Download_Faturas +// +// Copyright (c) Smart Energia. All rights reserved. +// + +namespace Download_Faturas { using System.Text.Json.Serialization; #pragma warning disable CS8618, SA1300, SA1402 + + /// + /// Root object class representing the invoice JSON structure. + /// public class Rootobject { + /// + /// Gets or sets the version. + /// public string version { get; set; } + /// + /// Gets or sets the MD5 hash. + /// public string md5 { get; set; } + /// + /// Gets or sets the provider. + /// public string provider { get; set; } + /// + /// Gets or sets the provider data. + /// public Providerdata providerData { get; set; } + /// + /// Gets or sets the location number. + /// public string locationNumber { get; set; } + /// + /// Gets or sets the subclass. + /// public string subclass { get; set; } + /// + /// Gets or sets the subgroup. + /// public string subgroup { get; set; } + /// + /// Gets or sets the customer. + /// public Customer customer { get; set; } + /// + /// Gets or sets the losses. + /// public float losses { get; set; } + /// + /// Gets or sets the total charges. + /// public float totalCharges { get; set; } + /// + /// Gets or sets the tariff modality. + /// public string tariffModality { get; set; } + /// + /// Gets or sets the dates. + /// public Dates dates { get; set; } + /// + /// Gets or sets the measured items. + /// public Measureditem[] measuredItems { get; set; } + /// + /// Gets or sets the items. + /// public Item[] items { get; set; } } + /// + /// Provider data class representing provider information. + /// public class Providerdata { + /// + /// Gets or sets the name. + /// public Name name { get; set; } + /// + /// Gets or sets the CNPJ. + /// public Cnpj cnpj { get; set; } } + /// + /// Class representing the name information. + /// public class Name { + /// + /// Gets or sets the value. + /// public string value { get; set; } + /// + /// Gets or sets the confidence. + /// public string confidence { get; set; } } + /// + /// Class representing the CNPJ information. + /// public class Cnpj { + /// + /// Gets or sets the value. + /// public string value { get; set; } + /// + /// Gets or sets the confidence. + /// public string confidence { get; set; } } + /// + /// Customer class representing customer information. + /// public class Customer { + /// + /// Gets or sets the CNPJ. + /// public string cnpj { get; set; } + /// + /// Gets or sets the name. + /// public string name { get; set; } + /// + /// Gets or sets the address. + /// public Address address { get; set; } } + /// + /// Address class representing customer address information. + /// public class Address { + /// + /// Gets or sets the street and number. + /// public string streetAndNumber { get; set; } + /// + /// Gets or sets the city. + /// public string city { get; set; } + /// + /// Gets or sets the state. + /// public string state { get; set; } + /// + /// Gets or sets the zip code. + /// public string zipCode { get; set; } + /// + /// Gets or sets the district. + /// public string district { get; set; } } + /// + /// Dates class representing various date information. + /// public class Dates { + /// + /// Gets or sets the due date. + /// public DateTime due { get; set; } + /// + /// Gets or sets the issue month. + /// public DateTime month { get; set; } + /// + /// Gets or sets the reading information. + /// public Reading reading { get; set; } } + /// + /// Reading class representing reading period information. + /// public class Reading { + /// + /// Gets or sets the start of the reading period. + /// [JsonConverter(typeof(DefaultDateTimeConverter))] public DateTime periodFrom { get; set; } + /// + /// Gets or sets the end of the reading period. + /// [JsonConverter(typeof(DefaultDateTimeConverter))] public DateTime periodUntil { get; set; } } + /// + /// Measured item class representing measured item information. + /// public class Measureditem { + /// + /// Gets or sets the type. + /// public string type { get; set; } + /// + /// Gets or sets the kind. + /// public string kind { get; set; } + /// + /// Gets or sets the period. + /// public string period { get; set; } + /// + /// Gets or sets the texts. + /// public string[] texts { get; set; } + /// + /// Gets or sets the measured values. + /// [JsonConverter(typeof(FloatArrayOrSingleConverter))] public float[] measured { get; set; } } + /// + /// Item class representing invoice item information. + /// public class Item { + /// + /// Gets or sets the item type. + /// public string type { get; set; } + /// + /// Gets or sets the kind. + /// public string kind { get; set; } + /// + /// Gets or sets the period. + /// public string period { get; set; } + /// + /// Gets or sets the billed amount. + /// public float billed { get; set; } + /// + /// Gets or sets the rate. + /// public float? rate { get; set; } + /// + /// Gets or sets the charge. + /// public float charge { get; set; } + /// + /// Gets or sets the TUSD rate. + /// public float tusdRate { get; set; } + /// + /// Gets or sets the TE rate. + /// public float teRate { get; set; } + /// + /// Gets or sets the texts. + /// public string[] texts { get; set; } + /// + /// Gets or sets the basic rate. + /// public float basicRate { get; set; } + /// + /// Gets or sets the contract. + /// public float contract { get; set; } + /// + /// Gets or sets the name. + /// public string name { get; set; } + /// + /// Gets or sets the taxable amount. + /// public float? taxable { get; set; } + /// + /// Gets or sets a value indicating whether the item is summable. + /// public bool summable { get; set; } } #pragma warning restore CS8618, SA1300, SA1402 diff --git a/Download Faturas/stylecop.json b/Download Faturas/stylecop.json new file mode 100644 index 0000000..496cf68 --- /dev/null +++ b/Download Faturas/stylecop.json @@ -0,0 +1,8 @@ +{ + "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", + "settings": { + "documentationRules": { + "companyName": "Smart Energia" + } + } +} diff --git a/Upload Faturas/GlobalSuppressions.cs b/Upload Faturas/GlobalSuppressions.cs new file mode 100644 index 0000000..e33baa7 --- /dev/null +++ b/Upload Faturas/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Program.SendFatura(System.String,System.String,System.Boolean)~System.Net.Http.HttpResponseMessage")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Download_Faturas.Program.IsFileLocked(System.IO.FileInfo)~System.Boolean")] diff --git a/Upload Faturas/Program.cs b/Upload Faturas/Program.cs index b69b5b9..582b6ac 100644 --- a/Upload Faturas/Program.cs +++ b/Upload Faturas/Program.cs @@ -1,132 +1,172 @@ -using System.Net; -using System.Net.Http.Headers; -using System.Text; -using System.Text.Json; +// +// Copyright (c) PlaceholderCompany. All rights reserved. +// -public class Program +namespace Download_Faturas { + using System.Net; + using System.Net.Http.Headers; + using System.Text; + using System.Text.Json; + + /// + /// Main program class. + /// + public class Program + { #if DEBUG - public const string LogFaturas = @"X:\Back\Carteira x.x\4Docs\import.txt"; + /// + /// Path to the log file for invoices. + /// + public const string LogFaturas = @"X:\Back\Carteira x.x\4Docs\import.txt"; #else public const string LogFaturas = "import.txt"; #endif - private static HttpClient httpClient = new HttpClient(); + private static readonly HttpClient HttpClient = new (); - public static void Main() - { - for (int i = 1; i < 3; i++) + /// + /// Main entry point of the program. + /// + public static void Main() { - for (int j = 1; j < 7; j++) + for (int i = 1; i < 3; i++) { - DirectoryInfo pasta = new DirectoryInfo(@"X:\Middle\Carteira " + i + @"\Carteira " + i + "." + j + @"\Faturas fourdocs\1 - INDIVIDUAIS"); - DirectoryInfo pasta_agrupadas = new DirectoryInfo(@"X:\Middle\Carteira " + i + @"\Carteira " + i + "." + j + @"\Faturas fourdocs\2 - AGRUPADAS"); - - if (LerPasta(pasta, agrupada: false)) + for (int j = 1; j < 7; j++) { - LerPasta(pasta_agrupadas, agrupada: true); - } - } - } - } + DirectoryInfo pasta = new (@"X:\Middle\Carteira " + i + @"\Carteira " + i + "." + j + @"\Faturas fourdocs\1 - INDIVIDUAIS"); + DirectoryInfo pasta_agrupadas = new (@"X:\Middle\Carteira " + i + @"\Carteira " + i + "." + j + @"\Faturas fourdocs\2 - AGRUPADAS"); - public static bool LerPasta(DirectoryInfo pasta, bool agrupada) - { - if (pasta.Exists) - { - string token = "UFY4VWzqcHYcGNd0gkBOMFL9G5ZThV6gXBQIJ79F5HSqITzavz4Fe7iXvAbJLvZJ"; - - // token = await req_token(); - FileInfo[] faturas = pasta.GetFiles("*.pdf"); - StreamWriter sw = new StreamWriter(LogFaturas, true); - - foreach (FileInfo fatura in faturas) - { - if (!IsFileLocked(fatura)) - { - HttpResponseMessage response = SendFatura(token, fatura.FullName, agrupada); - if (response.IsSuccessStatusCode) + if (LerPasta(pasta, agrupada: false)) { - var iD = JsonDocument.Parse(response.Content.ReadAsStringAsync().Result).RootElement.GetProperty("requestId"); - fatura.MoveTo(fatura.Directory?.Parent?.FullName + $@"\3 - PROCESSANDO\ID {iD} - " + fatura.Name.Replace(",", string.Empty)); - sw.Write(iD); - sw.Write(","); - sw.Write(","); - sw.WriteLine(fatura.FullName); + LerPasta(pasta_agrupadas, agrupada: true); } } } - - sw.Close(); - return true; } - else + + /// + /// Reads the specified folder and processes the invoices. + /// + /// The directory to read invoices from. + /// Indicates whether the invoices are grouped. + /// True if the folder was read successfully; otherwise, false. + public static bool LerPasta(DirectoryInfo pasta, bool agrupada) { + if (pasta.Exists) + { + string token = "UFY4VWzqcHYcGNd0gkBOMFL9G5ZThV6gXBQIJ79F5HSqITzavz4Fe7iXvAbJLvZJ"; + + // token = await req_token(); + FileInfo[] faturas = pasta.GetFiles("*.pdf"); + StreamWriter sw = new (LogFaturas, true); + + foreach (FileInfo fatura in faturas) + { + if (!IsFileLocked(fatura)) + { + HttpResponseMessage response = SendFatura(token, fatura.FullName, agrupada); + if (response.IsSuccessStatusCode) + { + var iD = JsonDocument.Parse(response.Content.ReadAsStringAsync().Result).RootElement.GetProperty("requestId"); + fatura.MoveTo(fatura.Directory?.Parent?.FullName + $@"\3 - PROCESSANDO\ID {iD} - " + fatura.Name.Replace(",", string.Empty)); + sw.Write(iD); + sw.Write(","); + sw.Write(","); + sw.WriteLine(fatura.FullName); + } + } + } + + sw.Close(); + return true; + } + else + { + return false; + } + } + + /// + /// Requests an authentication token. + /// + /// The authentication token as a string. + public static string? ReqToken() + { + 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(); + } + + /// + /// Sends an invoice to the API for processing. + /// + /// The authentication token. + /// The path to the invoice file. + /// Indicates whether the invoices are grouped. + /// The HTTP response from the API. + public static HttpResponseMessage SendFatura(string token, string fatura, bool agrupada) + { + var handler = new HttpClientHandler + { + // Proxy = new WebProxy("http://127.0.0.1:8888"), + // UseProxy = true, + // ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true + }; + + using (var httpClient = new HttpClient(handler)) + { + var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.4docs.cloud/v2/parse"); + + request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); + + var multipartContent = new MultipartFormDataContent + { + { new ByteArrayContent(File.ReadAllBytes(fatura)), @"""file""", @$"""{Path.GetFileName(fatura)}""" }, + }; + multipartContent.ElementAt(0).Headers.Add("Content-Type", "application/pdf"); + + multipartContent.Add(new StringContent($"{{\"callbackUrl\":\"https://api.4docs.cloud/v2/null\",\"pipelineName\":\"energy\",\"multiple\":{agrupada.ToString().ToLower()},\"clientData\":{{\"fatura_PATH\":\"{fatura.Replace(",", string.Empty)}\"}}}}"), "json"); + + request.Content = multipartContent; + + return httpClient.Send(request); + } + } + + /// + /// Checks if a file is locked. + /// + /// The file to check. + /// True if the file is locked; otherwise, false. + public static bool IsFileLocked(FileInfo file) + { + try + { + using (FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None)) + { + stream.Close(); + } + } + catch (IOException) + { + // the file is unavailable because it is: + // still being written to + // or being processed by another thread + // or does not exist (has already been processed) + return true; + } + + // file is not locked return false; } } - - public static string? ReqToken() - { - 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 static HttpResponseMessage SendFatura(string token, string fatura, bool agrupada) - { - var handler = new HttpClientHandler - { - //Proxy = new WebProxy("http://127.0.0.1:8888"), - //UseProxy = true, - //ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true - }; - - using (var httpClient = new HttpClient(handler)) - { - var request = new HttpRequestMessage(new HttpMethod("POST"), "https://api.4docs.cloud/v2/parse"); - - request.Headers.TryAddWithoutValidation("Authorization", $"Bearer {token}"); - - var multipartContent = new MultipartFormDataContent(); - multipartContent.Add(new ByteArrayContent(File.ReadAllBytes(fatura)), @"""file""", @$"""{Path.GetFileName(fatura)}"""); - multipartContent.ElementAt(0).Headers.Add("Content-Type", "application/pdf"); - - multipartContent.Add(new StringContent($"{{\"callbackUrl\":\"https://api.4docs.cloud/v2/null\",\"pipelineName\":\"energy\",\"multiple\":{agrupada.ToString().ToLower()},\"clientData\":{{\"fatura_PATH\":\"{fatura.Replace(",", string.Empty)}\"}}}}"), "json"); - - request.Content = multipartContent; - - return httpClient.Send(request); - } - } - - public static bool IsFileLocked(FileInfo file) - { - try - { - using (FileStream stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None)) - { - stream.Close(); - } - } - catch (IOException) - { - // the file is unavailable because it is: - // still being written to - // or being processed by another thread - // or does not exist (has already been processed) - return true; - } - - // file is not locked - return false; - } -} +} \ No newline at end of file diff --git a/Upload Faturas/Upload Faturas.csproj b/Upload Faturas/Upload Faturas.csproj index 3e97a07..8a6f9d1 100644 --- a/Upload Faturas/Upload Faturas.csproj +++ b/Upload Faturas/Upload Faturas.csproj @@ -6,6 +6,7 @@ Download_Faturas enable enable + true diff --git a/Webhook 4docs/GlobalSuppressions.cs b/Webhook 4docs/GlobalSuppressions.cs new file mode 100644 index 0000000..b5e1747 --- /dev/null +++ b/Webhook 4docs/GlobalSuppressions.cs @@ -0,0 +1,11 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Usage", "CA2254:O modelo deve ser uma expressão estática", Justification = "", Scope = "member", Target = "~M:Webhook_4docs.Program.Main(System.String[])")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Webhook_4docs.Program.Main(System.String[])")] +[assembly: SuppressMessage("Style", "IDE0063:Usar a instrução 'using' simples", Justification = "", Scope = "member", Target = "~M:Webhook_4docs.Program.UpdateErrorIdStatusAsync(System.String,System.Double,System.Double,System.String,Microsoft.Extensions.Logging.ILogger)~System.Threading.Tasks.Task{System.Int32}")] +[assembly: SuppressMessage("Usage", "CA2254:O modelo deve ser uma expressão estática", Justification = "", Scope = "member", Target = "~M:Webhook_4docs.Program.UpdateErrorIdStatusAsync(System.String,System.Double,System.Double,System.String,Microsoft.Extensions.Logging.ILogger)~System.Threading.Tasks.Task{System.Int32}")] diff --git a/Webhook 4docs/ProcessedInvoices.cs b/Webhook 4docs/ProcessedInvoices.cs index 21f8575..89eba19 100644 --- a/Webhook 4docs/ProcessedInvoices.cs +++ b/Webhook 4docs/ProcessedInvoices.cs @@ -2,11 +2,14 @@ using System.ComponentModel.DataAnnotations.Schema; using System.Text.Json.Serialization; -public class ProcessedInvoices +namespace Webhook_4docs { - [Key] - public int InvoiceId { get; set; } - public DateTime DateTimeProcessed { get; set; } - public string? Status { get; set; } - public string? InvoicePath { get; set; } + public class ProcessedInvoices + { + [Key] + public int InvoiceId { get; set; } + public DateTime DateTimeProcessed { get; set; } + public string? Status { get; set; } + public string? InvoicePath { get; set; } + } } \ No newline at end of file diff --git a/Webhook 4docs/Program.cs b/Webhook 4docs/Program.cs index 4430d82..fe09f58 100644 --- a/Webhook 4docs/Program.cs +++ b/Webhook 4docs/Program.cs @@ -257,6 +257,8 @@ namespace Webhook_4docs endpoints.MapPut("/api", async context => { var a = 10; + a++; + await Task.CompletedTask; }); }); app.Run(); @@ -264,7 +266,7 @@ namespace Webhook_4docs //tenta pegar o deactivationReport, se não conseguir ou for null, tenta pegar o websiteText, se não conseguir ou for null, tenta pegar o systemText. As propriedades podem não exisir public static string GetErrorText(JsonElement root) { - string errorText = string.Empty; + string errorText; if (root.TryGetProperty("deactivationReport", out JsonElement deactivationReportElement) && deactivationReportElement.ValueKind != JsonValueKind.Null) { @@ -299,11 +301,11 @@ namespace Webhook_4docs { try { - using (OleDbConnection conn = new OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) + using (OleDbConnection conn = new (@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) { await conn.OpenAsync(); - using (OleDbCommand cmd = new OleDbCommand( + using (OleDbCommand cmd = new ( @"UPDATE AgVirtual4Docs SET errorID = @errorID, status = @status WHERE location_id = @location_id", conn)) diff --git a/Webhook 4docs/WebhookDbContext.cs b/Webhook 4docs/WebhookDbContext.cs index c8b5453..a76cd03 100644 --- a/Webhook 4docs/WebhookDbContext.cs +++ b/Webhook 4docs/WebhookDbContext.cs @@ -1,10 +1,9 @@ using Microsoft.EntityFrameworkCore; -public class WebhookDbContext : DbContext +namespace Webhook_4docs { - public WebhookDbContext(DbContextOptions options) : base(options) + public class WebhookDbContext(DbContextOptions options) : DbContext(options) { + public DbSet ProcessedInvoices { get; set; } } - - public DbSet ProcessedInvoices { get; set; } -} +} \ No newline at end of file