From 7fec1214faa68ddb3ce0fa8caf741b29d4c4b0ea Mon Sep 17 00:00:00 2001 From: Jeferson Almeida Date: Thu, 2 Jan 2025 15:22:13 -0300 Subject: [PATCH 1/5] #242 - Facade com o gateway de pagamento - feature/sp7/#242 --- src/services/JSE.Pagamento.API/appsettings.Development.json | 1 - 1 file changed, 1 deletion(-) diff --git a/src/services/JSE.Pagamento.API/appsettings.Development.json b/src/services/JSE.Pagamento.API/appsettings.Development.json index ec61c56..d96fd35 100644 --- a/src/services/JSE.Pagamento.API/appsettings.Development.json +++ b/src/services/JSE.Pagamento.API/appsettings.Development.json @@ -25,5 +25,4 @@ "DefaultApiKey": "ak_ewr4dsWehiwAT", "DefaultEncryptionKey": "ek_SweRsdFas4uT5" } - } From 2c141d2529f02d76956803663bd0cb932d610b3c Mon Sep 17 00:00:00 2001 From: Jeferson Almeida Date: Thu, 2 Jan 2025 15:55:34 -0300 Subject: [PATCH 2/5] #243 - Facade com o gateway de pagamento - feature/sp7/#243 --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9074ed0..6975a89 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ - EasyNetQ - Application Query Stack e Specification Pattern - NetDevPack +- Facade # Ferramentas - Visual Studio 2022 - Version 17.11.4 ++ From e71a4e079588e336ca8683bf399ceba06c8c2581 Mon Sep 17 00:00:00 2001 From: Jeferson Almeida Date: Thu, 2 Jan 2025 16:35:55 -0300 Subject: [PATCH 3/5] =?UTF-8?q?#244=20-=20Testar=20a=20aplica=C3=A7=C3=A3o?= =?UTF-8?q?=20-=20feature/sp7/#244?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Views/Pedido/ConfirmacaoPedido.cshtml | 110 ++++++++++++++++++ .../Views/Pedido/MeusPedidos.cshtml | 68 +++++++++++ 2 files changed, 178 insertions(+) create mode 100644 src/web/JSE.WebApp.MVC/Views/Pedido/ConfirmacaoPedido.cshtml create mode 100644 src/web/JSE.WebApp.MVC/Views/Pedido/MeusPedidos.cshtml diff --git a/src/web/JSE.WebApp.MVC/Views/Pedido/ConfirmacaoPedido.cshtml b/src/web/JSE.WebApp.MVC/Views/Pedido/ConfirmacaoPedido.cshtml new file mode 100644 index 0000000..0c44488 --- /dev/null +++ b/src/web/JSE.WebApp.MVC/Views/Pedido/ConfirmacaoPedido.cshtml @@ -0,0 +1,110 @@ +@using JSE.WebApp.MVC.Extensions +@model JSE.WebApp.MVC.Models.PedidoViewModel + +@{ + ViewData["Title"] = "Pedido confirmado!"; +} + +
+
+ + + + @{ + if (Model.PedidoItems.Any()) + { +
+
+
+ + + + Endereço +
+
+ + + + Pagamento +
+
+ + + + Confirmação +
+
+
+
+

Pedido concluído com sucesso!

+
+
+ @{ + foreach (var item in Model.PedidoItems) + { +
+
+
+ @item.Nome +
+
+

+ @item.Nome +

+ @this.UnidadesPorProdutoValorTotal(item.Quantidade, item.Valor) +
+
+
+ } + } + +
+
+ +
+

Pedido número: #@Model.Codigo

+
+
+ +
+
+
+
Entregar em
+

+ @Model.Endereco.ToString() +

+
+
+
Pagamento
+ + + Transação em cartão de crédito + +

+ Total: @this.FormatoMoeda(Model.ValorTotal) +

+
+
+ +
+
+ + + +
+ } + } +
+
+ +@section Scripts { + + @{ + await Html.RenderPartialAsync("_ValidationScriptsPartial"); + } + +} \ No newline at end of file diff --git a/src/web/JSE.WebApp.MVC/Views/Pedido/MeusPedidos.cshtml b/src/web/JSE.WebApp.MVC/Views/Pedido/MeusPedidos.cshtml new file mode 100644 index 0000000..eab2bee --- /dev/null +++ b/src/web/JSE.WebApp.MVC/Views/Pedido/MeusPedidos.cshtml @@ -0,0 +1,68 @@ +@using JSE.WebApp.MVC.Extensions +@model IEnumerable + +@{ + ViewData["Title"] = "Meus Pedidos"; +} + +
+
+ + @{ + foreach (var pedido in Model.OrderBy(p=>p.Data)) + { +
+
+
+ Pedido ID: #@pedido.Codigo @Html.Raw(this.ExibeStatus(pedido.Status)) + @pedido.Data.ToLongDateString() +
+
+
+
+
Pagamento
+ + + Transação em cartão de crédito + + +

+ Total: @this.FormatoMoeda(pedido.ValorTotal) +

+ +
+
+
Endereço de entrega
+

+ @pedido.Endereco.ToString() +

+
+
+
+
    + @{ + foreach (var item in pedido.PedidoItems) + { +
  • +
    +
    + @item.Nome +
    +
    +

    + @item.Nome +

    + @this.UnidadesPorProdutoValorTotal(item.Quantidade, item.Valor) +
    +
    +
  • + } + } +
+
+
+
+ } + } +
+
\ No newline at end of file From 51b1898561666fc92ff8338e301ef737458b2e89 Mon Sep 17 00:00:00 2001 From: Jeferson Almeida Date: Thu, 2 Jan 2025 17:41:32 -0300 Subject: [PATCH 4/5] #246 - Rodar tarefas agendadas de forma nativa - feature/sp7/#246 --- .../Configuration/MessageBusConfig.cs | 4 +- .../Controllers/PedidoController.cs | 2 +- .../PedidoOrquestradorIntegrationHandler.cs | 43 +++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs diff --git a/src/services/JSE.Pedido.API/Configuration/MessageBusConfig.cs b/src/services/JSE.Pedido.API/Configuration/MessageBusConfig.cs index 9269e8c..1497f78 100644 --- a/src/services/JSE.Pedido.API/Configuration/MessageBusConfig.cs +++ b/src/services/JSE.Pedido.API/Configuration/MessageBusConfig.cs @@ -1,5 +1,6 @@ using JSE.Core.Utils; using JSE.MessageBus; +using JSE.Pedidos.API.Services; namespace JSE.Pedidos.API.Configuration { @@ -8,7 +9,8 @@ public static class MessageBusConfig public static void AddMessageBusConfiguration(this IServiceCollection services, IConfiguration configuration) { - services.AddMessageBus(configuration.GetMessageQueueConnection("MessageBus")); + services.AddMessageBus(configuration.GetMessageQueueConnection("MessageBus")) + .AddHostedService(); } } } \ No newline at end of file diff --git a/src/services/JSE.Pedido.API/Controllers/PedidoController.cs b/src/services/JSE.Pedido.API/Controllers/PedidoController.cs index e575396..726d757 100644 --- a/src/services/JSE.Pedido.API/Controllers/PedidoController.cs +++ b/src/services/JSE.Pedido.API/Controllers/PedidoController.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; -namespace JSE.Pedido_API.Controllers +namespace JSE.Pedidos.API.Controllers { [Authorize] public class PedidoController : MainController diff --git a/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs b/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs new file mode 100644 index 0000000..bc69ac7 --- /dev/null +++ b/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs @@ -0,0 +1,43 @@ + +namespace JSE.Pedidos.API.Services +{ + public class PedidoOrquestradorIntegrationHandler : IHostedService, IDisposable + { + private readonly ILogger _logger; + private Timer _timer; + + public PedidoOrquestradorIntegrationHandler(ILogger logger) + { + _logger = logger; + } + + public Task StartAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Serviço de pedidos iniciado."); + + _timer = new Timer(ProcessarPedidos, null, TimeSpan.Zero, + TimeSpan.FromSeconds(15)); + + return Task.CompletedTask; + } + + private async void ProcessarPedidos(object state) + { + _logger.LogInformation("Processando Pedidos"); + } + + public Task StopAsync(CancellationToken cancellationToken) + { + _logger.LogInformation("Serviço de pedidos finalizado."); + + _timer?.Change(Timeout.Infinite, 0); + + return Task.CompletedTask; + } + + public void Dispose() + { + _timer?.Dispose(); + } + } +} From 2e20b1ce408050a852e971cfee62c87cb35f7782 Mon Sep 17 00:00:00 2001 From: Jeferson Almeida Date: Thu, 2 Jan 2025 20:20:40 -0300 Subject: [PATCH 5/5] #247 - Obter pedidos autorizados via Dapper - feature/sp7/#247 --- .../PedidoAutorizadoIntegrationEvent.cs | 16 ++++++++++ .../Application/DTO/PedidoDTO.cs | 2 +- .../Application/Queries/IPedidoQueries.cs | 2 +- .../Application/Queries/PedidoQueries.cs | 31 +++++++++++++++++++ .../PedidoOrquestradorIntegrationHandler.cs | 26 ++++++++++++++-- 5 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 src/building blocks/JSE.Core/Messages/Integration/PedidoAutorizadoIntegrationEvent.cs diff --git a/src/building blocks/JSE.Core/Messages/Integration/PedidoAutorizadoIntegrationEvent.cs b/src/building blocks/JSE.Core/Messages/Integration/PedidoAutorizadoIntegrationEvent.cs new file mode 100644 index 0000000..fbeea69 --- /dev/null +++ b/src/building blocks/JSE.Core/Messages/Integration/PedidoAutorizadoIntegrationEvent.cs @@ -0,0 +1,16 @@ +namespace JSE.Core.Messages.Integration +{ + public class PedidoAutorizadoIntegrationEvent : IntegrationEvent + { + public Guid ClienteId { get; private set; } + public Guid PedidoId { get; private set; } + public IDictionary Itens { get; private set; } + + public PedidoAutorizadoIntegrationEvent(Guid clienteId, Guid pedidoId, IDictionary itens) + { + ClienteId = clienteId; + PedidoId = pedidoId; + Itens = itens; + } + } +} \ No newline at end of file diff --git a/src/services/JSE.Pedido.API/Application/DTO/PedidoDTO.cs b/src/services/JSE.Pedido.API/Application/DTO/PedidoDTO.cs index 44e8a44..b445cd2 100644 --- a/src/services/JSE.Pedido.API/Application/DTO/PedidoDTO.cs +++ b/src/services/JSE.Pedido.API/Application/DTO/PedidoDTO.cs @@ -6,7 +6,7 @@ public class PedidoDTO { public Guid Id { get; set; } public int Codigo { get; set; } - + public Guid ClienteId { get; set; } public int Status { get; set; } public DateTime Data { get; set; } public decimal ValorTotal { get; set; } diff --git a/src/services/JSE.Pedido.API/Application/Queries/IPedidoQueries.cs b/src/services/JSE.Pedido.API/Application/Queries/IPedidoQueries.cs index cdd01b7..f8303ca 100644 --- a/src/services/JSE.Pedido.API/Application/Queries/IPedidoQueries.cs +++ b/src/services/JSE.Pedido.API/Application/Queries/IPedidoQueries.cs @@ -6,6 +6,6 @@ public interface IPedidoQueries { Task ObterUltimoPedido(Guid clienteId); Task> ObterListaPorClienteId(Guid clienteId); + Task ObterPedidosAutorizados(); } - } \ No newline at end of file diff --git a/src/services/JSE.Pedido.API/Application/Queries/PedidoQueries.cs b/src/services/JSE.Pedido.API/Application/Queries/PedidoQueries.cs index 273929f..a2c73aa 100644 --- a/src/services/JSE.Pedido.API/Application/Queries/PedidoQueries.cs +++ b/src/services/JSE.Pedido.API/Application/Queries/PedidoQueries.cs @@ -40,6 +40,37 @@ public async Task> ObterListaPorClienteId(Guid clienteId) return pedidos.Select(PedidoDTO.ParaPedidoDTO); } + public async Task ObterPedidosAutorizados() + { + // Correção para pegar todos os itens do pedido e ordernar pelo pedido mais antigo + const string sql = @"SELECT + P.ID as 'PedidoId', P.ID, P.CLIENTEID, + PI.ID as 'PedidoItemId', PI.ID, PI.PRODUTOID, PI.QUANTIDADE + FROM PEDIDOS P + INNER JOIN PEDIDOITEMS PI ON P.ID = PI.PEDIDOID + WHERE P.PEDIDOSTATUS = 1 + ORDER BY P.DATACADASTRO"; + + // Utilizacao do lookup para manter o estado a cada ciclo de registro retornado + var lookup = new Dictionary(); + + await _pedidoRepository.ObterConexao().QueryAsync(sql, + (p, pi) => + { + if (!lookup.TryGetValue(p.Id, out var pedidoDTO)) + lookup.Add(p.Id, pedidoDTO = p); + + pedidoDTO.PedidoItems ??= new List(); + pedidoDTO.PedidoItems.Add(pi); + + return pedidoDTO; + + }, splitOn: "PedidoId,PedidoItemId"); + + // Obtendo dados o lookup + return lookup.Values.OrderBy(p => p.Data).FirstOrDefault(); + } + private PedidoDTO MapearPedido(dynamic result) { var pedido = new PedidoDTO diff --git a/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs b/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs index bc69ac7..8e1d681 100644 --- a/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs +++ b/src/services/JSE.Pedido.API/Services/PedidoOrquestradorIntegrationHandler.cs @@ -1,14 +1,21 @@  +using JSE.Core.Messages.Integration; +using JSE.MessageBus; +using JSE.Pedidos.API.Application.Queries; + namespace JSE.Pedidos.API.Services { public class PedidoOrquestradorIntegrationHandler : IHostedService, IDisposable { + + private readonly IServiceProvider _serviceProvider; private readonly ILogger _logger; private Timer _timer; - public PedidoOrquestradorIntegrationHandler(ILogger logger) + public PedidoOrquestradorIntegrationHandler(ILogger logger, IServiceProvider serviceProvider) { _logger = logger; + _serviceProvider = serviceProvider; } public Task StartAsync(CancellationToken cancellationToken) @@ -23,7 +30,22 @@ public Task StartAsync(CancellationToken cancellationToken) private async void ProcessarPedidos(object state) { - _logger.LogInformation("Processando Pedidos"); + using (var scope = _serviceProvider.CreateScope()) + { + var pedidoQueries = scope.ServiceProvider.GetRequiredService(); + var pedido = await pedidoQueries.ObterPedidosAutorizados(); + + if (pedido == null) return; + + var bus = scope.ServiceProvider.GetRequiredService(); + + var pedidoAutorizado = new PedidoAutorizadoIntegrationEvent(pedido.ClienteId, pedido.Id, + pedido.PedidoItems.ToDictionary(p => p.ProdutoId, p => p.Quantidade)); + + await bus.PublishAsync(pedidoAutorizado); + + _logger.LogInformation($"Pedido ID: {pedido.Id} foi encaminhado para baixa no estoque."); + } } public Task StopAsync(CancellationToken cancellationToken)