using GestionIntegral.Api.Dtos.Distribucion; using GestionIntegral.Api.Services.Distribucion; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Collections.Generic; using System.Security.Claims; using System.Threading.Tasks; namespace GestionIntegral.Api.Controllers.Distribucion { [Route("api/publicaciones/{idPublicacion}/porcentajespago")] // Anidado [ApiController] [Authorize] public class PorcentajesPagoController : ControllerBase // Para Porcentajes de Pago Distribuidores { private readonly IPorcPagoService _porcPagoService; private readonly ILogger _logger; // Permiso DG004 para gestionar porcentajes de pago de distribuidores private const string PermisoGestionarPorcentajes = "DG004"; public PorcentajesPagoController(IPorcPagoService porcPagoService, ILogger logger) { _porcPagoService = porcPagoService; _logger = logger; } private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc); private int? GetCurrentUserId() { if (int.TryParse(User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"), out int userId)) return userId; return null; } [HttpGet] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task GetPorcentajesPorPublicacion(int idPublicacion) { if (!TienePermiso("DP001") && !TienePermiso(PermisoGestionarPorcentajes)) return Forbid(); // DP001 para ver Publicación var porcentajes = await _porcPagoService.ObtenerPorPublicacionIdAsync(idPublicacion); return Ok(porcentajes); } [HttpGet("{idPorcentaje:int}", Name = "GetPorcPagoById")] [ProducesResponseType(typeof(PorcPagoDto), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetPorcPagoById(int idPublicacion, int idPorcentaje) { if (!TienePermiso("DP001") && !TienePermiso(PermisoGestionarPorcentajes)) return Forbid(); var porcPago = await _porcPagoService.ObtenerPorIdAsync(idPorcentaje); if (porcPago == null || porcPago.IdPublicacion != idPublicacion) return NotFound(); return Ok(porcPago); } [HttpPost] [ProducesResponseType(typeof(PorcPagoDto), StatusCodes.Status201Created)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task CreatePorcPago(int idPublicacion, [FromBody] CreatePorcPagoDto createDto) { if (!TienePermiso(PermisoGestionarPorcentajes)) return Forbid(); if (idPublicacion != createDto.IdPublicacion) return BadRequest(new { message = "ID de publicación en ruta no coincide con el del cuerpo." }); if (!ModelState.IsValid) return BadRequest(ModelState); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var (dto, error) = await _porcPagoService.CrearAsync(createDto, userId.Value); if (error != null) return BadRequest(new { message = error }); if (dto == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear porcentaje."); return CreatedAtRoute("GetPorcPagoById", new { idPublicacion = dto.IdPublicacion, idPorcentaje = dto.IdPorcentaje }, dto); } [HttpPut("{idPorcentaje:int}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task UpdatePorcPago(int idPublicacion, int idPorcentaje, [FromBody] UpdatePorcPagoDto updateDto) { if (!TienePermiso(PermisoGestionarPorcentajes)) return Forbid(); if (!ModelState.IsValid) return BadRequest(ModelState); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var existente = await _porcPagoService.ObtenerPorIdAsync(idPorcentaje); if (existente == null || existente.IdPublicacion != idPublicacion) return NotFound(new { message = "Porcentaje no encontrado para esta publicación."}); var (exito, error) = await _porcPagoService.ActualizarAsync(idPorcentaje, updateDto, userId.Value); if (!exito) return BadRequest(new { message = error }); return NoContent(); } [HttpDelete("{idPorcentaje:int}")] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task DeletePorcPago(int idPublicacion, int idPorcentaje) { if (!TienePermiso(PermisoGestionarPorcentajes)) return Forbid(); var userId = GetCurrentUserId(); if (userId == null) return Unauthorized(); var existente = await _porcPagoService.ObtenerPorIdAsync(idPorcentaje); if (existente == null || existente.IdPublicacion != idPublicacion) return NotFound(new { message = "Porcentaje no encontrado para esta publicación."}); var (exito, error) = await _porcPagoService.EliminarAsync(idPorcentaje, userId.Value); if (!exito) return BadRequest(new { message = error }); return NoContent(); } } }