From d27555401914e386486521b9a5f8d49aff613751 Mon Sep 17 00:00:00 2001 From: Jeferson Almeida Date: Thu, 2 Jan 2025 21:02:24 -0300 Subject: [PATCH] #248 - Baixar o pedido do estoque - feature/sp7/#248 --- .../Configuration/MessageBusConfig.cs | 16 ++++ .../JSE.Catalogo.API/JSE.Catalogo.API.csproj | 1 + .../JSE.Catalogo.API/Models/Produto.cs | 13 ++- src/services/JSE.Catalogo.API/Program.cs | 1 + .../Services/CatalogoIntegrationHandler.cs | 84 +++++++++++++++++++ .../appsettings.Development.json | 11 ++- 6 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 src/services/JSE.Catalogo.API/Configuration/MessageBusConfig.cs create mode 100644 src/services/JSE.Catalogo.API/Services/CatalogoIntegrationHandler.cs diff --git a/src/services/JSE.Catalogo.API/Configuration/MessageBusConfig.cs b/src/services/JSE.Catalogo.API/Configuration/MessageBusConfig.cs new file mode 100644 index 0000000..d3fab3c --- /dev/null +++ b/src/services/JSE.Catalogo.API/Configuration/MessageBusConfig.cs @@ -0,0 +1,16 @@ +using JSE.Catalogo.API.Services; +using JSE.Core.Utils; +using JSE.MessageBus; + +namespace JSE.Catalogo.API.Configuration +{ + public static class MessageBusConfig + { + public static void AddMessageBusConfiguration(this IServiceCollection services, + IConfiguration configuration) + { + services.AddMessageBus(configuration.GetMessageQueueConnection("MessageBus")) + .AddHostedService(); + } + } +} \ No newline at end of file diff --git a/src/services/JSE.Catalogo.API/JSE.Catalogo.API.csproj b/src/services/JSE.Catalogo.API/JSE.Catalogo.API.csproj index 8b4546e..c66dcc2 100644 --- a/src/services/JSE.Catalogo.API/JSE.Catalogo.API.csproj +++ b/src/services/JSE.Catalogo.API/JSE.Catalogo.API.csproj @@ -28,6 +28,7 @@ + diff --git a/src/services/JSE.Catalogo.API/Models/Produto.cs b/src/services/JSE.Catalogo.API/Models/Produto.cs index 49af852..95212a3 100644 --- a/src/services/JSE.Catalogo.API/Models/Produto.cs +++ b/src/services/JSE.Catalogo.API/Models/Produto.cs @@ -5,11 +5,22 @@ namespace JSE.Catalogo.API.Models public class Produto : Entity, IAggregateRoot { public string Nome { get; set; } - public string Descricao { get; set; } + public string Descricao { get; set; } public bool Ativo { get; set; } public decimal Valor { get; set; } public DateTime DataCadastro { get; set; } public string Imagem { get; set; } public int QuantidadeEstoque { get; set; } + + public void RetirarEstoque(int quantidade) + { + if (QuantidadeEstoque >= quantidade) + QuantidadeEstoque -= quantidade; + } + + public bool EstaDisponivel(int quantidade) + { + return Ativo && QuantidadeEstoque >= quantidade; + } } } diff --git a/src/services/JSE.Catalogo.API/Program.cs b/src/services/JSE.Catalogo.API/Program.cs index 0929d71..01fdd54 100644 --- a/src/services/JSE.Catalogo.API/Program.cs +++ b/src/services/JSE.Catalogo.API/Program.cs @@ -13,6 +13,7 @@ .AddUserSecrets(typeof(Program).Assembly).Build(); builder.Services.AddApiConfiguration(configuration); +builder.Services.AddMessageBusConfiguration(configuration); builder.Services.AddJwtConfiguration(configuration); builder.Services.AddSwaggerConfiguration(); builder.Services.AddEndpointsApiExplorer(); diff --git a/src/services/JSE.Catalogo.API/Services/CatalogoIntegrationHandler.cs b/src/services/JSE.Catalogo.API/Services/CatalogoIntegrationHandler.cs new file mode 100644 index 0000000..cb0ae73 --- /dev/null +++ b/src/services/JSE.Catalogo.API/Services/CatalogoIntegrationHandler.cs @@ -0,0 +1,84 @@ +using JSE.Catalogo.API.Models; +using JSE.Core.DomainObjects; +using JSE.Core.Messages.Integration; +using JSE.MessageBus; + +namespace JSE.Catalogo.API.Services +{ + public class CatalogoIntegrationHandler : BackgroundService + { + private readonly IMessageBus _bus; + private readonly IServiceProvider _serviceProvider; + + public CatalogoIntegrationHandler(IServiceProvider serviceProvider, IMessageBus bus) + { + _serviceProvider = serviceProvider; + _bus = bus; + } + protected override Task ExecuteAsync(CancellationToken stoppingToken) + { + SetSubscribers(); + return Task.CompletedTask; + } + + private void SetSubscribers() + { + _bus.SubscribeAsync("PedidoAutorizado", async request => + await BaixarEstoque(request)); + } + + private async Task BaixarEstoque(PedidoAutorizadoIntegrationEvent message) + { + using (var scope = _serviceProvider.CreateScope()) + { + var produtosComEstoque = new List(); + var produtoRepository = scope.ServiceProvider.GetRequiredService(); + + var idsProdutos = string.Join(",", message.Itens.Select(c => c.Key)); + var produtos = await produtoRepository.ObterProdutosPorId(idsProdutos); + + if (produtos.Count != message.Itens.Count) + { + CancelarPedidoSemEstoque(message); + return; + } + + foreach (var produto in produtos) + { + var quantidadeProduto = message.Itens.FirstOrDefault(p => p.Key == produto.Id).Value; + + if (produto.EstaDisponivel(quantidadeProduto)) + { + produto.RetirarEstoque(quantidadeProduto); + produtosComEstoque.Add(produto); + } + } + + if (produtosComEstoque.Count != message.Itens.Count) + { + CancelarPedidoSemEstoque(message); + return; + } + + foreach (var produto in produtosComEstoque) + { + produtoRepository.Atualizar(produto); + } + + if (!await produtoRepository.UnitOfWork.Commit()) + { + throw new DomainException($"Problemas ao atualizar estoque do pedido {message.PedidoId}"); + } + + var pedidoBaixado = new PedidoBaixadoEstoqueIntegrationEvent(message.ClienteId, message.PedidoId); + await _bus.PublishAsync(pedidoBaixado); + } + } + + public async void CancelarPedidoSemEstoque(PedidoAutorizadoIntegrationEvent message) + { + var pedidoCancelado = new PedidoCanceladoIntegrationEvent(message.ClienteId, message.PedidoId); + await _bus.PublishAsync(pedidoCancelado); + } + } +} \ No newline at end of file diff --git a/src/services/JSE.Catalogo.API/appsettings.Development.json b/src/services/JSE.Catalogo.API/appsettings.Development.json index e93ace3..f0b1f7a 100644 --- a/src/services/JSE.Catalogo.API/appsettings.Development.json +++ b/src/services/JSE.Catalogo.API/appsettings.Development.json @@ -1,7 +1,4 @@ { - "ConnectionStrings": { - "DefaultConnection": "Server=.\\SQLEXPRESS;Database=JeffStoreEnterprise;User Id=sa;Password=Asd123!!;Trusted_Connection=true;MultipleActiveResultSets=true;TrustServerCertificate=True;" - }, "Logging": { "LogLevel": { "Default": "Information", @@ -9,6 +6,14 @@ } }, + "ConnectionStrings": { + "DefaultConnection": "Server=.\\SQLEXPRESS;Database=JeffStoreEnterprise;User Id=sa;Password=Asd123!!;Trusted_Connection=true;MultipleActiveResultSets=true;TrustServerCertificate=True;" + }, + + "MessageQueueConnection": { + "MessageBus": "host=localhost:5672;publisherConfirms=true;timeout=10" + }, + "AppSettings": { "Secret": "F9F52344-59C3-4EAC-90E6-CB47935038BE", "ExpirationHours": 2,