190 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			190 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using GestionIntegral.Api.Dtos.Zonas;     // Para los DTOs | ||
|  | using GestionIntegral.Api.Services.Distribucion;         // Para IZonaService | ||
|  | using Microsoft.AspNetCore.Authorization;   // Para [Authorize] | ||
|  | using Microsoft.AspNetCore.Mvc; | ||
|  | using System.Security.Claims; | ||
|  | 
 | ||
|  | namespace GestionIntegral.Api.Controllers.Distribucion | ||
|  | { | ||
|  |     [Route("api/[controller]")]
 | ||
|  |     [ApiController] | ||
|  |     [Authorize] // <-- Protección GENERAL: El usuario debe estar logueado | ||
|  |     public class ZonasController : ControllerBase | ||
|  |     { | ||
|  |         private readonly IZonaService _zonaService; | ||
|  |         private readonly ILogger<ZonasController> _logger; | ||
|  | 
 | ||
|  |         public ZonasController(IZonaService zonaService, ILogger<ZonasController> logger) | ||
|  |         { | ||
|  |             _zonaService = zonaService; | ||
|  |             _logger = logger; | ||
|  |         } | ||
|  | 
 | ||
|  |         // Helper para verificar permisos directamente desde los claims del token | ||
|  |         private bool TienePermiso(string codAccRequerido) | ||
|  |         { | ||
|  |             // SuperAdmin siempre tiene permiso | ||
|  |             if (User.IsInRole("SuperAdmin")) return true; | ||
|  |             // Busca si el claim 'permission' con el valor requerido existe | ||
|  |             return User.HasClaim(c => c.Type == "permission" && c.Value == codAccRequerido); | ||
|  |         } | ||
|  | 
 | ||
|  |         // Helper para obtener el ID del usuario del token | ||
|  |         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 ZonasController."); | ||
|  |             return null; | ||
|  |         } | ||
|  | 
 | ||
|  | 
 | ||
|  |         // GET: api/zonas | ||
|  |         [HttpGet] | ||
|  |         [ProducesResponseType(typeof(IEnumerable<ZonaDto>), StatusCodes.Status200OK)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         public async Task<IActionResult> GetAllZonas([FromQuery] string? nombre, [FromQuery] string? descripcion) | ||
|  |         { | ||
|  |             // Verificar permiso ZD001 | ||
|  |             if (!TienePermiso("ZD001")) | ||
|  |             { | ||
|  |                  _logger.LogWarning("Acceso denegado a GetAllZonas para el usuario {UserId}", GetCurrentUserId() ?? 0); | ||
|  |                  return Forbid(); // Devolver 403 Forbidden | ||
|  |             } | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var zonas = await _zonaService.ObtenerTodasAsync(nombre, descripcion); | ||
|  |                 return Ok(zonas); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al obtener todas las Zonas."); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al procesar la solicitud."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // GET: api/zonas/{id} | ||
|  |         [HttpGet("{id:int}", Name = "GetZonaById")] | ||
|  |         [ProducesResponseType(typeof(ZonaDto), StatusCodes.Status200OK)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||
|  |         public async Task<IActionResult> GetZonaById(int id) | ||
|  |         { | ||
|  |             if (!TienePermiso("ZD001")) return Forbid(); | ||
|  | 
 | ||
|  |             try | ||
|  |             { | ||
|  |                 var zona = await _zonaService.ObtenerPorIdAsync(id); | ||
|  |                 if (zona == null) | ||
|  |                 { | ||
|  |                     return NotFound(new { message = $"Zona con ID {id} no encontrada o inactiva." }); | ||
|  |                 } | ||
|  |                 return Ok(zona); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al obtener Zona por ID: {Id}", id); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al procesar la solicitud."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // POST: api/zonas | ||
|  |         [HttpPost] | ||
|  |         [ProducesResponseType(typeof(ZonaDto), StatusCodes.Status201Created)] | ||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         public async Task<IActionResult> CreateZona([FromBody] CreateZonaDto createDto) | ||
|  |         { | ||
|  |             if (!TienePermiso("ZD002")) 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 (zonaCreada, error) = await _zonaService.CrearAsync(createDto, idUsuario.Value); | ||
|  | 
 | ||
|  |                 if (error != null) return BadRequest(new { message = error }); | ||
|  |                 if (zonaCreada == null) return StatusCode(StatusCodes.Status500InternalServerError, "Error al crear la zona."); | ||
|  | 
 | ||
|  |                 return CreatedAtRoute("GetZonaById", new { id = zonaCreada.IdZona }, zonaCreada); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al crear Zona. Nombre: {Nombre}", createDto.Nombre); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al procesar la solicitud."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // PUT: api/zonas/{id} | ||
|  |         [HttpPut("{id:int}")] | ||
|  |         [ProducesResponseType(StatusCodes.Status204NoContent)] | ||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||
|  |         public async Task<IActionResult> UpdateZona(int id, [FromBody] UpdateZonaDto updateDto) | ||
|  |         { | ||
|  |             if (!TienePermiso("ZD003")) 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 _zonaService.ActualizarAsync(id, updateDto, idUsuario.Value); | ||
|  | 
 | ||
|  |                 if (!exito) | ||
|  |                 { | ||
|  |                     if (error != null && (error.Contains("no encontrada") || error.Contains("eliminada (inactiva)"))) | ||
|  |                         return NotFound(new { message = error }); | ||
|  |                     return BadRequest(new { message = error ?? "Error desconocido al actualizar." }); | ||
|  |                 } | ||
|  |                 return NoContent(); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al actualizar Zona ID: {Id}", id); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al procesar la solicitud."); | ||
|  |             } | ||
|  |         } | ||
|  | 
 | ||
|  |         // DELETE: api/zonas/{id} | ||
|  |         [HttpDelete("{id:int}")] | ||
|  |         [ProducesResponseType(StatusCodes.Status204NoContent)] | ||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] // Si está en uso | ||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||
|  |         public async Task<IActionResult> DeleteZona(int id) | ||
|  |         { | ||
|  |             if (!TienePermiso("ZD004")) 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 _zonaService.EliminarAsync(id, idUsuario.Value); | ||
|  | 
 | ||
|  |                 if (!exito) | ||
|  |                 { | ||
|  |                     if (error == "Zona no encontrada.") return NotFound(new { message = error }); | ||
|  |                     return BadRequest(new { message = error ?? "Error desconocido al eliminar." }); // Ej: "En uso" | ||
|  |                 } | ||
|  |                 return NoContent(); | ||
|  |             } | ||
|  |             catch (Exception ex) | ||
|  |             { | ||
|  |                 _logger.LogError(ex, "Error al eliminar Zona ID: {Id}", id); | ||
|  |                 return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al procesar la solicitud."); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  | } |