< Summary

Information
Class: FAU.API.Controllers.BeneficiosSocialesBeneficiariosController
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/BeneficiosSocialesBeneficiariosController.cs
Line coverage
95%
Covered lines: 102
Uncovered lines: 5
Coverable lines: 107
Total lines: 266
Line coverage: 95.3%
Branch coverage
89%
Covered branches: 34
Total branches: 38
Branch coverage: 89.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%
Listar()100%11100%
Obtener()100%44100%
Agregar()50%2293.33%
Actualizar()100%44100%
Eliminar()100%44100%
SubirDocumento()100%8893.33%
ListarDocumentos()100%44100%
EliminarDocumento()100%44100%
DescargarDocumento()66.66%6676.92%
ObtenerUsuarioId()50%22100%

File(s)

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

#LineLine coverage
 1using System.Security.Claims;
 2using FAU.Logica.DTOs;
 3using FAU.Logica.Services;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Http;
 6using Microsoft.AspNetCore.Mvc;
 7
 8namespace FAU.API.Controllers;
 9
 10[ApiController]
 11[Route("api/beneficios-sociales/{beneficioId:long}/beneficiarios")]
 12[Authorize(Roles = "Administrador")]
 13[Produces("application/json")]
 14public class BeneficiosSocialesBeneficiariosController : ControllerBase
 15{
 16    private readonly IBeneficioSocialBeneficiarioService _service;
 17    private readonly ILogger<BeneficiosSocialesBeneficiariosController> _logger;
 18
 3419    public BeneficiosSocialesBeneficiariosController(
 3420        IBeneficioSocialBeneficiarioService service,
 3421        ILogger<BeneficiosSocialesBeneficiariosController> logger)
 22    {
 3423        _service = service;
 3424        _logger  = logger;
 3425    }
 26
 27    [HttpGet]
 28    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
 29    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 30    public async Task<IActionResult> Listar(long beneficioId, [FromQuery] bool soloActivos = true)
 31    {
 32        try
 33        {
 234            var items = await _service.ObtenerPorBeneficioAsync(beneficioId, soloActivos);
 135            return Ok(ApiResponse<object>.SuccessResult(items));
 36        }
 137        catch (Exception ex)
 38        {
 139            _logger.LogError(ex, "Error al listar beneficiarios del beneficio {BeneficioId}", beneficioId);
 140            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 41        }
 242    }
 43
 44    [HttpGet("{id:long}")]
 45    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
 46    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 47    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 48    public async Task<IActionResult> Obtener(long beneficioId, long id)
 49    {
 50        try
 51        {
 452            var item = await _service.ObtenerPorIdAsync(id);
 353            if (item is null || item.BeneficioId != beneficioId)
 254                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 155            return Ok(ApiResponse<object>.SuccessResult(item));
 56        }
 157        catch (Exception ex)
 58        {
 159            _logger.LogError(ex, "Error al obtener beneficiario {Id}", id);
 160            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 61        }
 462    }
 63
 64    [HttpPost]
 65    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status201Created)]
 66    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status400BadRequest)]
 67    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status409Conflict)]
 68    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 69    public async Task<IActionResult> Agregar(long beneficioId, [FromBody] CrearBeneficiarioSocialRequest request)
 70    {
 471        if (!ModelState.IsValid)
 072            return BadRequest(ApiResponse<string>.ErrorResult("Datos inválidos"));
 73
 74        try
 75        {
 476            var usuarioId = ObtenerUsuarioId();
 477            var creado = await _service.AgregarAsync(beneficioId, request, usuarioId);
 178            return CreatedAtAction(nameof(Obtener),
 179                new { beneficioId, id = creado.Id },
 180                ApiResponse<object>.SuccessResult(creado, "Beneficiario agregado correctamente"));
 81        }
 182        catch (ArgumentException ex)
 83        {
 184            return BadRequest(ApiResponse<string>.ErrorResult(ex.Message));
 85        }
 186        catch (InvalidOperationException ex)
 87        {
 188            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 89        }
 190        catch (Exception ex)
 91        {
 192            _logger.LogError(ex, "Error al agregar beneficiario al beneficio {BeneficioId}", beneficioId);
 193            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 94        }
 495    }
 96
 97    [HttpPut("{id:long}")]
 98    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
 99    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status400BadRequest)]
 100    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 101    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 102    public async Task<IActionResult> Actualizar(
 103        long beneficioId, long id, [FromBody] ActualizarBeneficiarioSocialRequest request)
 104    {
 105        try
 106        {
 5107            var item = await _service.ObtenerPorIdAsync(id);
 5108            if (item is null || item.BeneficioId != beneficioId)
 2109                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 110
 3111            var actualizado = await _service.ActualizarAsync(id, request);
 1112            return Ok(ApiResponse<object>.SuccessResult(actualizado, "Beneficiario actualizado correctamente"));
 113        }
 1114        catch (ArgumentException ex)
 115        {
 1116            return BadRequest(ApiResponse<string>.ErrorResult(ex.Message));
 117        }
 1118        catch (Exception ex)
 119        {
 1120            _logger.LogError(ex, "Error al actualizar beneficiario {Id}", id);
 1121            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 122        }
 5123    }
 124
 125    [HttpDelete("{id:long}")]
 126    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status200OK)]
 127    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status400BadRequest)]
 128    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 129    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 130    public async Task<IActionResult> Eliminar(long beneficioId, long id)
 131    {
 132        try
 133        {
 5134            var item = await _service.ObtenerPorIdAsync(id);
 5135            if (item is null || item.BeneficioId != beneficioId)
 2136                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 137
 3138            await _service.EliminarAsync(id);
 1139            return Ok(ApiResponse<string>.SuccessResult("ok", "Beneficiario eliminado correctamente"));
 140        }
 1141        catch (ArgumentException ex)
 142        {
 1143            return BadRequest(ApiResponse<string>.ErrorResult(ex.Message));
 144        }
 1145        catch (Exception ex)
 146        {
 1147            _logger.LogError(ex, "Error al eliminar beneficiario {Id}", id);
 1148            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 149        }
 5150    }
 151
 152    [HttpPost("{id:long}/documentos")]
 153    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
 154    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status400BadRequest)]
 155    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 156    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 157    public async Task<IActionResult> SubirDocumento(long beneficioId, long id, IFormFile archivo)
 158    {
 4159        if (archivo is null || archivo.Length == 0)
 1160            return BadRequest(ApiResponse<string>.ErrorResult("Debe adjuntar un archivo"));
 161
 162        try
 163        {
 3164            var item = await _service.ObtenerPorIdAsync(id);
 3165            if (item is null || item.BeneficioId != beneficioId)
 1166                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 167
 2168            var usuarioId = ObtenerUsuarioId();
 2169            using var stream = archivo.OpenReadStream();
 2170            var ruta = await _service.SubirDocumentoAsync(id, stream, archivo.FileName, archivo.ContentType, usuarioId);
 0171            return Ok(ApiResponse<object>.SuccessResult(new { ruta }, "Documento subido correctamente"));
 172        }
 1173        catch (ArgumentException ex)
 174        {
 1175            return BadRequest(ApiResponse<string>.ErrorResult(ex.Message));
 176        }
 1177        catch (Exception ex)
 178        {
 1179            _logger.LogError(ex, "Error al subir documento para beneficiario {Id}", id);
 1180            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 181        }
 4182    }
 183
 184    [HttpGet("{id:long}/documentos")]
 185    [ProducesResponseType(typeof(ApiResponse<object>), StatusCodes.Status200OK)]
 186    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 187    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 188    public async Task<IActionResult> ListarDocumentos(long beneficioId, long id)
 189    {
 190        try
 191        {
 3192            var item = await _service.ObtenerPorIdAsync(id);
 3193            if (item is null || item.BeneficioId != beneficioId)
 1194                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 195
 2196            var docs = await _service.ObtenerDocumentosAsync(id);
 1197            return Ok(ApiResponse<object>.SuccessResult(docs));
 198        }
 1199        catch (Exception ex)
 200        {
 1201            _logger.LogError(ex, "Error al listar documentos del beneficiario {Id}", id);
 1202            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 203        }
 3204    }
 205
 206    [HttpDelete("{id:long}/documentos/{docId:long}")]
 207    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status200OK)]
 208    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 209    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 210    public async Task<IActionResult> EliminarDocumento(long beneficioId, long id, long docId)
 211    {
 212        try
 213        {
 4214            var item = await _service.ObtenerPorIdAsync(id);
 4215            if (item is null || item.BeneficioId != beneficioId)
 1216                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 217
 3218            await _service.EliminarDocumentoAsync(id, docId);
 1219            return Ok(ApiResponse<string>.SuccessResult("ok", "Documento eliminado correctamente"));
 220        }
 1221        catch (KeyNotFoundException)
 222        {
 1223            return NotFound(ApiResponse<string>.ErrorResult("Documento no encontrado"));
 224        }
 1225        catch (Exception ex)
 226        {
 1227            _logger.LogError(ex, "Error al eliminar documento {DocId} del beneficiario {Id}", docId, id);
 1228            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 229        }
 4230    }
 231
 232    [HttpGet("{id:long}/documentos/{docId:long}")]
 233    [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
 234    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 235    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 236    public async Task<IActionResult> DescargarDocumento(
 237        long beneficioId, long id, long docId, [FromQuery] bool inline = false)
 238    {
 239        try
 240        {
 3241            var item = await _service.ObtenerPorIdAsync(id);
 3242            if (item is null || item.BeneficioId != beneficioId)
 1243                return NotFound(ApiResponse<string>.ErrorResult("Beneficiario no encontrado"));
 244
 2245            var (stream, nombre, contentType) = await _service.DescargarDocumentoAsync(id, docId);
 0246            var disposition = inline ? "inline" : "attachment";
 0247            Response.Headers.Append("Content-Disposition", $"{disposition}; filename=\"{nombre}\"");
 0248            return File(stream, contentType);
 249        }
 1250        catch (KeyNotFoundException)
 251        {
 1252            return NotFound(ApiResponse<string>.ErrorResult("Documento no encontrado"));
 253        }
 1254        catch (Exception ex)
 255        {
 1256            _logger.LogError(ex, "Error al descargar documento {DocId} del beneficiario {Id}", docId, id);
 1257            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 258        }
 3259    }
 260
 261    private long ObtenerUsuarioId()
 262    {
 6263        var claim = User.FindFirstValue(ClaimTypes.NameIdentifier);
 6264        return long.TryParse(claim, out var id) ? id : 0;
 265    }
 266}