Skip to content

Commit

Permalink
Merge pull request #75 from pedroMF1996/BffCompras
Browse files Browse the repository at this point in the history
Gracas a Deus DEU CERTO
  • Loading branch information
pedroMF1996 authored Oct 19, 2023
2 parents 0b95e47 + 0eba2da commit 504167a
Show file tree
Hide file tree
Showing 50 changed files with 488 additions and 16 deletions.
Binary file not shown.
Binary file modified NerdStoreEnterprise/.vs/NerdStoreEnterprise/v17/.suo
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ public static IServiceCollection AddRegisterServiceConfiguration(this IServiceCo
.AddPolicyHandler(PolicyExtensions.EsperarTentar())
.AddTransientHttpErrorPolicy(
p => p.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));

services.AddHttpClient<IClienteService, ClienteService>()
.AddHttpMessageHandler<HttpCientAuthorizationDelegateHandler>()
.AddPolicyHandler(PolicyExtensions.EsperarTentar())
.AddTransientHttpErrorPolicy(
p => p.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));

services.AddHttpClient<IPedidoService, PedidoService>()
.AddHttpMessageHandler<HttpCientAuthorizationDelegateHandler>()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
using Microsoft.AspNetCore.Mvc;
using NSE.BFF.Compras.Models;
using NSE.BFF.Compras.Services;
using NSE.WebAPI.Core.Controllers;
using System.Globalization;

namespace NSE.BFF.Compras.Controllers
{
[Route("compras")]
public class PedidoController : MainController
{
private readonly ICatalogoService _catalogoService;
private readonly ICarrinhoService _carrinhoService;
private readonly IPedidoService _pedidoService;
private readonly IClienteService _clienteService;

public PedidoController(
ICatalogoService catalogoService,
ICarrinhoService carrinhoService,
IPedidoService pedidoService,
IClienteService clienteService)
{
_catalogoService = catalogoService;
_carrinhoService = carrinhoService;
_pedidoService = pedidoService;
_clienteService = clienteService;
}

[HttpPost]
[Route("pedido")]
public async Task<IActionResult> AdicionarPedido(PedidoTransacaoDTO pedido)
{
var carrinho = await _carrinhoService.ObterCarrinho();
var produtos = await _catalogoService.ObterItens(carrinho.Itens.Select(p => p.ProdutoId));
var endereco = await _clienteService.ObterEndereco();

if (!await ValidarCarrinhoProdutos(carrinho, produtos)) return CustomResponse();

PopularDadosPedido(carrinho, endereco, pedido);

return CustomResponse(await _pedidoService.FinalizarPedido(pedido));
}

[HttpGet("pedido/ultimo")]
public async Task<IActionResult> UltimoPedido()
{
var pedido = await _pedidoService.ObterUltimoPedido();
if (pedido is null)
{
AdicionarErroProcessamento("Pedido não encontrado!");
return CustomResponse();
}

return CustomResponse(pedido);
}

[HttpGet("pedido/lista-cliente")]
public async Task<IActionResult> ListaPorCliente()
{
var pedidos = await _pedidoService.ObterListaPorClienteId();

return pedidos == null ? NotFound() : CustomResponse(pedidos);
}

private async Task<bool> ValidarCarrinhoProdutos(CarrinhoDTO carrinho, IEnumerable<ItemProdutoDTO> produtos)
{
if (carrinho.Itens.Count != produtos.Count())
{
var itensIndisponiveis = carrinho.Itens.Select(c => c.ProdutoId).Except(produtos.Select(p => p.Id)).ToList();

foreach (var itemId in itensIndisponiveis)
{
var itemCarrinho = carrinho.Itens.FirstOrDefault(c => c.ProdutoId == itemId);
AdicionarErroProcessamento($"O item {itemCarrinho.Nome} não está mais disponível no catálogo, o remova do carrinho para prosseguir com a compra");
}

return false;
}

foreach (var itemCarrinho in carrinho.Itens)
{
var produtoCatalogo = produtos.FirstOrDefault(p => p.Id == itemCarrinho.ProdutoId);

if (produtoCatalogo.Valor != itemCarrinho.Valor)
{
var msgErro = $"O produto {itemCarrinho.Nome} mudou de valor (de: " +
$"{string.Format(CultureInfo.GetCultureInfo("pt-BR"), "{0:C}", itemCarrinho.Valor)} para: " +
$"{string.Format(CultureInfo.GetCultureInfo("pt-BR"), "{0:C}", produtoCatalogo.Valor)}) desde que foi adicionado ao carrinho.";

AdicionarErroProcessamento(msgErro);

var responseRemover = await _carrinhoService.RemoverItemCarrinho(itemCarrinho.ProdutoId);
if (ResponsePossuiErros(responseRemover))
{
AdicionarErroProcessamento($"Não foi possível remover automaticamente o produto {itemCarrinho.Nome} do seu carrinho, _" +
"remova e adicione novamente caso ainda deseje comprar este item");
return false;
}

itemCarrinho.Valor = produtoCatalogo.Valor;
var responseAdicionar = await _carrinhoService.AdicionarItemCarrinho(itemCarrinho);

if (ResponsePossuiErros(responseAdicionar))
{
AdicionarErroProcessamento($"Não foi possível atualizar automaticamente o produto {itemCarrinho.Nome} do seu carrinho, _" +
"adicione novamente caso ainda deseje comprar este item");
return false;
}

LimparErroProcessamento();
AdicionarErroProcessamento(msgErro + " Atualizamos o valor em seu carrinho, realize a conferência do pedido e se preferir remova o produto");

return false;
}
}

return true;
}

private void PopularDadosPedido(CarrinhoDTO carrinho, EnderecoDTO endereco, PedidoTransacaoDTO pedido)
{
pedido.VoucherCodigo = carrinho.Voucher?.Codigo;
pedido.VoucherUtilizado = carrinho.VoucherUtilizado;
pedido.ValorTotal = carrinho.ValorTotal;
pedido.Desconto = carrinho.Desconto;

carrinho.Itens.ForEach(item => pedido.PedidoItems.Add(new ItemPedidoDTO() { Nome = item.Nome,
ProdutoId = item.ProdutoId,
Quantidade = item.Quantidade,
ValorUnitario = item.Valor,
Imagem = item.Imagem}));


pedido.Endereco = endereco;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ public class AppServiceSettings
public string CatalogoUrl { get; set; }
public string PedidoUrl { get; set; }
public string PagamentoUrl { get; set; }
public string ClienteUrl { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace NSE.BFF.Compras.Models
{
public class EnderecoDTO
{
public string Logradouro { get; set; }
public string Numero { get; set; }
public string Complemento { get; set; }
public string Bairro { get; set; }
public string Cep { get; set; }
public string Cidade { get; set; }
public string Estado { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace NSE.BFF.Compras.Models
{
public class ItemPedidoDTO
{
public Guid ProdutoId { get; set; }
public string Nome { get; set; }
public decimal ValorUnitario { get; set; }
public string Imagem { get; set; }
public int Quantidade { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using NSE.Core.Validations;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;

namespace NSE.BFF.Compras.Models
{
public class PedidoDTO
{
#region Pedido

public int Codigo { get; set; }
// Autorizado = 1,
// Pago = 2,
// Recusado = 3,
// Entregue = 4,
// Cancelado = 5
public int Status { get; set; }
public DateTime Data { get; set; }
public decimal ValorTotal { get; set; }

public decimal Desconto { get; set; }
public string VoucherCodigo { get; set; }
public bool VoucherUtilizado { get; set; }

public List<ItemCarrinhoDTO> PedidoItems { get; set; } = new();

#endregion

#region Endereco

public EnderecoDTO Endereco { get; set; }

#endregion

#region Cartão

[Required(ErrorMessage = "Informe o número do cartão")]
[DisplayName("Número do Cartão")]
public string NumeroCartao { get; set; }

[Required(ErrorMessage = "Informe o nome do portador do cartão")]
[DisplayName("Nome do Portador")]
public string NomeCartao { get; set; }

[RegularExpression(@"(0[1-9]|1[0-2])\/[0-9]{2}", ErrorMessage = "O vencimento deve estar no padrão MM/AA")]
[CartaoExpiracao(ErrorMessage = "Cartão Expirado")]
[Required(ErrorMessage = "Informe o vencimento")]
[DisplayName("Data de Vencimento MM/AA")]
public string ExpiracaoCartao { get; set; }

[Required(ErrorMessage = "Informe o código de segurança")]
[DisplayName("Código de Segurança")]
public string CvvCartao { get; set; }

#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using NSE.Core.Validations;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;

namespace NSE.BFF.Compras.Models
{
public class PedidoTransacaoDTO
{
#region Pedido

public decimal ValorTotal { get; set; }
public List<ItemPedidoDTO> PedidoItems { get; set; } = new();


public string VoucherCodigo { get; set; }
public bool VoucherUtilizado { get; set; }
public decimal Desconto { get; set; }


#endregion

#region Endereco

public EnderecoDTO Endereco { get; set; }

#endregion

#region Cartão

[Required(ErrorMessage = "Informe o número do cartão")]
[DisplayName("Número do Cartão")]
public string NumeroCartao { get; set; }

[Required(ErrorMessage = "Informe o nome do portador do cartão")]
[DisplayName("Nome do Portador")]
public string NomeCartao { get; set; }

[RegularExpression(@"(0[1-9]|1[0-2])\/[0-9]{2}", ErrorMessage = "O vencimento deve estar no padrão MM/AA")]
[CartaoExpiracao(ErrorMessage = "Cartão Expirado")]
[Required(ErrorMessage = "Informe o vencimento")]
[DisplayName("Data de Vencimento MM/AA")]
public string ExpiracaoCartao { get; set; }

[Required(ErrorMessage = "Informe o código de segurança")]
[DisplayName("Código de Segurança")]
public string CvvCartao { get; set; }
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@
using NSE.BFF.Compras.Enum;
using NSE.BFF.Compras.Extensions;
using NSE.BFF.Compras.Models;
using NuGet.Packaging.Signing;

namespace NSE.BFF.Compras.Services
{
public interface ICatalogoService
{
Task<IEnumerable<ItemProdutoDTO>> ObterTodos();
Task<ItemProdutoDTO> ObterPorId(Guid id);
Task<IEnumerable<ItemProdutoDTO>> ObterItens(IEnumerable<Guid> ids);
}
public class CatalogoService : Service, ICatalogoService
{
Expand All @@ -17,6 +19,17 @@ public CatalogoService(HttpClient httpClient, IOptions<AppServiceSettings> appSe
{
}

public async Task<IEnumerable<ItemProdutoDTO>> ObterItens(IEnumerable<Guid> ids)
{
var idsRequest = string.Join(",", ids);

var response = await _httpClient.GetAsync($"/catalogo/produtos/lista/{idsRequest}/");

TratarErrosResponse(response);

return await DeserializarObjetoResponse<IEnumerable<ItemProdutoDTO>>(response);
}

public async Task<ItemProdutoDTO> ObterPorId(Guid id)
{
var response = await _httpClient.GetAsync($"/catalogo/produtos/{id}");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Microsoft.Extensions.Options;
using NSE.BFF.Compras.Enum;
using NSE.BFF.Compras.Extensions;
using NSE.BFF.Compras.Models;
using System.Net;

namespace NSE.BFF.Compras.Services
{
public interface IClienteService
{
Task<EnderecoDTO> ObterEndereco();
}
public class ClienteService : Service, IClienteService
{
public ClienteService(HttpClient httpClient, IOptions<AppServiceSettings> appSettingsOpt) :
base(httpClient, AppSettingsUrlEnum.Cliente, appSettingsOpt)
{
}

public async Task<EnderecoDTO> ObterEndereco()
{
var response = await _httpClient.GetAsync("/cliente/endereco/");

if (response.StatusCode == HttpStatusCode.NotFound) return null;

TratarErrosResponse(response);

return await DeserializarObjetoResponse<EnderecoDTO>(response);
}
}
}
Loading

0 comments on commit 504167a

Please sign in to comment.