212 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			212 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using GestionIntegral.Api.Dtos.Distribucion; | ||
|  | using GestionIntegral.Api.Services.Distribucion; | ||
|  | using Microsoft.AspNetCore.Authorization; | ||
|  | using Microsoft.AspNetCore.Mvc; | ||
|  | using Microsoft.Extensions.Logging; | ||
|  | using System; | ||
|  | using System.Collections.Generic; | ||
|  | using System.Linq; | ||
|  | using System.Security.Claims; | ||
|  | using System.Threading.Tasks; | ||
|  | 
 | ||
|  | namespace GestionIntegral.Api.Controllers.Distribucion | ||
|  | { | ||
|  |     [Route("api/novedadescanilla")] // Ruta base más genérica para las novedades | ||
|  |     [ApiController] | ||
|  |     [Authorize] // Todas las acciones requieren autenticación | ||
|  |     public class NovedadesCanillaController : ControllerBase | ||
|  |     { | ||
|  |         private readonly INovedadCanillaService _novedadService; | ||
|  |         private readonly ILogger<NovedadesCanillaController> _logger; | ||
|  | 
 | ||
|  |         public NovedadesCanillaController(INovedadCanillaService novedadService, ILogger<NovedadesCanillaController> logger) | ||
|  |         { | ||
|  |             _novedadService = novedadService; | ||
|  |             _logger = logger; | ||
|  |         } | ||
|  | 
 | ||
|  |         // --- Helper para verificar permisos --- | ||
|  |         private bool TienePermiso(string codAccRequerido) | ||
|  |         { | ||
|  |             if (User.IsInRole("SuperAdmin")) return true; | ||
|  |             return User.HasClaim(c => c.Type == "permission" && c.Value == codAccRequerido); | ||
|  |         } | ||
|  | 
 | ||
|  |         // --- Helper para obtener User ID --- | ||
|  |         private int? GetCurrentUserId() | ||
|  |         { | ||
|  |             var userIdClaim = User.FindFirstValue(ClaimTypes.NameIdentifier) ?? User.FindFirstValue("sub"); | ||
|  |             if (int.TryParse(userIdClaim, out int userId)) | ||
|  |             { | ||
|  |                 return userId; | ||
|  |             } | ||
|  |             _logger.LogWarning("No se pudo obtener el UserId del token JWT en NovedadesCanillaController."); | ||
|  |             return null; | ||
|  |         } | ||
|  | 
 | ||
|  |         // GET: api/novedadescanilla/porcanilla/{idCanilla} | ||
|  |         // Obtiene todas las novedades para un canillita específico, opcionalmente filtrado por fecha. | ||
|  |         // Permiso: CG001 (Ver Canillas) o CG006 (Gestionar Novedades). | ||
|  |         // Si CG006 es "Permite la Carga/Modificación", entonces CG001 podría ser más apropiado solo para ver. | ||
|  |         // Vamos a usar CG001 para ver. Si se quiere más granularidad, se puede crear un permiso "Ver Novedades". | ||
|  |         [HttpGet("porcanilla/{idCanilla:int}")] | ||
|  |         [ProducesResponseType(typeof(IEnumerable<NovedadCanillaDto>), StatusCodes.Status200OK)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
|  |         public async Task<IActionResult> GetNovedadesPorCanilla(int idCanilla, [FromQuery] DateTime? fechaDesde, [FromQuery] DateTime? fechaHasta) | ||
|  |         { | ||
|  |             if (!TienePermiso("CG001") && !TienePermiso("CG006")) // Necesita al menos uno de los dos | ||
|  |             { | ||
|  |                  _logger.LogWarning("Acceso denegado a GetNovedadesPorCanilla para el usuario {UserId} y canillita {IdCanilla}", GetCurrentUserId() ?? 0, idCanilla); | ||
|  |                 return Forbid(); | ||
|  |             } | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var novedades = await _novedadService.ObtenerPorCanillaAsync(idCanilla, fechaDesde, fechaHasta); | ||
|  |                 return Ok(novedades); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al obtener novedades para Canillita ID: {IdCanilla}", idCanilla); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener las novedades."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // GET: api/novedadescanilla/{idNovedad} | ||
|  |         // Obtiene una novedad específica por su ID. | ||
|  |         // Permiso: CG001 o CG006 | ||
|  |         [HttpGet("{idNovedad:int}", Name = "GetNovedadCanillaById")] | ||
|  |         [ProducesResponseType(typeof(NovedadCanillaDto), StatusCodes.Status200OK)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||
|  |         [ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
|  |         public async Task<IActionResult> GetNovedadCanillaById(int idNovedad) | ||
|  |         { | ||
|  |             if (!TienePermiso("CG001") && !TienePermiso("CG006")) return Forbid(); | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var novedad = await _novedadService.ObtenerPorIdAsync(idNovedad); | ||
|  |                 if (novedad == null) | ||
|  |                 { | ||
|  |                     return NotFound(new { message = $"Novedad con ID {idNovedad} no encontrada." }); | ||
|  |                 } | ||
|  |                 return Ok(novedad); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al obtener NovedadCanilla por ID: {IdNovedad}", idNovedad); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al obtener la novedad."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |         // POST: api/novedadescanilla | ||
|  |         // Crea una nueva novedad. El IdCanilla viene en el DTO. | ||
|  |         // Permiso: CG006 (Permite la Carga/Modificación de Novedades) | ||
|  |         [HttpPost] | ||
|  |         [ProducesResponseType(typeof(NovedadCanillaDto), StatusCodes.Status201Created)] | ||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||
|  |         [ProducesResponseType(StatusCodes.Status401Unauthorized)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
|  |         public async Task<IActionResult> CreateNovedadCanilla([FromBody] CreateNovedadCanillaDto createDto) | ||
|  |         { | ||
|  |             if (!TienePermiso("CG006")) return Forbid(); | ||
|  | 
 | ||
|  |             if (!ModelState.IsValid) return BadRequest(ModelState); | ||
|  | 
 | ||
|  |             var idUsuario = GetCurrentUserId(); | ||
|  |             if (idUsuario == null) return Unauthorized("No se pudo obtener el ID del usuario del token."); | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var (novedadCreada, error) = await _novedadService.CrearAsync(createDto, idUsuario.Value); | ||
|  | 
 | ||
|  |                 if (error != null) return BadRequest(new { message = error }); | ||
|  |                 if (novedadCreada == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear la novedad."); | ||
|  |                  | ||
|  |                 // Devuelve la ruta al recurso creado y el recurso mismo | ||
|  |                 return CreatedAtRoute("GetNovedadCanillaById", new { idNovedad = novedadCreada.IdNovedad }, novedadCreada); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al crear NovedadCanilla para Canilla ID: {IdCanilla} por Usuario ID: {UsuarioId}", createDto.IdCanilla, idUsuario); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al crear la novedad."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // PUT: api/novedadescanilla/{idNovedad} | ||
|  |         // Actualiza una novedad existente. | ||
|  |         // Permiso: CG006 | ||
|  |         [HttpPut("{idNovedad:int}")] | ||
|  |         [ProducesResponseType(StatusCodes.Status204NoContent)] | ||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||
|  |         [ProducesResponseType(StatusCodes.Status401Unauthorized)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||
|  |         [ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
|  |         public async Task<IActionResult> UpdateNovedadCanilla(int idNovedad, [FromBody] UpdateNovedadCanillaDto updateDto) | ||
|  |         { | ||
|  |             if (!TienePermiso("CG006")) return Forbid(); | ||
|  | 
 | ||
|  |             if (!ModelState.IsValid) return BadRequest(ModelState); | ||
|  | 
 | ||
|  |             var idUsuario = GetCurrentUserId(); | ||
|  |             if (idUsuario == null) return Unauthorized("No se pudo obtener el ID del usuario del token."); | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var (exito, error) = await _novedadService.ActualizarAsync(idNovedad, updateDto, idUsuario.Value); | ||
|  | 
 | ||
|  |                 if (!exito) | ||
|  |                 { | ||
|  |                     if (error == "Novedad no encontrada.") return NotFound(new { message = error }); | ||
|  |                     return BadRequest(new { message = error }); | ||
|  |                 } | ||
|  |                 return NoContent(); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al actualizar NovedadCanilla ID: {IdNovedad} por Usuario ID: {UsuarioId}", idNovedad, idUsuario); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al actualizar la novedad."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // DELETE: api/novedadescanilla/{idNovedad} | ||
|  |         // Elimina una novedad. | ||
|  |         // Permiso: CG006 (Asumiendo que el mismo permiso para Carga/Modificación incluye eliminación) | ||
|  |         // Si la eliminación es un permiso separado (ej: CG00X), ajústalo. | ||
|  |         [HttpDelete("{idNovedad:int}")] | ||
|  |         [ProducesResponseType(StatusCodes.Status204NoContent)] | ||
|  |         [ProducesResponseType(StatusCodes.Status401Unauthorized)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||
|  |         [ProducesResponseType(StatusCodes.Status500InternalServerError)] | ||
|  |         public async Task<IActionResult> DeleteNovedadCanilla(int idNovedad) | ||
|  |         { | ||
|  |             if (!TienePermiso("CG006")) return Forbid(); | ||
|  | 
 | ||
|  |             var idUsuario = GetCurrentUserId(); | ||
|  |             if (idUsuario == null) return Unauthorized("No se pudo obtener el ID del usuario del token."); | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var (exito, error) = await _novedadService.EliminarAsync(idNovedad, idUsuario.Value); | ||
|  | 
 | ||
|  |                 if (!exito) | ||
|  |                 { | ||
|  |                     if (error == "Novedad no encontrada.") return NotFound(new { message = error }); | ||
|  |                     return BadRequest(new { message = error }); // Podría ser otro error, como "no se pudo eliminar" | ||
|  |                 } | ||
|  |                 return NoContent(); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al eliminar NovedadCanilla ID: {IdNovedad} por Usuario ID: {UsuarioId}", idNovedad, idUsuario); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al eliminar la novedad."); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } |