diff --git a/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs b/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs index 6b869b9..5aaa3b8 100644 --- a/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs +++ b/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs @@ -7,7 +7,10 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using GestionIntegral.Api.Dtos.Reportes; -using GestionIntegral.Api.Data.Repositories.Impresion; // Para ExistenciaPapelDto +using GestionIntegral.Api.Data.Repositories.Impresion; +using System.IO; +using System.Linq; +using GestionIntegral.Api.Data.Repositories.Distribucion; namespace GestionIntegral.Api.Controllers { @@ -16,18 +19,39 @@ namespace GestionIntegral.Api.Controllers [Authorize] public class ReportesController : ControllerBase { - private readonly IReportesService _reportesService; + 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 - // Asumimos un permiso genérico para reportes o uno específico + + // 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, ILogger logger, IPlantaRepository plantaRepository) + + public ReportesController( + IReportesService reportesService, // <--- CORREGIDO + ILogger logger, + IPlantaRepository plantaRepository, + IPublicacionRepository publicacionRepository, + IEmpresaRepository empresaRepository, + IDistribuidorRepository distribuidorRepository) // Añadido { - _reportesService = reportesService; + _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); @@ -41,8 +65,8 @@ namespace GestionIntegral.Api.Controllers public async Task GetReporteExistenciaPapel( [FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta, - [FromQuery] int? idPlanta, // Opcional - [FromQuery] bool consolidado = false) // Por defecto no consolidado + [FromQuery] int? idPlanta, + [FromQuery] bool consolidado = false) { if (!TienePermiso(PermisoVerReporteExistenciaPapel)) { @@ -50,7 +74,7 @@ namespace GestionIntegral.Api.Controllers return Forbid(); } - var (data, error) = await _reportesService.ObtenerExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); + var (data, error) = await _reportesService.ObtenerExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); // <--- CORREGIDO if (error != null) { @@ -59,7 +83,6 @@ namespace GestionIntegral.Api.Controllers return Ok(data); } - // Nuevo endpoint para PDF [HttpGet("existencia-papel/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] @@ -73,7 +96,7 @@ namespace GestionIntegral.Api.Controllers { if (!TienePermiso(PermisoVerReporteExistenciaPapel)) return Forbid(); - var (data, error) = await _reportesService.ObtenerExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); + var (data, error) = await _reportesService.ObtenerExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); // <--- CORREGIDO if (error != null) { @@ -87,17 +110,35 @@ namespace GestionIntegral.Api.Controllers try { LocalReport report = new LocalReport(); - using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteExistenciaPapel.rdlc", FileMode.Open)) // Ruta a tu .rdlc + 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)); // Nombre del DataSet en el RDLC + report.DataSources.Add(new ReportDataSource("DSConsumoBobinas", data)); - var parameters = new ReportParameter[3]; - parameters[0] = new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")); - parameters[1] = new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")); - var planta = idPlanta.HasValue ? await _plantaRepository.GetByIdAsync(idPlanta.Value) : null; - parameters[2] = new ReportParameter("NomPlanta", consolidado ? "Consolidado" : planta?.Nombre ?? "N/A"); + 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"); @@ -110,5 +151,719 @@ namespace GestionIntegral.Api.Controllers 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."); } + } } } \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs index 7b3f935..ac2a0cb 100644 --- a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs +++ b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs @@ -1,4 +1,5 @@ -using GestionIntegral.Api.Dtos.Reportes; // Para ExistenciaPapelDto +// src/Data/Repositories/Reportes/IReportesRepository.cs +using GestionIntegral.Api.Dtos.Reportes; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -8,6 +9,36 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes public interface IReportesRepository { Task> GetExistenciaPapelAsync(DateTime fechaDesde, DateTime fechaHasta, int? idPlanta, bool consolidado); - // ... Aquí irán los métodos para otros reportes ... + Task> GetMovimientoBobinasAsync(DateTime fechaInicio, int diasPeriodo, int idPlanta); + Task> GetMovimientoBobinasEstadoDetalleAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta); + Task> GetMovimientoBobinasEstadoTotalesAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta); + + // --- MÉTODOS AÑADIDOS AQUÍ --- + Task> GetListadoDistribucionGeneralResumenAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + Task> GetListadoDistribucionGeneralPromedioDiaAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + Task> GetListadoDistribucionCanillasSimpleAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + Task> GetListadoDistribucionCanillasPromedioDiaAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + Task> GetListadoDistribucionCanillasImporteAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, bool esAccionista); + Task> GetVentaMensualSecretariaElDiaAsync(DateTime fechaDesde, DateTime fechaHasta); + Task> GetVentaMensualSecretariaElPlataAsync(DateTime fechaDesde, DateTime fechaHasta); + Task> GetVentaMensualSecretariaTirDevoAsync(DateTime fechaDesde, DateTime fechaHasta); + Task> GetDetalleDistribucionCanillasPubliAsync(DateTime fecha, int idEmpresa); + Task> GetDetalleDistribucionCanillasAccPubliAsync(DateTime fecha, int idEmpresa); + Task> GetDetalleDistribucionCanillasAllPubliAsync(DateTime fecha, int idEmpresa); + Task> GetDetalleDistribucionCanillasPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa); + Task> GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa); + Task> GetReporteObtenerCtrlDevolucionesAsync(DateTime fecha, int idEmpresa); + Task> GetReporteCtrlDevolucionesParaDistCanAsync(DateTime fecha, int idEmpresa); + Task> GetTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); + Task> GetTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + Task> GetConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta); + Task> GetConsumoBobinasPorSeccionConsolidadoAsync(DateTime fechaDesde, DateTime fechaHasta); + Task> GetConsumoBobinasPorPublicacionAsync(DateTime fechaDesde, DateTime fechaHasta); + Task> GetComparativaConsumoBobinasAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB, int idPlanta); + Task> GetComparativaConsumoBobinasConsolidadoAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB); + Task> GetBalanceCuentaDistEntradaSalidaPorEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta); + Task> GetBalanceCuentDistDebCredEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta); + Task> GetBalanceCuentDistPagosEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta); + Task> GetBalanceCuentSaldosEmpresasAsync(string destino, int idDestino, int idEmpresa); } } \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs index cd855e1..2ebbfef 100644 --- a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs +++ b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs @@ -1,3 +1,4 @@ +// src/Data/Repositories/Reportes/ReportesRepository.cs using Dapper; using GestionIntegral.Api.Dtos.Reportes; using Microsoft.Extensions.Logging; @@ -26,24 +27,16 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes var parameters = new DynamicParameters(); parameters.Add("FechaDesde", fechaDesde, DbType.Date); - parameters.Add("FechaHasta", fechaHasta, DbType.Date); // SP_ConsumoBobinasConsolidado solo usa estas dos + parameters.Add("FechaHasta", fechaHasta, DbType.Date); if (!consolidado) { if (!idPlanta.HasValue) { - _logger.LogError("idPlanta es requerido para el reporte de existencia de papel no consolidado."); - // Podríamos lanzar una ArgumentNullException o devolver una lista vacía. - // Por ahora, el servicio debería validar esto antes. - // Para el repositorio, asumimos que si no es consolidado, idPlanta viene. - throw new ArgumentNullException(nameof(idPlanta), "El ID de planta es requerido para el reporte no consolidado."); + throw new ArgumentNullException(nameof(idPlanta), "El ID de planta es requerido para el reporte no consolidado de existencia de papel."); } parameters.Add("@idPlanta", idPlanta.Value, DbType.Int32); - } - // Si los SPs realmente necesitaran @DiasPeriodo, lo calcularíamos así: - // int diasPeriodo = (fechaHasta - fechaDesde).Days + 1; // +1 para incluir ambos días - // parameters.Add("DiasPeriodo", diasPeriodo, DbType.Int32); _logger.LogInformation("Ejecutando SP: {SPName} con parámetros: FechaDesde={FechaDesde}, FechaHasta={FechaHasta}, IdPlanta={IdPlanta}, Consolidado={Consolidado}", @@ -63,6 +56,358 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes } } - // ... Implementaciones para otros reportes ... + public async Task> GetMovimientoBobinasAsync(DateTime fechaInicio, int diasPeriodo, int idPlanta) + { + const string spName = "dbo.SP_MovimientoBobinas"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicio", fechaInicio, DbType.Date); // El SP espera DateTime + parameters.Add("@DiasPeriodo", diasPeriodo, DbType.Int32); + parameters.Add("@idPlanta", idPlanta, DbType.Int32); + + _logger.LogInformation("Ejecutando SP: {SPName} con parámetros: FechaInicio={FechaInicio}, DiasPeriodo={DiasPeriodo}, IdPlanta={IdPlanta}", + spName, fechaInicio, diasPeriodo, idPlanta); + try + { + using var connection = _dbConnectionFactory.CreateConnection(); + return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error al ejecutar SP {SPName} para Movimiento de Bobinas.", spName); + return Enumerable.Empty(); + } + } + + public async Task> GetMovimientoBobinasEstadoDetalleAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta) + { + const string spName = "dbo.SP_MovimientosBobinasEstado"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicio", fechaInicio, DbType.Date); + parameters.Add("@FechaFin", fechaFin, DbType.Date); + parameters.Add("@IdPlanta", idPlanta, DbType.Int32); + + _logger.LogInformation("Ejecutando SP: {SPName} con parámetros: FechaInicio={FechaInicio}, FechaFin={FechaFin}, IdPlanta={IdPlanta}", + spName, fechaInicio, fechaFin, idPlanta); + try + { + using var connection = _dbConnectionFactory.CreateConnection(); + return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error al ejecutar SP {SPName} para Detalle de Movimiento de Bobinas por Estado.", spName); + return Enumerable.Empty(); + } + } + + public async Task> GetMovimientoBobinasEstadoTotalesAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta) + { + const string spName = "dbo.SP_MovimientosBobinasEstadoTotales"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicio", fechaInicio, DbType.Date); + parameters.Add("@FechaFin", fechaFin, DbType.Date); + parameters.Add("@IdPlanta", idPlanta, DbType.Int32); + + _logger.LogInformation("Ejecutando SP: {SPName} con parámetros: FechaInicio={FechaInicio}, FechaFin={FechaFin}, IdPlanta={IdPlanta}", + spName, fechaInicio, fechaFin, idPlanta); + try + { + using var connection = _dbConnectionFactory.CreateConnection(); + return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error al ejecutar SP {SPName} para Totales de Movimiento de Bobinas por Estado.", spName); + return Enumerable.Empty(); + } + } + + // Implementaciones que faltaban + public async Task> GetListadoDistribucionGeneralResumenAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_DistObtenerResumenMensual"; + var parameters = new DynamicParameters(); + parameters.Add("@Id_Publicacion", idPublicacion, DbType.Int32); + parameters.Add("@Mes", fechaDesde.Month, DbType.Int32); + parameters.Add("@Anio", fechaDesde.Year, DbType.Int32); + // El SP no usa fechaHasta explícitamente, calcula el fin de mes internamente + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetListadoDistribucionGeneralPromedioDiaAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_DistObtenerResumenMensualPorDiaSemana"; + var parameters = new DynamicParameters(); + parameters.Add("@Id_Publicacion", idPublicacion, DbType.Int32); + parameters.Add("@Mes", fechaDesde.Month, DbType.Int32); + parameters.Add("@Anio", fechaDesde.Year, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetListadoDistribucionCanillasSimpleAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_CantidadEntradaSalidaCanillas"; + var parameters = new DynamicParameters(); + parameters.Add("@idPublicacion", idPublicacion, DbType.Int32); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetListadoDistribucionCanillasPromedioDiaAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_CantidadEntradaSalidaCPromAgDiaCanilla"; + var parameters = new DynamicParameters(); + parameters.Add("@idPublicacion", idPublicacion, DbType.Int32); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetListadoDistribucionCanillasImporteAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, bool esAccionista) + { + const string spName = "dbo.SP_CantidadESCanillasConImporte"; + var parameters = new DynamicParameters(); + parameters.Add("@idPublicacion", idPublicacion, DbType.Int32); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + parameters.Add("@accionista", esAccionista, DbType.Boolean); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetVentaMensualSecretariaElDiaAsync(DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_VentaMensualSecretariaElDia"; + var parameters = new DynamicParameters(); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetVentaMensualSecretariaElPlataAsync(DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_VentaMensualSecretariaElPlata"; + var parameters = new DynamicParameters(); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetVentaMensualSecretariaTirDevoAsync(DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_VentaMensualSecretariaTirDevo"; + var parameters = new DynamicParameters(); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetDetalleDistribucionCanillasPubliAsync(DateTime fecha, int idEmpresa) + { + const string spName = "dbo.SP_DistCanillasEntradaSalidaPubli"; + var parameters = new DynamicParameters(); + parameters.Add("@fecha", fecha, DbType.DateTime); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetDetalleDistribucionCanillasAccPubliAsync(DateTime fecha, int idEmpresa) + { + const string spName = "dbo.SP_DistCanillasAccEntradaSalidaPubli"; + var parameters = new DynamicParameters(); + parameters.Add("@fecha", fecha, DbType.DateTime); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetDetalleDistribucionCanillasAllPubliAsync(DateTime fecha, int idEmpresa) + { + const string spName = "dbo.SP_DistCanALLEntradaSalidaPubli"; + var parameters = new DynamicParameters(); + parameters.Add("@fecha", fecha, DbType.DateTime); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetDetalleDistribucionCanillasPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa) + { + const string spName = "dbo.SP_DistCanillasEntradaSalidaPubliFechaLiq"; + var parameters = new DynamicParameters(); + parameters.Add("@fecha", fechaLiquidacion, DbType.DateTime); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa) + { + const string spName = "dbo.SP_DistCanillasAccEntradaSalidaPubliFechaLiq"; + var parameters = new DynamicParameters(); + parameters.Add("@fecha", fechaLiquidacion, DbType.DateTime); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetReporteObtenerCtrlDevolucionesAsync(DateTime fecha, int idEmpresa) + { + const string spName = "dbo.SP_ObtenerCtrlDevoluciones"; + var parameters = new DynamicParameters(); + parameters.Add("@Fecha", fecha, DbType.DateTime); + parameters.Add("@IdEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetReporteCtrlDevolucionesParaDistCanAsync(DateTime fecha, int idEmpresa) + { + const string spName = "dbo.SP_DistCanillasCantidadEntradaSalida"; + var parameters = new DynamicParameters(); + parameters.Add("@fecha", fecha, DbType.DateTime); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta) + { + const string spName = "dbo.SP_TiradasPublicacionesSecciones"; + var parameters = new DynamicParameters(); + parameters.Add("@IdPublicacion", idPublicacion, DbType.Int32); + parameters.Add("@FechaInicio", fechaDesde, DbType.Date); + parameters.Add("@FechaFin", fechaHasta, DbType.Date); + parameters.Add("@IdPlanta", idPlanta, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_TiradasPublicacionesSeccionesConsolidado"; + var parameters = new DynamicParameters(); + parameters.Add("@IdPublicacion", idPublicacion, DbType.Int32); + parameters.Add("@FechaInicio", fechaDesde, DbType.Date); + parameters.Add("@FechaFin", fechaHasta, DbType.Date); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta) + { + const string spName = "dbo.SP_BobinasUtilizadasPorSeccion"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicio", fechaDesde, DbType.DateTime2); + parameters.Add("@FechaFin", fechaHasta, DbType.DateTime2); + parameters.Add("@idPlanta", idPlanta, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetConsumoBobinasPorSeccionConsolidadoAsync(DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_BobinasUtilizadasPorSeccionConsolidado"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicio", fechaDesde, DbType.DateTime2); + parameters.Add("@FechaFin", fechaHasta, DbType.DateTime2); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetConsumoBobinasPorPublicacionAsync(DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_BobinasUtilizadasPorPublicacion"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicio", fechaDesde, DbType.DateTime2); + parameters.Add("@FechaFin", fechaHasta, DbType.DateTime2); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetComparativaConsumoBobinasAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB, int idPlanta) + { + const string spName = "dbo.SP_CompararConsumoBobinasMeses"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicioMesA", fechaInicioMesA, DbType.Date); + parameters.Add("@FechaFinMesA", fechaFinMesA, DbType.Date); + parameters.Add("@FechaInicioMesB", fechaInicioMesB, DbType.Date); + parameters.Add("@FechaFinMesB", fechaFinMesB, DbType.Date); + parameters.Add("@IdPlanta", idPlanta, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + public async Task> GetComparativaConsumoBobinasConsolidadoAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB) + { + const string spName = "dbo.SP_CompararConsumoBobinasMesesConsolidado"; + var parameters = new DynamicParameters(); + parameters.Add("@FechaInicioMesA", fechaInicioMesA, DbType.Date); + parameters.Add("@FechaFinMesA", fechaFinMesA, DbType.Date); + parameters.Add("@FechaInicioMesB", fechaInicioMesB, DbType.Date); + parameters.Add("@FechaFinMesB", fechaFinMesB, DbType.Date); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + // Implementación para SP_BalanceCuentaDistEntradaSalidaPorEmpresa + public async Task> GetBalanceCuentaDistEntradaSalidaPorEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_BalanceCuentaDistEntradaSalidaPorEmpresa"; + var parameters = new DynamicParameters(); + parameters.Add("@idDistribuidor", idDistribuidor, DbType.Int32); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + // Implementación para SP_BalanceCuentDistDebCredEmpresa + public async Task> GetBalanceCuentDistDebCredEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_BalanceCuentDistDebCredEmpresa"; + var parameters = new DynamicParameters(); + parameters.Add("@idDistribuidor", idDistribuidor, DbType.Int32); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + // Implementación para SP_BalanceCuentDistPagosEmpresa + public async Task> GetBalanceCuentDistPagosEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta) + { + const string spName = "dbo.SP_BalanceCuentDistPagosEmpresa"; + var parameters = new DynamicParameters(); + parameters.Add("@idDistribuidor", idDistribuidor, DbType.Int32); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime); + parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } + + // Implementación para SP_BalanceCuentSaldosEmpresas + public async Task> GetBalanceCuentSaldosEmpresasAsync(string destino, int idDestino, int idEmpresa) + { + const string spName = "dbo.SP_BalanceCuentSaldosEmpresas"; + var parameters = new DynamicParameters(); + parameters.Add("@Destino", destino, DbType.String); + parameters.Add("@idDestino", idDestino, DbType.Int32); + parameters.Add("@idEmpresa", idEmpresa, DbType.Int32); + try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync(spName, parameters, commandType: CommandType.StoredProcedure); } + catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty(); } + } } } \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaDebCredDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaDebCredDto.cs new file mode 100644 index 0000000..58de12a --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaDebCredDto.cs @@ -0,0 +1,7 @@ +public class BalanceCuentaDebCredDto // Para SP_BalanceCuentDistDebCred y SP_BalanceCuentDistDebCredEmpresa +{ + public DateTime Fecha { get; set; } + public string? Referencia { get; set; } + public decimal Debe { get; set; } + public decimal Haber { get; set; } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaDistDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaDistDto.cs new file mode 100644 index 0000000..667ae4f --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaDistDto.cs @@ -0,0 +1,11 @@ +public class BalanceCuentaDistDto // Para SP_BalanceCuentaDistEntradaSalida y SP_BalanceCuentaDistEntradaSalidaPorEmpresa +{ + public DateTime Fecha { get; set; } + public string Publicacion { get; set; } = string.Empty; + public string Distribuidor { get; set; } = string.Empty; + public int Cantidad { get; set; } + public string Remito { get; set; } = string.Empty; // En SP es int, pero en RDLC puede ser string + public string? Observacion { get; set; } + public decimal Debe { get; set; } + public decimal Haber { get; set; } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaPagosDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaPagosDto.cs new file mode 100644 index 0000000..98cf0cd --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/BalanceCuentaPagosDto.cs @@ -0,0 +1,9 @@ +public class BalanceCuentaPagosDto // Para SP_BalanceCuentDistPagos y SP_BalanceCuentDistPagosEmpresa +{ + public DateTime Fecha { get; set; } + public int Recibo { get; set; } + public string Tipo { get; set; } = string.Empty; + public decimal Debe { get; set; } + public decimal Haber { get; set; } + public string? Detalle { get; set; } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ComparativaConsumoBobinasDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ComparativaConsumoBobinasDto.cs new file mode 100644 index 0000000..4eeff94 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ComparativaConsumoBobinasDto.cs @@ -0,0 +1,13 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ComparativaConsumoBobinasDto + { + public string TipoBobina { get; set; } = string.Empty; + public int BobinasUtilizadasMesA { get; set; } + public int BobinasUtilizadasMesB { get; set; } + public int DiferenciaBobinasUtilizadas { get; set; } + public int KilosUtilizadosMesA { get; set; } + public int KilosUtilizadosMesB { get; set; } + public int DiferenciaKilosUtilizados { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ConsumoBobinasPublicacionDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ConsumoBobinasPublicacionDto.cs new file mode 100644 index 0000000..7289e09 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ConsumoBobinasPublicacionDto.cs @@ -0,0 +1,10 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ConsumoBobinasPublicacionDto + { + public string NombrePlanta { get; set; } = string.Empty; + public string NombrePublicacion { get; set; } = string.Empty; + public int TotalKilos { get; set; } + public int CantidadBobinas { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ConsumoBobinasSeccionDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ConsumoBobinasSeccionDto.cs new file mode 100644 index 0000000..9edf374 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ConsumoBobinasSeccionDto.cs @@ -0,0 +1,11 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ConsumoBobinasSeccionDto + { + public string NombrePublicacion { get; set; } = string.Empty; + public string NombreSeccion { get; set; } = string.Empty; + public string NombreBobina { get; set; } = string.Empty; + public int CantidadBobinas { get; set; } + public int TotalKilos { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesReporteDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesReporteDto.cs new file mode 100644 index 0000000..df0c4e9 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesReporteDto.cs @@ -0,0 +1,14 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ControlDevolucionesReporteDto + { + public int Ingresados { get; set; } + public int Sobrantes { get; set; } + public string Publicacion { get; set; } = string.Empty; + public int Llevados { get; set; } + public int Devueltos { get; set; } + public string Tipo { get; set; } = string.Empty; // "Accionistas" o "Canillitas" + public int TotalNoAccionistas { get; set; } + public int SinCargo {get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DetalleDistribucionCanillaAllDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DetalleDistribucionCanillaAllDto.cs new file mode 100644 index 0000000..91b87ff --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DetalleDistribucionCanillaAllDto.cs @@ -0,0 +1,11 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class DetalleDistribucionCanillaAllDto + { + public string Publicacion { get; set; } = string.Empty; + public int TotalCantSalida { get; set; } + public int TotalCantEntrada { get; set; } + public decimal TotalRendir { get; set; } + public string TipoVendedor { get; set; } = string.Empty; + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DetalleDistribucionCanillaDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DetalleDistribucionCanillaDto.cs new file mode 100644 index 0000000..ff1d3ec --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DetalleDistribucionCanillaDto.cs @@ -0,0 +1,14 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class DetalleDistribucionCanillaDto + { + public string Publicacion { get; set; } = string.Empty; + public string Canilla { get; set; } = string.Empty; + public int TotalCantSalida { get; set; } + public int TotalCantEntrada { get; set; } + public decimal TotalRendir { get; set; } + // 'Fecha' si es para SP_DistCanillasEntradaSalidaPubliFechaLiq + // y SP_DistCanillasAccEntradaSalidaPubliFechaLiq + public DateTime? Fecha { get; set; } // Hacemos nullable para adaptarlo + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasImporteDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasImporteDto.cs new file mode 100644 index 0000000..ebb8772 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasImporteDto.cs @@ -0,0 +1,12 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionCanillasImporteDto + { + public string Fecha { get; set; } = string.Empty; + public int Llevados { get; set; } + public int Devueltos { get; set; } + public int Vendidos { get; set; } + public decimal TotalRendirPublicacion { get; set; } + public decimal TotalRendirGeneral { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasPromedioDiaDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasPromedioDiaDto.cs new file mode 100644 index 0000000..517bc1a --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasPromedioDiaDto.cs @@ -0,0 +1,13 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionCanillasPromedioDiaDto + { + public string Dia { get; set; } = string.Empty; // Nombre del día + public int Cant { get; set; } // Cantidad de días con ese nombre en el mes + public int Llevados { get; set; } + public int Devueltos { get; set; } + public int Promedio_Llevados { get; set; } + public int Promedio_Devueltos { get; set; } + public int Promedio_Ventas { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasSimpleDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasSimpleDto.cs new file mode 100644 index 0000000..800d947 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasSimpleDto.cs @@ -0,0 +1,9 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionCanillasSimpleDto + { + public int Dia { get; set; } // Día del mes + public int Llevados { get; set; } + public int Devueltos { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralPromedioDiaDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralPromedioDiaDto.cs new file mode 100644 index 0000000..ffd225b --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralPromedioDiaDto.cs @@ -0,0 +1,14 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionGeneralPromedioDiaDto + { + public string Dia { get; set; } = string.Empty; + public int CantidadDias { get; set; } + public int PromedioTirada { get; set; } + public int PromedioSinCargo { get; set; } + public int PromedioPerdidos { get; set; } + public int PromedioLlevados { get; set; } + public int PromedioDevueltos { get; set; } + public int PromedioVendidos { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResumenDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResumenDto.cs new file mode 100644 index 0000000..427b0ff --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResumenDto.cs @@ -0,0 +1,15 @@ +using System; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionGeneralResumenDto + { + public DateTime Fecha { get; set; } + public int CantidadTirada { get; set; } + public int SinCargo { get; set; } + public int Perdidos { get; set; } + public int Llevados { get; set; } + public int Devueltos { get; set; } + public int Vendidos { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinaEstadoDetalleDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinaEstadoDetalleDto.cs new file mode 100644 index 0000000..58c6bfa --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinaEstadoDetalleDto.cs @@ -0,0 +1,13 @@ +using System; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class MovimientoBobinaEstadoDetalleDto + { + public string TipoBobina { get; set; } = string.Empty; + public string NumeroRemito { get; set; } = string.Empty; + public DateTime FechaMovimiento { get; set; } + public int Cantidad { get; set; } + public string TipoMovimiento { get; set; } = string.Empty; // "Ingreso", "Utilizada", "Dañada" + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinaEstadoTotalDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinaEstadoTotalDto.cs new file mode 100644 index 0000000..a906452 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinaEstadoTotalDto.cs @@ -0,0 +1,9 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class MovimientoBobinaEstadoTotalDto + { + public string TipoMovimiento { get; set; } = string.Empty; // "Ingresos", "Utilizadas", "Dañadas" + public int TotalBobinas { get; set; } + public int TotalKilos { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasDto.cs new file mode 100644 index 0000000..c204ad4 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasDto.cs @@ -0,0 +1,17 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class MovimientoBobinasDto + { + public string TipoBobina { get; set; } = string.Empty; + public int BobinasIniciales { get; set; } + public int KilosIniciales { get; set; } + public int BobinasCompradas { get; set; } + public int KilosComprados { get; set; } + public int BobinasConsumidas { get; set; } + public int KilosConsumidos { get; set; } + public int BobinasDaniadas { get; set; } + public int KilosDaniados { get; set; } + public int BobinasFinales { get; set; } + public int KilosFinales { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ObtenerCtrlDevolucionesDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ObtenerCtrlDevolucionesDto.cs new file mode 100644 index 0000000..349a0c4 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ObtenerCtrlDevolucionesDto.cs @@ -0,0 +1,7 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ObtenerCtrlDevolucionesDto + { + public int Remito { get; set; } // El SP devuelve una columna 'Remito' que en la tabla es 'Entrada' + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/SaldoDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/SaldoDto.cs new file mode 100644 index 0000000..8af8897 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/SaldoDto.cs @@ -0,0 +1,4 @@ +public class SaldoDto // Para SP_BalanceCuentSaldos y SP_BalanceCuentSaldosEmpresas +{ + public decimal Monto { get; set; } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/TiradasPublicacionesSeccionesDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/TiradasPublicacionesSeccionesDto.cs new file mode 100644 index 0000000..0ba058d --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/TiradasPublicacionesSeccionesDto.cs @@ -0,0 +1,12 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class TiradasPublicacionesSeccionesDto + { + public string NombreSeccion { get; set; } = string.Empty; + public int TotalPaginasImpresas { get; set; } + public int CantidadTiradas { get; set; } + public int TotalPaginasEjemplares { get; set; } + public int TotalEjemplares { get; set; } + public int PromedioPaginasPorEjemplar { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaElDiaDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaElDiaDto.cs new file mode 100644 index 0000000..363e75a --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaElDiaDto.cs @@ -0,0 +1,13 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class VentaMensualSecretariaElDiaDto + { + public int Dia { get; set; } + public int CantidadCanillas { get; set; } + public int Tirajes { get; set; } + public int Ventas { get; set; } + public int Accionistas { get; set; } + public int TotalCooperativa { get; set; } + public int TotalGeneral { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaElPlataDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaElPlataDto.cs new file mode 100644 index 0000000..6fa6e7d --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaElPlataDto.cs @@ -0,0 +1,13 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class VentaMensualSecretariaElPlataDto + { + public int Dia { get; set; } + public int TiradaCoop { get; set; } + public int DevolucionCoop { get; set; } + public int VentaCoop { get; set; } + public int TiradaCan { get; set; } + public int VentaCan { get; set; } + public int Total { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaTirDevoDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaTirDevoDto.cs new file mode 100644 index 0000000..9f62dea --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/VentaMensualSecretariaTirDevoDto.cs @@ -0,0 +1,20 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class VentaMensualSecretariaTirDevoDto + { + public int Dia { get; set; } + public int TiradaCoop { get; set; } + public int DevolucionCoop { get; set; } + public int VentaCoop { get; set; } + public int VentaCan { get; set; } + public int TiradaPopular { get; set; } + public int DevolucionPopular { get; set; } + public int VentaPopular { get; set; } + public int TiradaClarin { get; set; } + public int DevolucionClarin { get; set; } + public int VentaClarin { get; set; } + public int TiradaNacion { get; set; } + public int DevolucionNacion { get; set; } + public int VentaNacion { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Services/Reportes/IReportesService.cs b/Backend/GestionIntegral.Api/Services/Reportes/IReportesService.cs index 9bd0416..4fbc1c2 100644 --- a/Backend/GestionIntegral.Api/Services/Reportes/IReportesService.cs +++ b/Backend/GestionIntegral.Api/Services/Reportes/IReportesService.cs @@ -1,3 +1,4 @@ +// src/Services/Reportes/IReportesService.cs using GestionIntegral.Api.Dtos.Reportes; using System; using System.Collections.Generic; @@ -8,6 +9,57 @@ namespace GestionIntegral.Api.Services.Reportes public interface IReportesService { Task<(IEnumerable Data, string? Error)> ObtenerExistenciaPapelAsync(DateTime fechaDesde, DateTime fechaHasta, int? idPlanta, bool consolidado); - // ... + Task<(IEnumerable Data, string? Error)> ObtenerMovimientoBobinasAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta); + Task<(IEnumerable Detalle, IEnumerable Totales, string? Error)> ObtenerMovimientoBobinasPorEstadoAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta); + + // Reporte Listado Distribucion General (RR002) + Task<(IEnumerable Resumen, IEnumerable Promedios, string? Error)> ObtenerListadoDistribucionGeneralAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + + // Reporte Listado Distribucion Canillas (RR002) + Task<(IEnumerable Simple, IEnumerable Promedios, string? Error)> ObtenerListadoDistribucionCanillasAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + + // Reporte Listado Distribucion Canillas con Importes (RR002) + Task<(IEnumerable Data, string? Error)> ObtenerListadoDistribucionCanillasConImporteAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, bool esAccionista); + + // Reportes Venta Mensual Secretaria + Task<(IEnumerable Data, string? Error)> ObtenerVentaMensualSecretariaElDiaAsync(DateTime fechaDesde, DateTime fechaHasta); + Task<(IEnumerable Data, string? Error)> ObtenerVentaMensualSecretariaElPlataAsync(DateTime fechaDesde, DateTime fechaHasta); + Task<(IEnumerable Data, string? Error)> ObtenerVentaMensualSecretariaTirDevoAsync(DateTime fechaDesde, DateTime fechaHasta); + + // Reporte Distribucion Canillas (MC005) - Este es un reporte más complejo + Task<( + IEnumerable Canillas, + IEnumerable CanillasAcc, + IEnumerable CanillasAll, + IEnumerable CanillasFechaLiq, + IEnumerable CanillasAccFechaLiq, + IEnumerable CtrlDevoluciones, + IEnumerable CtrlDevolucionesParaDistCan, + string? Error + )> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa); // ESTA ES LA FIRMA CORRECTA Y ÚNICA PARA ESTE MÉTODO + + // Reporte Tiradas por Publicación y Secciones (RR008) + Task<(IEnumerable Data, string? Error)> ObtenerTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); + Task<(IEnumerable Data, string? Error)> ObtenerTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); + + // Reporte Consumo Bobinas por Seccion (RR007) + Task<(IEnumerable Data, string? Error)> ObtenerConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta); + Task<(IEnumerable Data, string? Error)> ObtenerConsumoBobinasPorSeccionConsolidadoAsync(DateTime fechaDesde, DateTime fechaHasta); + + // Reporte Consumo Bobinas por Publicacion (RR007) - Consolidado + Task<(IEnumerable Data, string? Error)> ObtenerConsumoBobinasPorPublicacionAsync(DateTime fechaDesde, DateTime fechaHasta); + + // Reporte Comparativa Consumo Bobinas (RR007) + Task<(IEnumerable Data, string? Error)> ObtenerComparativaConsumoBobinasAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB, int idPlanta); + Task<(IEnumerable Data, string? Error)> ObtenerComparativaConsumoBobinasConsolidadoAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB); + + // DTOs para ReporteCuentasDistribuidores + Task<( + IEnumerable EntradasSalidas, + IEnumerable DebitosCreditos, + IEnumerable Pagos, + IEnumerable Saldos, + string? Error + )> ObtenerReporteCuentasDistribuidorAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta); } } \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs b/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs index ef56d25..ee5c555 100644 --- a/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs +++ b/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs @@ -1,3 +1,4 @@ +// src/Services/Reportes/ReportesService.cs using GestionIntegral.Api.Data.Repositories.Reportes; using GestionIntegral.Api.Dtos.Reportes; using Microsoft.Extensions.Logging; @@ -12,6 +13,7 @@ namespace GestionIntegral.Api.Services.Reportes { private readonly IReportesRepository _reportesRepository; private readonly ILogger _logger; + // No necesitas _connectionFactory aquí si toda la lógica de BD está en el repositorio. public ReportesService(IReportesRepository reportesRepository, ILogger logger) { @@ -20,7 +22,7 @@ namespace GestionIntegral.Api.Services.Reportes } public async Task<(IEnumerable Data, string? Error)> ObtenerExistenciaPapelAsync( - DateTime fechaDesde, DateTime fechaHasta, int? idPlanta, bool consolidado) + DateTime fechaDesde, DateTime fechaHasta, int? idPlanta, bool consolidado) { if (fechaDesde > fechaHasta) { @@ -35,34 +37,386 @@ namespace GestionIntegral.Api.Services.Reportes try { var dataFromRepo = await _reportesRepository.GetExistenciaPapelAsync(fechaDesde, fechaHasta, idPlanta, consolidado); - - // Ajustar DateTimeKind a Utc aquí var dataWithUtcDates = dataFromRepo.Select(dto => { if (dto.FechaEstimacionFinStock.HasValue) { - // Aseguramos que solo tomamos la parte de la fecha y la especificamos como UTC - // Si ya viene con hora 00:00:00 del SP, .Date no cambia nada. - // Si viniera con hora, .Date la trunca a 00:00:00. dto.FechaEstimacionFinStock = DateTime.SpecifyKind(dto.FechaEstimacionFinStock.Value.Date, DateTimeKind.Utc); } return dto; }).ToList(); - return (dataWithUtcDates, null); } - catch (ArgumentNullException ex) when (ex.ParamName == "idPlanta") // Capturar la excepción del repositorio + catch (ArgumentNullException ex) when (ex.ParamName == "idPlanta") { _logger.LogWarning(ex, "ArgumentNullException para idPlanta en ObtenerExistenciaPapelAsync."); - return (Enumerable.Empty(), ex.Message); // Devolver el mensaje de error del repo + return (Enumerable.Empty(), ex.Message); } catch (Exception ex) { _logger.LogError(ex, "Error en ReportesService al obtener Existencia de Papel."); - return (Enumerable.Empty(), "Error interno al generar el reporte."); + return (Enumerable.Empty(), "Error interno al generar el reporte de existencia de papel."); } } + public async Task<(IEnumerable Data, string? Error)> ObtenerMovimientoBobinasAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta) + { + if (fechaDesde > fechaHasta) + { + return (Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + } + int diasPeriodo = (fechaHasta.Date - fechaDesde.Date).Days + 1; + try + { + var data = await _reportesRepository.GetMovimientoBobinasAsync(fechaDesde.Date, diasPeriodo, idPlanta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Movimiento de Bobinas."); + return (Enumerable.Empty(), "Error interno al generar el reporte de movimiento de bobinas."); + } + } + + public async Task<(IEnumerable Detalle, IEnumerable Totales, string? Error)> ObtenerMovimientoBobinasPorEstadoAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta) + { + if (fechaDesde > fechaHasta) + { + return (Enumerable.Empty(), Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + } + + try + { + var detalle = await _reportesRepository.GetMovimientoBobinasEstadoDetalleAsync(fechaDesde.Date, fechaHasta.Date, idPlanta); + var totales = await _reportesRepository.GetMovimientoBobinasEstadoTotalesAsync(fechaDesde.Date, fechaHasta.Date, idPlanta); + + var detalleUtc = detalle.Select(d => { + d.FechaMovimiento = DateTime.SpecifyKind(d.FechaMovimiento, DateTimeKind.Utc); + return d; + }).ToList(); + + return (detalleUtc, totales, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Movimiento de Bobinas por Estado."); + return (Enumerable.Empty(), Enumerable.Empty(), "Error interno al generar el reporte de movimiento de bobinas por estado."); + } + } + + public async Task<(IEnumerable Resumen, IEnumerable Promedios, string? Error)> ObtenerListadoDistribucionGeneralAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) + return (Enumerable.Empty(), Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + + try + { + // El SP SP_DistObtenerResumenMensual usa Mes y Año de fechaDesde. + // El SP SP_DistObtenerResumenMensualPorDiaSemana también. + var resumenData = await _reportesRepository.GetListadoDistribucionGeneralResumenAsync(idPublicacion, fechaDesde, fechaHasta); + var promediosData = await _reportesRepository.GetListadoDistribucionGeneralPromedioDiaAsync(idPublicacion, fechaDesde, fechaHasta); + + var resumenUtc = resumenData.Select(r => { r.Fecha = DateTime.SpecifyKind(r.Fecha, DateTimeKind.Utc); return r; }).ToList(); + + return (resumenUtc, promediosData, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion General."); + return (Enumerable.Empty(), Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Simple, IEnumerable Promedios, string? Error)> ObtenerListadoDistribucionCanillasAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) + return (Enumerable.Empty(), Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + + try + { + var simpleData = await _reportesRepository.GetListadoDistribucionCanillasSimpleAsync(idPublicacion, fechaDesde, fechaHasta); + var promediosData = await _reportesRepository.GetListadoDistribucionCanillasPromedioDiaAsync(idPublicacion, fechaDesde, fechaHasta); + return (simpleData, promediosData, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion Canillas."); + return (Enumerable.Empty(), Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerListadoDistribucionCanillasConImporteAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, bool esAccionista) + { + if (fechaDesde > fechaHasta) + return (Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + + try + { + var data = await _reportesRepository.GetListadoDistribucionCanillasImporteAsync(idPublicacion, fechaDesde, fechaHasta, esAccionista); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion Canillas con Importe."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerVentaMensualSecretariaElDiaAsync(DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + try + { + var data = await _reportesRepository.GetVentaMensualSecretariaElDiaAsync(fechaDesde, fechaHasta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Venta Mensual Secretaria El Dia."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerVentaMensualSecretariaElPlataAsync(DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + try + { + var data = await _reportesRepository.GetVentaMensualSecretariaElPlataAsync(fechaDesde, fechaHasta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Venta Mensual Secretaria El Plata."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerVentaMensualSecretariaTirDevoAsync(DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); + try + { + var data = await _reportesRepository.GetVentaMensualSecretariaTirDevoAsync(fechaDesde, fechaHasta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Venta Mensual Secretaria Tirada/Devolucion."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<( + IEnumerable Canillas, + IEnumerable CanillasAcc, + IEnumerable CanillasAll, + IEnumerable CanillasFechaLiq, + IEnumerable CanillasAccFechaLiq, + IEnumerable CtrlDevoluciones, + IEnumerable CtrlDevolucionesParaDistCan, + string? Error + )> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa) + { + try + { + var canillasTask = _reportesRepository.GetDetalleDistribucionCanillasPubliAsync(fecha, idEmpresa); + var canillasAccTask = _reportesRepository.GetDetalleDistribucionCanillasAccPubliAsync(fecha, idEmpresa); + var canillasAllTask = _reportesRepository.GetDetalleDistribucionCanillasAllPubliAsync(fecha, idEmpresa); + var canillasFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasPubliFechaLiqAsync(fecha, idEmpresa); + var canillasAccFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(fecha, idEmpresa); + var ctrlDevolucionesTask = _reportesRepository.GetReporteObtenerCtrlDevolucionesAsync(fecha, idEmpresa); + var ctrlDevolucionesParaDistCanTask = _reportesRepository.GetReporteCtrlDevolucionesParaDistCanAsync(fecha, idEmpresa); + + await Task.WhenAll(canillasTask, canillasAccTask, canillasAllTask, canillasFechaLiqTask, canillasAccFechaLiqTask, ctrlDevolucionesTask, ctrlDevolucionesParaDistCanTask); + + Func, IEnumerable> toUtc = + items => items?.Select(c => { if(c.Fecha.HasValue) c.Fecha = DateTime.SpecifyKind(c.Fecha.Value.Date, DateTimeKind.Utc); return c; }).ToList() + ?? Enumerable.Empty(); + + return ( + toUtc(await canillasTask), + toUtc(await canillasAccTask), + await canillasAllTask ?? Enumerable.Empty(), + toUtc(await canillasFechaLiqTask), + toUtc(await canillasAccFechaLiqTask), + await ctrlDevolucionesTask ?? Enumerable.Empty(), + await ctrlDevolucionesParaDistCanTask ?? Enumerable.Empty(), + null + ); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Reporte Distribucion Canillas para fecha {Fecha} y empresa {IdEmpresa}.", fecha, idEmpresa); + return ( + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + "Error interno al generar el reporte de distribución de canillas." + ); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); + try + { + var data = await _reportesRepository.GetTiradasPublicacionesSeccionesAsync(idPublicacion, fechaDesde, fechaHasta, idPlanta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Tiradas por Publicación y Secciones."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); + try + { + var data = await _reportesRepository.GetTiradasPublicacionesSeccionesConsolidadoAsync(idPublicacion, fechaDesde, fechaHasta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Tiradas por Publicación y Secciones (Consolidado)."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); + try + { + var data = await _reportesRepository.GetConsumoBobinasPorSeccionAsync(fechaDesde, fechaHasta, idPlanta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Consumo de Bobinas por Sección."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerConsumoBobinasPorSeccionConsolidadoAsync(DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); + try + { + var data = await _reportesRepository.GetConsumoBobinasPorSeccionConsolidadoAsync(fechaDesde, fechaHasta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Consumo de Bobinas por Sección (Consolidado)."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerConsumoBobinasPorPublicacionAsync(DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); + try + { + var data = await _reportesRepository.GetConsumoBobinasPorPublicacionAsync(fechaDesde, fechaHasta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Consumo de Bobinas por Publicación."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerComparativaConsumoBobinasAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB, int idPlanta) + { + if (fechaInicioMesA > fechaFinMesA || fechaInicioMesB > fechaFinMesB) return (Enumerable.Empty(), "Fechas de inicio no pueden ser mayores que las de fin para los meses."); + try + { + var data = await _reportesRepository.GetComparativaConsumoBobinasAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB, idPlanta); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Comparativa de Consumo de Bobinas."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + public async Task<(IEnumerable Data, string? Error)> ObtenerComparativaConsumoBobinasConsolidadoAsync(DateTime fechaInicioMesA, DateTime fechaFinMesA, DateTime fechaInicioMesB, DateTime fechaFinMesB) + { + if (fechaInicioMesA > fechaFinMesA || fechaInicioMesB > fechaFinMesB) return (Enumerable.Empty(), "Fechas de inicio no pueden ser mayores que las de fin para los meses."); + try + { + var data = await _reportesRepository.GetComparativaConsumoBobinasConsolidadoAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB); + return (data, null); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Comparativa de Consumo de Bobinas (Consolidado)."); + return (Enumerable.Empty(), "Error interno al generar el reporte."); + } + } + + // Implementación para ReporteCuentasDistribuidores + public async Task<( + IEnumerable EntradasSalidas, + IEnumerable DebitosCreditos, + IEnumerable Pagos, + IEnumerable Saldos, + string? Error + )> ObtenerReporteCuentasDistribuidorAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta) + { + if (fechaDesde > fechaHasta) + return (Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); + + try + { + var esTask = _reportesRepository.GetBalanceCuentaDistEntradaSalidaPorEmpresaAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta); + var dcTask = _reportesRepository.GetBalanceCuentDistDebCredEmpresaAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta); + var paTask = _reportesRepository.GetBalanceCuentDistPagosEmpresaAsync(idDistribuidor, idEmpresa, fechaDesde, fechaHasta); + var saTask = _reportesRepository.GetBalanceCuentSaldosEmpresasAsync("Distribuidores", idDistribuidor, idEmpresa); + + await Task.WhenAll(esTask, dcTask, paTask, saTask); + + Func, IEnumerable> esToUtc = + items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList() + ?? Enumerable.Empty(); + Func, IEnumerable> dcToUtc = + items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList() + ?? Enumerable.Empty(); + Func, IEnumerable> paToUtc = + items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList() + ?? Enumerable.Empty(); + + return ( + esToUtc(await esTask), + dcToUtc(await dcTask), + paToUtc(await paTask), + await saTask ?? Enumerable.Empty(), + null + ); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error en ReportesService al obtener Reporte Cuentas Distribuidor."); + return ( + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + Enumerable.Empty(), + "Error interno al generar el reporte." + ); + } + } } } \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/obj/Debug/net9.0/GestionIntegral.Api.AssemblyInfo.cs b/Backend/GestionIntegral.Api/obj/Debug/net9.0/GestionIntegral.Api.AssemblyInfo.cs index cf7910b..30d2df1 100644 --- a/Backend/GestionIntegral.Api/obj/Debug/net9.0/GestionIntegral.Api.AssemblyInfo.cs +++ b/Backend/GestionIntegral.Api/obj/Debug/net9.0/GestionIntegral.Api.AssemblyInfo.cs @@ -13,7 +13,7 @@ using System.Reflection; [assembly: System.Reflection.AssemblyCompanyAttribute("GestionIntegral.Api")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] -[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+3c1fe15b1f03aef4b6b6b6482c8e9fa92dfbf7cd")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+298bc0d0941b976d5de4c53a7b17a88b500bc8e2")] [assembly: System.Reflection.AssemblyProductAttribute("GestionIntegral.Api")] [assembly: System.Reflection.AssemblyTitleAttribute("GestionIntegral.Api")] [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] diff --git a/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmcshtml.dswa.cache.json b/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmcshtml.dswa.cache.json index 6215c5b..5a4bdb1 100644 --- a/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmcshtml.dswa.cache.json +++ b/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmcshtml.dswa.cache.json @@ -1 +1 @@ -{"GlobalPropertiesHash":"C9goqBDGh4B0L1HpPwpJHjfbRNoIuzqnU7zFMHk1LhM=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["lgiSIq1Xdt6PC6CpA82eiZlqBZS3M8jckHELlrL00LI=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","88ziwhzzz1t8H52ibX38BcmB6qWJK\u002BVe/a7PtkJkK7w="],"CachedAssets":{},"CachedCopyCandidates":{}} \ No newline at end of file +{"GlobalPropertiesHash":"C9goqBDGh4B0L1HpPwpJHjfbRNoIuzqnU7zFMHk1LhM=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["lgiSIq1Xdt6PC6CpA82eiZlqBZS3M8jckHELlrL00LI=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","NpxIifDE4FyR4jhkRXHNdK9IIbA/joaTINJDnFlccPA="],"CachedAssets":{},"CachedCopyCandidates":{}} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmrazor.dswa.cache.json b/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmrazor.dswa.cache.json index aba73d8..63bc9eb 100644 --- a/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmrazor.dswa.cache.json +++ b/Backend/GestionIntegral.Api/obj/Debug/net9.0/rjsmrazor.dswa.cache.json @@ -1 +1 @@ -{"GlobalPropertiesHash":"w3MBbMV9Msh0YEq9AW/8s16bzXJ93T9lMVXKPm/r6es=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["lgiSIq1Xdt6PC6CpA82eiZlqBZS3M8jckHELlrL00LI=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","88ziwhzzz1t8H52ibX38BcmB6qWJK\u002BVe/a7PtkJkK7w="],"CachedAssets":{},"CachedCopyCandidates":{}} \ No newline at end of file +{"GlobalPropertiesHash":"w3MBbMV9Msh0YEq9AW/8s16bzXJ93T9lMVXKPm/r6es=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["lgiSIq1Xdt6PC6CpA82eiZlqBZS3M8jckHELlrL00LI=","bxlPVWHR7EivQofjz9PzA8dMpKpZqCfOZ\u002BHD\u002Bf1Ew9Y=","\u002BzMwu5DIAA49kPmSydn2WMzj\u002Bdcf0MC3YakKoR6HwYg=","FUb20tYUiusFv5/KhAPdh2OB4ArUWiGApXbQJdx8tX0=","pTWqrhLBwEeWg1GsRlTKzfOAnT1JEklZ8F1/EYlc1Nk=","Hu0oNH4YYNcbnR5Ts4qd5yzC5j5JbY2kEDXces8V1vs=","TKMARE0bLM2dm9NOqxxWztnuqao5IvCh24TEHCtht6I=","84UEEMEbmmNwHVXD5Iw3dtKHTZC0Zqbk3rIRO\u002BxOq4o=","qfTzsJ\u002B5ilLyrc6EhNm61KkSH37yRi85MtgW1\u002BUD2Vo=","4ayt/JAApEOfr0yjg9szkYMPzSs6x2k3QEwmrK5RZVY=","d0weYwKWe3mH5R2BURuNLkAyytO/viA6zivv9AcIBtQ=","Ssyx6SvSGgWMOzhc9pQpk6f6\u002BmVbKQNKeDJbvVA2tjs=","FSqDybxILZmKXw160ANhj76usnM83geRrbPvJxr89OA=","fdI2RZZ9M9QOVHCYU5cE\u002BgVVuT7ssRbMzdXvX8rHofc=","8ePFhqKT0OT9nEg3b5T7COC81U\u002BQBcf\u002BindBGyMy6z0=","/ghcduGmSd1I25YtYli\u002BqxF0xuscxc4cTDkbEC6XYVA=","/a3YEu0oBUeA5Qr2VMdppqLuz4CQPWJt2JfBl2dtUwA=","jEO/q4IO3UFTWxlyFwRr7kbGWcTIiS\u002BClxx3kahX/Fk=","4iYOCKYvhsROdGkA1hINVBejb6r8IkwFj9SNMKub3DM=","CeDswsZIn5a7t\u002BKeHJA222yhFvDVVEW1ky98Xxnxebc=","50j34YXOc950QSqaQBMtgezD3tV5mWWR9c5qZcYQoz4=","W/aX9jIKpjNEVoGrU6RXFOY8SDJVT6XB4Rg4QCaeQkQ=","16IbB\u002B3zYHZvsWbCQK6hBFmKJ6Z28SecBn2jm8R3w8I=","COJtHNQqycTJqXkFv2hhpLUT\u002B/AD4IWyQlmxkUVQPNk=","cp6a5bdvkLnUn3x47KQODzPycnx57RmWO\u002B9q8MuoGQo=","oKZRNhIQRaZrETEa3L6JiwIp0\u002BmjzJo193EWBoCuVUg=","sjwbCAEQX51sEWhYVGBihWUNBxniUKZALVJIGK\u002BYgsk=","A4m4kVcox60bvdkJ1CswoZADAT70WPcs4TAKdpMoUjM=","zSzyOuNcK0NQJLwK8Yg4sH4EflX7RPf65Fl2CZUWIGs=","NpxIifDE4FyR4jhkRXHNdK9IIbA/joaTINJDnFlccPA="],"CachedAssets":{},"CachedCopyCandidates":{}} \ No newline at end of file