< Summary

Information
Class: FAU.API.Controllers.PersonalController
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/PersonalController.cs
Line coverage
100%
Covered lines: 70
Uncovered lines: 0
Coverable lines: 70
Total lines: 223
Line coverage: 100%
Branch coverage
84%
Covered branches: 37
Total branches: 44
Branch coverage: 84%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetPersonal()50%66100%
GetPersonalDetalle()100%22100%
CreatePersonal()91.66%1212100%
UpdatePersonal()87.5%88100%
RegistrarBaja()87.5%88100%
RegistrarAscenso()87.5%88100%

File(s)

/home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/PersonalController.cs

#LineLine coverage
 1using FAU.Entidades;
 2using FAU.Logica.DTOs;
 3using FAU.Logica.Services;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Mvc;
 6
 7namespace FAU.API.Controllers;
 8
 9/// <summary>
 10/// Gestión de personal militar
 11/// </summary>
 12[ApiController]
 13[Route("api/[controller]")]
 14[Authorize]
 15public class PersonalController : ControllerBase
 16{
 17    private readonly IPersonalService _personalService;
 18    private readonly ILogger<PersonalController> _logger;
 19
 2220    public PersonalController(
 2221        IPersonalService personalService,
 2222        ILogger<PersonalController> logger)
 23    {
 2224        _personalService = personalService;
 2225        _logger = logger;
 2226    }
 27
 28    /// <summary>
 29    /// Listar personal con filtros y paginación
 30    /// GET /api/personal?buscar=&cargoId=&estado=&ley=&page=&pageSize=&orderBy=&sort=
 31    /// </summary>
 32    [HttpGet]
 33    [FAU.API.Security.RequirePermission(PermisoEnum.VerPersonal)]
 34    public async Task<IActionResult> GetPersonal(
 35        [FromQuery] string? buscar = null,
 36        [FromQuery] long? cargoId = null,
 37        [FromQuery] string? estado = null,
 38        [FromQuery] string? ley = null,
 39        [FromQuery] int page = 1,
 40        [FromQuery] int pageSize = 25,
 41        [FromQuery] string? orderBy = null,
 42        [FromQuery] string sort = "asc")
 43    {
 44        try
 45        {
 46            // Validación de parámetros
 347            if (page < 1) page = 1;
 348            if (pageSize < 1) pageSize = 25;
 349            if (pageSize > 100) pageSize = 100;
 50
 351            var result = await _personalService.GetPersonalListAsync(
 352                buscar, cargoId, estado, ley, page, pageSize, orderBy, sort);
 53
 254            return Ok(ApiResponse<object>.SuccessResult(result));
 55        }
 156        catch (Exception ex)
 57        {
 158            _logger.LogError(ex, "Error al obtener listado de personal");
 159            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 60        }
 361    }
 62
 63    /// <summary>
 64    /// Obtener detalle completo de personal
 65    /// GET /api/personal/{id}
 66    /// Retorna: {id, datosPersonales, datosLaborales, historial}
 67    /// </summary>
 68    [HttpGet("{id}")]
 69    [FAU.API.Security.RequirePermission(PermisoEnum.VerPersonal)]
 70    public async Task<IActionResult> GetPersonalDetalle(long id)
 71    {
 72        try
 73        {
 374            var detalle = await _personalService.GetDetalleAsync(id);
 75
 276            if (detalle == null)
 77            {
 178                return NotFound(ApiResponse<string>.ErrorResult("Personal no encontrado"));
 79            }
 80
 181            return Ok(ApiResponse<PersonalDetalleDto>.SuccessResult(detalle));
 82        }
 183        catch (Exception ex)
 84        {
 185            _logger.LogError(ex, "Error al obtener detalle de personal {Id}", id);
 186            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 87        }
 388    }
 89
 90    /// <summary>
 91    /// Alta de personal
 92    /// POST /api/personal
 93    /// Body: { ci, nombre, apellido, fechaNacimiento, email, telefono, direccion, codigoPostal, departamento, localidad
 94    /// Response: { id, creado:true }
 95    /// </summary>
 96    [HttpPost]
 97    [FAU.API.Security.RequirePermission(PermisoEnum.CrearPersonal)]
 98    public async Task<IActionResult> CreatePersonal([FromBody] CreatePersonalRequest request)
 99    {
 100        try
 101        {
 4102            var (success, personalId, error) = await _personalService.CreatePersonalAsync(request);
 103
 3104            if (!success)
 105            {
 2106                if (error?.Contains("ya existe") == true || error?.Contains("única") == true)
 107                {
 1108                    return Conflict(ApiResponse<string>.ErrorResult(error));
 109                }
 1110                return BadRequest(ApiResponse<string>.ErrorResult(error ?? "Error al crear personal"));
 111            }
 112
 1113            return CreatedAtAction(
 1114                nameof(GetPersonalDetalle),
 1115                new { id = personalId },
 1116                ApiResponse<object>.SuccessResult(new { id = personalId, creado = true }));
 117        }
 1118        catch (Exception ex)
 119        {
 1120            _logger.LogError(ex, "Error al crear personal");
 1121            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 122        }
 4123    }
 124
 125    /// <summary>
 126    /// Modificar personal
 127    /// PUT /api/personal/{id}
 128    /// Body: { ...campos editables..., estado? }
 129    /// Response: { actualizado:true }
 130    /// </summary>
 131    [HttpPut("{id}")]
 132    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarPersonal)]
 133    public async Task<IActionResult> UpdatePersonal(long id, [FromBody] UpdatePersonalRequest request)
 134    {
 135        try
 136        {
 4137            var (success, error) = await _personalService.UpdatePersonalAsync(id, request);
 138
 3139            if (!success)
 140            {
 2141                if (error?.Contains("no encontrado") == true)
 142                {
 1143                    return NotFound(ApiResponse<string>.ErrorResult(error));
 144                }
 1145                return BadRequest(ApiResponse<string>.ErrorResult(error ?? "Error al actualizar personal"));
 146            }
 147
 1148            return Ok(ApiResponse<object>.SuccessResult(new { actualizado = true }));
 149        }
 1150        catch (Exception ex)
 151        {
 1152            _logger.LogError(ex, "Error al actualizar personal {Id}", id);
 1153            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 154        }
 4155    }
 156
 157    /// <summary>
 158    /// Registrar baja de personal
 159    /// DELETE /api/personal/{id}/baja
 160    /// Body: { motivoId, motivoBajaId, fechaBaja, observaciones }
 161    /// Response: { id, estado:'Inactivo' }
 162    /// </summary>
 163    [HttpDelete("{id}/baja")]
 164    [FAU.API.Security.RequirePermission(PermisoEnum.BajaPersonal)]
 165    public async Task<IActionResult> RegistrarBaja(long id, [FromBody] RegistrarBajaRequest request)
 166    {
 167        try
 168        {
 4169            var (success, error) = await _personalService.RegistrarBajaAsync(id, request);
 170
 3171            if (!success)
 172            {
 2173                if (error?.Contains("no encontrado") == true)
 174                {
 1175                    return NotFound(ApiResponse<string>.ErrorResult(error));
 176                }
 1177                return BadRequest(ApiResponse<string>.ErrorResult(error ?? "Error al registrar baja"));
 178            }
 179
 1180            return Ok(ApiResponse<object>.SuccessResult(
 1181                new { id = id, estado = "Inactivo" },
 1182                "Baja registrada exitosamente"));
 183        }
 1184        catch (Exception ex)
 185        {
 1186            _logger.LogError(ex, "Error al registrar baja de personal {Id}", id);
 1187            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 188        }
 4189    }
 190
 191    /// <summary>
 192    /// Registrar ascenso
 193    /// POST /api/personal/{id}/ascenso
 194    /// Body: { nuevoGradoId, fechaAscenso, Observacion, unidadId, leyId }
 195    /// Response: { id, gradoActualizado:true }
 196    /// </summary>
 197    [HttpPost("{id}/ascenso")]
 198    [FAU.API.Security.RequirePermission(PermisoEnum.AscensoPersonal)]
 199    public async Task<IActionResult> RegistrarAscenso(long id, [FromBody] FAU.Logica.DTOs.AscensoRequest request)
 200    {
 201        try
 202        {
 4203            var (success, error) = await _personalService.RegistrarAscensoAsync(id, request);
 204
 3205            if (!success)
 206            {
 2207                _logger.LogWarning("Error al registrar ascenso para PersonaId {Id}: {Error}", id, error);
 2208                if (error?.Contains("no encontrado") == true)
 209                {
 1210                    return NotFound(ApiResponse<string>.ErrorResult(error));
 211                }
 1212                return BadRequest(ApiResponse<string>.ErrorResult(error ?? "Error al registrar ascenso"));
 213            }
 214
 1215            return Ok(ApiResponse<object>.SuccessResult(new { id = id, gradoActualizado = true }, "Ascenso registrado ex
 216        }
 1217        catch (Exception ex)
 218        {
 1219            _logger.LogError(ex, "Error al registrar ascenso de personal {Id}", id);
 1220            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 221        }
 4222    }
 223}