< Summary

Information
Class: FAU.API.Controllers.PeriodosController
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/PeriodosController.cs
Line coverage
63%
Covered lines: 70
Uncovered lines: 40
Coverable lines: 110
Total lines: 249
Line coverage: 63.6%
Branch coverage
75%
Covered branches: 44
Total branches: 58
Branch coverage: 75.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
AbrirPeriodo()80%131069.23%
GetPeriodoActivo()100%2262.5%
GetPeriodo()100%2262.5%
GetPrecondiciones()0%620%
ValidarInsumos()0%620%
CerrarInsumos()75%211673.33%
ReabrirInsumos()75%12860%
Calcular()87.5%10870%
Cerrar()87.5%10870%
MapearPeriodo(...)100%11100%

File(s)

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

#LineLine coverage
 1using FAU.API.Security;
 2using FAU.Entidades;
 3using FAU.Logica.DTOs;
 4using FAU.Logica.Exceptions;
 5using FAU.Logica.Services;
 6using Microsoft.AspNetCore.Authorization;
 7using Microsoft.AspNetCore.Mvc;
 8
 9namespace FAU.API.Controllers;
 10
 11[ApiController]
 12[Route("api/liquidacion/[controller]")]
 13[Authorize(Roles = "Administrador")]
 14public class PeriodosController : ControllerBase
 15{
 16    private readonly IPeriodoService _periodoService;
 17    private readonly ILogger<PeriodosController> _logger;
 18
 1919    public PeriodosController(IPeriodoService periodoService, ILogger<PeriodosController> logger)
 20    {
 1921        _periodoService = periodoService;
 1922        _logger = logger;
 1923    }
 24
 25    [HttpPost]
 26    public async Task<IActionResult> AbrirPeriodo([FromBody] AbrirPeriodoRequest request)
 27    {
 28        try
 29        {
 330            if (!ModelState.IsValid)
 31            {
 032                return BadRequest(ApiResponse<string>.ErrorResult("Solicitud de apertura de período inválida"));
 33            }
 34
 335            var (success, periodo, error) = await _periodoService.AbrirPeriodoAsync(request.Anio, request.Mes);
 36
 337            if (!success)
 38            {
 239                if (error?.Contains("Ya existe un período activo", StringComparison.OrdinalIgnoreCase) == true)
 40                {
 141                    return Conflict(ApiResponse<string>.ErrorResult(error));
 42                }
 43
 144                return BadRequest(ApiResponse<string>.ErrorResult(error ?? "Error al abrir el período"));
 45            }
 46
 147            var dto = MapearPeriodo(periodo!);
 148            return CreatedAtAction(nameof(GetPeriodo), new { id = periodo!.Id }, ApiResponse<PeriodoDto>.SuccessResult(d
 49        }
 050        catch (Exception ex)
 51        {
 052            _logger.LogError(ex, "Error al abrir período");
 053            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 54        }
 355    }
 56
 57    [HttpGet("activo")]
 58    public async Task<IActionResult> GetPeriodoActivo()
 59    {
 60        try
 61        {
 262            var periodo = await _periodoService.ObtenerEnCursoAsync();
 263            if (periodo == null)
 64            {
 165                return NotFound(ApiResponse<string>.ErrorResult("No hay un período activo"));
 66            }
 67
 168            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo)));
 69        }
 070        catch (Exception ex)
 71        {
 072            _logger.LogError(ex, "Error al obtener período activo");
 073            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 74        }
 275    }
 76
 77    [HttpGet("{id}")]
 78    public async Task<IActionResult> GetPeriodo(long id)
 79    {
 80        try
 81        {
 282            var periodo = await _periodoService.ObtenerPorIdAsync(id);
 283            if (periodo == null)
 84            {
 185                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 86            }
 87
 188            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo)));
 89        }
 090        catch (Exception ex)
 91        {
 092            _logger.LogError(ex, "Error al obtener período {Id}", id);
 093            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 94        }
 295    }
 96
 97    [HttpGet("{id}/precondiciones")]
 98    public async Task<IActionResult> GetPrecondiciones(long id)
 99    {
 100        try
 101        {
 0102            var precondiciones = await _periodoService.ObtenerPrecondicionesAsync(id);
 0103            if (precondiciones == null)
 0104                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 0105            return Ok(ApiResponse<PrecondicionesDto>.SuccessResult(precondiciones));
 106        }
 0107        catch (Exception ex)
 108        {
 0109            _logger.LogError(ex, "Error al obtener precondiciones del período {Id}", id);
 0110            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 111        }
 0112    }
 113
 114    [HttpGet("{id}/validar-insumos")]
 115    public async Task<IActionResult> ValidarInsumos(long id)
 116    {
 117        try
 118        {
 0119            var validacion = await _periodoService.ValidarInsumosAsync(id);
 0120            if (validacion == null)
 0121                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 0122            return Ok(ApiResponse<ValidacionInsumosDto>.SuccessResult(validacion));
 123        }
 0124        catch (Exception ex)
 125        {
 0126            _logger.LogError(ex, "Error al validar insumos del período {Id}", id);
 0127            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 128        }
 0129    }
 130
 131    [HttpPost("{id}/cerrar-insumos")]
 132    public async Task<IActionResult> CerrarInsumos(long id, [FromBody] CerrarInsumosRequest? request = null)
 133    {
 134        try
 135        {
 4136            var (success, periodo, validacion, error) =
 4137                await _periodoService.CerrarInsumosAsync(id, request?.Confirmaciones);
 138
 4139            if (!success)
 140            {
 3141                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 1142                    return NotFound(ApiResponse<string>.ErrorResult(error));
 2143                if (error?.Contains("Solo se puede", StringComparison.OrdinalIgnoreCase) == true)
 1144                    return Conflict(ApiResponse<string>.ErrorResult(error));
 1145                if (validacion != null)
 1146                    return UnprocessableEntity(validacion);
 0147                return UnprocessableEntity(ApiResponse<string>.ErrorResult(error ?? "Error al cerrar insumos"));
 148            }
 149
 1150            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Insumos cerrados. Período listo pa
 151        }
 0152        catch (Exception ex)
 153        {
 0154            _logger.LogError(ex, "Error al cerrar insumos del período {Id}", id);
 0155            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 156        }
 4157    }
 158
 159    [HttpPost("{id}/reabrir-insumos")]
 160    [RequirePermission(PermisoEnum.ReabrirPeriodo)]
 161    public async Task<IActionResult> ReabrirInsumos(long id)
 162    {
 163        try
 164        {
 2165            var (success, periodo, error) = await _periodoService.ReabrirInsumosAsync(id);
 166
 2167            if (!success)
 168            {
 1169                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 0170                    return NotFound(ApiResponse<string>.ErrorResult(error));
 1171                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al reabrir insumos"));
 172            }
 173
 1174            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Insumos reabiertos. Período en est
 175        }
 0176        catch (Exception ex)
 177        {
 0178            _logger.LogError(ex, "Error al reabrir insumos del período {Id}", id);
 0179            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 180        }
 2181    }
 182
 183    [HttpPost("{id}/calcular")]
 184    public async Task<IActionResult> Calcular(long id)
 185    {
 186        try
 187        {
 3188            var (success, periodo, error) = await _periodoService.IniciarCalculoAsync(id);
 189
 3190            if (!success)
 191            {
 2192                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 1193                    return NotFound(ApiResponse<string>.ErrorResult(error));
 1194                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al iniciar cálculo"));
 195            }
 196
 1197            return Accepted(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Cálculo iniciado. El período
 198        }
 0199        catch (Exception ex)
 200        {
 0201            _logger.LogError(ex, "Error al iniciar cálculo del período {Id}", id);
 0202            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 203        }
 3204    }
 205
 206    [HttpPost("{id}/cerrar")]
 207    [RequirePermission(PermisoEnum.CerrarPeriodo)]
 208    public async Task<IActionResult> Cerrar(long id)
 209    {
 210        try
 211        {
 3212            var (success, periodo, error) = await _periodoService.CerrarAsync(id);
 213
 3214            if (!success)
 215            {
 2216                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 1217                    return NotFound(ApiResponse<string>.ErrorResult(error));
 1218                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al cerrar período"));
 219            }
 220
 1221            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Período cerrado definitivamente.")
 222        }
 0223        catch (Exception ex)
 224        {
 0225            _logger.LogError(ex, "Error al cerrar período {Id}", id);
 0226            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 227        }
 3228    }
 229
 230    private static PeriodoDto MapearPeriodo(Periodo periodo)
 231    {
 7232        return new PeriodoDto
 7233        {
 7234            Id = periodo.Id,
 7235            Anio = periodo.Anio,
 7236            Mes = periodo.Mes,
 7237            Estado = periodo.Estado,
 7238            SnapshotId = periodo.SnapshotId,
 7239            FechaApertura = periodo.FechaApertura,
 7240            UsuarioApertura = periodo.UsuarioApertura,
 7241            HashSnapshot = periodo.HashSnapshot,
 7242            FechaCierreInsumos = periodo.FechaCierreInsumos,
 7243            UsuarioCierreInsumosId = periodo.UsuarioCierreInsumosId,
 7244            FechaCalculo = periodo.FechaCalculo,
 7245            FechaCierre = periodo.FechaCierre,
 7246            UsuarioCierreId = periodo.UsuarioCierreId
 7247        };
 248    }
 249}