< 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
74%
Covered lines: 68
Uncovered lines: 23
Coverable lines: 91
Total lines: 212
Line coverage: 74.7%
Branch coverage
86%
Covered branches: 43
Total branches: 50
Branch coverage: 86%
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%
CerrarInsumos()91.66%141275%
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.ObtenerActivoAsync();
 263            if (periodo == null)
 64            {
 165                return NotFound(ApiResponse<string>.ErrorResult("No hay un período abierto"));
 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    [HttpPost("{id}/cerrar-insumos")]
 98    public async Task<IActionResult> CerrarInsumos(long id)
 99    {
 100        try
 101        {
 4102            var (success, periodo, error) = await _periodoService.CerrarInsumosAsync(id);
 103
 4104            if (!success)
 105            {
 3106                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 1107                    return NotFound(ApiResponse<string>.ErrorResult(error));
 2108                if (error?.Contains("Solo se puede", StringComparison.OrdinalIgnoreCase) == true)
 1109                    return Conflict(ApiResponse<string>.ErrorResult(error));
 1110                return UnprocessableEntity(ApiResponse<string>.ErrorResult(error ?? "Error al cerrar insumos"));
 111            }
 112
 1113            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Insumos cerrados. Período listo pa
 114        }
 0115        catch (Exception ex)
 116        {
 0117            _logger.LogError(ex, "Error al cerrar insumos del período {Id}", id);
 0118            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 119        }
 4120    }
 121
 122    [HttpPost("{id}/reabrir-insumos")]
 123    [RequirePermission(PermisoEnum.ReabrirPeriodo)]
 124    public async Task<IActionResult> ReabrirInsumos(long id)
 125    {
 126        try
 127        {
 2128            var (success, periodo, error) = await _periodoService.ReabrirInsumosAsync(id);
 129
 2130            if (!success)
 131            {
 1132                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 0133                    return NotFound(ApiResponse<string>.ErrorResult(error));
 1134                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al reabrir insumos"));
 135            }
 136
 1137            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Insumos reabiertos. Período en est
 138        }
 0139        catch (Exception ex)
 140        {
 0141            _logger.LogError(ex, "Error al reabrir insumos del período {Id}", id);
 0142            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 143        }
 2144    }
 145
 146    [HttpPost("{id}/calcular")]
 147    public async Task<IActionResult> Calcular(long id)
 148    {
 149        try
 150        {
 3151            var (success, periodo, error) = await _periodoService.IniciarCalculoAsync(id);
 152
 3153            if (!success)
 154            {
 2155                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 1156                    return NotFound(ApiResponse<string>.ErrorResult(error));
 1157                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al iniciar cálculo"));
 158            }
 159
 1160            return Accepted(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Cálculo iniciado. El período
 161        }
 0162        catch (Exception ex)
 163        {
 0164            _logger.LogError(ex, "Error al iniciar cálculo del período {Id}", id);
 0165            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 166        }
 3167    }
 168
 169    [HttpPost("{id}/cerrar")]
 170    [RequirePermission(PermisoEnum.CerrarPeriodo)]
 171    public async Task<IActionResult> Cerrar(long id)
 172    {
 173        try
 174        {
 3175            var (success, periodo, error) = await _periodoService.CerrarAsync(id);
 176
 3177            if (!success)
 178            {
 2179                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 1180                    return NotFound(ApiResponse<string>.ErrorResult(error));
 1181                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al cerrar período"));
 182            }
 183
 1184            return Ok(ApiResponse<PeriodoDto>.SuccessResult(MapearPeriodo(periodo!), "Período cerrado definitivamente.")
 185        }
 0186        catch (Exception ex)
 187        {
 0188            _logger.LogError(ex, "Error al cerrar período {Id}", id);
 0189            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 190        }
 3191    }
 192
 193    private static PeriodoDto MapearPeriodo(Periodo periodo)
 194    {
 7195        return new PeriodoDto
 7196        {
 7197            Id = periodo.Id,
 7198            Anio = periodo.Anio,
 7199            Mes = periodo.Mes,
 7200            Estado = periodo.Estado,
 7201            SnapshotId = periodo.SnapshotId,
 7202            FechaApertura = periodo.FechaApertura,
 7203            UsuarioApertura = periodo.UsuarioApertura,
 7204            HashSnapshot = periodo.HashSnapshot,
 7205            FechaCierreInsumos = periodo.FechaCierreInsumos,
 7206            UsuarioCierreInsumosId = periodo.UsuarioCierreInsumosId,
 7207            FechaCalculo = periodo.FechaCalculo,
 7208            FechaCierre = periodo.FechaCierre,
 7209            UsuarioCierreId = periodo.UsuarioCierreId
 7210        };
 211    }
 212}