From 2273ebb1e018273a6e35d3f9ab0afe55ae1814bc Mon Sep 17 00:00:00 2001 From: eldiadmolinari Date: Wed, 28 May 2025 16:01:59 -0300 Subject: [PATCH] =?UTF-8?q?Finalizaci=C3=B3n=20de=20Endpoints=20para=20la?= =?UTF-8?q?=20gesti=C3=B3n=20de=20Reportes.=20Se=20contin=C3=BAa=20con=20e?= =?UTF-8?q?l=20Frontend.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reportes/ReportesController.cs | 447 +++++++++++++++++- .../Reportes/IReportesRepository.cs | 2 +- .../Reportes/ReportesRepository.cs | 26 +- .../ControlDevolucionesDataResponseDto.cs | 11 + .../Dtos/Reportes/DevueltosOtrosDiasDto.cs | 7 + .../ListadoDistribucionCanillasResponseDto.cs | 10 + .../ListadoDistribucionGeneralResponseDto.cs | 10 + .../MovimientoBobinasPorEstadoResponseDto.cs | 10 + .../Reportes/ObtenerCtrlDevolucionesDto.cs | 2 +- .../ReporteCuentasDistribuidorResponseDto.cs | 14 + .../ReporteDistribucionCanillasResponseDto.cs | 16 + .../Services/Reportes/IReportesService.cs | 10 +- .../Services/Reportes/ReportesService.cs | 67 +-- .../GestionIntegral.Api.AssemblyInfo.cs | 2 +- .../Debug/net9.0/rjsmcshtml.dswa.cache.json | 2 +- .../Debug/net9.0/rjsmrazor.dswa.cache.json | 2 +- Frontend/src/routes/AppRoutes.tsx | 5 - 17 files changed, 581 insertions(+), 62 deletions(-) create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesDataResponseDto.cs create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/DevueltosOtrosDiasDto.cs create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasResponseDto.cs create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResponseDto.cs create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasPorEstadoResponseDto.cs create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteCuentasDistribuidorResponseDto.cs create mode 100644 Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteDistribucionCanillasResponseDto.cs diff --git a/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs b/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs index 5aaa3b8..150411d 100644 --- a/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs +++ b/Backend/GestionIntegral.Api/Controllers/Reportes/ReportesController.cs @@ -19,7 +19,7 @@ namespace GestionIntegral.Api.Controllers [Authorize] public class ReportesController : ControllerBase { - private readonly IReportesService _reportesService; // <--- CORREGIDO + private readonly IReportesService _reportesService; private readonly ILogger _logger; private readonly IPlantaRepository _plantaRepository; private readonly IPublicacionRepository _publicacionRepository; @@ -217,6 +217,37 @@ namespace GestionIntegral.Api.Controllers } } + // GET: api/reportes/movimiento-bobinas-estado + [HttpGet("movimiento-bobinas-estado")] // Endpoint para los datos JSON + [ProducesResponseType(typeof(MovimientoBobinasPorEstadoResponseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteMovimientoBobinasPorEstado( + [FromQuery] DateTime fechaDesde, + [FromQuery] DateTime fechaHasta, + [FromQuery] int idPlanta) + { + if (!TienePermiso(PermisoVerReporteMovimientoBobinas)) return Forbid(); // Reutilizar permiso + + var (detalle, totales, error) = await _reportesService.ObtenerMovimientoBobinasPorEstadoAsync(fechaDesde, fechaHasta, idPlanta); + + 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 el reporte de movimiento de bobinas por estado." }); + } + + var response = new MovimientoBobinasPorEstadoResponseDto + { + Detalle = detalle ?? Enumerable.Empty(), + Totales = totales ?? Enumerable.Empty() + }; + + return Ok(response); + } + [HttpGet("movimiento-bobinas-estado/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] @@ -266,7 +297,35 @@ namespace GestionIntegral.Api.Controllers } } - // --- Nuevos Endpoints --- + // GET: api/reportes/listado-distribucion-general + [HttpGet("listado-distribucion-general")] + [ProducesResponseType(typeof(ListadoDistribucionGeneralResponseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetListadoDistribucionGeneral( + [FromQuery] int idPublicacion, + [FromQuery] DateTime fechaDesde, + [FromQuery] DateTime fechaHasta) + { + 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 el listado de distribución general." }); + } + + var response = new ListadoDistribucionGeneralResponseDto + { + Resumen = resumen ?? Enumerable.Empty(), + PromediosPorDia = promedios ?? Enumerable.Empty() + }; + + return Ok(response); + } [HttpGet("listado-distribucion-general/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] @@ -318,6 +377,36 @@ namespace GestionIntegral.Api.Controllers } } + // GET: api/reportes/listado-distribucion-canillas + [HttpGet("listado-distribucion-canillas")] + [ProducesResponseType(typeof(ListadoDistribucionCanillasResponseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetListadoDistribucionCanillas( + [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 el listado de distribución de canillas." }); + } + + var response = new ListadoDistribucionCanillasResponseDto + { + DetalleSimple = simple ?? Enumerable.Empty(), + PromediosPorDia = promedios ?? Enumerable.Empty() + }; + + return Ok(response); + } + [HttpGet("listado-distribucion-canillas/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status400BadRequest)] @@ -367,6 +456,31 @@ namespace GestionIntegral.Api.Controllers return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte."); } } + + // GET: api/reportes/listado-distribucion-canillas-importe + [HttpGet("listado-distribucion-canillas-importe")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetListadoDistribucionCanillasConImporte( + [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 el listado de distribución de canillas con importe." }); + } + + return Ok(data); + } [HttpGet("listado-distribucion-canillas-importe/pdf")] [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] @@ -420,6 +534,21 @@ namespace GestionIntegral.Api.Controllers } } + // GET: api/reportes/venta-mensual-secretaria/el-dia + [HttpGet("venta-mensual-secretaria/el-dia")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetVentaMensualSecretariaElDia([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) + { + if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); // Asumiendo RR002 para todos estos + 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 de ventas 'El Día'." }); + return Ok(data); + } + [HttpGet("venta-mensual-secretaria/el-dia/pdf")] public async Task GetVentaMensualSecretariaElDiaPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { @@ -446,6 +575,21 @@ namespace GestionIntegral.Api.Controllers catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaElDia."); return StatusCode(500, "Error interno."); } } + // GET: api/reportes/venta-mensual-secretaria/el-plata + [HttpGet("venta-mensual-secretaria/el-plata")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetVentaMensualSecretariaElPlata([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 de ventas 'El Plata'." }); + return Ok(data); + } + [HttpGet("venta-mensual-secretaria/el-plata/pdf")] public async Task GetVentaMensualSecretariaElPlataPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) { @@ -471,6 +615,21 @@ namespace GestionIntegral.Api.Controllers } catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaElPlata."); return StatusCode(500, "Error interno."); } } + + // GET: api/reportes/venta-mensual-secretaria/tirada-devolucion + [HttpGet("venta-mensual-secretaria/tirada-devolucion")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetVentaMensualSecretariaTirDevo([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 de tirada/devolución." }); + return Ok(data); + } [HttpGet("venta-mensual-secretaria/tirada-devolucion/pdf")] public async Task GetVentaMensualSecretariaTirDevoPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) @@ -497,20 +656,74 @@ namespace GestionIntegral.Api.Controllers } catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaTirDevo."); return StatusCode(500, "Error interno."); } } + + // GET: api/reportes/distribucion-canillas + [HttpGet("distribucion-canillas")] // Endpoint para los datos JSON + [ProducesResponseType(typeof(ReporteDistribucionCanillasResponseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteDistribucionCanillasData([FromQuery] DateTime fecha, [FromQuery] int idEmpresa) + { + if (!TienePermiso(PermisoVerComprobanteLiquidacionCanilla)) return Forbid(); + + var (canillas, canillasAcc, canillasAll, canillasFechaLiq, canillasAccFechaLiq, + ctrlDevolucionesRemitos, ctrlDevolucionesParaDistCan, ctrlDevolucionesOtrosDias, error) = + await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); + + if (error != null) return BadRequest(new { message = error }); + + // Una validación simple, podrías hacerla más granular si es necesario + bool noHayDatos = (canillas == null || !canillas.Any()) && + (canillasAcc == null || !canillasAcc.Any()) && + (canillasAll == null || !canillasAll.Any()) && + (ctrlDevolucionesParaDistCan == null || !ctrlDevolucionesParaDistCan.Any()); // Podrías añadir más aquí + + if (noHayDatos) + { + return NotFound(new { message = "No hay datos para el reporte de distribución de canillas." }); + } + + var response = new ReporteDistribucionCanillasResponseDto + { + Canillas = canillas ?? Enumerable.Empty(), + CanillasAccionistas = canillasAcc ?? Enumerable.Empty(), + CanillasTodos = canillasAll ?? Enumerable.Empty(), + CanillasLiquidadasOtraFecha = canillasFechaLiq ?? Enumerable.Empty(), + CanillasAccionistasLiquidadasOtraFecha = canillasAccFechaLiq ?? Enumerable.Empty(), + ControlDevolucionesRemitos = ctrlDevolucionesRemitos ?? Enumerable.Empty(), + ControlDevolucionesDetalle = ctrlDevolucionesParaDistCan ?? Enumerable.Empty(), + ControlDevolucionesOtrosDias = ctrlDevolucionesOtrosDias ?? Enumerable.Empty() + }; + + return Ok(response); + } [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); + // CORRECCIÓN AQUÍ: Añadir la variable para el nuevo elemento de la tupla + var ( + canillas, + canillasAcc, + canillasAll, + canillasFechaLiq, + canillasAccFechaLiq, + ctrlDevolucionesRemitos, // Renombrado para claridad + ctrlDevolucionesParaDistCan, + _ , // Descartamos ctrlDevolucionesOtrosDias si no se usa aquí + error + ) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); if (error != null) return BadRequest(new { message = error }); + // La lógica de noHayDatosParaTotales y noHayDatosParaDetalle debería usar los nombres correctos bool noHayDatosParaTotales = (canillasAll == null || !canillasAll.Any()) && - (ctrlDevoluciones == null || !ctrlDevoluciones.Any()) && + (ctrlDevolucionesRemitos == null || !ctrlDevolucionesRemitos.Any()) && // Usar ctrlDevolucionesRemitos o ctrlDevolucionesParaDistCan según el RDLC (ctrlDevolucionesParaDistCan == null || !ctrlDevolucionesParaDistCan.Any()); + bool noHayDatosParaDetalle = noHayDatosParaTotales && (canillas == null || !canillas.Any()) && (canillasAcc == null || !canillasAcc.Any()) && @@ -537,7 +750,7 @@ namespace GestionIntegral.Api.Controllers 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("DSObtenerCtrlDevoluciones", ctrlDevolucionesRemitos ?? new List())); // Usa el renombrado report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCan ?? new List())); var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); @@ -560,20 +773,69 @@ namespace GestionIntegral.Api.Controllers } } + // GET: api/reportes/control-devoluciones + [HttpGet("control-devoluciones")] + [ProducesResponseType(typeof(ControlDevolucionesDataResponseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetControlDevolucionesData([FromQuery] DateTime fecha, [FromQuery] int idEmpresa) + { + if (!TienePermiso(PermisoVerControlDevoluciones)) return Forbid(); + + var ( + _, // canillas + _, // canillasAcc + _, // canillasAll + _, // canillasFechaLiq + _, // canillasAccFechaLiq + ctrlDevolucionesRemitosData, // Para SP_ObtenerCtrlDevoluciones -> DataSet "DSObtenerCtrlDevoluciones" + ctrlDevolucionesParaDistCanData, // Para SP_DistCanillasCantidadEntradaSalida -> DataSet "DSCtrlDevoluciones" + ctrlDevolucionesOtrosDiasData, // Para SP_DistCanillasCantidadEntradaSalidaOtrosDias -> DataSet "DSCtrlDevolucionesOtrosDias" + error + ) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); // Reutilizamos este método + + if (error != null) return BadRequest(new { message = error }); + + // Adaptar la condición de "no hay datos" a los DataSets que realmente usa este reporte + if ((ctrlDevolucionesParaDistCanData == null || !ctrlDevolucionesParaDistCanData.Any()) && + (ctrlDevolucionesOtrosDiasData == null || !ctrlDevolucionesOtrosDiasData.Any()) && + (ctrlDevolucionesRemitosData == null || !ctrlDevolucionesRemitosData.Any())) + { + return NotFound(new { message = "No hay datos para generar el reporte de control de devoluciones." }); + } + + var response = new ControlDevolucionesDataResponseDto + { + DetallesCtrlDevoluciones = ctrlDevolucionesParaDistCanData ?? Enumerable.Empty(), + DevolucionesOtrosDias = ctrlDevolucionesOtrosDiasData ?? Enumerable.Empty(), + RemitosIngresados = ctrlDevolucionesRemitosData ?? Enumerable.Empty() + }; + + return Ok(response); + } [HttpGet("control-devoluciones/pdf")] public async Task GetReporteControlDevolucionesPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa) { if (!TienePermiso(PermisoVerControlDevoluciones)) return Forbid(); + + // La tupla ahora devuelve un campo más var ( _, _, _, _, _, - ctrlDevolucionesData, // Este es el que usa el DataSet "DSObtenerCtrlDevoluciones" - ctrlDevolucionesParaDistCanData, // Este es el que usa el DataSet "DSCtrlDevoluciones" + ctrlDevolucionesRemitosData, // Para DSObtenerCtrlDevoluciones + ctrlDevolucionesParaDistCanData, // Para DSCtrlDevoluciones + ctrlDevolucionesOtrosDiasData, // <--- NUEVO: Para DSCtrlDevolucionesOtrosDias error ) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); if (error != null) return BadRequest(new { message = error }); - if ((ctrlDevolucionesData == null || !ctrlDevolucionesData.Any()) && (ctrlDevolucionesParaDistCanData == null || !ctrlDevolucionesParaDistCanData.Any())) + + // Ajustamos la condición para verificar los DataSets que realmente usa este reporte específico + if ((ctrlDevolucionesRemitosData == null || !ctrlDevolucionesRemitosData.Any()) && + (ctrlDevolucionesParaDistCanData == null || !ctrlDevolucionesParaDistCanData.Any()) && + (ctrlDevolucionesOtrosDiasData == null || !ctrlDevolucionesOtrosDiasData.Any()) // <--- AÑADIDO A LA VERIFICACIÓN + ) { return NotFound(new { message = "No hay datos para generar el PDF para control de devoluciones." }); } @@ -585,8 +847,15 @@ namespace GestionIntegral.Api.Controllers { report.LoadReportDefinition(fs); } + + // DataSet que usa SP_DistCanillasCantidadEntradaSalida report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCanData ?? new List())); - report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevolucionesData ?? new List())); + + // DataSet que usa SP_DistCanillasCantidadEntradaSalidaOtrosDias + report.DataSources.Add(new ReportDataSource("DSCtrlDevolucionesOtrosDias", ctrlDevolucionesOtrosDiasData ?? new List())); // <--- CORREGIDO + + // DataSet que usa SP_ObtenerCtrlDevoluciones + report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevolucionesRemitosData ?? new List())); var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); @@ -608,6 +877,44 @@ namespace GestionIntegral.Api.Controllers } } + // GET: api/reportes/cuentas-distribuidores + [HttpGet("cuentas-distribuidores")] + [ProducesResponseType(typeof(ReporteCuentasDistribuidorResponseDto), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteCuentasDistribuidoresData( + [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." }); + } + + var distribuidor = await _distribuidorRepository.GetByIdAsync(idDistribuidor); + var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); + + var response = new ReporteCuentasDistribuidorResponseDto + { + EntradasSalidas = entradasSalidas ?? Enumerable.Empty(), + DebitosCreditos = debitosCreditos ?? Enumerable.Empty(), + Pagos = pagos ?? Enumerable.Empty(), + Saldos = saldos ?? Enumerable.Empty(), + NombreDistribuidor = distribuidor.Distribuidor?.Nombre, + NombreEmpresa = empresa?.Nombre + }; + + return Ok(response); + } [HttpGet("cuentas-distribuidores/pdf")] public async Task GetReporteCuentasDistribuidoresPdf( @@ -658,6 +965,40 @@ namespace GestionIntegral.Api.Controllers } } + // GET: api/reportes/tiradas-publicaciones-secciones + [HttpGet("tiradas-publicaciones-secciones")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteTiradasPublicacionesSeccionesData( + [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; + + 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." }); + + return Ok(data); + } + [HttpGet("tiradas-publicaciones-secciones/pdf")] public async Task GetReporteTiradasPublicacionesSeccionesPdf( [FromQuery] int idPublicacion, @@ -718,6 +1059,39 @@ namespace GestionIntegral.Api.Controllers catch (Exception ex) { _logger.LogError(ex, "Error PDF Tiradas Publicaciones Secciones."); return StatusCode(500, "Error interno."); } } + // GET: api/reportes/consumo-bobinas-seccion + [HttpGet("consumo-bobinas-seccion")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteConsumoBobinasSeccionData( + [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." }); + + return Ok(data); + } + [HttpGet("consumo-bobinas-seccion/pdf")] public async Task GetReporteConsumoBobinasSeccionPdf( [FromQuery] DateTime fechaDesde, @@ -774,6 +1148,26 @@ namespace GestionIntegral.Api.Controllers catch (Exception ex) { _logger.LogError(ex, "Error PDF Consumo Bobinas por Seccion."); return StatusCode(500, "Error interno."); } } + // GET: api/reportes/consumo-bobinas-publicacion + [HttpGet("consumo-bobinas-publicacion")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteConsumoBobinasPublicacionData( + [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." }); + + return Ok(data); + } + [HttpGet("consumo-bobinas-publicacion/pdf")] public async Task GetReporteConsumoBobinasPublicacionPdf( [FromQuery] DateTime fechaDesde, @@ -809,6 +1203,39 @@ namespace GestionIntegral.Api.Controllers catch (Exception ex) { _logger.LogError(ex, "Error PDF Consumo Bobinas por Publicacion."); return StatusCode(500, "Error interno."); } } + // GET: api/reportes/comparativa-consumo-bobinas + [HttpGet("comparativa-consumo-bobinas")] + [ProducesResponseType(typeof(IEnumerable), StatusCodes.Status200OK)] + [ProducesResponseType(StatusCodes.Status400BadRequest)] + [ProducesResponseType(StatusCodes.Status403Forbidden)] + [ProducesResponseType(StatusCodes.Status404NotFound)] + public async Task GetReporteComparativaConsumoBobinasData( + [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." }); + + return Ok(data); + } + [HttpGet("comparativa-consumo-bobinas/pdf")] public async Task GetReporteComparativaConsumoBobinasPdf( [FromQuery] DateTime fechaInicioMesA, [FromQuery] DateTime fechaFinMesA, diff --git a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs index ac2a0cb..ee17c87 100644 --- a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs +++ b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/IReportesRepository.cs @@ -1,4 +1,3 @@ -// src/Data/Repositories/Reportes/IReportesRepository.cs using GestionIntegral.Api.Dtos.Reportes; using System; using System.Collections.Generic; @@ -29,6 +28,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes Task> GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa); Task> GetReporteObtenerCtrlDevolucionesAsync(DateTime fecha, int idEmpresa); Task> GetReporteCtrlDevolucionesParaDistCanAsync(DateTime fecha, int idEmpresa); + Task> GetEntradaSalidaOtrosDiasAsync(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); diff --git a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs index 2ebbfef..e3d91c6 100644 --- a/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs +++ b/Backend/GestionIntegral.Api/Data/Repositories/Reportes/ReportesRepository.cs @@ -1,4 +1,3 @@ -// src/Data/Repositories/Reportes/ReportesRepository.cs using Dapper; using GestionIntegral.Api.Dtos.Reportes; using Microsoft.Extensions.Logging; @@ -25,7 +24,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes { string spName = consolidado ? "dbo.SP_ConsumoBobinasConsolidado" : "dbo.SP_ConsumoBobinas"; var parameters = new DynamicParameters(); - + parameters.Add("FechaDesde", fechaDesde, DbType.Date); parameters.Add("FechaHasta", fechaHasta, DbType.Date); @@ -77,6 +76,17 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes return Enumerable.Empty(); } } + public async Task> GetEntradaSalidaOtrosDiasAsync(DateTime fecha, int idEmpresa) + { + using var conn = _dbConnectionFactory.CreateConnection() as IDbConnection; + // si no es IDbConnection, haz conn.Open() manual + var parametros = new { fecha, idEmpresa }; + return await conn.QueryAsync( + "SP_DistCanillasCantidadEntradaSalidaOtrosDias", + parametros, + commandType: CommandType.StoredProcedure + ); + } public async Task> GetMovimientoBobinasEstadoDetalleAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta) { @@ -156,7 +166,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes 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"; @@ -209,7 +219,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes 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"; @@ -229,7 +239,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes 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"; @@ -269,7 +279,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes 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"; @@ -291,7 +301,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes 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"; @@ -358,7 +368,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes 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) { diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesDataResponseDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesDataResponseDto.cs new file mode 100644 index 0000000..8942feb --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ControlDevolucionesDataResponseDto.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ControlDevolucionesDataResponseDto + { + public IEnumerable DetallesCtrlDevoluciones { get; set; } = new List(); + public IEnumerable DevolucionesOtrosDias { get; set; } = new List(); + public IEnumerable RemitosIngresados { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DevueltosOtrosDiasDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DevueltosOtrosDiasDto.cs new file mode 100644 index 0000000..a6a2818 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/DevueltosOtrosDiasDto.cs @@ -0,0 +1,7 @@ +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class DevueltosOtrosDiasDto + { + public int Devueltos { get; set; } + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasResponseDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasResponseDto.cs new file mode 100644 index 0000000..1bcbdd2 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionCanillasResponseDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionCanillasResponseDto + { + public IEnumerable DetalleSimple { get; set; } = new List(); + public IEnumerable PromediosPorDia { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResponseDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResponseDto.cs new file mode 100644 index 0000000..c01d026 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ListadoDistribucionGeneralResponseDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ListadoDistribucionGeneralResponseDto + { + public IEnumerable Resumen { get; set; } = new List(); + public IEnumerable PromediosPorDia { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasPorEstadoResponseDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasPorEstadoResponseDto.cs new file mode 100644 index 0000000..229a964 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/MovimientoBobinasPorEstadoResponseDto.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class MovimientoBobinasPorEstadoResponseDto + { + public IEnumerable Detalle { get; set; } = new List(); + public IEnumerable Totales { get; set; } = new List(); + } +} \ 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 index 349a0c4..b24ec6c 100644 --- a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ObtenerCtrlDevolucionesDto.cs +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ObtenerCtrlDevolucionesDto.cs @@ -2,6 +2,6 @@ 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' + public int Remito { get; set; } } } \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteCuentasDistribuidorResponseDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteCuentasDistribuidorResponseDto.cs new file mode 100644 index 0000000..6b67a41 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteCuentasDistribuidorResponseDto.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ReporteCuentasDistribuidorResponseDto + { + public IEnumerable EntradasSalidas { get; set; } = new List(); + public IEnumerable DebitosCreditos { get; set; } = new List(); + public IEnumerable Pagos { get; set; } = new List(); + public IEnumerable Saldos { get; set; } = new List(); // O podría ser SaldoDto SaldoActual si siempre es uno + public string? NombreDistribuidor { get; set; } // Para el título del reporte + public string? NombreEmpresa { get; set; } // Para el título del reporte + } +} \ No newline at end of file diff --git a/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteDistribucionCanillasResponseDto.cs b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteDistribucionCanillasResponseDto.cs new file mode 100644 index 0000000..5d1fab4 --- /dev/null +++ b/Backend/GestionIntegral.Api/Models/Dtos/Reportes/ReporteDistribucionCanillasResponseDto.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace GestionIntegral.Api.Dtos.Reportes +{ + public class ReporteDistribucionCanillasResponseDto + { + public IEnumerable Canillas { get; set; } = new List(); + public IEnumerable CanillasAccionistas { get; set; } = new List(); + public IEnumerable CanillasTodos { get; set; } = new List(); + public IEnumerable CanillasLiquidadasOtraFecha { get; set; } = new List(); + public IEnumerable CanillasAccionistasLiquidadasOtraFecha { get; set; } = new List(); + public IEnumerable ControlDevolucionesRemitos { get; set; } = new List(); + public IEnumerable ControlDevolucionesDetalle { get; set; } = new List(); + public IEnumerable ControlDevolucionesOtrosDias { get; set; } = new List(); + } +} \ 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 4fbc1c2..1abb49e 100644 --- a/Backend/GestionIntegral.Api/Services/Reportes/IReportesService.cs +++ b/Backend/GestionIntegral.Api/Services/Reportes/IReportesService.cs @@ -1,4 +1,3 @@ -// src/Services/Reportes/IReportesService.cs using GestionIntegral.Api.Dtos.Reportes; using System; using System.Collections.Generic; @@ -33,10 +32,11 @@ namespace GestionIntegral.Api.Services.Reportes IEnumerable CanillasAll, IEnumerable CanillasFechaLiq, IEnumerable CanillasAccFechaLiq, - IEnumerable CtrlDevoluciones, - IEnumerable CtrlDevolucionesParaDistCan, + IEnumerable CtrlDevolucionesRemitos, // Para SP_ObtenerCtrlDevoluciones + IEnumerable CtrlDevolucionesParaDistCan, // Para SP_DistCanillasCantidadEntradaSalida + IEnumerable CtrlDevolucionesOtrosDias, // <--- NUEVO para SP_DistCanillasCantidadEntradaSalidaOtrosDias string? Error - )> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa); // ESTA ES LA FIRMA CORRECTA Y ÚNICA PARA ESTE MÉTODO + )> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa); // Reporte Tiradas por Publicación y Secciones (RR008) Task<(IEnumerable Data, string? Error)> ObtenerTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); @@ -52,7 +52,7 @@ namespace GestionIntegral.Api.Services.Reportes // 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, diff --git a/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs b/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs index ee5c555..b7a38da 100644 --- a/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs +++ b/Backend/GestionIntegral.Api/Services/Reportes/ReportesService.cs @@ -1,4 +1,3 @@ -// src/Services/Reportes/ReportesService.cs using GestionIntegral.Api.Data.Repositories.Reportes; using GestionIntegral.Api.Dtos.Reportes; using Microsoft.Extensions.Logging; @@ -65,7 +64,7 @@ namespace GestionIntegral.Api.Services.Reportes { return (Enumerable.Empty(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'."); } - int diasPeriodo = (fechaHasta.Date - fechaDesde.Date).Days + 1; + int diasPeriodo = (fechaHasta.Date - fechaDesde.Date).Days + 1; try { @@ -90,8 +89,9 @@ namespace GestionIntegral.Api.Services.Reportes { 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 => { + + var detalleUtc = detalle.Select(d => + { d.FechaMovimiento = DateTime.SpecifyKind(d.FechaMovimiento, DateTimeKind.Utc); return d; }).ToList(); @@ -116,7 +116,7 @@ namespace GestionIntegral.Api.Services.Reportes // 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); @@ -132,7 +132,7 @@ namespace GestionIntegral.Api.Services.Reportes { 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); @@ -145,7 +145,7 @@ namespace GestionIntegral.Api.Services.Reportes 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) @@ -192,7 +192,7 @@ namespace GestionIntegral.Api.Services.Reportes 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'."); @@ -207,17 +207,18 @@ namespace GestionIntegral.Api.Services.Reportes 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) + IEnumerable Canillas, + IEnumerable CanillasAcc, + IEnumerable CanillasAll, + IEnumerable CanillasFechaLiq, + IEnumerable CanillasAccFechaLiq, + IEnumerable CtrlDevolucionesRemitos, + IEnumerable CtrlDevolucionesParaDistCan, + IEnumerable CtrlDevolucionesOtrosDias, + string? Error +)> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa) { try { @@ -226,13 +227,19 @@ namespace GestionIntegral.Api.Services.Reportes 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); + var ctrlDevolucionesRemitosTask = _reportesRepository.GetReporteObtenerCtrlDevolucionesAsync(fecha, idEmpresa); // SP_ObtenerCtrlDevoluciones + var ctrlDevolucionesParaDistCanTask = _reportesRepository.GetReporteCtrlDevolucionesParaDistCanAsync(fecha, idEmpresa); // SP_DistCanillasCantidadEntradaSalida + var ctrlDevolucionesOtrosDiasTask = _reportesRepository.GetEntradaSalidaOtrosDiasAsync(fecha, idEmpresa); // SP_DistCanillasCantidadEntradaSalidaOtrosDias - await Task.WhenAll(canillasTask, canillasAccTask, canillasAllTask, canillasFechaLiqTask, canillasAccFechaLiqTask, ctrlDevolucionesTask, ctrlDevolucionesParaDistCanTask); + await Task.WhenAll( + canillasTask, canillasAccTask, canillasAllTask, + canillasFechaLiqTask, canillasAccFechaLiqTask, + ctrlDevolucionesRemitosTask, ctrlDevolucionesParaDistCanTask, + ctrlDevolucionesOtrosDiasTask + ); - Func, IEnumerable> toUtc = - items => items?.Select(c => { if(c.Fecha.HasValue) c.Fecha = DateTime.SpecifyKind(c.Fecha.Value.Date, DateTimeKind.Utc); return c; }).ToList() + 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 ( @@ -241,8 +248,9 @@ namespace GestionIntegral.Api.Services.Reportes await canillasAllTask ?? Enumerable.Empty(), toUtc(await canillasFechaLiqTask), toUtc(await canillasAccFechaLiqTask), - await ctrlDevolucionesTask ?? Enumerable.Empty(), + await ctrlDevolucionesRemitosTask ?? Enumerable.Empty(), await ctrlDevolucionesParaDistCanTask ?? Enumerable.Empty(), + await ctrlDevolucionesOtrosDiasTask ?? Enumerable.Empty(), null ); } @@ -257,6 +265,7 @@ namespace GestionIntegral.Api.Services.Reportes Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty(), + Enumerable.Empty(), "Error interno al generar el reporte de distribución de canillas." ); } @@ -376,7 +385,7 @@ namespace GestionIntegral.Api.Services.Reportes string? Error )> ObtenerReporteCuentasDistribuidorAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta) { - if (fechaDesde > fechaHasta) + if (fechaDesde > fechaHasta) return (Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty(), Enumerable.Empty(), "Fecha 'Desde' no puede ser mayor que 'Hasta'."); try @@ -388,13 +397,13 @@ namespace GestionIntegral.Api.Services.Reportes 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() + Func, IEnumerable> esToUtc = + items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList() ?? Enumerable.Empty(); - Func, IEnumerable> dcToUtc = + Func, IEnumerable> dcToUtc = items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList() ?? Enumerable.Empty(); - Func, IEnumerable> paToUtc = + Func, IEnumerable> paToUtc = items => items?.Select(i => { i.Fecha = DateTime.SpecifyKind(i.Fecha.Date, DateTimeKind.Utc); return i; }).ToList() ?? Enumerable.Empty(); 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 30d2df1..30bf741 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+298bc0d0941b976d5de4c53a7b17a88b500bc8e2")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+cdd4d3e0f71f866aabb489394a273ab4d013284c")] [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 5a4bdb1..e7b28b5 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=","NpxIifDE4FyR4jhkRXHNdK9IIbA/joaTINJDnFlccPA="],"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=","RFpydTIMf9fxYfNnrif0YQNHLgrUW58SpaLEeCZ9nXg="],"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 63bc9eb..4573e4f 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=","NpxIifDE4FyR4jhkRXHNdK9IIbA/joaTINJDnFlccPA="],"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=","RFpydTIMf9fxYfNnrif0YQNHLgrUW58SpaLEeCZ9nXg="],"CachedAssets":{},"CachedCopyCandidates":{}} \ No newline at end of file diff --git a/Frontend/src/routes/AppRoutes.tsx b/Frontend/src/routes/AppRoutes.tsx index c845156..eda7361 100644 --- a/Frontend/src/routes/AppRoutes.tsx +++ b/Frontend/src/routes/AppRoutes.tsx @@ -90,11 +90,6 @@ const MainLayoutWrapper: React.FC = () => ( ); -// Placeholder simple -const PlaceholderPage: React.FC<{ moduleName: string }> = ({ moduleName }) => ( - Página Principal del Módulo: {moduleName} -); - const AppRoutes = () => { return (