< Summary

Information
Class: FAU.API.Controllers.EditarDescuentoPersonalRequest
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/DescuentosPersonalesController.cs
Line coverage
100%
Covered lines: 2
Uncovered lines: 0
Coverable lines: 2
Total lines: 244
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_Importe()100%11100%
get_Observaciones()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.Importe <= 0)
 47                return BadRequest(ApiResponse<string>.ErrorResult("importe debe ser mayor a cero"));
 48
 49            var usuarioId = _currentUser.UserId ?? 0;
 50            var creado = await _service.CrearAsync(
 51                request.PeriodoId,
 52                request.CedulaTitular,
 53                request.CodigoConcepto,
 54                request.Importe,
 55                request.Observaciones,
 56                usuarioId);
 57
 58            return CreatedAtAction(
 59                nameof(Listar),
 60                new { periodoId = request.PeriodoId },
 61                ApiResponse<object>.SuccessResult(
 62                    new { id = creado.Id, creado = true },
 63                    "Descuento personal creado exitosamente"));
 64        }
 65        catch (ArgumentException ex)
 66        {
 67            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 68        }
 69        catch (InvalidOperationException ex)
 70        {
 71            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 72        }
 73        catch (Exception ex)
 74        {
 75            _logger.LogError(ex, "Error al crear descuento personal");
 76            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 77        }
 78    }
 79
 80    /// <summary>
 81    /// Listar descuentos personales del período
 82    /// GET /api/descuentos-personales?periodoId=...&cedulaTitular=...&codigoConcepto=...&estado=...
 83    /// </summary>
 84    [HttpGet]
 85    [FAU.API.Security.RequirePermission(PermisoEnum.VerDescuentosPersonales)]
 86    public async Task<IActionResult> Listar(
 87        [FromQuery] long periodoId,
 88        [FromQuery] string? cedulaTitular = null,
 89        [FromQuery] int? codigoConcepto = null,
 90        [FromQuery] string? estado = null)
 91    {
 92        try
 93        {
 94            if (periodoId <= 0)
 95                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 96
 97            var items = await _service.ListarAsync(periodoId, cedulaTitular, codigoConcepto, estado);
 98
 99            var response = items.Select(d => new
 100            {
 101                id = d.Id,
 102                periodoId = d.PeriodoId,
 103                personaId = d.PersonaId,
 104                cedula = d.Persona?.Cedula,
 105                nombreCompleto = d.Persona?.NombreCompleto,
 106                catalogoItemId = d.CatalogoItemId,
 107                codigoConcepto = d.CatalogoItem?.Codigo,
 108                nombreConcepto = d.CatalogoItem?.Nombre,
 109                importe = d.Importe,
 110                estado = d.Estado,
 111                observaciones = d.Observaciones,
 112                fechaCreacion = d.FechaCreacion,
 113                usuarioCreacionId = d.UsuarioCreacionId
 114            });
 115
 116            return Ok(ApiResponse<object>.SuccessResult(response));
 117        }
 118        catch (Exception ex)
 119        {
 120            _logger.LogError(ex, "Error al listar descuentos personales");
 121            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 122        }
 123    }
 124
 125    /// <summary>
 126    /// Editar un descuento personal en borrador
 127    /// PUT /api/descuentos-personales/{id}
 128    /// </summary>
 129    [HttpPut("{id}")]
 130    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarDescuentosPersonales)]
 131    public async Task<IActionResult> Editar(long id, [FromBody] EditarDescuentoPersonalRequest request)
 132    {
 133        try
 134        {
 135            if (request.Importe <= 0)
 136                return BadRequest(ApiResponse<string>.ErrorResult("importe debe ser mayor a cero"));
 137
 138            var actualizado = await _service.EditarAsync(id, request.Importe, request.Observaciones);
 139            return Ok(ApiResponse<object>.SuccessResult(
 140                new { id = actualizado.Id, actualizado = true },
 141                "Descuento personal actualizado exitosamente"));
 142        }
 143        catch (ArgumentException ex)
 144        {
 145            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 146        }
 147        catch (InvalidOperationException ex)
 148        {
 149            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 150        }
 151        catch (Exception ex)
 152        {
 153            _logger.LogError(ex, "Error al actualizar descuento personal {Id}", id);
 154            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 155        }
 156    }
 157
 158    /// <summary>
 159    /// Eliminar un descuento personal en borrador
 160    /// DELETE /api/descuentos-personales/{id}
 161    /// </summary>
 162    [HttpDelete("{id}")]
 163    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarDescuentosPersonales)]
 164    public async Task<IActionResult> Eliminar(long id)
 165    {
 166        try
 167        {
 168            await _service.EliminarAsync(id);
 169            return NoContent();
 170        }
 171        catch (ArgumentException ex)
 172        {
 173            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 174        }
 175        catch (InvalidOperationException ex)
 176        {
 177            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 178        }
 179        catch (Exception ex)
 180        {
 181            _logger.LogError(ex, "Error al eliminar descuento personal {Id}", id);
 182            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 183        }
 184    }
 185
 186    /// <summary>
 187    /// Confirmar todos los borradores de un período
 188    /// POST /api/descuentos-personales/confirmar
 189    /// </summary>
 190    [HttpPost("confirmar")]
 191    [FAU.API.Security.RequirePermission(PermisoEnum.ConfirmarDescuentosPersonales)]
 192    public async Task<IActionResult> Confirmar([FromBody] ConfirmarDescuentosRequest request)
 193    {
 194        try
 195        {
 196            if (request.PeriodoId <= 0)
 197                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 198
 199            var cantidad = await _service.ConfirmarBorradoresAsync(request.PeriodoId);
 200            return Ok(ApiResponse<object>.SuccessResult(
 201                new { confirmados = cantidad },
 202                $"Se confirmaron {cantidad} descuento(s) personal(es)"));
 203        }
 204        catch (Exception ex)
 205        {
 206            _logger.LogError(ex, "Error al confirmar descuentos personales del período {PeriodoId}", request.PeriodoId);
 207            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 208        }
 209    }
 210}
 211
 212public class CrearDescuentoPersonalRequest
 213{
 214    [Required]
 215    public long PeriodoId { get; set; }
 216
 217    [Required]
 218    [MaxLength(12)]
 219    public string CedulaTitular { get; set; } = string.Empty;
 220
 221    [Required]
 222    public int CodigoConcepto { get; set; }
 223
 224    [Required]
 225    public decimal Importe { get; set; }
 226
 227    [MaxLength(500)]
 228    public string? Observaciones { get; set; }
 229}
 230
 231public class EditarDescuentoPersonalRequest
 232{
 233    [Required]
 6234    public decimal Importe { get; set; }
 235
 236    [MaxLength(500)]
 3237    public string? Observaciones { get; set; }
 238}
 239
 240public class ConfirmarDescuentosRequest
 241{
 242    [Required]
 243    public long PeriodoId { get; set; }
 244}

Methods/Properties

get_Importe()
get_Observaciones()