< Summary

Information
Class: FAU.API.Controllers.ConfirmarDescuentosRequest
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/DescuentosPersonalesController.cs
Line coverage
100%
Covered lines: 1
Uncovered lines: 0
Coverable lines: 1
Total lines: 254
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_PeriodoId()100%11100%

File(s)

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

#LineLine coverage
 1using FAU.Entidades;
 2using FAU.Logica.DTOs;
 3using FAU.Logica.Services;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Mvc;
 6using System.ComponentModel.DataAnnotations;
 7
 8namespace FAU.API.Controllers;
 9
 10/// <summary>
 11/// Gestión de descuentos personales del período
 12/// </summary>
 13[ApiController]
 14[Route("api/descuentos-personales")]
 15[Authorize]
 16public class DescuentosPersonalesController : ControllerBase
 17{
 18    private readonly IDescuentoPersonalService _service;
 19    private readonly ICurrentUserContext _currentUser;
 20    private readonly ILogger<DescuentosPersonalesController> _logger;
 21
 22    public DescuentosPersonalesController(
 23        IDescuentoPersonalService service,
 24        ICurrentUserContext currentUser,
 25        ILogger<DescuentosPersonalesController> logger)
 26    {
 27        _service = service;
 28        _currentUser = currentUser;
 29        _logger = logger;
 30    }
 31
 32    /// <summary>
 33    /// Crear un descuento personal en borrador
 34    /// POST /api/descuentos-personales
 35    /// </summary>
 36    [HttpPost]
 37    [FAU.API.Security.RequirePermission(PermisoEnum.CrearDescuentosPersonales)]
 38    public async Task<IActionResult> Crear([FromBody] CrearDescuentoPersonalRequest request)
 39    {
 40        try
 41        {
 42            if (request.PeriodoId <= 0)
 43                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 44            if (string.IsNullOrWhiteSpace(request.CedulaTitular))
 45                return BadRequest(ApiResponse<string>.ErrorResult("cedulaTitular es requerida"));
 46            if (request.AcreedorId <= 0)
 47                return BadRequest(ApiResponse<string>.ErrorResult("acreedorId es requerido"));
 48            if (request.Importe <= 0)
 49                return BadRequest(ApiResponse<string>.ErrorResult("importe debe ser mayor a cero"));
 50
 51            var usuarioId = _currentUser.UserId ?? 0;
 52            var creado = await _service.CrearAsync(
 53                request.PeriodoId,
 54                request.CedulaTitular,
 55                request.CodigoConcepto,
 56                request.AcreedorId,
 57                request.Importe,
 58                request.Observaciones,
 59                usuarioId);
 60
 61            return CreatedAtAction(
 62                nameof(Listar),
 63                new { periodoId = request.PeriodoId },
 64                ApiResponse<object>.SuccessResult(
 65                    new { id = creado.Id, creado = true },
 66                    "Descuento personal creado exitosamente"));
 67        }
 68        catch (ArgumentException ex)
 69        {
 70            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 71        }
 72        catch (InvalidOperationException ex)
 73        {
 74            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 75        }
 76        catch (Exception ex)
 77        {
 78            _logger.LogError(ex, "Error al crear descuento personal");
 79            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 80        }
 81    }
 82
 83    /// <summary>
 84    /// Listar descuentos personales del período
 85    /// GET /api/descuentos-personales?periodoId=...&cedulaTitular=...&codigoConcepto=...&estado=...
 86    /// </summary>
 87    [HttpGet]
 88    [FAU.API.Security.RequirePermission(PermisoEnum.VerDescuentosPersonales)]
 89    public async Task<IActionResult> Listar(
 90        [FromQuery] long periodoId,
 91        [FromQuery] string? cedulaTitular = null,
 92        [FromQuery] int? codigoConcepto = null,
 93        [FromQuery] string? estado = null)
 94    {
 95        try
 96        {
 97            if (periodoId <= 0)
 98                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 99
 100            var items = await _service.ListarAsync(periodoId, cedulaTitular, codigoConcepto, estado);
 101
 102            var response = items.Select(d => new
 103            {
 104                id = d.Id,
 105                periodoId = d.PeriodoId,
 106                personaId = d.PersonaId,
 107                cedula = d.Persona?.Cedula,
 108                nombreCompleto = d.Persona?.NombreCompleto,
 109                acreedorId = d.AcreedorId,
 110                acreedorCodigo = d.Acreedor?.Codigo,
 111                acreedorNombre = d.Acreedor?.Nombre,
 112                prioridadDeficit = d.Acreedor?.PrioridadDeficit,
 113                catalogoItemId = d.CatalogoItemId,
 114                codigoConcepto = d.CatalogoItem?.Codigo,
 115                nombreConcepto = d.CatalogoItem?.Nombre,
 116                importe = d.Importe,
 117                estado = d.Estado,
 118                observaciones = d.Observaciones,
 119                fechaCreacion = d.FechaCreacion,
 120                usuarioCreacionId = d.UsuarioCreacionId
 121            });
 122
 123            return Ok(ApiResponse<object>.SuccessResult(response));
 124        }
 125        catch (Exception ex)
 126        {
 127            _logger.LogError(ex, "Error al listar descuentos personales");
 128            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 129        }
 130    }
 131
 132    /// <summary>
 133    /// Editar un descuento personal en borrador
 134    /// PUT /api/descuentos-personales/{id}
 135    /// </summary>
 136    [HttpPut("{id}")]
 137    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarDescuentosPersonales)]
 138    public async Task<IActionResult> Editar(long id, [FromBody] EditarDescuentoPersonalRequest request)
 139    {
 140        try
 141        {
 142            if (request.Importe <= 0)
 143                return BadRequest(ApiResponse<string>.ErrorResult("importe debe ser mayor a cero"));
 144
 145            var actualizado = await _service.EditarAsync(id, request.Importe, request.Observaciones);
 146            return Ok(ApiResponse<object>.SuccessResult(
 147                new { id = actualizado.Id, actualizado = true },
 148                "Descuento personal actualizado exitosamente"));
 149        }
 150        catch (ArgumentException ex)
 151        {
 152            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 153        }
 154        catch (InvalidOperationException ex)
 155        {
 156            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 157        }
 158        catch (Exception ex)
 159        {
 160            _logger.LogError(ex, "Error al actualizar descuento personal {Id}", id);
 161            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 162        }
 163    }
 164
 165    /// <summary>
 166    /// Eliminar un descuento personal en borrador
 167    /// DELETE /api/descuentos-personales/{id}
 168    /// </summary>
 169    [HttpDelete("{id}")]
 170    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarDescuentosPersonales)]
 171    public async Task<IActionResult> Eliminar(long id)
 172    {
 173        try
 174        {
 175            await _service.EliminarAsync(id);
 176            return NoContent();
 177        }
 178        catch (ArgumentException ex)
 179        {
 180            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 181        }
 182        catch (InvalidOperationException ex)
 183        {
 184            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 185        }
 186        catch (Exception ex)
 187        {
 188            _logger.LogError(ex, "Error al eliminar descuento personal {Id}", id);
 189            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 190        }
 191    }
 192
 193    /// <summary>
 194    /// Confirmar todos los borradores de un período
 195    /// POST /api/descuentos-personales/confirmar
 196    /// </summary>
 197    [HttpPost("confirmar")]
 198    [FAU.API.Security.RequirePermission(PermisoEnum.ConfirmarDescuentosPersonales)]
 199    public async Task<IActionResult> Confirmar([FromBody] ConfirmarDescuentosRequest request)
 200    {
 201        try
 202        {
 203            if (request.PeriodoId <= 0)
 204                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 205
 206            var cantidad = await _service.ConfirmarBorradoresAsync(request.PeriodoId);
 207            return Ok(ApiResponse<object>.SuccessResult(
 208                new { confirmados = cantidad },
 209                $"Se confirmaron {cantidad} descuento(s) personal(es)"));
 210        }
 211        catch (Exception ex)
 212        {
 213            _logger.LogError(ex, "Error al confirmar descuentos personales del período {PeriodoId}", request.PeriodoId);
 214            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 215        }
 216    }
 217}
 218
 219public class CrearDescuentoPersonalRequest
 220{
 221    [Required]
 222    public long PeriodoId { get; set; }
 223
 224    [Required]
 225    [MaxLength(12)]
 226    public string CedulaTitular { get; set; } = string.Empty;
 227
 228    [Required]
 229    public int CodigoConcepto { get; set; }
 230
 231    [Required]
 232    public long AcreedorId { get; set; }
 233
 234    [Required]
 235    public decimal Importe { get; set; }
 236
 237    [MaxLength(500)]
 238    public string? Observaciones { get; set; }
 239}
 240
 241public class EditarDescuentoPersonalRequest
 242{
 243    [Required]
 244    public decimal Importe { get; set; }
 245
 246    [MaxLength(500)]
 247    public string? Observaciones { get; set; }
 248}
 249
 250public class ConfirmarDescuentosRequest
 251{
 252    [Required]
 7253    public long PeriodoId { get; set; }
 254}

Methods/Properties

get_PeriodoId()