Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ public PedidoAutorizadoIntegrationEvent(Guid clienteId, Guid pedidoId, IDictiona
Itens = itens;
}
}

}
16 changes: 16 additions & 0 deletions src/services/JSE.Catalogo.API/Configuration/MessageBusConfig.cs
Original file line number Diff line number Diff line change
@@ -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<CatalogoIntegrationHandler>();
}
}
}
1 change: 1 addition & 0 deletions src/services/JSE.Catalogo.API/JSE.Catalogo.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

<ItemGroup>
<ProjectReference Include="..\..\building blocks\JSE.Core\JSE.Core.csproj" />
<ProjectReference Include="..\..\building blocks\JSE.MessageBus\JSE.MessageBus.csproj" />
<ProjectReference Include="..\..\building blocks\JSE.WebAPI.Core\JSE.WebAPI.Core.csproj" />
<ProjectReference Include="..\JSE.Identidade.API\JSE.Identidade.API.csproj" />
</ItemGroup>
Expand Down
13 changes: 12 additions & 1 deletion src/services/JSE.Catalogo.API/Models/Produto.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
1 change: 1 addition & 0 deletions src/services/JSE.Catalogo.API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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<PedidoAutorizadoIntegrationEvent>("PedidoAutorizado", async request =>
await BaixarEstoque(request));
}

private async Task BaixarEstoque(PedidoAutorizadoIntegrationEvent message)
{
using (var scope = _serviceProvider.CreateScope())
{
var produtosComEstoque = new List<Produto>();
var produtoRepository = scope.ServiceProvider.GetRequiredService<IProdutoRepository>();

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);
}
}
}
11 changes: 8 additions & 3 deletions src/services/JSE.Catalogo.API/appsettings.Development.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=.\\SQLEXPRESS;Database=JeffStoreEnterprise;User Id=sa;Password=Asd123!!;Trusted_Connection=true;MultipleActiveResultSets=true;TrustServerCertificate=True;"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},

"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,
Expand Down
69 changes: 69 additions & 0 deletions src/services/JSE.Pedido.API/Services/PedidoIntegrationHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
using JSE.Core.DomainObjects;
using JSE.Core.Messages.Integration;
using JSE.MessageBus;
using JSE.Pedidos.Domain.Pedidos;

namespace JSE.Pedidos.API.Services
{
public class PedidoIntegrationHandler : BackgroundService
{
private readonly IMessageBus _bus;
private readonly IServiceProvider _serviceProvider;

public PedidoIntegrationHandler(IServiceProvider serviceProvider, IMessageBus bus)
{
_serviceProvider = serviceProvider;
_bus = bus;
}
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
SetSubscribers();
return Task.CompletedTask;
}

private void SetSubscribers()
{
_bus.SubscribeAsync<PedidoCanceladoIntegrationEvent>("PedidoCancelado",
async request => await CancelarPedido(request));

_bus.SubscribeAsync<PedidoPagoIntegrationEvent>("PedidoPago",
async request => await FinalizarPedido(request));
}

private async Task CancelarPedido(PedidoCanceladoIntegrationEvent message)
{
using (var scope = _serviceProvider.CreateScope())
{
var pedidoRepository = scope.ServiceProvider.GetRequiredService<IPedidoRepository>();

var pedido = await pedidoRepository.ObterPorId(message.PedidoId);
pedido.CancelarPedido();

pedidoRepository.Atualizar(pedido);

if (!await pedidoRepository.UnitOfWork.Commit())
{
throw new DomainException($"Problemas ao cancelar o pedido {message.PedidoId}");
}
}
}

private async Task FinalizarPedido(PedidoPagoIntegrationEvent message)
{
using (var scope = _serviceProvider.CreateScope())
{
var pedidoRepository = scope.ServiceProvider.GetRequiredService<IPedidoRepository>();

var pedido = await pedidoRepository.ObterPorId(message.PedidoId);
pedido.FinalizarPedido();

pedidoRepository.Atualizar(pedido);

if (!await pedidoRepository.UnitOfWork.Commit())
{
throw new DomainException($"Problemas ao finalizar o pedido {message.PedidoId}");
}
}
}
}
}
10 changes: 10 additions & 0 deletions src/services/JSE.Pedido.Domain/Pedidos/Pedido.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ public void AutorizarPedido()
PedidoStatus = PedidoStatus.Autorizado;
}

public void CancelarPedido()
{
PedidoStatus = PedidoStatus.Cancelado;
}

public void FinalizarPedido()
{
PedidoStatus = PedidoStatus.Pago;
}

public void AtribuirVoucher(Voucher voucher)
{
VoucherUtilizado = true;
Expand Down
Loading