Skip to content

Commit

Permalink
Merge pull request #29 from decimo3/PdfSender
Browse files Browse the repository at this point in the history
Asynchronous invoice send system.
  • Loading branch information
decimo3 authored Feb 21, 2025
2 parents 26ec7b2 + ee19916 commit 64bd609
Show file tree
Hide file tree
Showing 13 changed files with 233 additions and 212 deletions.
4 changes: 2 additions & 2 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
"request": "launch",
"preLaunchTask": "build",
// If you have changed target frameworks, make sure to update the program path.
"program": "../tmp/net7.0/win-x64/bot.dll",
"args": ["--em-desenvolvimento", "--sap-instancia=4"],
"program": "${workspaceFolder}/bin/Debug/net7.0/win-x64/bot.dll",
"args": ["--sap-instancia=4" ,"--use-sqlite"],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "internalConsole",
Expand Down
83 changes: 13 additions & 70 deletions Handles/HandleAsynchronous.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public static async Task Chief
(
Int32 minInstance,
Int32 maxInstance,
Expression<Func<logsModel,bool>> filtro
Expression<Func<logsModel,bool>>? filtro = null
)
{
var instances = maxInstance - minInstance;
Expand Down Expand Up @@ -284,28 +284,20 @@ await bot.SendDocumentAsyncWraper(
await bot.ErrorReport(erro, solicitacao);
break;
}
var fluxo_atual = 0;
var resposta_txt = ExecutarSap(
"instalacao",
solicitacao.information,
solicitacao.instance
);
if(!Int64.TryParse(resposta_txt, out Int64 instalation))
// Testar se foi enviada o número de instalação
if (solicitacao.information > 999999999 || solicitacao.information < 99999999)
{
solicitacao.status = 500;
solicitacao.status = 400;
var erro = new Exception(
"Não foi recebido o número da instalação!");
"Só será aceita solicitação de fatura pela instalação!");
await bot.ErrorReport(erro, solicitacao);
break;
}
var agora = DateTime.Now;
logger.LogDebug("Solicitando as faturas...");
resposta_txt = ExecutarSap(
var resposta_txt = ExecutarSap(
solicitacao.application,
instalation,
solicitacao.information,
solicitacao.instance
);
logger.LogDebug("Quantidade experada: {quantidade}", resposta_txt);
if(!Int32.TryParse(resposta_txt, out Int32 quantidade_experada))
{
solicitacao.status = 500;
Expand All @@ -314,62 +306,13 @@ await bot.SendDocumentAsyncWraper(
await bot.ErrorReport(erro, solicitacao);
break;
}
var faturas = new List<pdfsModel>();
var tasks = new List<Task>();
while (true)
{
await Task.Delay(cfg.TASK_DELAY_LONG);
logger.LogDebug("Realizando a checagem");
faturas = database.RecuperarFatura(
f => f.instalation == instalation &&
f.timestamp >= agora
);
foreach (var fatura in faturas)
logger.LogDebug(fatura.filename);
if(faturas.Count == quantidade_experada) break;
if(agora.AddMilliseconds(cfg.SAP_ESPERA) < DateTime.Now) break;
}
logger.LogDebug("Quantidade de faturas: ", faturas.Count);
if(!faturas.Any())
{
solicitacao.status = 503;
var erro = new Exception(
"Não foi gerada nenhuma fatura pelo sistema SAP!");
await bot.ErrorReport(erro, solicitacao);
logger.LogError("Não foi gerada nenhuma fatura pelo sistema SAP!");
break;
}
if(faturas.Count != quantidade_experada)
{
solicitacao.status = 503;
var erro = new Exception(
"A quantidade de faturas não condiz com a quantidade esperada!");
await bot.ErrorReport(erro, solicitacao);
logger.LogError("A quantidade de faturas não condiz com a quantidade esperada!");
break;
}
var fluxos = new Stream[quantidade_experada];
foreach (var fatura in faturas)
{
if(fatura.status == pdfsModel.Status.sent) continue;
var caminho = System.IO.Path.Combine(cfg.TEMP_FOLDER, fatura.filename);
fluxos[fluxo_atual] = System.IO.File.OpenRead(caminho);
tasks.Add(bot.SendDocumentAsyncWraper(
solicitacao.identifier,
fluxos[fluxo_atual],
fatura.filename
));
fatura.status = pdfsModel.Status.sent;
database.AlterarFatura(fatura);
logger.LogInformation("Enviada fatura ({fluxo_atual}/{quantidade_experada}): {filename}",
++fluxo_atual, quantidade_experada, fatura.filename
solicitacao.instance = quantidade_experada;
solicitacao.response_at = DateTime.Now;
solicitacao.status = 300;
database.AlterarSolicitacao(solicitacao);
await bot.sendTextMesssageWraper(solicitacao.identifier,
"Sua fatura foi solicitada, favor aguardar a geração!"
);
}
await Task.WhenAll(tasks);
foreach(var fluxo in fluxos) fluxo.Close();
PdfHandle.Remove(faturas);
bot.SucessReport(solicitacao);
logger.LogInformation("Enviadas faturas para a instalação {instalation}", instalation);
break;
}
case TypeRequest.ofsInfo:
Expand Down
43 changes: 18 additions & 25 deletions Handles/HandleCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,8 @@ public async static Task HandleCommand(logsModel request, UsersModel user)
await bot.sendTextMesssageWraper(user.identifier, "*CONTROLADOR* para alterar para um usuário que pode receber avisos sobre outros usuário");
await bot.sendTextMesssageWraper(user.identifier, "*COMUNICADOR* para alterar para um usuário capaz de enviar transmissões pelo sistema");
break;
default:
{
var erro = new Exception("Comando solicitado não foi programado! Verifique e tente um válido!");
request.status = 400;
await bot.ErrorReport(erro, request);
return;
}
case "/info":
{
var info = new System.Text.StringBuilder();
info.Append($"*Identificador:* {user.identifier}\n");
info.Append($"*Telefone:* {user.phone_number}\n");
Expand All @@ -63,13 +57,13 @@ public async static Task HandleCommand(logsModel request, UsersModel user)
}
info.Append($"*Versão:* {Updater.CurrentVersion().ToString("yyyyMMdd")}");
await bot.sendTextMesssageWraper(user.identifier, info.ToString());
}
break;
case "/update":
if(user.privilege != UsersModel.userLevel.proprietario)
{
var erro = new Exception("Somente o proprietario podem usar esse comando!");
await bot.ErrorReport(erro, request);
return;
request.status = 403;
throw new InvalidOperationException("Somente o proprietario podem usar esse comando!");
}
try
{
Expand All @@ -91,17 +85,15 @@ public async static Task HandleCommand(logsModel request, UsersModel user)
}
catch
{
var erro = new Exception("Não foi possível atualizar o sistema remotamente!");
await bot.ErrorReport(erro, request);
return;
request.status = 500;
throw new InvalidOperationException("Não foi possível atualizar o sistema remotamente!");
}
break;
case "/hotfix":
if(user.privilege != UsersModel.userLevel.proprietario)
{
var erro = new Exception("Somente o proprietario podem usar esse comando!");
await bot.ErrorReport(erro, request);
return;
request.status = 403;
throw new InvalidOperationException("Somente o proprietario podem usar esse comando!");
}
if(!Updater.IsChangedVersionFile())
{
Expand All @@ -114,9 +106,8 @@ public async static Task HandleCommand(logsModel request, UsersModel user)
case "/restart":
if(!user.pode_promover())
{
var erro = new Exception("Somente o proprietario ou administrador podem usar esse comando!");
await bot.ErrorReport(erro, request);
return;
request.status = 403;
throw new InvalidOperationException("Somente o proprietario ou administrador podem usar esse comando!");
}
if(Updater.IsChangedVersionFile())
{
Expand All @@ -131,9 +122,8 @@ public async static Task HandleCommand(logsModel request, UsersModel user)
case "/database":
if(user.privilege != UsersModel.userLevel.proprietario)
{
var erro = new Exception("Somente o proprietario podem usar esse comando!");
await bot.ErrorReport(erro, request);
return;
request.status = 403;
throw new InvalidOperationException("Somente o proprietario podem usar esse comando!");
}
var solicitacoes = Database.GetInstance().RecuperarSolicitacao();
var tabela_texto = TableMaker<logsModel>.Serialize(solicitacoes, ';');
Expand Down Expand Up @@ -161,14 +151,17 @@ public async static Task HandleCommand(logsModel request, UsersModel user)
await bot.sendTextMesssageWraper(user.identifier, stringbuilder.ToString(), markdown: false);
}
break;
default:
{
request.status = 400;
throw new InvalidOperationException("Comando solicitado não foi programado!");
}
}
bot.SucessReport(request);
}
catch (System.Exception)
catch (System.Exception error)
{
var error = new Exception("Houve um erro ao processar o seu comando!");
await bot.ErrorReport(error, request);
}
return;
}
}
2 changes: 1 addition & 1 deletion Helpers/PdfChecker.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
namespace telbot.Helpers;
public partial class PdfHandle
{
public static Int64 Check(String filepath)
private static Int64 Check(String filepath)
{
using var reader = new iTextSharp.text.pdf.PdfReader(filepath);
var re = new System.Text.RegularExpressions.Regex("^[0-9]{10}$");
Expand Down
31 changes: 31 additions & 0 deletions Helpers/PdfHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.Extensions.Logging;
using telbot.Interfaces;
using telbot.Services;
using telbot.models;
using telbot.handle;
using System.Collections.Concurrent;
namespace telbot.Helpers;
public partial class PdfHandle
{
private readonly IDatabase database;
private readonly Configuration cfg;
private readonly HandleMessage bot;
private readonly ILogger logger;
private readonly ConcurrentDictionary<String, pdfsModel> faturas = new();
private readonly Object _lock = new(); // Dedicated lock object
public PdfHandle()
{
this.bot = HandleMessage.GetInstance();
this.cfg = Configuration.GetInstance();
this.database = Database.GetInstance();
this.logger = Logger.GetInstance<PdfHandle>();
// Delete all files in the temporary folder
var files = Directory.GetFiles(cfg.TEMP_FOLDER);
foreach (var file in files)
{
File.Delete(file);
}
var folders = Directory.GetDirectories(cfg.TEMP_FOLDER);

}
}
89 changes: 89 additions & 0 deletions Helpers/PdfSender.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using Microsoft.Extensions.Logging;
using telbot.models;
namespace telbot.Helpers
{
public partial class PdfHandle
{
public async void Sender()
{
logger.LogDebug("Realizando a procura de faturas para entregar...");
while (true)
{
try
{
await Task.Delay(cfg.TASK_DELAY);
// Recupera as solicitações redirecionadas
var solicitacoes = database.RecuperarSolicitacao(
r => r.status == 300 &&
r.typeRequest == models.TypeRequest.pdfInfo);
// Verifica se há solicitações a serem enviadas
if (solicitacoes is null)
{
continue;
}
var tasks = new List<Task>();
// Verifica em cada solicitação, se já foi gerada a fatura
foreach (var solicitacao in solicitacoes)
{
// Recupera a lista de faturas geradas

var faturas_info = new List<pdfsModel>(
faturas.Where(f =>
f.Value.timestamp >= solicitacao.received_at &&
f.Value.instalation == solicitacao.information
).Select(f => f.Value).ToList());
// Verifica se já tem faturas para a solicitação e se é a quantidade esperada
if (faturas_info.Count == solicitacao.instance)
{
//! Se tudo der certo, aqui tem que começar a entregar as faturas
tasks.Add(Sender(new List<pdfsModel>(faturas_info), solicitacao));
}
// Verifica se a solicitação já não expirou
if(solicitacao.response_at.AddMilliseconds(cfg.SAP_ESPERA) < DateTime.Now)
{
solicitacao.status = 503;
tasks.Add(bot.ErrorReport(
request: solicitacao,
error: new Exception("Não foi gerada nenhuma fatura pelo sistema SAP!")
));
}
}
await Task.WhenAll(tasks);
}
catch (System.Exception erro)
{
logger.LogError(erro, "Ocorreu um erro ao tentar enviar a fatura!");
}
}
}
// Método separado para enviar as faturas
private async Task Sender(List<pdfsModel> faturasInfo, logsModel solicitacao)
{
var fluxoAtual = 0;
var tasks = new List<Task>();
var fluxos = new Stream[solicitacao.instance];
foreach (var fatura in faturasInfo)
{
if (fatura.status == pdfsModel.Status.sent) continue;
var caminho = System.IO.Path.Combine(cfg.TEMP_FOLDER, fatura.filename);
fluxos[fluxoAtual] = System.IO.File.OpenRead(caminho);
tasks.Add(bot.SendDocumentAsyncWraper(
solicitacao.identifier,
fluxos[fluxoAtual],
fatura.filename
));
fatura.status = pdfsModel.Status.sent;
logger.LogInformation("Enviada fatura ({fluxoAtual}/{quantidadeEsperada}): {filename}",
++fluxoAtual, solicitacao.instance, fatura.filename);
}
await Task.WhenAll(tasks);
foreach (var fluxo in fluxos)
{
fluxo.Close();
}
Remove(new List<pdfsModel>(faturasInfo));
bot.SucessReport(solicitacao);
logger.LogInformation("Enviadas faturas para a instalação {instalation}", solicitacao.information);
}
}
}
Loading

0 comments on commit 64bd609

Please sign in to comment.