< 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
35%
Covered lines: 32
Uncovered lines: 59
Coverable lines: 91
Total lines: 212
Line coverage: 35.1%
Branch coverage
16%
Covered branches: 8
Total branches: 50
Branch coverage: 16%
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()70%161061.53%
GetPeriodoActivo()50%3250%
GetPeriodo()0%620%
CerrarInsumos()0%156120%
ReabrirInsumos()0%7280%
Calcular()0%7280%
Cerrar()0%7280%
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
 319    public PeriodosController(IPeriodoService periodoService, ILogger<PeriodosController> logger)
 20    {
 321        _periodoService = periodoService;
 322        _logger = logger;
 323    }
 24
 25    [HttpPost]
 26    public async Task<IActionResult> AbrirPeriodo([FromBody] AbrirPeriodoRequest request)
 27    {
 28        try
 29        {
 230            if (!ModelState.IsValid)
 31            {
 032                return BadRequest(ApiResponse<string>.ErrorResult("Solicitud de apertura de período inválida"));
 33            }
 34
 235            var (success, periodo, error) = await _periodoService.AbrirPeriodoAsync(request.Anio, request.Mes);
 36
 237            if (!success)
 38            {
 139                if (error?.Contains("Ya existe un período activo", StringComparison.OrdinalIgnoreCase) == true)
 40                {
 041                    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        }
 255    }
 56
 57    [HttpGet("activo")]
 58    public async Task<IActionResult> GetPeriodoActivo()
 59    {
 60        try
 61        {
 162            var periodo = await _periodoService.ObtenerActivoAsync();
 163            if (periodo == null)
 64            {
 165                return NotFound(ApiResponse<string>.ErrorResult("No hay un período abierto"));
 66            }
 67
 068            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        }
 175    }
 76
 77    [HttpGet("{id}")]
 78    public async Task<IActionResult> GetPeriodo(long id)
 79    {
 80        try
 81        {
 082            var periodo = await _periodoService.ObtenerPorIdAsync(id);
 083            if (periodo == null)
 84            {
 085                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 86            }
 87
 088            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        }
 095    }
 96
 97    [HttpPost("{id}/cerrar-insumos")]
 98    public async Task<IActionResult> CerrarInsumos(long id)
 99    {
 100        try
 101        {
 0102            var (success, periodo, error) = await _periodoService.CerrarInsumosAsync(id);
 103
 0104            if (!success)
 105            {
 0106                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 0107                    return NotFound(ApiResponse<string>.ErrorResult(error));
 0108                if (error?.Contains("Solo se puede", StringComparison.OrdinalIgnoreCase) == true)
 0109                    return Conflict(ApiResponse<string>.ErrorResult(error));
 0110                return UnprocessableEntity(ApiResponse<string>.ErrorResult(error ?? "Error al cerrar insumos"));
 111            }
 112
 0113            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        }
 0120    }
 121
 122    [HttpPost("{id}/reabrir-insumos")]
 123    [RequirePermission(PermisoEnum.ReabrirPeriodo)]
 124    public async Task<IActionResult> ReabrirInsumos(long id)
 125    {
 126        try
 127        {
 0128            var (success, periodo, error) = await _periodoService.ReabrirInsumosAsync(id);
 129
 0130            if (!success)
 131            {
 0132                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 0133                    return NotFound(ApiResponse<string>.ErrorResult(error));
 0134                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al reabrir insumos"));
 135            }
 136
 0137            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        }
 0144    }
 145
 146    [HttpPost("{id}/calcular")]
 147    public async Task<IActionResult> Calcular(long id)
 148    {
 149        try
 150        {
 0151            var (success, periodo, error) = await _periodoService.IniciarCalculoAsync(id);
 152
 0153            if (!success)
 154            {
 0155                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 0156                    return NotFound(ApiResponse<string>.ErrorResult(error));
 0157                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al iniciar cálculo"));
 158            }
 159
 0160            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        }
 0167    }
 168
 169    [HttpPost("{id}/cerrar")]
 170    [RequirePermission(PermisoEnum.CerrarPeriodo)]
 171    public async Task<IActionResult> Cerrar(long id)
 172    {
 173        try
 174        {
 0175            var (success, periodo, error) = await _periodoService.CerrarAsync(id);
 176
 0177            if (!success)
 178            {
 0179                if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 0180                    return NotFound(ApiResponse<string>.ErrorResult(error));
 0181                return Conflict(ApiResponse<string>.ErrorResult(error ?? "Error al cerrar período"));
 182            }
 183
 0184            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        }
 0191    }
 192
 193    private static PeriodoDto MapearPeriodo(Periodo periodo)
 194    {
 1195        return new PeriodoDto
 1196        {
 1197            Id = periodo.Id,
 1198            Anio = periodo.Anio,
 1199            Mes = periodo.Mes,
 1200            Estado = periodo.Estado,
 1201            SnapshotId = periodo.SnapshotId,
 1202            FechaApertura = periodo.FechaApertura,
 1203            UsuarioApertura = periodo.UsuarioApertura,
 1204            HashSnapshot = periodo.HashSnapshot,
 1205            FechaCierreInsumos = periodo.FechaCierreInsumos,
 1206            UsuarioCierreInsumosId = periodo.UsuarioCierreInsumosId,
 1207            FechaCalculo = periodo.FechaCalculo,
 1208            FechaCierre = periodo.FechaCierre,
 1209            UsuarioCierreId = periodo.UsuarioCierreId
 1210        };
 211    }
 212}