< Summary

Information
Class: FAU.API.Controllers.ReportePresupuestalController
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/ReportePresupuestalController.cs
Line coverage
76%
Covered lines: 139
Uncovered lines: 42
Coverable lines: 181
Total lines: 375
Line coverage: 76.7%
Branch coverage
100%
Covered branches: 56
Total branches: 56
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
GetResumenPrograma()100%4472.72%
GetResumenProgramaCsv()100%4475%
GetRubro083()100%4472.72%
GetRubro083Csv()100%4475%
GetPadronRubro()100%4472.72%
GetPadronRubroCsv()100%4475%
GetPadronMensual()100%4472.72%
GetPadronMensualCsv()100%4475%
GetMovimientos()100%4472.72%
GetMovimientosCsv()100%4475%
GetDiferencias()100%4472.72%
GetDiferenciasCsv()100%4475%
GetNoDisponibles()100%4472.72%
GetNoDisponiblesCsv()100%4475%
RegistrarAuditoriaAsync(...)100%11100%

File(s)

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

#LineLine coverage
 1using FAU.API.Security;
 2using FAU.Entidades;
 3using FAU.Logica.DTOs;
 4using FAU.Logica.Services;
 5using Microsoft.AspNetCore.Authorization;
 6using Microsoft.AspNetCore.Mvc;
 7
 8namespace FAU.API.Controllers;
 9
 10[ApiController]
 11[Route("api/liquidacion/reportes")]
 12[Authorize]
 13public class ReportePresupuestalController : ControllerBase
 14{
 15    private readonly IReportePresupuestalService _service;
 16    private readonly IPeriodoService _periodoService;
 17    private readonly IAuditoriaService _auditoriaService;
 18    private readonly ICurrentUserContext _currentUser;
 19    private readonly ILogger<ReportePresupuestalController> _logger;
 20
 4221    public ReportePresupuestalController(
 4222        IReportePresupuestalService service,
 4223        IPeriodoService periodoService,
 4224        IAuditoriaService auditoriaService,
 4225        ICurrentUserContext currentUser,
 4226        ILogger<ReportePresupuestalController> logger)
 27    {
 4228        _service          = service;
 4229        _periodoService   = periodoService;
 4230        _auditoriaService = auditoriaService;
 4231        _currentUser      = currentUser;
 4232        _logger           = logger;
 4233    }
 34
 35    // ─── Resumen por programa ────────────────────────────────────────────────
 36
 37    [HttpGet("{periodoId}/resumen-programa")]
 38    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 39    public async Task<IActionResult> GetResumenPrograma(long periodoId)
 40    {
 41        try
 42        {
 343            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 344            if (periodo == null)
 145                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 246            if (periodo.Estado != Periodo.EstadoCerrada)
 147                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 48
 149            var result = await _service.ObtenerResumenProgramaAsync(periodoId);
 150            return Ok(ApiResponse<ResumenProgramaDto>.SuccessResult(result));
 51        }
 052        catch (Exception ex)
 53        {
 054            _logger.LogError(ex, "Error al obtener resumen programa del período {PeriodoId}", periodoId);
 055            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 56        }
 357    }
 58
 59    [HttpGet("{periodoId}/resumen-programa/csv")]
 60    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 61    public async Task<IActionResult> GetResumenProgramaCsv(long periodoId)
 62    {
 63        try
 64        {
 365            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 366            if (periodo == null)
 167                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 268            if (periodo.Estado != Periodo.EstadoCerrada)
 169                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 70
 171            var csv = await _service.GenerarCsvResumenProgramaAsync(periodoId);
 172            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteResumenPrograma, periodoId);
 173            return File(csv, "text/csv", $"resumen_programa_{periodo.Anio}_{periodo.Mes:D2}.csv");
 74        }
 075        catch (Exception ex)
 76        {
 077            _logger.LogError(ex, "Error al generar CSV resumen programa del período {PeriodoId}", periodoId);
 078            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 79        }
 380    }
 81
 82    // ─── Rubro 083 ───────────────────────────────────────────────────────────
 83
 84    [HttpGet("{periodoId}/rubro-083")]
 85    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 86    public async Task<IActionResult> GetRubro083(long periodoId)
 87    {
 88        try
 89        {
 390            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 391            if (periodo == null)
 192                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 293            if (periodo.Estado != Periodo.EstadoCerrada)
 194                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 95
 196            var result = await _service.ObtenerResumenRubro083Async(periodoId);
 197            return Ok(ApiResponse<SiifResumenDto>.SuccessResult(result));
 98        }
 099        catch (Exception ex)
 100        {
 0101            _logger.LogError(ex, "Error al obtener resumen rubro 083 del período {PeriodoId}", periodoId);
 0102            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 103        }
 3104    }
 105
 106    [HttpGet("{periodoId}/rubro-083/csv")]
 107    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 108    public async Task<IActionResult> GetRubro083Csv(long periodoId)
 109    {
 110        try
 111        {
 3112            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3113            if (periodo == null)
 1114                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2115            if (periodo.Estado != Periodo.EstadoCerrada)
 1116                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 117
 1118            var csv = await _service.GenerarCsvRubro083Async(periodoId);
 1119            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteRubro083, periodoId);
 1120            return File(csv, "text/csv", $"rubro083_{periodo.Anio}_{periodo.Mes:D2}.csv");
 121        }
 0122        catch (Exception ex)
 123        {
 0124            _logger.LogError(ex, "Error al generar CSV rubro 083 del período {PeriodoId}", periodoId);
 0125            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 126        }
 3127    }
 128
 129    // ─── Padrón por rubro ────────────────────────────────────────────────────
 130
 131    [HttpGet("{periodoId}/padron-rubro")]
 132    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 133    public async Task<IActionResult> GetPadronRubro(long periodoId)
 134    {
 135        try
 136        {
 3137            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3138            if (periodo == null)
 1139                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2140            if (periodo.Estado != Periodo.EstadoCerrada)
 1141                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 142
 1143            var result = await _service.ObtenerPadronRubroAsync(periodoId);
 1144            return Ok(ApiResponse<PadronRubroDto>.SuccessResult(result));
 145        }
 0146        catch (Exception ex)
 147        {
 0148            _logger.LogError(ex, "Error al obtener padrón rubro del período {PeriodoId}", periodoId);
 0149            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 150        }
 3151    }
 152
 153    [HttpGet("{periodoId}/padron-rubro/csv")]
 154    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 155    public async Task<IActionResult> GetPadronRubroCsv(long periodoId)
 156    {
 157        try
 158        {
 3159            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3160            if (periodo == null)
 1161                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2162            if (periodo.Estado != Periodo.EstadoCerrada)
 1163                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 164
 1165            var csv = await _service.GenerarCsvPadronRubroAsync(periodoId);
 1166            await RegistrarAuditoriaAsync(AccionEnum.GenerarReportePadronRubro, periodoId);
 1167            return File(csv, "text/csv", $"padron_rubro_{periodo.Anio}_{periodo.Mes:D2}.csv");
 168        }
 0169        catch (Exception ex)
 170        {
 0171            _logger.LogError(ex, "Error al generar CSV padrón rubro del período {PeriodoId}", periodoId);
 0172            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 173        }
 3174    }
 175
 176    // ─── Padrón mensual ──────────────────────────────────────────────────────
 177
 178    [HttpGet("{periodoId}/padron-mensual")]
 179    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 180    public async Task<IActionResult> GetPadronMensual(long periodoId)
 181    {
 182        try
 183        {
 3184            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3185            if (periodo == null)
 1186                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2187            if (periodo.Estado != Periodo.EstadoCerrada)
 1188                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 189
 1190            var result = await _service.ObtenerPadronMensualAsync(periodoId);
 1191            return Ok(ApiResponse<List<PadronMensualFilaDto>>.SuccessResult(result));
 192        }
 0193        catch (Exception ex)
 194        {
 0195            _logger.LogError(ex, "Error al obtener padrón mensual del período {PeriodoId}", periodoId);
 0196            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 197        }
 3198    }
 199
 200    [HttpGet("{periodoId}/padron-mensual/csv")]
 201    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 202    public async Task<IActionResult> GetPadronMensualCsv(long periodoId)
 203    {
 204        try
 205        {
 3206            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3207            if (periodo == null)
 1208                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2209            if (periodo.Estado != Periodo.EstadoCerrada)
 1210                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 211
 1212            var csv = await _service.GenerarCsvPadronMensualAsync(periodoId);
 1213            await RegistrarAuditoriaAsync(AccionEnum.GenerarReportePadronMensual, periodoId);
 1214            return File(csv, "text/csv", $"padron_mensual_{periodo.Anio}_{periodo.Mes:D2}.csv");
 215        }
 0216        catch (Exception ex)
 217        {
 0218            _logger.LogError(ex, "Error al generar CSV padrón mensual del período {PeriodoId}", periodoId);
 0219            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 220        }
 3221    }
 222
 223    // ─── Movimientos ─────────────────────────────────────────────────────────
 224
 225    [HttpGet("{periodoId}/movimientos")]
 226    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 227    public async Task<IActionResult> GetMovimientos(long periodoId)
 228    {
 229        try
 230        {
 3231            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3232            if (periodo == null)
 1233                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2234            if (periodo.Estado != Periodo.EstadoCerrada)
 1235                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 236
 1237            var result = await _service.ObtenerMovimientosAsync(periodoId);
 1238            return Ok(ApiResponse<List<MovimientoPersonalDto>>.SuccessResult(result));
 239        }
 0240        catch (Exception ex)
 241        {
 0242            _logger.LogError(ex, "Error al obtener movimientos del período {PeriodoId}", periodoId);
 0243            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 244        }
 3245    }
 246
 247    [HttpGet("{periodoId}/movimientos/csv")]
 248    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 249    public async Task<IActionResult> GetMovimientosCsv(long periodoId)
 250    {
 251        try
 252        {
 3253            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3254            if (periodo == null)
 1255                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2256            if (periodo.Estado != Periodo.EstadoCerrada)
 1257                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 258
 1259            var csv = await _service.GenerarCsvMovimientosAsync(periodoId);
 1260            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteMovimientos, periodoId);
 1261            return File(csv, "text/csv", $"movimientos_{periodo.Anio}_{periodo.Mes:D2}.csv");
 262        }
 0263        catch (Exception ex)
 264        {
 0265            _logger.LogError(ex, "Error al generar CSV movimientos del período {PeriodoId}", periodoId);
 0266            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 267        }
 3268    }
 269
 270    // ─── Diferencias ─────────────────────────────────────────────────────────
 271
 272    [HttpGet("{periodoId}/diferencias")]
 273    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 274    public async Task<IActionResult> GetDiferencias(long periodoId)
 275    {
 276        try
 277        {
 3278            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3279            if (periodo == null)
 1280                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2281            if (periodo.Estado != Periodo.EstadoCerrada)
 1282                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 283
 1284            var result = await _service.ObtenerDiferenciasAsync(periodoId);
 1285            return Ok(ApiResponse<PadronDiferenciasDto>.SuccessResult(result));
 286        }
 0287        catch (Exception ex)
 288        {
 0289            _logger.LogError(ex, "Error al obtener diferencias del período {PeriodoId}", periodoId);
 0290            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 291        }
 3292    }
 293
 294    [HttpGet("{periodoId}/diferencias/csv")]
 295    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 296    public async Task<IActionResult> GetDiferenciasCsv(long periodoId)
 297    {
 298        try
 299        {
 3300            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3301            if (periodo == null)
 1302                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2303            if (periodo.Estado != Periodo.EstadoCerrada)
 1304                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 305
 1306            var csv = await _service.GenerarCsvDiferenciasAsync(periodoId);
 1307            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteDiferencias, periodoId);
 1308            return File(csv, "text/csv", $"diferencias_{periodo.Anio}_{periodo.Mes:D2}.csv");
 309        }
 0310        catch (Exception ex)
 311        {
 0312            _logger.LogError(ex, "Error al generar CSV diferencias del período {PeriodoId}", periodoId);
 0313            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 314        }
 3315    }
 316
 317    // ─── No disponibles ──────────────────────────────────────────────────────
 318
 319    [HttpGet("{periodoId}/no-disponibles")]
 320    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 321    public async Task<IActionResult> GetNoDisponibles(long periodoId)
 322    {
 323        try
 324        {
 3325            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3326            if (periodo == null)
 1327                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2328            if (periodo.Estado != Periodo.EstadoCerrada)
 1329                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 330
 1331            var result = await _service.ObtenerNoDisponiblesAsync(periodoId);
 1332            return Ok(ApiResponse<List<NoDisponibleDto>>.SuccessResult(result));
 333        }
 0334        catch (Exception ex)
 335        {
 0336            _logger.LogError(ex, "Error al obtener no disponibles del período {PeriodoId}", periodoId);
 0337            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 338        }
 3339    }
 340
 341    [HttpGet("{periodoId}/no-disponibles/csv")]
 342    [RequirePermission(PermisoEnum.VerReportesPresupuestales)]
 343    public async Task<IActionResult> GetNoDisponiblesCsv(long periodoId)
 344    {
 345        try
 346        {
 3347            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 3348            if (periodo == null)
 1349                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 2350            if (periodo.Estado != Periodo.EstadoCerrada)
 1351                return Conflict(ApiResponse<string>.ErrorResult("El período no está cerrado"));
 352
 1353            var csv = await _service.GenerarCsvNoDisponiblesAsync(periodoId);
 1354            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteNoDisponibles, periodoId);
 1355            return File(csv, "text/csv", $"no_disponibles_{periodo.Anio}_{periodo.Mes:D2}.csv");
 356        }
 0357        catch (Exception ex)
 358        {
 0359            _logger.LogError(ex, "Error al generar CSV no disponibles del período {PeriodoId}", periodoId);
 0360            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 361        }
 3362    }
 363
 364    // ─── Helper ──────────────────────────────────────────────────────────────
 365
 366    private Task RegistrarAuditoriaAsync(AccionEnum accion, long periodoId) =>
 7367        _auditoriaService.LogAuditoriaAsync(
 7368            _currentUser.UserId ?? 0,
 7369            accion,
 7370            ContextoEnum.Liquidaciones,
 7371            _currentUser.Host,
 7372            entidad: "ReportePresupuestal",
 7373            entidadId: periodoId,
 7374            detalle: new { periodoId });
 375}