< Summary

Information
Class: FAU.API.Controllers.BeneficiosSocialesController
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/BeneficiosSocialesController.cs
Line coverage
60%
Covered lines: 53
Uncovered lines: 34
Coverable lines: 87
Total lines: 203
Line coverage: 60.9%
Branch coverage
60%
Covered branches: 29
Total branches: 48
Branch coverage: 60.4%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetBeneficiosSociales()100%1180%
GetBeneficioSocial()100%2262.5%
CreateBeneficioSocial()100%2261.53%
UpdateBeneficioSocial()50%3250%
SubirDocumento()0%7280%
DeleteBeneficioSocial()100%2262.5%
MapearError(...)92.85%1414100%
ObtenerUsuarioIdActual()50%101085.71%
ObtenerHost()50%88100%

File(s)

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

#LineLine coverage
 1using System.Security.Claims;
 2using FAU.Logica.DTOs;
 3using FAU.Logica.Exceptions;
 4using FAU.Logica.Services;
 5using Microsoft.AspNetCore.Authorization;
 6using Microsoft.AspNetCore.Mvc;
 7
 8namespace FAU.API.Controllers;
 9
 10[ApiController]
 11[Route("api/beneficios-sociales")]
 12[Authorize(Roles = "Administrador,Supervisor")]
 13public class BeneficiosSocialesController : ControllerBase
 14{
 15    private readonly IBeneficioSocialService _beneficioSocialService;
 16    private readonly ILogger<BeneficiosSocialesController> _logger;
 17
 1018    public BeneficiosSocialesController(
 1019        IBeneficioSocialService beneficioSocialService,
 1020        ILogger<BeneficiosSocialesController> logger)
 21    {
 1022        _beneficioSocialService = beneficioSocialService;
 1023        _logger = logger;
 1024    }
 25
 26    [HttpGet]
 27    public async Task<IActionResult> GetBeneficiosSociales(
 28        [FromQuery] int pagina = 1,
 29        [FromQuery] int tamano = 10,
 30        [FromQuery] long? personaId = null,
 31        [FromQuery] string? estado = null)
 32    {
 33        try
 34        {
 135            var resultado = await _beneficioSocialService.ObtenerPaginadoAsync(pagina, tamano, personaId, estado);
 136            return Ok(ApiResponse<object>.SuccessResult(new
 137            {
 138                items = resultado.Items,
 139                page = resultado.Page,
 140                pageSize = resultado.PageSize,
 141                totalCount = resultado.TotalCount,
 142                totalPages = resultado.TotalPages,
 143                hasPreviousPage = resultado.HasPreviousPage,
 144                hasNextPage = resultado.HasNextPage
 145            }));
 46        }
 047        catch (Exception ex)
 48        {
 049            _logger.LogError(ex, "Error al listar beneficios sociales");
 050            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 51        }
 152    }
 53
 54    [HttpGet("{id:long}")]
 55    public async Task<IActionResult> GetBeneficioSocial(long id)
 56    {
 57        try
 58        {
 259            var beneficio = await _beneficioSocialService.ObtenerPorIdAsync(id);
 260            if (beneficio == null)
 61            {
 162                return NotFound(ApiResponse<string>.ErrorResult("Beneficio social no encontrado"));
 63            }
 64
 165            return Ok(ApiResponse<BeneficioSocialDto>.SuccessResult(beneficio));
 66        }
 067        catch (Exception ex)
 68        {
 069            _logger.LogError(ex, "Error al obtener beneficio social {Id}", id);
 070            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 71        }
 272    }
 73
 74    [HttpPost]
 75    public async Task<IActionResult> CreateBeneficioSocial([FromBody] CrearBeneficioSocialRequest request)
 76    {
 77        try
 78        {
 379            var (exito, resultado, error) = await _beneficioSocialService.CrearAsync(request, ObtenerUsuarioIdActual(), 
 380            if (!exito)
 81            {
 282                return MapearError(error, "Error al crear beneficio social");
 83            }
 84
 185            return CreatedAtAction(
 186                nameof(GetBeneficioSocial),
 187                new { id = resultado!.Id },
 188                ApiResponse<object>.SuccessResult(new { id = resultado.Id, creado = true }, "Beneficio social creado exi
 89        }
 090        catch (PeriodoBloqueadoException ex)
 91        {
 092            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 93        }
 094        catch (Exception ex)
 95        {
 096            _logger.LogError(ex, "Error al crear beneficio social");
 097            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 98        }
 399    }
 100
 101    [HttpPut("{id:long}")]
 102    public async Task<IActionResult> UpdateBeneficioSocial(long id, [FromBody] ActualizarBeneficioSocialRequest request)
 103    {
 104        try
 105        {
 2106            var (exito, resultado, error) = await _beneficioSocialService.ActualizarAsync(id, request, ObtenerUsuarioIdA
 2107            if (!exito)
 108            {
 2109                return MapearError(error, "Error al actualizar beneficio social");
 110            }
 111
 0112            return Ok(ApiResponse<object>.SuccessResult(new { actualizado = true, id = resultado!.Id }, "Beneficio socia
 113        }
 0114        catch (Exception ex)
 115        {
 0116            _logger.LogError(ex, "Error al actualizar beneficio social {Id}", id);
 0117            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 118        }
 2119    }
 120
 121    [HttpPost("{id:long}/documento")]
 122    [RequestSizeLimit(20_000_000)]
 123    public async Task<IActionResult> SubirDocumento(long id, IFormFile file)
 124    {
 0125        if (file == null || file.Length == 0)
 0126            return BadRequest(ApiResponse<string>.ErrorResult("Archivo requerido"));
 127
 128        try
 129        {
 0130            await using var stream = file.OpenReadStream();
 0131            var ruta = await _beneficioSocialService.SubirDocumentoAsync(
 0132                id, stream, file.FileName, file.ContentType, ObtenerUsuarioIdActual());
 0133            return Ok(ApiResponse<object>.SuccessResult(new { rutaRelativa = ruta, subido = true }, "Documento subido ex
 0134        }
 0135        catch (ArgumentException ex)
 136        {
 0137            return ex.Message.Contains("no encontrado", StringComparison.OrdinalIgnoreCase)
 0138                ? NotFound(ApiResponse<string>.ErrorResult(ex.Message))
 0139                : BadRequest(ApiResponse<string>.ErrorResult(ex.Message));
 140        }
 0141        catch (Exception ex)
 142        {
 0143            _logger.LogError(ex, "Error al subir documento de beneficio {Id}", id);
 0144            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 145        }
 0146    }
 147
 148    [HttpDelete("{id:long}")]
 149    public async Task<IActionResult> DeleteBeneficioSocial(long id)
 150    {
 151        try
 152        {
 2153            var (exito, bajaLogica, error) = await _beneficioSocialService.EliminarAsync(id, ObtenerUsuarioIdActual(), O
 2154            if (!exito)
 155            {
 1156                return MapearError(error, "Error al eliminar beneficio social");
 157            }
 158
 1159            return Ok(ApiResponse<object>.SuccessResult(new { eliminado = true, bajaLogica }, "Beneficio social dado de 
 160        }
 0161        catch (Exception ex)
 162        {
 0163            _logger.LogError(ex, "Error al eliminar beneficio social {Id}", id);
 0164            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 165        }
 2166    }
 167
 168    private IActionResult MapearError(string? error, string errorPorDefecto)
 169    {
 5170        if (error?.Contains("no encontrado", StringComparison.OrdinalIgnoreCase) == true)
 171        {
 1172            return NotFound(ApiResponse<string>.ErrorResult(error));
 173        }
 174
 4175        if (error?.Contains("duplicado", StringComparison.OrdinalIgnoreCase) == true
 4176            || error?.Contains("ya existe", StringComparison.OrdinalIgnoreCase) == true)
 177        {
 2178            return Conflict(ApiResponse<string>.ErrorResult(error));
 179        }
 180
 2181        return BadRequest(ApiResponse<string>.ErrorResult(error ?? errorPorDefecto));
 182    }
 183
 184    private long ObtenerUsuarioIdActual()
 185    {
 7186        var usuario = HttpContext?.User;
 7187        if (usuario == null)
 188        {
 0189            return 0;
 190        }
 191
 7192        var claimId = usuario.FindFirstValue(ClaimTypes.NameIdentifier)
 7193                      ?? usuario.FindFirstValue("sub")
 7194                      ?? usuario.FindFirstValue("id");
 195
 7196        return long.TryParse(claimId, out var usuarioId) ? usuarioId : 0;
 197    }
 198
 199    private string ObtenerHost()
 200    {
 7201        return HttpContext?.Connection?.RemoteIpAddress?.ToString() ?? "Desconocido";
 202    }
 203}