Skip to content
This repository has been archived by the owner on Apr 27, 2024. It is now read-only.

refatorando produtos usando abordagem clean arch #100

Merged
merged 4 commits into from
Jan 20, 2024
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 @@ -39,6 +39,11 @@ public async Task<string> GerarPagamentoEQrCode(string pagamentoMercadoPago, str
return result.qr_data;
}

public Task<string> GerarPedidoEQrCode(string pedidoMercadoPago, string usuarioId, string posId)
gabriellima09 marked this conversation as resolved.
Show resolved Hide resolved
{
throw new NotImplementedException();
}

private StatusPagamentoEnum ConverterResultadoParaEnum(string statusStr)
{
return statusStr.ToLower() switch
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,17 @@ namespace TechLanches.Adapter.SqlServer.Repositories
public class ProdutoRepository : IProdutoRepository
{
private readonly TechLanchesDbContext _context;

public IUnitOfWork UnitOfWork => _context;

public ProdutoRepository(TechLanchesDbContext context)
{
_context = context ?? throw new ArgumentNullException(nameof(context));
}

public void Atualizar(Produto produto)
{
_context.Entry(produto).State = EntityState.Modified;
}

public async Task<List<Produto>> BuscarPorCategoria(CategoriaProduto categoria)
{
return await _context.Produtos.Where(x => x.Categoria.Id == categoria.Id).ToListAsync(); //mesmo erro do Cliente?
return await _context.Produtos.Where(x => x.Categoria.Id == categoria.Id).ToListAsync();
}

public async Task<Produto> BuscarPorId(int produtoId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder.ApplyConfigurationsFromAssembly(typeof(TechLanchesDbContext).Assembly);
}

public async Task Commit()
public async Task CommitAsync()
{
await base.SaveChangesAsync();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
using TechLanches.Adapter.ACL.Pagamento.QrCode.Provedores.MercadoPago;
using TechLanches.Adapter.RabbitMq.Messaging;
using TechLanches.Adapter.SqlServer.Repositories;
using TechLanches.Application.Controllers;
using TechLanches.Application.Controllers.Interfaces;
using TechLanches.Application.Gateways;
using TechLanches.Application.Gateways.Interfaces;
using TechLanches.Application.Ports.Repositories;
using TechLanches.Application.Ports.Services;
using TechLanches.Application.Ports.Services.Interfaces;
using TechLanches.Application.Presenters;
using TechLanches.Application.Presenters.Interfaces;
using TechLanches.Domain.Services;
using TechLanches.Domain.Validations;

Expand All @@ -24,15 +30,21 @@ public static void AddDependencyInjectionConfiguration(this IServiceCollection s
services.AddScoped<IStatusPedidoValidacao, StatusPedidoRecebidoValidacao>();
services.AddScoped<IStatusPedidoValidacao, StatusPedidoRetiradoValidacao>();

services.AddSingleton<IProdutoPresenter, ProdutoPresenter>();

services.AddScoped<IProdutoController, ProdutoController>();

services.AddScoped<IProdutoGateway, ProdutoGateway>();

services.AddScoped<IClienteService, ClienteService>();
services.AddScoped<IPedidoService, PedidoService>();
services.AddScoped<IProdutoService, ProdutoService>();
services.AddScoped<IPagamentoService, PagamentoService>();
services.AddScoped<ICheckoutService, CheckoutService>();
services.AddScoped<IQrCodeGeneratorService, QrCodeGeneratorService>();
services.AddScoped<IMercadoPagoMockadoService, MercadoPagoMockadoService>();
services.AddScoped<IMercadoPagoService, MercadoPagoService>();
services.AddScoped<IStatusPedidoValidacaoService, StatusPedidoValidacaoService>();

services.AddScoped<IClienteRepository, ClienteRepository>();
services.AddScoped<IPedidoRepository, PedidoRepository>();
services.AddScoped<IProdutoRepository, ProdutoRepository>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using TechLanches.Application.Ports.Services.Interfaces;
using TechLanches.Domain.Enums;
using TechLanches.Domain.ValueObjects;
using TechLanches.Application.Controllers.Interfaces;

namespace TechLanches.Adapter.API.Endpoints;

Expand Down Expand Up @@ -97,15 +98,15 @@ private static async Task<IResult> BuscarPedidosPorStatus(

private static async Task<IResult> CadastrarPedido(
[FromBody] PedidoRequestDTO pedidoDto,
[FromServices] IPedidoService pedidoService, IClienteService clienteService, IProdutoService produtoService)
[FromServices] IPedidoService pedidoService, IClienteService clienteService, IProdutoController produtoController)
{
if (!pedidoDto.ItensPedido.Any())
return Results.BadRequest(MensagensConstantes.SEM_NENHUM_ITEM_PEDIDO);

var itensPedido = new List<ItemPedido>();
foreach (var itemPedido in pedidoDto.ItensPedido)
{
var dadosProduto = await produtoService.BuscarPorId(itemPedido.IdProduto);
var dadosProduto = await produtoController.BuscarPorId(itemPedido.IdProduto);
var itemPedidoCompleto = new ItemPedido(dadosProduto.Id, itemPedido.Quantidade, dadosProduto.Preco);

itensPedido.Add(itemPedidoCompleto);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
using TechLanches.Adapter.API.Constantes;
using Swashbuckle.AspNetCore.Annotations;
using TechLanches.Application.DTOs;
using TechLanches.Application.Ports.Services.Interfaces;
using TechLanches.Domain.ValueObjects;
using TechLanches.Application.Controllers.Interfaces;

namespace TechLanches.Adapter.API.Endpoints
{
Expand Down Expand Up @@ -72,21 +72,30 @@ public static void MapProdutoEndpoints(this IEndpointRouteBuilder app)

private static async Task<IResult> CadastrarProduto(
[FromBody] ProdutoRequestDTO produtoRequest,
[FromServices] IProdutoService produtoService)
[FromServices] IProdutoController produtoController)
{
var produto = await produtoService.Cadastrar(produtoRequest.Nome, produtoRequest.Descricao, produtoRequest.Preco, produtoRequest.CategoriaId);
var produto = await produtoController.Cadastrar(
produtoRequest.Nome,
produtoRequest.Descricao,
produtoRequest.Preco,
produtoRequest.CategoriaId);

return produto is not null
? Results.Created($"api/produtos/{produto.Id}", produto.Adapt<ProdutoResponseDTO>())
? Results.Created($"api/produtos/{produto.Id}", produto)
: Results.BadRequest(new ErrorResponseDTO { MensagemErro = "Erro ao cadastrar produto.", StatusCode = HttpStatusCode.BadRequest });
}

private static async Task<IResult> AtualizarProduto(
int id,
[FromBody] ProdutoRequestDTO produtoRequest,
[FromServices] IProdutoService produtoService)
[FromServices] IProdutoController produtoController)
{
await produtoService.Atualizar(id, produtoRequest.Nome, produtoRequest.Descricao, produtoRequest.Preco, produtoRequest.CategoriaId);
await produtoController.Atualizar(
id,
produtoRequest.Nome,
produtoRequest.Descricao,
produtoRequest.Preco,
produtoRequest.CategoriaId);

return produtoRequest is not null
? Results.Ok(produtoRequest.Adapt<ProdutoResponseDTO>())
Expand All @@ -95,51 +104,49 @@ private static async Task<IResult> AtualizarProduto(

private static async Task<IResult> DeletarProduto(
[FromRoute] int id,
[FromServices] IProdutoService produtoService)
[FromServices] IProdutoController produtoController)
{
var produto = await produtoService.BuscarPorId(id);
var produto = await produtoController.BuscarPorId(id);

if (produto is null)
return Results.NotFound(new ErrorResponseDTO { MensagemErro = $"Nenhum produto encontrado para o id: {id}", StatusCode = HttpStatusCode.BadRequest });
return Results.NotFound(RetornarErroDtoNotFound());

await produtoService.Deletar(produto);
await produtoController.Deletar(id);
return Results.Ok();
}

private static async Task<IResult> BuscarTodosProdutos(
[FromServices] IProdutoService produtoService)
[FromServices] IProdutoController produtoController)
{
var produtos = await produtoService.BuscarTodos();
var produtos = await produtoController.BuscarTodos();

if (produtos is null)
return Results.NotFound(new ErrorResponseDTO { MensagemErro = $"Nenhum produto encontrado", StatusCode = HttpStatusCode.BadRequest });
return Results.NotFound(RetornarErroDtoNotFound());


return Results.Ok(produtos.Adapt<List<ProdutoResponseDTO>>());
}

private static async Task<IResult> BuscarProdutoPorId(
[FromRoute] int id,
[FromServices] IProdutoService produtoService)
[FromServices] IProdutoController produtoController)
{
var produto = await produtoService.BuscarPorId(id);
if (produto is null)
return Results.NotFound(new ErrorResponseDTO { MensagemErro = $"Nenhum produto encontrado para o id: {id}", StatusCode = HttpStatusCode.BadRequest });
var produto = await produtoController.BuscarPorId(id);

return produto is not null
? Results.Ok(produto.Adapt<ProdutoResponseDTO>())
: Results.NotFound(id);
? Results.Ok(produto)
: Results.NotFound(RetornarErroDtoNotFound());
}

private static async Task<IResult> BuscarProdutosPorCategoria(
[FromRoute] int categoriaId,
[FromServices] IProdutoService produtoService)
[FromServices] IProdutoController produtoController)
{
var produtos = await produtoService.BuscarPorCategoria(categoriaId);
var produtos = await produtoController.BuscarPorCategoria(categoriaId);

return produtos is not null
return produtos is not null || produtos!.Count > 0
? Results.Ok(produtos.Adapt<List<ProdutoResponseDTO>>())
: Results.NotFound(new ErrorResponseDTO { MensagemErro = $"Nenhum produto encontrado para a categoria id: {categoriaId}", StatusCode = HttpStatusCode.BadRequest });

: Results.NotFound(RetornarErroDtoNotFound());
}

private static async Task<IResult> BuscarCategorias()
Expand All @@ -152,5 +159,10 @@ private static async Task<IResult> BuscarCategorias()
? Results.Ok(await Task.FromResult(categorias))
: Results.NotFound(new ErrorResponseDTO { MensagemErro = "Nenhuma categoria encontrada.", StatusCode = HttpStatusCode.BadRequest });
}

private static ErrorResponseDTO RetornarErroDtoNotFound()
{
return new ErrorResponseDTO { MensagemErro = $"Nenhum produto encontrado", StatusCode = HttpStatusCode.NotFound };
}
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using Polly;
using Polly.Extensions.Http;
using System.Net.Http.Headers;
using TechLanches.Adapter.ACL.Pagamento.QrCode.Provedores.MercadoPago;
using TechLanches.Adapter.FilaPedidos;
using TechLanches.Adapter.FilaPedidos.Health;
Expand All @@ -6,9 +9,15 @@
using TechLanches.Adapter.RabbitMq.Options;
using TechLanches.Adapter.SqlServer;
using TechLanches.Adapter.SqlServer.Repositories;
using TechLanches.Application.Controllers;
using TechLanches.Application.Controllers.Interfaces;
using TechLanches.Application.Gateways;
using TechLanches.Application.Gateways.Interfaces;
using TechLanches.Application.Ports.Repositories;
using TechLanches.Application.Ports.Services;
using TechLanches.Application.Ports.Services.Interfaces;
using TechLanches.Application.Presenters;
using TechLanches.Application.Presenters.Interfaces;
using TechLanches.Domain.Services;
using TechLanches.Domain.Validations;

Expand All @@ -25,6 +34,17 @@
services.Configure<WorkerOptions>(settingsConfig.GetSection("Worker"));
services.Configure<RabbitOptions>(settingsConfig.GetSection("RabbitMQ"));

var retryPolicy = HttpPolicyExtensions.HandleTransientHttpError()
.WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(retryAttempt));

//Registrar httpclient
services.AddHttpClient("MercadoPago", httpClient =>
{
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", settingsConfig.GetSection($"ApiMercadoPago:AccessToken").Value);
httpClient.BaseAddress = new Uri(settingsConfig.GetSection($"ApiMercadoPago:BaseUrl").Value);
}).AddPolicyHandler(retryPolicy);

services.AddSingleton<IStatusPedidoValidacao, StatusPedidoCriadoValidacao>();
services.AddSingleton<IStatusPedidoValidacao, StatusPedidoCanceladoValidacao>();
services.AddSingleton<IStatusPedidoValidacao, StatusPedidoEmPreparacaoValidacao>();
Expand All @@ -38,9 +58,14 @@
services.AddSingleton<IFilaPedidoRepository, FilaPedidoRepository>();
services.AddSingleton<IFilaPedidoService, FilaPedidoService>();

services.AddSingleton<IProdutoPresenter, ProdutoPresenter>();

services.AddSingleton<IProdutoController, ProdutoController>();

services.AddSingleton<IProdutoGateway, ProdutoGateway>();

services.AddSingleton<IClienteService, ClienteService>();
services.AddSingleton<IPedidoService, PedidoService>();
services.AddSingleton<IProdutoService, ProdutoService>();
services.AddSingleton<IPagamentoService, PagamentoService>();
services.AddSingleton<ICheckoutService, CheckoutService>();
services.AddSingleton<IQrCodeGeneratorService, QrCodeGeneratorService>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.4" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
<PackageReference Include="Polly.Extensions.Http" Version="3.0.0" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using TechLanches.Application.DTOs;

namespace TechLanches.Application.Controllers.Interfaces
{
public interface IProdutoController
{
Task<List<ProdutoResponseDTO>> BuscarTodos();
Task<ProdutoResponseDTO> BuscarPorId(int produtoId);
Task<List<ProdutoResponseDTO>> BuscarPorCategoria(int categoriaId);
Task<ProdutoResponseDTO> Cadastrar(string nome, string descricao, decimal preco, int categoriaId);
Task Atualizar(int produtoId, string nome, string descricao, decimal preco, int categoriaId);
Task Deletar(int produtoId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using TechLanches.Application.Controllers.Interfaces;
using TechLanches.Application.DTOs;
using TechLanches.Application.Gateways.Interfaces;
using TechLanches.Application.Presenters;
using TechLanches.Application.Presenters.Interfaces;
using TechLanches.Application.UseCases.Produtos;
using TechLanches.Domain.Aggregates;
using TechLanches.Domain.ValueObjects;

namespace TechLanches.Application.Controllers
{
public class ProdutoController : IProdutoController
{
private readonly IProdutoGateway _produtoGateway;
private readonly IProdutoPresenter _produtoPresenter;

public ProdutoController(IProdutoGateway produtoGateway, IProdutoPresenter produtoPresenter)
{
_produtoGateway = produtoGateway;
_produtoPresenter = produtoPresenter;
}

public async Task Atualizar(
int produtoId,
string nome,
string descricao,
decimal preco,
int categoriaId)
{
await ProdutoUseCases.Atualizar(
produtoId,
nome,
descricao,
preco,
categoriaId,
_produtoGateway);

await _produtoGateway.CommitAsync();
}

public async Task<List<ProdutoResponseDTO>> BuscarPorCategoria(int categoriaId)
{
var categoriaProduto = CategoriaProduto.From(categoriaId);
var produtos = await _produtoGateway.BuscarPorCategoria(categoriaProduto);

return _produtoPresenter.ParaListaDto(produtos);
}

public async Task<ProdutoResponseDTO> BuscarPorId(int produtoId)
{
var produto = await _produtoGateway.BuscarPorId(produtoId);

return _produtoPresenter.ParaDto(produto);
}

public async Task<List<ProdutoResponseDTO>> BuscarTodos()
{
var produtos = await _produtoGateway.BuscarTodos();

return _produtoPresenter.ParaListaDto(produtos);
}

public async Task<ProdutoResponseDTO> Cadastrar(string nome, string descricao, decimal preco, int categoriaId)
{
var novoProduto = await ProdutoUseCases.Cadastrar(nome, descricao, preco, categoriaId, _produtoGateway);

await _produtoGateway.CommitAsync();

return _produtoPresenter.ParaDto(novoProduto);
}

public async Task Deletar(int produtoId)
{
var produto = await _produtoGateway.BuscarPorId(produtoId);

produto.DeletarProduto();

await _produtoGateway.CommitAsync();
}
}
}
Loading
Loading