using System.Data.OleDb; using System.Text; using System.Text.Json; using System.Threading.RateLimiting; using Download_Faturas; using iText.Layout.Splitting; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace Webhook_4docs { public class Program { private static readonly RateLimiter connRateLimiter = new ConcurrencyLimiter(new ConcurrencyLimiterOptions { PermitLimit = 4 }); public static void Main(string[] args) { static string IndexedFilename(string stub, string extension) { int ix = 0; string? filename = null; if (File.Exists(String.Format("{0}.{1}", stub, extension))) { do { ix++; filename = String.Format("{0} ({1}).{2}", stub, ix, extension); } while (File.Exists(filename)); } else { filename = String.Format("{0}.{1}", stub, extension); } return filename; } var builder = WebApplication.CreateBuilder(args); builder.Configuration.AddJsonFile("appsettings.json"); var connectionString = builder.Configuration.GetConnectionString("WebhookDbContext"); string? appFolder = builder.Configuration["PathBase"]; builder.Services.AddDbContext(options => options.UseNpgsql(connectionString) ); builder.Services.AddLogging(loggingBuilder => { loggingBuilder.ClearProviders(); loggingBuilder.AddConsole(); }); // Add services to the container. builder.Services.AddRazorPages(); var app = builder.Build(); var logger = app.Services.GetRequiredService>(); using (var scope = app.Services.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService(); dbContext.Database.EnsureCreated(); dbContext.Database.Migrate(); } string fatura_arquivo; // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UsePathBase(appFolder); app.UseRouting(); app.UseStaticFiles(); app.UseAuthorization(); app.MapRazorPages(); app.Use((context, next) => { context.Request.PathBase = new PathString(appFolder); return next(context); }); // Endpoint para \api app.UseEndpoints(endpoints => { endpoints.MapControllers(); endpoints.MapPatch("/api", async context => { string requestBody; using (var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true)) { requestBody = await reader.ReadToEndAsync(); } var JsonBody = JsonDocument.Parse(requestBody).RootElement; string CaminhoDB = "X:/Middle/Informativo Setorial/Modelo Word/BD1_dados cadastrais e faturas.accdb"; if (JsonBody.TryGetProperty("requestID", out JsonElement fatura_ID_json)) { string fatura_ID = fatura_ID_json.ToString(); if (!JsonBody.TryGetProperty("json", out JsonElement root)) { return; } JsonElement DadosJson = JsonDocument.Parse(root.ToString()).RootElement; if (root.Get("documentType")?.ToString().ToLower() == "devec") { return; } Fatura fatura = new(fatura_ID, JsonBody); bool completed = false; while (!completed) { var connLease = await connRateLimiter.AcquireAsync(); if (connLease.IsAcquired) { using (OleDbConnection conn = new(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) { if (conn != null) { if (conn.State == System.Data.ConnectionState.Closed) { await conn.OpenAsync(); } try { fatura.Processar(conn); } catch (Exception ex) { completed = true; connLease.Dispose(); throw new Exception(ex.Message); } } } completed = true; connLease.Dispose(); } } string? status = fatura.Status; int status_id = 0; switch (status) { case ("FATURA DUPLICADA NO BD"): status_id = 4; break; case ("UNIDADE CONSUMIDORA NÃO LOCALIZADA NO BD"): status_id = 5; break; case ("FATURA INCLUIDA NO BD"): status_id = 6; break; case (_): status = "ERRO"; status_id = 7; break; } try { string path = $@"X:\Middle\Carteira {fatura.Gestao![0]}\Carteira {fatura.Gestao}\Faturas fourdocs\{status_id} - {status}"; if (status_id == 6 && fatura.PastaTUSD!.Exists) { path = fatura.PastaTUSD!.FullName; } fatura_arquivo = IndexedFilename($@"{path}\ID {fatura_ID!} - Mês {fatura.Mes} - Empresa {fatura.Empresa} - Unidade {fatura.Unidade}", "pdf"); CriarArquivo(fatura_arquivo, JsonBody.GetProperty("pdfFile").ToString()); var DatabaseModel = new ProcessedInvoices { InvoiceId = Int32.Parse(fatura_ID), DateTimeProcessed = DateTime.UtcNow, Status = status, InvoicePath = fatura_arquivo }; logger.LogInformation("Fatura incluída no BD"); using (var scope = app.Services.CreateScope()) { var dbContext = scope.ServiceProvider.GetRequiredService(); dbContext.ProcessedInvoices.Add(DatabaseModel); await dbContext.SaveChangesAsync(); } logger.LogInformation("Fatura salva na pasta " + fatura_arquivo); } catch { logger.LogError("Erro no processamento da fatura"); } } else if (JsonBody.TryGetProperty("healthy", out _) && JsonBody.TryGetProperty("blame", out _) && JsonBody.TryGetProperty("locationID", out _)) { double errorID = 0; switch (JsonBody.GetProperty("healthy").GetBoolean(), JsonBody.GetProperty("blame").ToString().ToLower()) { case (false, "user"): logger.LogError("Loc ID: " + JsonBody.GetProperty("locationID").ToString() + " Sem acesso"); errorID = 1; break; case (false, "system"): logger.LogError("Loc ID: " + JsonBody.GetProperty("locationID").ToString() + " Com erro de sistema"); errorID = 2; break; case (false, _): logger.LogError("Loc ID: " + JsonBody.GetProperty("locationID").ToString() + " Com erro " + JsonBody.GetProperty("blame").ToString()); errorID = 3; break; case (true, _): //logger.LogInformation("Loc ID: " + JsonBody.GetProperty("locationID").ToString() + " está saudável"); break; } int test = await UpdateErrorIdStatusAsync(CaminhoDB, JsonBody.GetProperty("locationID").GetInt64(), errorID, JsonBody.GetProperty("systemText").ToString()); if (test == 0) { InsertErrorIdStatus(CaminhoDB, errorID, requestBody); } } }); }); app.Run(); } public static async void InsertErrorIdStatus(string CaminhoDB, double errorID, string requestBody) { var JsonBody = JsonDocument.Parse(requestBody).RootElement; double locationID = JsonBody.GetProperty("locationID").GetInt64() ; string accountID = JsonBody.GetProperty("accountID").ToString() ; string deliveryTimeStamp = JsonBody.GetProperty("deliveryTimestamp").ToString() ; string provider = JsonBody.GetProperty("provider").ToString() ; string accessPoint = JsonBody.GetProperty("accessPoint").ToString() ; string slaStatus = JsonBody.GetProperty("slaStatus").ToString() ; string healthy = JsonBody.GetProperty("healthy").ToString() ; string blame = JsonBody.GetProperty("blame").ToString() ; string lastSuccess = JsonBody.GetProperty("lastSuccess").ToString() ; string active = JsonBody.GetProperty("active").ToString() ; string blacklistStatus = JsonBody.GetProperty("blacklistStatus").ToString() ; string lastActivated = JsonBody.GetProperty("lastActivated").ToString() ; string lastDeactivated = JsonBody.GetProperty("lastDeactivated").ToString() ; string lastDeactivatedBy = JsonBody.GetProperty("lastDeactivatedBy").ToString() ; int test = 0; bool completed = false; while (!completed) { var connLease = await connRateLimiter.AcquireAsync(); if (connLease.IsAcquired) { using (OleDbConnection conn = new(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) { if (conn != null) { if (conn.State == System.Data.ConnectionState.Closed) { await conn.OpenAsync(); } } using OleDbCommand cmd = new($"INSERT INTO AgVirtual4DocsErros (locationID, accountID, errorID, deliveryTimeStamp, provider, accessPoint, slaStatus, healthy, blame, lastSuccess, active, blacklistStatus, lastActivated, lastDeactivated, lastDeactivatedBy) VALUES ({locationID}, {accountID}, {errorID}, \'{deliveryTimeStamp}\', \'{provider}\', \'{accessPoint}\', \'{slaStatus}\', \'{healthy}\', \'{blame}\', \'{lastSuccess}\', \'{active}\', \'{blacklistStatus}\', \'{lastActivated}\', \'{lastDeactivated}\', \'{lastDeactivatedBy}\')", conn); //cmd.Parameters.AddWithValue("@location_id", location_id); //cmd.Parameters.AddWithValue("@errorID", errorID); test = await cmd.ExecuteNonQueryAsync(); } completed = true; connLease.Dispose(); } } } public static async Task UpdateErrorIdStatusAsync(string CaminhoDB, double location_id, double errorID, string systemText) { int test = 0; bool completed = false; while (!completed) { var connLease = await connRateLimiter.AcquireAsync(); if (connLease.IsAcquired) { try { using (OleDbConnection conn = new(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + CaminhoDB + ";Jet OLEDB:Database Password=gds21")) { if (conn != null) { if (conn.State == System.Data.ConnectionState.Closed) { await conn.OpenAsync(); } using (OleDbCommand cmd = new($"UPDATE AgVirtual4Docs SET AgVirtual4Docs.errorID = {errorID}, AgVirtual4Docs.status = \"{systemText}\"\r\nWHERE (((AgVirtual4Docs.location_id)={location_id}));\r\n", conn)) { //cmd.Parameters.AddWithValue("@errorID", errorID); //cmd.Parameters.AddWithValue("@location_id", location_id); test = await cmd.ExecuteNonQueryAsync(); } } } } finally { completed = true; connLease.Dispose(); } } } return test; } public static void CriarArquivo(string fatura_arquivo, string pdfFile64) { //string fatura_arquivo = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\test.pdf"; if (!File.Exists(fatura_arquivo)) { byte[] bytes = Convert.FromBase64String(pdfFile64); System.IO.FileStream stream = new(fatura_arquivo, FileMode.CreateNew); System.IO.BinaryWriter writer = new(stream); writer.Write(bytes, 0, bytes.Length); writer.Close(); } } } public static partial class JsonExtensions { public static JsonElement? Get(this JsonElement element, string name) => element.ValueKind != JsonValueKind.Null && element.ValueKind != JsonValueKind.Undefined && element.TryGetProperty(name, out var value) ? value : (JsonElement?)null; public static JsonElement? Get(this JsonElement element, int index) { if (element.ValueKind == JsonValueKind.Null || element.ValueKind == JsonValueKind.Undefined) return null; // Throw if index < 0 return index < element.GetArrayLength() ? element[index] : null; } } }