using GestionIntegral.Api.Services.Reportes; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Reporting.NETCore; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Threading.Tasks; using GestionIntegral.Api.Dtos.Reportes; using GestionIntegral.Api.Data.Repositories.Impresion; using System.IO; using System.Linq; using GestionIntegral.Api.Data.Repositories.Distribucion; namespace GestionIntegral.Api.Controllers { [Route("api/[controller]")] [ApiController] [Authorize] public class ReportesController : ControllerBase { private readonly IReportesService _reportesService; // <--- CORREGIDO private readonly ILogger _logger; private readonly IPlantaRepository _plantaRepository; private readonly IPublicacionRepository _publicacionRepository; private readonly IEmpresaRepository _empresaRepository; private readonly IDistribuidorRepository _distribuidorRepository; // Para obtener el nombre del distribuidor // Permisos private const string PermisoVerReporteExistenciaPapel = "RR005"; private const string PermisoVerReporteMovimientoBobinas = "RR006"; private const string PermisoVerListadoDistribucion = "RR002"; private const string PermisoVerControlDevoluciones = "RR003"; private const string PermisoVerComprobanteLiquidacionCanilla = "MC005"; private const string PermisoVerBalanceCuentas = "RR001"; private const string PermisoVerReporteTiradas = "RR008"; private const string PermisoVerReporteConsumoBobinas = "RR007"; public ReportesController( IReportesService reportesService, // <--- CORREGIDO ILogger logger, IPlantaRepository plantaRepository, IPublicacionRepository publicacionRepository, IEmpresaRepository empresaRepository, IDistribuidorRepository distribuidorRepository) // Añadido { _reportesService = reportesService; // <--- CORREGIDO _logger = logger; _plantaRepository = plantaRepository; _publicacionRepository = publicacionRepository; _empresaRepository = empresaRepository; _distribuidorRepository = distribuidorRepository; // Añadido } private bool TienePermiso(string codAcc) => User.IsInRole("SuperAdmin") || User.HasClaim(c => c.Type == "permission" && c.Value == codAcc); // GET: api/reportes/existencia-papel [HttpGet("existencia-papel")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task GetReporteExistenciaPapel( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int? idPlanta, [FromQuery] bool consolidado = false) { if (!TienePermiso(PermisoVerReporteExistenciaPapel)) { _logger.LogWarning("Acceso denegado a GetReporteExistenciaPapel. Usuario: {User}", User.Identity?.Name ?? "Desconocido"); return Forbid(); } var (data, error) = await _reportesService.ObtenerExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); // <--- CORREGIDO if (error != null) { return BadRequest(new { message = error }); } return Ok(data); } [HttpGet("existencia-papel/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status500InternalServerError)] public async Task GetReporteExistenciaPapelPdf( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int? idPlanta, [FromQuery] bool consolidado = false) { if (!TienePermiso(PermisoVerReporteExistenciaPapel)) return Forbid(); var (data, error) = await _reportesService.ObtenerExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); // <--- CORREGIDO if (error != null) { return BadRequest(new { message = error }); } if (data == null || !data.Any()) { return NotFound(new { message = "No hay datos para generar el PDF con los parámetros seleccionados." }); } try { LocalReport report = new LocalReport(); string rdlcPath = consolidado ? "Controllers/Reportes/RDLC/ReporteExistenciaPapelConsolidado.rdlc" : "Controllers/Reportes/RDLC/ReporteExistenciaPapel.rdlc"; using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSConsumoBobinas", data)); var parameters = new List(); parameters.Add(new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy"))); parameters.Add(new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))); string nombrePlantaParam = "Consolidado"; if (!consolidado && idPlanta.HasValue) { var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value); nombrePlantaParam = planta?.Nombre ?? "N/A"; } else if (consolidado) { // Para el consolidado, el RDLC ReporteExistenciaPapelConsolidado.txt NO espera NomPlanta } else { // No consolidado pero idPlanta es NULL (aunque el servicio ya valida esto) nombrePlantaParam = "N/A"; } // Solo añadir NomPlanta si NO es consolidado, porque el RDLC consolidado no lo tiene. if (!consolidado) { parameters.Add(new ReportParameter("NomPlanta", nombrePlantaParam)); } report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ExistenciaPapel_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}_{(consolidado ? "Consolidado" : $"Planta{idPlanta}")}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Existencia de Papel."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("movimiento-bobinas")] [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] public async Task GetReporteMovimientoBobinas( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int idPlanta) { if (!TienePermiso(PermisoVerReporteMovimientoBobinas)) return Forbid(); var (data, error) = await _reportesService.ObtenerMovimientoBobinasAsync(fechaDesde, fechaHasta, idPlanta); // <--- CORREGIDO if (error != null) return BadRequest(new { message = error }); return Ok(data); } [HttpGet("movimiento-bobinas/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetReporteMovimientoBobinasPdf( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int idPlanta) { if (!TienePermiso(PermisoVerReporteMovimientoBobinas)) return Forbid(); var (data, error) = await _reportesService.ObtenerMovimientoBobinasAsync(fechaDesde, fechaHasta, idPlanta); // <--- CORREGIDO if (error != null) return BadRequest(new { message = error }); if (data == null || !data.Any()) { return NotFound(new { message = "No hay datos para generar el PDF del movimiento de bobinas con los parámetros seleccionados." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteMovimientoBobinas.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSMovimientoBobinas", data)); // El RDLC usa "DSMovimientoBobinas" var planta = await _plantaRepository.GetByIdAsync(idPlanta); var parameters = new List(); parameters.Add(new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy"))); parameters.Add(new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))); parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A")); report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"MovimientoBobinas_Planta{idPlanta}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Movimiento de Bobinas."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("movimiento-bobinas-estado/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetReporteMovimientoBobinasEstadoPdf( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int idPlanta) { if (!TienePermiso(PermisoVerReporteMovimientoBobinas)) return Forbid(); var (detalle, totales, error) = await _reportesService.ObtenerMovimientoBobinasPorEstadoAsync(fechaDesde, fechaHasta, idPlanta); // <--- CORREGIDO if (error != null) return BadRequest(new { message = error }); if ((detalle == null || !detalle.Any()) && (totales == null || !totales.Any())) { return NotFound(new { message = "No hay datos para generar el PDF del movimiento de bobinas por estado con los parámetros seleccionados." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteMovimientoBobinasEstado.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSMovimientoBobinasEstado", detalle ?? new List())); report.DataSources.Add(new ReportDataSource("DSMovimientoBobinasEstadoTotales", totales ?? new List())); var planta = await _plantaRepository.GetByIdAsync(idPlanta); var parameters = new List(); parameters.Add(new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy"))); parameters.Add(new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))); parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A")); report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"MovimientoBobinasEstado_Planta{idPlanta}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Movimiento de Bobinas por Estado."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } // --- Nuevos Endpoints --- [HttpGet("listado-distribucion-general/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetListadoDistribucionGeneralPdf( [FromQuery] int idPublicacion, [FromQuery] DateTime fechaDesde, // Usado para Mes y Año en el SP [FromQuery] DateTime fechaHasta) // Usado para el nombre del archivo y potencialmente como parámetro si el SP cambia { if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); var (resumen, promedios, error) = await _reportesService.ObtenerListadoDistribucionGeneralAsync(idPublicacion, fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if ((resumen == null || !resumen.Any()) && (promedios == null || !promedios.Any())) { return NotFound(new { message = "No hay datos para generar el PDF." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteListadoDistribucionGeneral.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } // Los nombres de DataSet deben coincidir con los del RDLC. Basado en DSListadoDistribucion.txt report.DataSources.Add(new ReportDataSource("DSResumenMensual", resumen ?? new List())); report.DataSources.Add(new ReportDataSource("DSResumenMensualPorDiaSemana", promedios ?? new List())); var publicacion = await _publicacionRepository.GetByIdSimpleAsync(idPublicacion); var parameters = new List { new ReportParameter("NomPubli", publicacion?.Nombre ?? "N/A"), new ReportParameter("FechaDesde", fechaDesde.ToString("MMMM 'de' yyyy")) // El RDLC espera un parámetro FechaDesde }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ListadoDistribucionGeneral_Pub{idPublicacion}_{fechaDesde:yyyyMM}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Listado Distribucion General."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("listado-distribucion-canillas/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetListadoDistribucionCanillasPdf( [FromQuery] int idPublicacion, [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); var (simple, promedios, error) = await _reportesService.ObtenerListadoDistribucionCanillasAsync(idPublicacion, fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if ((simple == null || !simple.Any()) && (promedios == null || !promedios.Any())) { return NotFound(new { message = "No hay datos para generar el PDF." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteListadoDistribucionCanillas.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", simple ?? new List())); report.DataSources.Add(new ReportDataSource("DSListadoDistribucionAgDias", promedios ?? new List())); var publicacion = await _publicacionRepository.GetByIdSimpleAsync(idPublicacion); var parameters = new List { new ReportParameter("NomPubli", publicacion?.Nombre ?? "N/A"), new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ListadoDistribucionCanillas_Pub{idPublicacion}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Listado Distribucion Canillas."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("listado-distribucion-canillas-importe/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status403Forbidden)] [ProducesResponseType(StatusCodes.Status404NotFound)] public async Task GetListadoDistribucionCanillasConImportePdf( [FromQuery] int idPublicacion, [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] bool esAccionista) { if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); var (data, error) = await _reportesService.ObtenerListadoDistribucionCanillasConImporteAsync(idPublicacion, fechaDesde, fechaHasta, esAccionista); if (error != null) return BadRequest(new { message = error }); if (data == null || !data.Any()) { return NotFound(new { message = "No hay datos para generar el PDF." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteListadoDistribucionCanImp.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCan", data)); var publicacion = await _publicacionRepository.GetByIdSimpleAsync(idPublicacion); var parameters = new List { new ReportParameter("NomPubli", publicacion?.Nombre ?? "N/A"), new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")), new ReportParameter("CanAcc", esAccionista ? "1" : "0") }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string tipoVendedor = esAccionista ? "Accionistas" : "Canillitas"; string fileName = $"ListadoDistCanImp_Pub{idPublicacion}_{tipoVendedor}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Listado Distribucion Canillas con Importe."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("venta-mensual-secretaria/el-dia/pdf")] public async Task GetVentaMensualSecretariaElDiaPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); // Asumiendo RR002 var (data, error) = await _reportesService.ObtenerVentaMensualSecretariaElDiaAsync(fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para el reporte." }); try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteVentaMensualSecretariaElDia.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", data)); // Basado en el RDLC report.SetParameters(new[] { new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }); byte[] pdfBytes = report.Render("PDF"); return File(pdfBytes, "application/pdf", $"VentaMensualSecretaria_ElDia_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"); } catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaElDia."); return StatusCode(500, "Error interno."); } } [HttpGet("venta-mensual-secretaria/el-plata/pdf")] public async Task GetVentaMensualSecretariaElPlataPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); // Asumiendo RR002 var (data, error) = await _reportesService.ObtenerVentaMensualSecretariaElPlataAsync(fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para el reporte." }); try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteVentaMensualSecretariaElPlata.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", data)); // Basado en el RDLC report.SetParameters(new[] { new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }); byte[] pdfBytes = report.Render("PDF"); return File(pdfBytes, "application/pdf", $"VentaMensualSecretaria_ElPlata_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"); } catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaElPlata."); return StatusCode(500, "Error interno."); } } [HttpGet("venta-mensual-secretaria/tirada-devolucion/pdf")] public async Task GetVentaMensualSecretariaTirDevoPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); // Asumiendo RR002 var (data, error) = await _reportesService.ObtenerVentaMensualSecretariaTirDevoAsync(fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para el reporte." }); try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteVentaMensualSecretariaTirDevo.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", data)); // Basado en el RDLC report.SetParameters(new[] { new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }); byte[] pdfBytes = report.Render("PDF"); return File(pdfBytes, "application/pdf", $"VentaMensualSecretaria_TirDevo_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"); } catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaTirDevo."); return StatusCode(500, "Error interno."); } } [HttpGet("distribucion-canillas/pdf")] public async Task GetReporteDistribucionCanillasPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa, [FromQuery] bool soloTotales = false) { if (!TienePermiso(PermisoVerComprobanteLiquidacionCanilla)) return Forbid(); var (canillas, canillasAcc, canillasAll, canillasFechaLiq, canillasAccFechaLiq, ctrlDevoluciones, ctrlDevolucionesParaDistCan, error) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); if (error != null) return BadRequest(new { message = error }); bool noHayDatosParaTotales = (canillasAll == null || !canillasAll.Any()) && (ctrlDevoluciones == null || !ctrlDevoluciones.Any()) && (ctrlDevolucionesParaDistCan == null || !ctrlDevolucionesParaDistCan.Any()); bool noHayDatosParaDetalle = noHayDatosParaTotales && (canillas == null || !canillas.Any()) && (canillasAcc == null || !canillasAcc.Any()) && (canillasFechaLiq == null || !canillasFechaLiq.Any()) && (canillasAccFechaLiq == null || !canillasAccFechaLiq.Any()); if ((soloTotales && noHayDatosParaTotales) || (!soloTotales && noHayDatosParaDetalle)) { return NotFound(new { message = "No hay datos para generar el PDF del reporte de distribución de canillas." }); } try { LocalReport report = new LocalReport(); string rdlcPath = soloTotales ? "Controllers/Reportes/RDLC/ReporteDistribucionCanillasTotales.rdlc" : "Controllers/Reportes/RDLC/ReporteDistribucionCanillas.rdlc"; using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCan", canillas ?? new List())); report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanAcc", canillasAcc ?? new List())); report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanALL", canillasAll ?? new List())); report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanFechaLiq", canillasFechaLiq ?? new List())); report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanAccFechaLiq", canillasAccFechaLiq ?? new List())); report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevoluciones ?? new List())); report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCan ?? new List())); var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); var parameters = new List { new ReportParameter("FechaConsultada", fecha.ToString("dd/MM/yyyy")), new ReportParameter("Empresa", empresa?.Nombre ?? "N/A") }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string tipoReporte = soloTotales ? "Totales" : "Detalle"; string fileName = $"DistribucionCanillas_{tipoReporte}_Emp{idEmpresa}_{fecha:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Reporte Distribucion Canillas."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("control-devoluciones/pdf")] public async Task GetReporteControlDevolucionesPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa) { if (!TienePermiso(PermisoVerControlDevoluciones)) return Forbid(); var ( _, _, _, _, _, ctrlDevolucionesData, // Este es el que usa el DataSet "DSObtenerCtrlDevoluciones" ctrlDevolucionesParaDistCanData, // Este es el que usa el DataSet "DSCtrlDevoluciones" error ) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); if (error != null) return BadRequest(new { message = error }); if ((ctrlDevolucionesData == null || !ctrlDevolucionesData.Any()) && (ctrlDevolucionesParaDistCanData == null || !ctrlDevolucionesParaDistCanData.Any())) { return NotFound(new { message = "No hay datos para generar el PDF para control de devoluciones." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteCtrlDevoluciones.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCanData ?? new List())); report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevolucionesData ?? new List())); var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); var parameters = new List { new ReportParameter("FechaConsultada", fecha.ToString("dd/MM/yyyy")), new ReportParameter("NomEmp", empresa?.Nombre ?? "N/A") }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ControlDevoluciones_Emp{idEmpresa}_{fecha:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Control Devoluciones."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("cuentas-distribuidores/pdf")] public async Task GetReporteCuentasDistribuidoresPdf( [FromQuery] int idDistribuidor, [FromQuery] int idEmpresa, [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { if (!TienePermiso(PermisoVerBalanceCuentas)) return Forbid(); var (entradasSalidas, debitosCreditos, pagos, saldos, error) = await _reportesService.ObtenerReporteCuentasDistribuidorAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if (!entradasSalidas.Any() && !debitosCreditos.Any() && !pagos.Any() && !saldos.Any()) { return NotFound(new { message = "No hay datos para generar el reporte de cuenta del distribuidor." }); } try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteCuentasDistribuidores.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSDistribuidoresEntradasSalidas", entradasSalidas ?? new List())); report.DataSources.Add(new ReportDataSource("DSDistribuidoresDebCred", debitosCreditos ?? new List())); report.DataSources.Add(new ReportDataSource("DSDistribuidoresPagos", pagos ?? new List())); report.DataSources.Add(new ReportDataSource("DSDistribuidoresSaldos", saldos ?? new List())); var parameters = new List { new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"CuentaDistribuidor_{idDistribuidor}_Emp{idEmpresa}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error al generar PDF para Cuentas Distribuidores."); return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } [HttpGet("tiradas-publicaciones-secciones/pdf")] public async Task GetReporteTiradasPublicacionesSeccionesPdf( [FromQuery] int idPublicacion, [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int? idPlanta, [FromQuery] bool consolidado = false) { if (!TienePermiso(PermisoVerReporteTiradas)) return Forbid(); IEnumerable data; string? errorMsg; // Para recibir el mensaje de error if (consolidado) { (data, errorMsg) = await _reportesService.ObtenerTiradasPublicacionesSeccionesConsolidadoAsync(idPublicacion, fechaDesde, fechaHasta); } else { if (!idPlanta.HasValue) return BadRequest(new { message = "Se requiere IdPlanta para reportes no consolidados." }); (data, errorMsg) = await _reportesService.ObtenerTiradasPublicacionesSeccionesAsync(idPublicacion, fechaDesde, fechaHasta, idPlanta.Value); } if (errorMsg != null) return BadRequest(new { message = errorMsg }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." }); try { LocalReport report = new LocalReport(); string rdlcPath = consolidado ? "Controllers/Reportes/RDLC/ReporteTiradasPublicacionesSeccionesConsolidado.rdlc" : "Controllers/Reportes/RDLC/ReporteTiradasPublicacionesSecciones.rdlc"; using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSTiradasPublicacionesSecciones", data)); var publicacion = await _publicacionRepository.GetByIdSimpleAsync(idPublicacion); var parameters = new List { new ReportParameter("Mes", fechaDesde.ToString("MMMM yyyy")), new ReportParameter("NomPubli", publicacion?.Nombre ?? "N/A") }; if (!consolidado && idPlanta.HasValue) { var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value); parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A")); } report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"TiradasSecciones_Pub{idPublicacion}_{(consolidado ? "Consolidado" : $"Planta{idPlanta}")}_{fechaDesde:yyyyMM}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error PDF Tiradas Publicaciones Secciones."); return StatusCode(500, "Error interno."); } } [HttpGet("consumo-bobinas-seccion/pdf")] public async Task GetReporteConsumoBobinasSeccionPdf( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, [FromQuery] int? idPlanta, [FromQuery] bool consolidado = false) { if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid(); IEnumerable data; string? errorMsg; if (consolidado) { (data, errorMsg) = await _reportesService.ObtenerConsumoBobinasPorSeccionConsolidadoAsync(fechaDesde, fechaHasta); } else { if (!idPlanta.HasValue) return BadRequest(new { message = "Se requiere IdPlanta para reportes no consolidados." }); (data, errorMsg) = await _reportesService.ObtenerConsumoBobinasPorSeccionAsync(fechaDesde, fechaHasta, idPlanta.Value); } if (errorMsg != null) return BadRequest(new { message = errorMsg }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." }); try { LocalReport report = new LocalReport(); string rdlcPath = consolidado ? "Controllers/Reportes/RDLC/ReporteConsumoBobinasSeccionConsolidado.rdlc" : "Controllers/Reportes/RDLC/ReporteConsumoBobinasSeccion.rdlc"; using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSConsumoBobinasSeccion", data)); var parameters = new List { new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }; if (!consolidado && idPlanta.HasValue) { var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value); parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A")); } report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ConsumoBobinasSeccion_{(consolidado ? "Consolidado" : $"Planta{idPlanta}")}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error PDF Consumo Bobinas por Seccion."); return StatusCode(500, "Error interno."); } } [HttpGet("consumo-bobinas-publicacion/pdf")] public async Task GetReporteConsumoBobinasPublicacionPdf( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid(); var (data, error) = await _reportesService.ObtenerConsumoBobinasPorPublicacionAsync(fechaDesde, fechaHasta); if (error != null) return BadRequest(new { message = error }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." }); try { LocalReport report = new LocalReport(); using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteConsumoBobinasPublicacion.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSConsumoBobinasPublicacion", data)); var parameters = new List { new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")), new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")) }; report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ConsumoBobinasPublicacion_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error PDF Consumo Bobinas por Publicacion."); return StatusCode(500, "Error interno."); } } [HttpGet("comparativa-consumo-bobinas/pdf")] public async Task GetReporteComparativaConsumoBobinasPdf( [FromQuery] DateTime fechaInicioMesA, [FromQuery] DateTime fechaFinMesA, [FromQuery] DateTime fechaInicioMesB, [FromQuery] DateTime fechaFinMesB, [FromQuery] int? idPlanta, [FromQuery] bool consolidado = false) { if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid(); IEnumerable data; string? errorMsg; if (consolidado) { (data, errorMsg) = await _reportesService.ObtenerComparativaConsumoBobinasConsolidadoAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB); } else { if (!idPlanta.HasValue) return BadRequest(new { message = "Se requiere IdPlanta para reportes no consolidados." }); (data, errorMsg) = await _reportesService.ObtenerComparativaConsumoBobinasAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB, idPlanta.Value); } if (errorMsg != null) return BadRequest(new { message = errorMsg }); if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." }); try { LocalReport report = new LocalReport(); string rdlcPath = consolidado ? "Controllers/Reportes/RDLC/ReporteConsumoBobinasMesesConsolidado.rdlc" : "Controllers/Reportes/RDLC/ReporteConsumoBobinasMeses.rdlc"; using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { report.LoadReportDefinition(fs); } report.DataSources.Add(new ReportDataSource("DSConsumoBobinasMeses", data)); var parameters = new List { new ReportParameter("MesA", fechaInicioMesA.ToString("MMMM yyyy")), new ReportParameter("MesB", fechaInicioMesB.ToString("MMMM yyyy")) }; if (!consolidado && idPlanta.HasValue) { var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value); parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A")); } report.SetParameters(parameters); byte[] pdfBytes = report.Render("PDF"); string fileName = $"ComparativaConsumoBobinas_{(consolidado ? "Consolidado" : $"Planta{idPlanta}")}_{fechaInicioMesA:yyyyMM}_vs_{fechaInicioMesB:yyyyMM}.pdf"; return File(pdfBytes, "application/pdf", fileName); } catch (Exception ex) { _logger.LogError(ex, "Error PDF Comparativa Consumo Bobinas."); return StatusCode(500, "Error interno."); } } } }