< 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: 3
Uncovered lines: 0
Coverable lines: 3
Total lines: 291
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%
get_FechaComunicacion()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                request.FechaComunicacion);
 61
 62            return CreatedAtAction(
 63                nameof(Listar),
 64                new { periodoId = request.PeriodoId },
 65                ApiResponse<object>.SuccessResult(
 66                    new { id = creado.Id, creado = true },
 67                    "Descuento personal creado exitosamente"));
 68        }
 69        catch (ArgumentException ex)
 70        {
 71            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 72        }
 73        catch (InvalidOperationException ex)
 74        {
 75            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 76        }
 77        catch (Exception ex)
 78        {
 79            _logger.LogError(ex, "Error al crear descuento personal");
 80            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 81        }
 82    }
 83
 84    /// <summary>
 85    /// Listar descuentos personales del período
 86    /// GET /api/descuentos-personales?periodoId=...&cedulaTitular=...&codigoConcepto=...&estado=...
 87    /// </summary>
 88    [HttpGet]
 89    [FAU.API.Security.RequirePermission(PermisoEnum.VerDescuentosPersonales)]
 90    public async Task<IActionResult> Listar(
 91        [FromQuery] long periodoId,
 92        [FromQuery] string? cedulaTitular = null,
 93        [FromQuery] int? codigoConcepto = null,
 94        [FromQuery] string? estado = null)
 95    {
 96        try
 97        {
 98            if (periodoId <= 0)
 99                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 100
 101            var items = await _service.ListarAsync(periodoId, cedulaTitular, codigoConcepto, estado);
 102
 103            var response = items.Select(d => new
 104            {
 105                id = d.Id,
 106                periodoId = d.PeriodoId,
 107                personaId = d.PersonaId,
 108                cedula = d.Persona?.Cedula,
 109                nombreCompleto = d.Persona?.NombreCompleto,
 110                acreedorId = d.AcreedorId,
 111                acreedorCodigo = d.Acreedor?.Codigo,
 112                acreedorNombre = d.Acreedor?.Nombre,
 113                categoriaDeficit = d.Acreedor?.CategoriaDeficit,
 114                ordenLegalDeficit = d.Acreedor?.OrdenLegalDeficit,
 115                catalogoItemId = d.CatalogoItemId,
 116                codigoConcepto = d.CatalogoItem?.Codigo,
 117                nombreConcepto = d.CatalogoItem?.Nombre,
 118                importe = d.Importe,
 119                estado = d.Estado,
 120                observaciones = d.Observaciones,
 121                fechaComunicacion = d.FechaComunicacion,
 122                fechaCreacion = d.FechaCreacion,
 123                usuarioCreacionId = d.UsuarioCreacionId
 124            });
 125
 126            return Ok(ApiResponse<object>.SuccessResult(response));
 127        }
 128        catch (Exception ex)
 129        {
 130            _logger.LogError(ex, "Error al listar descuentos personales");
 131            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 132        }
 133    }
 134
 135    /// <summary>
 136    /// Editar un descuento personal en borrador
 137    /// PUT /api/descuentos-personales/{id}
 138    /// </summary>
 139    [HttpPut("{id}")]
 140    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarDescuentosPersonales)]
 141    public async Task<IActionResult> Editar(long id, [FromBody] EditarDescuentoPersonalRequest request)
 142    {
 143        try
 144        {
 145            if (request.Importe <= 0)
 146                return BadRequest(ApiResponse<string>.ErrorResult("importe debe ser mayor a cero"));
 147
 148            var actualizado = await _service.EditarAsync(id, request.Importe, request.Observaciones, request.FechaComuni
 149            return Ok(ApiResponse<object>.SuccessResult(
 150                new { id = actualizado.Id, actualizado = true },
 151                "Descuento personal actualizado exitosamente"));
 152        }
 153        catch (ArgumentException ex)
 154        {
 155            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 156        }
 157        catch (InvalidOperationException ex)
 158        {
 159            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 160        }
 161        catch (Exception ex)
 162        {
 163            _logger.LogError(ex, "Error al actualizar descuento personal {Id}", id);
 164            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 165        }
 166    }
 167
 168    /// <summary>
 169    /// Eliminar un descuento personal en borrador
 170    /// DELETE /api/descuentos-personales/{id}
 171    /// </summary>
 172    [HttpDelete("{id}")]
 173    [FAU.API.Security.RequirePermission(PermisoEnum.ActualizarDescuentosPersonales)]
 174    public async Task<IActionResult> Eliminar(long id)
 175    {
 176        try
 177        {
 178            await _service.EliminarAsync(id);
 179            return NoContent();
 180        }
 181        catch (ArgumentException ex)
 182        {
 183            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 184        }
 185        catch (InvalidOperationException ex)
 186        {
 187            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 188        }
 189        catch (Exception ex)
 190        {
 191            _logger.LogError(ex, "Error al eliminar descuento personal {Id}", id);
 192            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 193        }
 194    }
 195
 196    /// <summary>
 197    /// Confirmar un descuento personal en borrador
 198    /// POST /api/descuentos-personales/{id}/confirmar
 199    /// </summary>
 200    [HttpPost("{id}/confirmar")]
 201    [FAU.API.Security.RequirePermission(PermisoEnum.ConfirmarDescuentosPersonales)]
 202    public async Task<IActionResult> ConfirmarUno(long id)
 203    {
 204        try
 205        {
 206            var confirmado = await _service.ConfirmarAsync(id);
 207            return Ok(ApiResponse<object>.SuccessResult(
 208                new { confirmado = true },
 209                $"Descuento personal {confirmado.Id} confirmado exitosamente"));
 210        }
 211        catch (ArgumentException ex)
 212        {
 213            return NotFound(ApiResponse<string>.ErrorResult(ex.Message));
 214        }
 215        catch (InvalidOperationException ex)
 216        {
 217            return Conflict(ApiResponse<string>.ErrorResult(ex.Message));
 218        }
 219        catch (Exception ex)
 220        {
 221            _logger.LogError(ex, "Error al confirmar descuento personal {Id}", id);
 222            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 223        }
 224    }
 225
 226    /// <summary>
 227    /// Confirmar todos los borradores de un período
 228    /// POST /api/descuentos-personales/confirmar
 229    /// </summary>
 230    [HttpPost("confirmar")]
 231    [FAU.API.Security.RequirePermission(PermisoEnum.ConfirmarDescuentosPersonales)]
 232    public async Task<IActionResult> Confirmar([FromBody] ConfirmarDescuentosRequest request)
 233    {
 234        try
 235        {
 236            if (request.PeriodoId <= 0)
 237                return BadRequest(ApiResponse<string>.ErrorResult("periodoId es requerido"));
 238
 239            var cantidad = await _service.ConfirmarBorradoresAsync(request.PeriodoId);
 240            return Ok(ApiResponse<object>.SuccessResult(
 241                new { confirmados = cantidad },
 242                $"Se confirmaron {cantidad} descuento(s) personal(es)"));
 243        }
 244        catch (Exception ex)
 245        {
 246            _logger.LogError(ex, "Error al confirmar descuentos personales del período {PeriodoId}", request.PeriodoId);
 247            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 248        }
 249    }
 250}
 251
 252public class CrearDescuentoPersonalRequest
 253{
 254    [Required]
 255    public long PeriodoId { get; set; }
 256
 257    [Required]
 258    [MaxLength(12)]
 259    public string CedulaTitular { get; set; } = string.Empty;
 260
 261    [Required]
 262    public int CodigoConcepto { get; set; }
 263
 264    [Required]
 265    public long AcreedorId { get; set; }
 266
 267    [Required]
 268    public decimal Importe { get; set; }
 269
 270    [MaxLength(500)]
 271    public string? Observaciones { get; set; }
 272
 273    public DateTime? FechaComunicacion { get; set; }
 274}
 275
 276public class EditarDescuentoPersonalRequest
 277{
 278    [Required]
 6279    public decimal Importe { get; set; }
 280
 281    [MaxLength(500)]
 3282    public string? Observaciones { get; set; }
 283
 2284    public DateTime? FechaComunicacion { get; set; }
 285}
 286
 287public class ConfirmarDescuentosRequest
 288{
 289    [Required]
 290    public long PeriodoId { get; set; }
 291}