< Summary

Information
Class: FAU.API.Controllers.ReporteMDNController
Assembly: FAU.API
File(s): /home/runner/work/Sistema.Liquidacion.BE/Sistema.Liquidacion.BE/FAU.API/Controllers/ReporteMDNController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 108
Coverable lines: 108
Total lines: 271
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 18
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

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

#LineLine coverage
 1using FAU.Entidades;
 2using FAU.Logica.DTOs;
 3using FAU.Logica.Services;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Mvc;
 6
 7namespace FAU.API.Controllers;
 8
 9[ApiController]
 10[Route("api/liquidacion/reportes/mdn")]
 11[Authorize]
 12[Produces("application/json")]
 13public class ReporteMDNController : ControllerBase
 14{
 15    private readonly IReporteMDNService _service;
 16    private readonly IExporteMdnExcelService _excelService;
 17    private readonly IPeriodoService _periodoService;
 18    private readonly IAuditoriaService _auditoriaService;
 19    private readonly ICurrentUserContext _currentUser;
 20    private readonly ILogger<ReporteMDNController> _logger;
 21
 022    public ReporteMDNController(
 023        IReporteMDNService service,
 024        IExporteMdnExcelService excelService,
 025        IPeriodoService periodoService,
 026        IAuditoriaService auditoriaService,
 027        ICurrentUserContext currentUser,
 028        ILogger<ReporteMDNController> logger)
 29    {
 030        _service = service;
 031        _excelService = excelService;
 032        _periodoService = periodoService;
 033        _auditoriaService = auditoriaService;
 034        _currentUser = currentUser;
 035        _logger = logger;
 036    }
 37
 38    // ─── RPT-MDN-1: Padrón del Personal ───────────────────────────────────────
 39
 40    [HttpGet("{periodoId}/padron-personal")]
 41    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 42    [ProducesResponseType(typeof(ApiResponse<List<PadronPersonalMdnDto>>), StatusCodes.Status200OK)]
 43    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 44    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 45    public async Task<IActionResult> GetPadronPersonal(long periodoId, [FromQuery] long? regimenId = null)
 46    {
 47        try
 48        {
 049            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 050            if (periodo == null)
 051                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 52
 053            var result = await _service.ObtenerPadronPersonalAsync(periodoId, regimenId);
 054            return Ok(ApiResponse<List<PadronPersonalMdnDto>>.SuccessResult(result));
 55        }
 056        catch (Exception ex)
 57        {
 058            _logger.LogError(ex, "Error al obtener padrón personal MDN del período {PeriodoId}", periodoId);
 059            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 60        }
 061    }
 62
 63    [HttpGet("{periodoId}/padron-personal/csv")]
 64    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 65    [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
 66    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 67    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 68    public async Task<IActionResult> GetPadronPersonalCsv(long periodoId, [FromQuery] long? regimenId = null)
 69    {
 70        try
 71        {
 072            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 073            if (periodo == null)
 074                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 75
 076            var csv = await _service.GenerarCsvPadronPersonalAsync(periodoId, regimenId);
 077            await RegistrarAuditoriaAsync(AccionEnum.GenerarReportePadronMensual, periodoId, "padron-personal-mdn");
 078            return File(csv, "text/csv", $"padron_personal_mdn_{periodo.Anio}_{periodo.Mes:D2}.csv");
 79        }
 080        catch (Exception ex)
 81        {
 082            _logger.LogError(ex, "Error al generar CSV padrón personal MDN del período {PeriodoId}", periodoId);
 083            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 84        }
 085    }
 86
 87    // ─── RPT-MDN-2: Liquidación por Rubros ────────────────────────────────────
 88
 89    [HttpGet("{periodoId}/liquidacion-rubros")]
 90    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 91    [ProducesResponseType(typeof(ApiResponse<LiquidacionRubrosMdnDto>), StatusCodes.Status200OK)]
 92    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 93    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 94    public async Task<IActionResult> GetLiquidacionRubros(long periodoId, [FromQuery] long? regimenId = null)
 95    {
 96        try
 97        {
 098            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 099            if (periodo == null)
 0100                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 101
 0102            var result = await _service.ObtenerLiquidacionPorRubrosAsync(periodoId, regimenId);
 0103            return Ok(ApiResponse<LiquidacionRubrosMdnDto>.SuccessResult(result));
 104        }
 0105        catch (Exception ex)
 106        {
 0107            _logger.LogError(ex, "Error al obtener liquidación por rubros MDN del período {PeriodoId}", periodoId);
 0108            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 109        }
 0110    }
 111
 112    [HttpGet("{periodoId}/liquidacion-rubros/csv")]
 113    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 114    [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
 115    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 116    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 117    public async Task<IActionResult> GetLiquidacionRubrosCsv(long periodoId, [FromQuery] long? regimenId = null)
 118    {
 119        try
 120        {
 0121            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 0122            if (periodo == null)
 0123                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 124
 0125            var csv = await _service.GenerarCsvLiquidacionPorRubrosAsync(periodoId, regimenId);
 0126            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteRubro083, periodoId, "liquidacion-rubros-mdn");
 0127            return File(csv, "text/csv", $"liquidacion_rubros_mdn_{periodo.Anio}_{periodo.Mes:D2}.csv");
 128        }
 0129        catch (Exception ex)
 130        {
 0131            _logger.LogError(ex, "Error al generar CSV liquidación por rubros MDN del período {PeriodoId}", periodoId);
 0132            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 133        }
 0134    }
 135
 136    // ─── RPT-MDN-3: Control Porcentual ────────────────────────────────────────
 137
 138    [HttpGet("{periodoId}/control-porcentual")]
 139    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 140    [ProducesResponseType(typeof(ApiResponse<ControlPorcentualMdnDto>), StatusCodes.Status200OK)]
 141    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 142    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 143    public async Task<IActionResult> GetControlPorcentual(long periodoId, [FromQuery] long? regimenId = null)
 144    {
 145        try
 146        {
 0147            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 0148            if (periodo == null)
 0149                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 150
 0151            var result = await _service.ObtenerControlPorcentualAsync(periodoId, regimenId);
 0152            return Ok(ApiResponse<ControlPorcentualMdnDto>.SuccessResult(result));
 153        }
 0154        catch (Exception ex)
 155        {
 0156            _logger.LogError(ex, "Error al obtener control porcentual MDN del período {PeriodoId}", periodoId);
 0157            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 158        }
 0159    }
 160
 161    [HttpGet("{periodoId}/control-porcentual/csv")]
 162    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 163    [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
 164    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 165    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 166    public async Task<IActionResult> GetControlPorcentualCsv(long periodoId, [FromQuery] long? regimenId = null)
 167    {
 168        try
 169        {
 0170            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 0171            if (periodo == null)
 0172                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 173
 0174            var csv = await _service.GenerarCsvControlPorcentualAsync(periodoId, regimenId);
 0175            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteEfectivosSuperior, periodoId, "control-porcentual-mdn
 0176            return File(csv, "text/csv", $"control_porcentual_mdn_{periodo.Anio}_{periodo.Mes:D2}.csv");
 177        }
 0178        catch (Exception ex)
 179        {
 0180            _logger.LogError(ex, "Error al generar CSV control porcentual MDN del período {PeriodoId}", periodoId);
 0181            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 182        }
 0183    }
 184
 185    // ─── RPT-MDN-4: Haberes Gravables / No Gravables ──────────────────────────
 186
 187    [HttpGet("{periodoId}/haberes-gravables")]
 188    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 189    [ProducesResponseType(typeof(ApiResponse<List<HaberesGravablesMdnFilaDto>>), StatusCodes.Status200OK)]
 190    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 191    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 192    public async Task<IActionResult> GetHaberesGravables(long periodoId, [FromQuery] long? regimenId = null)
 193    {
 194        try
 195        {
 0196            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 0197            if (periodo == null)
 0198                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 199
 0200            var result = await _service.ObtenerHaberesGravablesAsync(periodoId, regimenId);
 0201            return Ok(ApiResponse<List<HaberesGravablesMdnFilaDto>>.SuccessResult(result));
 202        }
 0203        catch (Exception ex)
 204        {
 0205            _logger.LogError(ex, "Error al obtener haberes gravables MDN del período {PeriodoId}", periodoId);
 0206            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 207        }
 0208    }
 209
 210    [HttpGet("{periodoId}/haberes-gravables/csv")]
 211    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 212    [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
 213    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 214    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 215    public async Task<IActionResult> GetHaberesGravablesCsv(long periodoId, [FromQuery] long? regimenId = null)
 216    {
 217        try
 218        {
 0219            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 0220            if (periodo == null)
 0221                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 222
 0223            var csv = await _service.GenerarCsvHaberesGravablesAsync(periodoId, regimenId);
 0224            await RegistrarAuditoriaAsync(AccionEnum.GenerarReporteEfectivosSubalterno, periodoId, "haberes-gravables-md
 0225            return File(csv, "text/csv", $"haberes_gravables_mdn_{periodo.Anio}_{periodo.Mes:D2}.csv");
 226        }
 0227        catch (Exception ex)
 228        {
 0229            _logger.LogError(ex, "Error al generar CSV haberes gravables MDN del período {PeriodoId}", periodoId);
 0230            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 231        }
 0232    }
 233
 234    // ─── RPT-MDN-5: Excel completo MDN (3 hojas legacy) ──────────────────────
 235
 236    [HttpGet("{periodoId}/excel")]
 237    [Authorize(Roles = "Administrador,Supervisor,Usuario")]
 238    [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
 239    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status404NotFound)]
 240    [ProducesResponseType(typeof(ApiResponse<string>), StatusCodes.Status500InternalServerError)]
 241    public async Task<IActionResult> GetExcelMdn(long periodoId, [FromQuery] long? regimenId = null)
 242    {
 243        try
 244        {
 0245            var periodo = await _periodoService.ObtenerPorIdAsync(periodoId);
 0246            if (periodo == null)
 0247                return NotFound(ApiResponse<string>.ErrorResult("Período no encontrado"));
 248
 0249            var (bytes, fileName) = await _excelService.GenerarExcelAsync(periodoId, regimenId);
 0250            await RegistrarAuditoriaAsync(AccionEnum.GenerarReportePadronMensual, periodoId, "excel-mdn-completo");
 0251            return File(bytes, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", fileName);
 252        }
 0253        catch (Exception ex)
 254        {
 0255            _logger.LogError(ex, "Error al generar Excel MDN del período {PeriodoId}", periodoId);
 0256            return StatusCode(500, ApiResponse<string>.ErrorResult("Error interno del servidor"));
 257        }
 0258    }
 259
 260    // ─── Helper ──────────────────────────────────────────────────────────────
 261
 262    private Task RegistrarAuditoriaAsync(AccionEnum accion, long periodoId, string tipoReporte) =>
 0263        _auditoriaService.LogAuditoriaAsync(
 0264            _currentUser.UserId ?? 0,
 0265            accion,
 0266            ContextoEnum.Liquidaciones,
 0267            _currentUser.Host,
 0268            entidad: "ReporteMDN",
 0269            entidadId: periodoId,
 0270            detalle: new { periodoId, tipoReporte });
 271}