diff --git a/OpenAdm.Api/Controllers/FaturaController.cs b/OpenAdm.Api/Controllers/FaturaController.cs index 1e93f85..df8cd0c 100644 --- a/OpenAdm.Api/Controllers/FaturaController.cs +++ b/OpenAdm.Api/Controllers/FaturaController.cs @@ -32,4 +32,13 @@ public async Task Criar(FaturaCriarAdmDto faturaCriarAdmDto) var result = await _faturaService.CriarAdmAsync(faturaCriarAdmDto); return Ok(result); } + + [HttpGet("get")] + [ProducesResponseType(200)] + [ProducesResponseType(400)] + public async Task Get([FromQuery] Guid id) + { + var result = await _faturaService.GetCompletaAsync(id); + return Ok(result); + } } diff --git a/OpenAdm.Api/Controllers/ParcelaController.cs b/OpenAdm.Api/Controllers/ParcelaController.cs index 9b6e2ba..2c5f8c5 100644 --- a/OpenAdm.Api/Controllers/ParcelaController.cs +++ b/OpenAdm.Api/Controllers/ParcelaController.cs @@ -4,6 +4,7 @@ using OpenAdm.Application.Dtos.Response; using OpenAdm.Application.Interfaces; using OpenAdm.Application.Models.ContasAReceberModel; +using OpenAdm.Application.Models.FaturasModel; using OpenAdm.Domain.Enuns; using OpenAdm.Domain.Model; using OpenAdm.Infra.Paginacao; @@ -68,4 +69,34 @@ public async Task Edit(FaturaEdit faturaAReceberEdit) var fatura = await _parcelaService.EditAsync(faturaAReceberEdit); return Ok(fatura); } + + [HttpPut("editar-parcela")] + [ProducesResponseType(200)] + [ProducesResponseType(400)] + public async Task EditarParcela(ParcelaEditDto parcelaEditDto) + { + var fatura = await _parcelaService.EditarAsync(parcelaEditDto); + return Ok(fatura); + } + + [HttpPost("nova-parcela")] + [ProducesResponseType(200)] + [ProducesResponseType(400)] + public async Task NovaParcela(ParcelaCriarDto parcelaCriarDto) + { + var fatura = await _parcelaService.AddAsync(parcelaCriarDto); + return Ok(fatura); + } + + [HttpDelete("excluir")] + [ProducesResponseType(200)] + [ProducesResponseType(400)] + public async Task Excluir([FromQuery] Guid id) + { + var result = await _parcelaService.ExcluirAsync(id); + return Ok(new + { + result + }); + } } diff --git a/OpenAdm.Application/Dtos/FaturasDtos/ParcelaCriarAdmDto.cs b/OpenAdm.Application/Dtos/FaturasDtos/ParcelaCriarAdmDto.cs index b86afb0..daa25fa 100644 --- a/OpenAdm.Application/Dtos/FaturasDtos/ParcelaCriarAdmDto.cs +++ b/OpenAdm.Application/Dtos/FaturasDtos/ParcelaCriarAdmDto.cs @@ -1,4 +1,5 @@ using OpenAdm.Domain.Enuns; +using OpenAdm.Domain.Exceptions; namespace OpenAdm.Application.Dtos.FaturasDtos; @@ -11,3 +12,27 @@ public class ParcelaCriarAdmDto public decimal? Desconto { get; set; } public string? Observacao { get; set; } } + +public class ParcelaCriarDto +{ + public Guid FaturaId { get; set; } + public DateTime? DataDeVencimento { get; set; } + public int NumeroDaFatura { get; set; } + public MeioDePagamentoEnum? MeioDePagamento { get; set; } + public decimal Valor { get; set; } + public decimal? Desconto { get; set; } + public string? Observacao { get; set; } + + public void Validar() + { + if (Valor == 0) + { + throw new ExceptionApi("Informe o valor da fatura!"); + } + + if (Desconto.HasValue && Desconto.Value > Valor) + { + throw new ExceptionApi("O desconto da fatura não pode ser maior que o desconto!"); + } + } +} diff --git a/OpenAdm.Application/Dtos/FaturasDtos/ParcelaEditDto.cs b/OpenAdm.Application/Dtos/FaturasDtos/ParcelaEditDto.cs new file mode 100644 index 0000000..27cb0a7 --- /dev/null +++ b/OpenAdm.Application/Dtos/FaturasDtos/ParcelaEditDto.cs @@ -0,0 +1,14 @@ +using OpenAdm.Domain.Enuns; + +namespace OpenAdm.Application.Dtos.FaturasDtos; + +public class ParcelaEditDto +{ + public Guid Id { get; set; } + public decimal Valor { get; set; } + public decimal? Desconto { get; set; } + public MeioDePagamentoEnum? MeioDePagamento { get; set; } + public StatusParcelaEnum Status { get; set; } + public DateTime DataDeVencimento { get; set; } + public DateTime? DataDePagamento { get; set; } +} diff --git a/OpenAdm.Application/Interfaces/IFaturaService.cs b/OpenAdm.Application/Interfaces/IFaturaService.cs index 1a05241..2133db8 100644 --- a/OpenAdm.Application/Interfaces/IFaturaService.cs +++ b/OpenAdm.Application/Interfaces/IFaturaService.cs @@ -11,4 +11,6 @@ public interface IFaturaService Task VerificarFechamentoAsync(Guid id); Task GerarPagamentoAsync(MeioDePagamentoEnum meioDePagamento, Guid pedidoId); Task CriarAdmAsync(FaturaCriarAdmDto faturaCriarAdmDto); + Task GetCompletaAsync(Guid id); + Task GetByIdAsync(Guid id); } diff --git a/OpenAdm.Application/Interfaces/IParcelaService.cs b/OpenAdm.Application/Interfaces/IParcelaService.cs index bcd7284..7c3c06f 100644 --- a/OpenAdm.Application/Interfaces/IParcelaService.cs +++ b/OpenAdm.Application/Interfaces/IParcelaService.cs @@ -13,8 +13,11 @@ public interface IParcelaService Task GetSumAReceberAsync(); Task> FaturasDashBoardAsync(); Task PagarAsync(PagarParcelaDto pagarFaturaAReceberDto); + Task EditarAsync(ParcelaEditDto parcelaEditDto); + Task AddAsync(ParcelaCriarDto parcelaCriarDto); Task GetByIdAsync(Guid id); Task EditAsync(FaturaEdit faturaAReceberEdit); + Task ExcluirAsync(Guid id); Task> PaginacaoAsync(PaginacaoParcelaDto paginacaoFaturaAReceberDto); Task> GetByPedidoIdAsync(Guid pedidoId, StatusParcelaEnum? statusFaturaContasAReceberEnum); } diff --git a/OpenAdm.Application/Interfaces/IPedidoService.cs b/OpenAdm.Application/Interfaces/IPedidoService.cs index 23a5ab4..cf2a9f0 100644 --- a/OpenAdm.Application/Interfaces/IPedidoService.cs +++ b/OpenAdm.Application/Interfaces/IPedidoService.cs @@ -9,6 +9,7 @@ public interface IPedidoService { Task> GetPaginacaoAsync(PaginacaoPedidoDto paginacaoPedidoDto); Task> GetPedidosEmAbertAsync(); + Task> GetPedidosAsync(IList ids); Task> GetPedidosUsuarioAsync(int statusPedido, Guid usuarioId); Task GetAsync(Guid pedidoId); Task PedidoProducaoAsync(RelatorioProducaoDto relatorioProducaoDto); diff --git a/OpenAdm.Application/Models/FaturasModel/ParcelaViewModel.cs b/OpenAdm.Application/Models/FaturasModel/ParcelaViewModel.cs index c9bb7ad..d021163 100644 --- a/OpenAdm.Application/Models/FaturasModel/ParcelaViewModel.cs +++ b/OpenAdm.Application/Models/FaturasModel/ParcelaViewModel.cs @@ -11,6 +11,7 @@ public class ParcelaViewModel : BaseViewModel public DateTime DataDeVencimento { get; set; } public DateTime? DataDePagamento { get; set; } public int NumeroDaFatura { get; set; } + public long NumeroDoPedido { get; set; } public MeioDePagamentoEnum? MeioDePagamento { get; set; } public decimal Valor { get; set; } public decimal? Desconto { get; set; } diff --git a/OpenAdm.Application/Services/FaturaService.cs b/OpenAdm.Application/Services/FaturaService.cs index 198aba0..73dbb1f 100644 --- a/OpenAdm.Application/Services/FaturaService.cs +++ b/OpenAdm.Application/Services/FaturaService.cs @@ -113,6 +113,21 @@ public async Task GerarPagamentoAsync(MeioDePagamentoEnum me }; } + public async Task GetByIdAsync(Guid id) + { + var fatura = await _contasAReceberRepository.GetByIdAsync(id) + ?? throw new ExceptionApi("Não foi possível localizar a fatura!"); + return (FaturaViewModel)fatura; + } + + public async Task GetCompletaAsync(Guid id) + { + var fatura = await _contasAReceberRepository.GetByIdCompletaAsync(id) + ?? throw new ExceptionApi("Não foi possível localizar a fatura!"); + + return (FaturaViewModel)fatura; + } + public async Task VerificarFechamentoAsync(Guid id) { var contasAReceber = await _contasAReceberRepository.GetByIdAsync(id) diff --git a/OpenAdm.Application/Services/ParcelaService.cs b/OpenAdm.Application/Services/ParcelaService.cs index 8aa97ca..a2031ea 100644 --- a/OpenAdm.Application/Services/ParcelaService.cs +++ b/OpenAdm.Application/Services/ParcelaService.cs @@ -3,6 +3,7 @@ using OpenAdm.Application.Interfaces.Pedidos; using OpenAdm.Application.Models.FaturasModel; using OpenAdm.Application.Models.ParcelasModel; +using OpenAdm.Domain.Entities; using OpenAdm.Domain.Enuns; using OpenAdm.Domain.Exceptions; using OpenAdm.Domain.Extensions; @@ -16,17 +17,41 @@ public sealed class ParcelaService : IParcelaService { private readonly IParcelaRepository _faturaContasAReceberRepository; private readonly IFaturaService _contasAReceberService; - private readonly IUpdateStatusPedidoService _pedidoService; + private readonly IUpdateStatusPedidoService _updateStatusPedidoService; + private readonly IPedidoService _pedidoService; public ParcelaService( IParcelaRepository faturaContasAReceberRepository, IFaturaService contasAReceberService, - IUpdateStatusPedidoService pedidoService) + IUpdateStatusPedidoService updateStatusPedidoService, + IPedidoService pedidoService) { _faturaContasAReceberRepository = faturaContasAReceberRepository; _contasAReceberService = contasAReceberService; + _updateStatusPedidoService = updateStatusPedidoService; _pedidoService = pedidoService; } + public async Task AddAsync(ParcelaCriarDto parcelaCriarDto) + { + parcelaCriarDto.Validar(); + var fatura = await _contasAReceberService.GetByIdAsync(parcelaCriarDto.FaturaId); + var proximoNumeroParcela = (fatura.Parcelas.MaxBy(x => x.NumeroDaFatura)?.NumeroDaFatura ?? 0) + 1; + + var parcela = Parcela.NovaFatura( + dataDeVencimento: parcelaCriarDto.DataDeVencimento ?? DateTime.Now, + numeroDaFatura: proximoNumeroParcela, + meioDePagamento: parcelaCriarDto.MeioDePagamento, + valor: parcelaCriarDto.Valor, + desconto: parcelaCriarDto.Desconto, + observacao: parcelaCriarDto.Observacao, + faturaId: parcelaCriarDto.FaturaId, + idExterno: null); + + await _faturaContasAReceberRepository.AddAsync(parcela); + + return (ParcelaViewModel)parcela; + } + public async Task BaixarFaturaWebHookAsync(NotificationFaturaWebHook notificationFaturaWebHook) { var fatura = await _faturaContasAReceberRepository.GetByIdExternoAsync(notificationFaturaWebHook.Data.Id); @@ -40,7 +65,7 @@ public async Task BaixarFaturaWebHookAsync(NotificationFaturaWebHook notificatio if (fatura.Fatura != null && fatura.Fatura.PedidoId.HasValue) { - await _pedidoService.UpdateStatusPedidoAsync(new() + await _updateStatusPedidoService.UpdateStatusPedidoAsync(new() { PedidoId = fatura.Fatura.PedidoId.Value, StatusPedido = StatusPedido.Faturado @@ -50,6 +75,25 @@ await _pedidoService.UpdateStatusPedidoAsync(new() await _contasAReceberService.VerificarFechamentoAsync(fatura.FaturaId); } + public async Task EditarAsync(ParcelaEditDto parcelaEditDto) + { + var parcela = await _faturaContasAReceberRepository.GetByIdAsync(parcelaEditDto.Id) + ?? throw new ExceptionApi("Não foi possível localizar a parcela"); + + parcela.Edit( + status: parcelaEditDto.Status, + dataDeVencimento: parcelaEditDto.DataDeVencimento, + dataDePagamento: parcelaEditDto.DataDePagamento, + meioDePagamento: parcelaEditDto.MeioDePagamento, + valor: parcelaEditDto.Valor, + desconto: parcelaEditDto.Desconto, + observacao: parcela.Observacao); + + await _faturaContasAReceberRepository.UpdateAsync(parcela); + + return (ParcelaViewModel)parcela; + } + public async Task EditAsync(FaturaEdit faturaAReceberEdit) { var fatura = await _faturaContasAReceberRepository.GetByIdAsync(faturaAReceberEdit.Id) @@ -69,6 +113,16 @@ public async Task EditAsync(FaturaEdit faturaAReceberEdit) return (ParcelaViewModel)fatura; } + public async Task ExcluirAsync(Guid id) + { + var parcela = await _faturaContasAReceberRepository.GetByIdAsync(id) + ?? throw new ExceptionApi("Não foi possível localizar a parcela"); + + await _faturaContasAReceberRepository.DeleteAsync(parcela); + + return true; + } + public async Task> FaturasDashBoardAsync() { var faturas = await _faturaContasAReceberRepository.SumTotalMesesAsync(TipoFaturaEnum.A_Receber); @@ -124,10 +178,29 @@ public async Task> PaginacaoAsync(Paginacao var paginacao = await _faturaContasAReceberRepository .PaginacaoAsync(paginacaoFaturaAReceberDto); + var pedidosIds = paginacao + .Values + .Where(x => x.Fatura.PedidoId.HasValue) + .Select(x => x.Fatura.PedidoId!.Value) + .ToList(); + + var pedidos = await _pedidoService.GetPedidosAsync(pedidosIds); + var parcelasViewModel = new List(); + + foreach (var parcela in paginacao.Values) + { + var parcelaViewModel = (ParcelaViewModel)parcela; + if (parcela.Fatura.PedidoId.HasValue && pedidos.TryGetValue(parcela.Fatura.PedidoId.Value, out var pedido)) + { + parcelaViewModel.NumeroDoPedido = pedido.Numero; + } + parcelasViewModel.Add(parcelaViewModel); + } + return new PaginacaoViewModel() { TotalDeRegistros = paginacao.TotalDeRegistros, - Values = paginacao.Values.Select(x => (ParcelaViewModel)x).ToList(), + Values = parcelasViewModel, TotalPaginas = paginacao.TotalPaginas, }; } diff --git a/OpenAdm.Application/Services/PedidoService.cs b/OpenAdm.Application/Services/PedidoService.cs index 251a37e..6082780 100644 --- a/OpenAdm.Application/Services/PedidoService.cs +++ b/OpenAdm.Application/Services/PedidoService.cs @@ -46,6 +46,19 @@ public async Task> GetPaginacaoAsync(Paginac }; } + public async Task> GetPedidosAsync(IList ids) + { + var pedidos = await _pedidoRepository.GetPedidosAsync(ids); + var pedidosViewModel = new Dictionary(); + + foreach (var pedido in pedidos) + { + pedidosViewModel.TryAdd(pedido.Key, new PedidoViewModel().ForModelPedidoEmAberto(pedido.Value)); + } + + return pedidosViewModel; + } + public async Task> GetPedidosEmAbertAsync() { var pedidos = await _pedidoRepository.GetPedidosEmAbertoAsync(); diff --git a/OpenAdm.Domain/Interfaces/IFaturaRepository.cs b/OpenAdm.Domain/Interfaces/IFaturaRepository.cs index ccb59ae..25e90c2 100644 --- a/OpenAdm.Domain/Interfaces/IFaturaRepository.cs +++ b/OpenAdm.Domain/Interfaces/IFaturaRepository.cs @@ -5,4 +5,5 @@ namespace OpenAdm.Domain.Interfaces; public interface IFaturaRepository : IGenericRepository { Task GetByIdAsync(Guid id); + Task GetByIdCompletaAsync(Guid id); } diff --git a/OpenAdm.Domain/Interfaces/IPedidoRepository.cs b/OpenAdm.Domain/Interfaces/IPedidoRepository.cs index e560c64..e68ca3c 100644 --- a/OpenAdm.Domain/Interfaces/IPedidoRepository.cs +++ b/OpenAdm.Domain/Interfaces/IPedidoRepository.cs @@ -14,5 +14,6 @@ public interface IPedidoRepository : IGenericRepository Task GetQuantidadePorStatusUsuarioAsync(Guid usuarioId, StatusPedido statusPedido); Task> GetPedidosByRelatorioPorPeriodoAsync(RelatorioPedidoDto relatorioPedidoDto); Task> GetPedidosEmAbertoAsync(); + Task> GetPedidosAsync(IList ids); Task GetCountPedidosEmAbertoAsync(); } diff --git a/OpenAdm.Infra/Cached/Cached/PedidoCached.cs b/OpenAdm.Infra/Cached/Cached/PedidoCached.cs index e4b86f4..867a88f 100644 --- a/OpenAdm.Infra/Cached/Cached/PedidoCached.cs +++ b/OpenAdm.Infra/Cached/Cached/PedidoCached.cs @@ -105,4 +105,7 @@ public async Task UpdateAsync(Pedido entity) public Task> PaginacaoDropDownAsync(PaginacaoDropDown paginacaoDropDown) => _pedidoRepository.PaginacaoDropDownAsync(paginacaoDropDown); + + public Task> GetPedidosAsync(IList ids) + => _pedidoRepository.GetPedidosAsync(ids); } diff --git a/OpenAdm.Infra/Repositories/FaturaRepository.cs b/OpenAdm.Infra/Repositories/FaturaRepository.cs index a4aabcd..7119fcb 100644 --- a/OpenAdm.Infra/Repositories/FaturaRepository.cs +++ b/OpenAdm.Infra/Repositories/FaturaRepository.cs @@ -19,4 +19,15 @@ public FaturaRepository(ParceiroContext parceiroContext) : base(parceiroContext) .Include(x => x.Parcelas) .FirstOrDefaultAsync(x => x.Id == id); } + + public async Task GetByIdCompletaAsync(Guid id) + { + return await _parceiroContext + .Faturas + .AsNoTracking() + .Include(x => x.Parcelas) + .Include(x => x.Usuario) + .Include(x => x.Pedido) + .FirstOrDefaultAsync(x => x.Id == id); + } } diff --git a/OpenAdm.Infra/Repositories/PedidoRepository.cs b/OpenAdm.Infra/Repositories/PedidoRepository.cs index 52c958b..9a97e17 100644 --- a/OpenAdm.Infra/Repositories/PedidoRepository.cs +++ b/OpenAdm.Infra/Repositories/PedidoRepository.cs @@ -89,6 +89,15 @@ public async Task GetCountPedidosEmAbertoAsync() return pedido; } + public async Task> GetPedidosAsync(IList ids) + { + return await _parceiroContext + .Pedidos + .AsNoTracking() + .Where(x => ids.Contains(x.Id)) + .ToDictionaryAsync(x => x.Id, x => x); + } + public async Task> GetPedidosByRelatorioPorPeriodoAsync(RelatorioPedidoDto relatorioPedidoDto) { return await _parceiroContext