Finalización de Endpoints para la gestión de Reportes. Se continúa con el Frontend.
This commit is contained in:
		| @@ -19,7 +19,7 @@ namespace GestionIntegral.Api.Controllers | |||||||
|     [Authorize] |     [Authorize] | ||||||
|     public class ReportesController : ControllerBase |     public class ReportesController : ControllerBase | ||||||
|     { |     { | ||||||
|         private readonly IReportesService _reportesService; // <--- CORREGIDO |         private readonly IReportesService _reportesService; | ||||||
|         private readonly ILogger<ReportesController> _logger; |         private readonly ILogger<ReportesController> _logger; | ||||||
|         private readonly IPlantaRepository _plantaRepository; |         private readonly IPlantaRepository _plantaRepository; | ||||||
|         private readonly IPublicacionRepository _publicacionRepository; |         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<IActionResult> 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<MovimientoBobinaEstadoDetalleDto>(), | ||||||
|  |                 Totales = totales ?? Enumerable.Empty<MovimientoBobinaEstadoTotalDto>() | ||||||
|  |             }; | ||||||
|  |              | ||||||
|  |             return Ok(response); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         [HttpGet("movimiento-bobinas-estado/pdf")] |         [HttpGet("movimiento-bobinas-estado/pdf")] | ||||||
|         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] |         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] | ||||||
|         [ProducesResponseType(StatusCodes.Status400BadRequest)] |         [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<IActionResult> 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<ListadoDistribucionGeneralResumenDto>(), | ||||||
|  |                 PromediosPorDia = promedios ?? Enumerable.Empty<ListadoDistribucionGeneralPromedioDiaDto>() | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             return Ok(response); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         [HttpGet("listado-distribucion-general/pdf")] |         [HttpGet("listado-distribucion-general/pdf")] | ||||||
|         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] |         [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<IActionResult> 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<ListadoDistribucionCanillasSimpleDto>(), | ||||||
|  |                 PromediosPorDia = promedios ?? Enumerable.Empty<ListadoDistribucionCanillasPromedioDiaDto>() | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             return Ok(response); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         [HttpGet("listado-distribucion-canillas/pdf")] |         [HttpGet("listado-distribucion-canillas/pdf")] | ||||||
|         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] |         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] | ||||||
|         [ProducesResponseType(StatusCodes.Status400BadRequest)] |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
| @@ -368,6 +457,31 @@ namespace GestionIntegral.Api.Controllers | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // GET: api/reportes/listado-distribucion-canillas-importe | ||||||
|  |         [HttpGet("listado-distribucion-canillas-importe")] | ||||||
|  |         [ProducesResponseType(typeof(IEnumerable<ListadoDistribucionCanillasImporteDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> 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")] |         [HttpGet("listado-distribucion-canillas-importe/pdf")] | ||||||
|         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] |         [ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)] | ||||||
|         [ProducesResponseType(StatusCodes.Status400BadRequest)] |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
| @@ -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<VentaMensualSecretariaElDiaDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> 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")] |         [HttpGet("venta-mensual-secretaria/el-dia/pdf")] | ||||||
|         public async Task<IActionResult> GetVentaMensualSecretariaElDiaPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) |         public async Task<IActionResult> 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."); } |             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<VentaMensualSecretariaElPlataDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> 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")] |         [HttpGet("venta-mensual-secretaria/el-plata/pdf")] | ||||||
|         public async Task<IActionResult> GetVentaMensualSecretariaElPlataPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) |         public async Task<IActionResult> GetVentaMensualSecretariaElPlataPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) | ||||||
|         { |         { | ||||||
| @@ -472,6 +616,21 @@ namespace GestionIntegral.Api.Controllers | |||||||
|             catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaElPlata."); return StatusCode(500, "Error interno."); } |             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<VentaMensualSecretariaTirDevoDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> 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")] |         [HttpGet("venta-mensual-secretaria/tirada-devolucion/pdf")] | ||||||
|         public async Task<IActionResult> GetVentaMensualSecretariaTirDevoPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) |         public async Task<IActionResult> GetVentaMensualSecretariaTirDevoPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta) | ||||||
|         { |         { | ||||||
| @@ -498,19 +657,73 @@ namespace GestionIntegral.Api.Controllers | |||||||
|             catch (Exception ex) { _logger.LogError(ex, "Error PDF VentaMensualSecretariaTirDevo."); return StatusCode(500, "Error interno."); } |             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<IActionResult> 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<DetalleDistribucionCanillaDto>(), | ||||||
|  |                 CanillasAccionistas = canillasAcc ?? Enumerable.Empty<DetalleDistribucionCanillaDto>(), | ||||||
|  |                 CanillasTodos = canillasAll ?? Enumerable.Empty<DetalleDistribucionCanillaAllDto>(), | ||||||
|  |                 CanillasLiquidadasOtraFecha = canillasFechaLiq ?? Enumerable.Empty<DetalleDistribucionCanillaDto>(), | ||||||
|  |                 CanillasAccionistasLiquidadasOtraFecha = canillasAccFechaLiq ?? Enumerable.Empty<DetalleDistribucionCanillaDto>(), | ||||||
|  |                 ControlDevolucionesRemitos = ctrlDevolucionesRemitos ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>(), | ||||||
|  |                 ControlDevolucionesDetalle = ctrlDevolucionesParaDistCan ?? Enumerable.Empty<ControlDevolucionesReporteDto>(), | ||||||
|  |                 ControlDevolucionesOtrosDias = ctrlDevolucionesOtrosDias ?? Enumerable.Empty<DevueltosOtrosDiasDto>() | ||||||
|  |             }; | ||||||
|  |              | ||||||
|  |             return Ok(response); | ||||||
|  |         } | ||||||
|  |          | ||||||
|         [HttpGet("distribucion-canillas/pdf")] |         [HttpGet("distribucion-canillas/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteDistribucionCanillasPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa, [FromQuery] bool soloTotales = false) |         public async Task<IActionResult> GetReporteDistribucionCanillasPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa, [FromQuery] bool soloTotales = false) | ||||||
|         { |         { | ||||||
|             if (!TienePermiso(PermisoVerComprobanteLiquidacionCanilla)) return Forbid(); |             if (!TienePermiso(PermisoVerComprobanteLiquidacionCanilla)) return Forbid(); | ||||||
|  |  | ||||||
|             var (canillas, canillasAcc, canillasAll, canillasFechaLiq, canillasAccFechaLiq, ctrlDevoluciones, ctrlDevolucionesParaDistCan, error) =  |             // CORRECCIÓN AQUÍ: Añadir la variable para el nuevo elemento de la tupla | ||||||
|                 await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); |             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 }); |             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()) && |             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()); |                                          (ctrlDevolucionesParaDistCan == null || !ctrlDevolucionesParaDistCan.Any()); | ||||||
|  |              | ||||||
|             bool noHayDatosParaDetalle = noHayDatosParaTotales && |             bool noHayDatosParaDetalle = noHayDatosParaTotales && | ||||||
|                                          (canillas == null || !canillas.Any()) && |                                          (canillas == null || !canillas.Any()) && | ||||||
|                                          (canillasAcc == null || !canillasAcc.Any()) && |                                          (canillasAcc == null || !canillasAcc.Any()) && | ||||||
| @@ -537,7 +750,7 @@ namespace GestionIntegral.Api.Controllers | |||||||
|                 report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanALL", canillasAll ?? new List<DetalleDistribucionCanillaAllDto>())); |                 report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanALL", canillasAll ?? new List<DetalleDistribucionCanillaAllDto>())); | ||||||
|                 report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanFechaLiq", canillasFechaLiq ?? new List<DetalleDistribucionCanillaDto>())); |                 report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanFechaLiq", canillasFechaLiq ?? new List<DetalleDistribucionCanillaDto>())); | ||||||
|                 report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanAccFechaLiq", canillasAccFechaLiq ?? new List<DetalleDistribucionCanillaDto>())); |                 report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanAccFechaLiq", canillasAccFechaLiq ?? new List<DetalleDistribucionCanillaDto>())); | ||||||
|                 report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevoluciones ?? new List<ObtenerCtrlDevolucionesDto>())); |                 report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevolucionesRemitos ?? new List<ObtenerCtrlDevolucionesDto>())); // Usa el renombrado | ||||||
|                 report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCan ?? new List<ControlDevolucionesReporteDto>())); |                 report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCan ?? new List<ControlDevolucionesReporteDto>())); | ||||||
|  |  | ||||||
|                 var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); |                 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<IActionResult> 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<ControlDevolucionesReporteDto>(), | ||||||
|  |                 DevolucionesOtrosDias = ctrlDevolucionesOtrosDiasData ?? Enumerable.Empty<DevueltosOtrosDiasDto>(), | ||||||
|  |                 RemitosIngresados = ctrlDevolucionesRemitosData ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>() | ||||||
|  |             }; | ||||||
|  |              | ||||||
|  |             return Ok(response); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         [HttpGet("control-devoluciones/pdf")] |         [HttpGet("control-devoluciones/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteControlDevolucionesPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa) |         public async Task<IActionResult> GetReporteControlDevolucionesPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa) | ||||||
|         { |         { | ||||||
|              if (!TienePermiso(PermisoVerControlDevoluciones)) return Forbid(); |              if (!TienePermiso(PermisoVerControlDevoluciones)) return Forbid(); | ||||||
|  |              | ||||||
|  |             // La tupla ahora devuelve un campo más | ||||||
|             var ( |             var ( | ||||||
|                 _, _, _, _, _,  |                 _, _, _, _, _,  | ||||||
|                 ctrlDevolucionesData, // Este es el que usa el DataSet "DSObtenerCtrlDevoluciones" |                 ctrlDevolucionesRemitosData,      // Para DSObtenerCtrlDevoluciones | ||||||
|                 ctrlDevolucionesParaDistCanData,  // Este es el que usa el DataSet "DSCtrlDevoluciones" |                 ctrlDevolucionesParaDistCanData,  // Para DSCtrlDevoluciones | ||||||
|  |                 ctrlDevolucionesOtrosDiasData,    // <--- NUEVO: Para DSCtrlDevolucionesOtrosDias | ||||||
|                 error |                 error | ||||||
|             ) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); |             ) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa); | ||||||
|  |  | ||||||
|             if (error != null) return BadRequest(new { message = error }); |             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." }); |                 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); |                     report.LoadReportDefinition(fs); | ||||||
|                 } |                 } | ||||||
|  |                  | ||||||
|  |                 // DataSet que usa SP_DistCanillasCantidadEntradaSalida | ||||||
|                 report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCanData ?? new List<ControlDevolucionesReporteDto>())); |                 report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCanData ?? new List<ControlDevolucionesReporteDto>())); | ||||||
|                 report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevolucionesData ?? new List<ObtenerCtrlDevolucionesDto>())); |                  | ||||||
|  |                 // DataSet que usa SP_DistCanillasCantidadEntradaSalidaOtrosDias | ||||||
|  |                 report.DataSources.Add(new ReportDataSource("DSCtrlDevolucionesOtrosDias", ctrlDevolucionesOtrosDiasData ?? new List<DevueltosOtrosDiasDto>())); // <--- CORREGIDO | ||||||
|  |                  | ||||||
|  |                 // DataSet que usa SP_ObtenerCtrlDevoluciones | ||||||
|  |                 report.DataSources.Add(new ReportDataSource("DSObtenerCtrlDevoluciones", ctrlDevolucionesRemitosData ?? new List<ObtenerCtrlDevolucionesDto>())); | ||||||
|  |  | ||||||
|  |  | ||||||
|                 var empresa = await _empresaRepository.GetByIdAsync(idEmpresa); |                 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<IActionResult> 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<BalanceCuentaDistDto>(), | ||||||
|  |                 DebitosCreditos = debitosCreditos ?? Enumerable.Empty<BalanceCuentaDebCredDto>(), | ||||||
|  |                 Pagos = pagos ?? Enumerable.Empty<BalanceCuentaPagosDto>(), | ||||||
|  |                 Saldos = saldos ?? Enumerable.Empty<SaldoDto>(), | ||||||
|  |                 NombreDistribuidor = distribuidor.Distribuidor?.Nombre, | ||||||
|  |                 NombreEmpresa = empresa?.Nombre | ||||||
|  |             }; | ||||||
|  |              | ||||||
|  |             return Ok(response); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         [HttpGet("cuentas-distribuidores/pdf")] |         [HttpGet("cuentas-distribuidores/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteCuentasDistribuidoresPdf( |         public async Task<IActionResult> GetReporteCuentasDistribuidoresPdf( | ||||||
| @@ -658,6 +965,40 @@ namespace GestionIntegral.Api.Controllers | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         // GET: api/reportes/tiradas-publicaciones-secciones | ||||||
|  |         [HttpGet("tiradas-publicaciones-secciones")] | ||||||
|  |         [ProducesResponseType(typeof(IEnumerable<TiradasPublicacionesSeccionesDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> GetReporteTiradasPublicacionesSeccionesData( | ||||||
|  |             [FromQuery] int idPublicacion, | ||||||
|  |             [FromQuery] DateTime fechaDesde,  | ||||||
|  |             [FromQuery] DateTime fechaHasta,  | ||||||
|  |             [FromQuery] int? idPlanta,      | ||||||
|  |             [FromQuery] bool consolidado = false) | ||||||
|  |         { | ||||||
|  |             if (!TienePermiso(PermisoVerReporteTiradas)) return Forbid(); | ||||||
|  |  | ||||||
|  |             IEnumerable<TiradasPublicacionesSeccionesDto> 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")] |         [HttpGet("tiradas-publicaciones-secciones/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteTiradasPublicacionesSeccionesPdf( |         public async Task<IActionResult> GetReporteTiradasPublicacionesSeccionesPdf( | ||||||
|             [FromQuery] int idPublicacion, |             [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."); } |             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<ConsumoBobinasSeccionDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> GetReporteConsumoBobinasSeccionData( | ||||||
|  |             [FromQuery] DateTime fechaDesde, | ||||||
|  |             [FromQuery] DateTime fechaHasta, | ||||||
|  |             [FromQuery] int? idPlanta, | ||||||
|  |             [FromQuery] bool consolidado = false) | ||||||
|  |         { | ||||||
|  |             if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();  | ||||||
|  |  | ||||||
|  |             IEnumerable<ConsumoBobinasSeccionDto> 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")] |         [HttpGet("consumo-bobinas-seccion/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteConsumoBobinasSeccionPdf( |         public async Task<IActionResult> GetReporteConsumoBobinasSeccionPdf( | ||||||
|             [FromQuery] DateTime fechaDesde, |             [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."); } |             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<ConsumoBobinasPublicacionDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> 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")] |         [HttpGet("consumo-bobinas-publicacion/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteConsumoBobinasPublicacionPdf( |         public async Task<IActionResult> GetReporteConsumoBobinasPublicacionPdf( | ||||||
|             [FromQuery] DateTime fechaDesde, |             [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."); } |             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<ComparativaConsumoBobinasDto>), StatusCodes.Status200OK)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status400BadRequest)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status403Forbidden)] | ||||||
|  |         [ProducesResponseType(StatusCodes.Status404NotFound)] | ||||||
|  |         public async Task<IActionResult> 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<ComparativaConsumoBobinasDto> 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")] |         [HttpGet("comparativa-consumo-bobinas/pdf")] | ||||||
|         public async Task<IActionResult> GetReporteComparativaConsumoBobinasPdf( |         public async Task<IActionResult> GetReporteComparativaConsumoBobinasPdf( | ||||||
|             [FromQuery] DateTime fechaInicioMesA, [FromQuery] DateTime fechaFinMesA, |             [FromQuery] DateTime fechaInicioMesA, [FromQuery] DateTime fechaFinMesA, | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| // src/Data/Repositories/Reportes/IReportesRepository.cs |  | ||||||
| using GestionIntegral.Api.Dtos.Reportes; | using GestionIntegral.Api.Dtos.Reportes; | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| @@ -29,6 +28,7 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes | |||||||
|         Task<IEnumerable<DetalleDistribucionCanillaDto>> GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa); |         Task<IEnumerable<DetalleDistribucionCanillaDto>> GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(DateTime fechaLiquidacion, int idEmpresa); | ||||||
|         Task<IEnumerable<ObtenerCtrlDevolucionesDto>> GetReporteObtenerCtrlDevolucionesAsync(DateTime fecha, int idEmpresa); |         Task<IEnumerable<ObtenerCtrlDevolucionesDto>> GetReporteObtenerCtrlDevolucionesAsync(DateTime fecha, int idEmpresa); | ||||||
|         Task<IEnumerable<ControlDevolucionesReporteDto>> GetReporteCtrlDevolucionesParaDistCanAsync(DateTime fecha, int idEmpresa); |         Task<IEnumerable<ControlDevolucionesReporteDto>> GetReporteCtrlDevolucionesParaDistCanAsync(DateTime fecha, int idEmpresa); | ||||||
|  |         Task<IEnumerable<DevueltosOtrosDiasDto>> GetEntradaSalidaOtrosDiasAsync(DateTime fecha, int idEmpresa); | ||||||
|         Task<IEnumerable<TiradasPublicacionesSeccionesDto>> GetTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); |         Task<IEnumerable<TiradasPublicacionesSeccionesDto>> GetTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); | ||||||
|         Task<IEnumerable<TiradasPublicacionesSeccionesDto>> GetTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); |         Task<IEnumerable<TiradasPublicacionesSeccionesDto>> GetTiradasPublicacionesSeccionesConsolidadoAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta); | ||||||
|         Task<IEnumerable<ConsumoBobinasSeccionDto>> GetConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta); |         Task<IEnumerable<ConsumoBobinasSeccionDto>> GetConsumoBobinasPorSeccionAsync(DateTime fechaDesde, DateTime fechaHasta, int idPlanta); | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| // src/Data/Repositories/Reportes/ReportesRepository.cs |  | ||||||
| using Dapper; | using Dapper; | ||||||
| using GestionIntegral.Api.Dtos.Reportes; | using GestionIntegral.Api.Dtos.Reportes; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| @@ -77,6 +76,17 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes | |||||||
|                 return Enumerable.Empty<MovimientoBobinasDto>(); |                 return Enumerable.Empty<MovimientoBobinasDto>(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         public async Task<IEnumerable<DevueltosOtrosDiasDto>> 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<DevueltosOtrosDiasDto>( | ||||||
|  |                 "SP_DistCanillasCantidadEntradaSalidaOtrosDias", | ||||||
|  |                 parametros, | ||||||
|  |                 commandType: CommandType.StoredProcedure | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         public async Task<IEnumerable<MovimientoBobinaEstadoDetalleDto>> GetMovimientoBobinasEstadoDetalleAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta) |         public async Task<IEnumerable<MovimientoBobinaEstadoDetalleDto>> GetMovimientoBobinasEstadoDetalleAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta) | ||||||
|         { |         { | ||||||
|   | |||||||
| @@ -0,0 +1,11 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class ControlDevolucionesDataResponseDto | ||||||
|  |     { | ||||||
|  |         public IEnumerable<ControlDevolucionesReporteDto> DetallesCtrlDevoluciones { get; set; } = new List<ControlDevolucionesReporteDto>(); | ||||||
|  |         public IEnumerable<DevueltosOtrosDiasDto> DevolucionesOtrosDias { get; set; } = new List<DevueltosOtrosDiasDto>(); | ||||||
|  |         public IEnumerable<ObtenerCtrlDevolucionesDto> RemitosIngresados { get; set; } = new List<ObtenerCtrlDevolucionesDto>();  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class DevueltosOtrosDiasDto | ||||||
|  |     { | ||||||
|  |         public int Devueltos { get; set; } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class ListadoDistribucionCanillasResponseDto | ||||||
|  |     { | ||||||
|  |         public IEnumerable<ListadoDistribucionCanillasSimpleDto> DetalleSimple { get; set; } = new List<ListadoDistribucionCanillasSimpleDto>(); | ||||||
|  |         public IEnumerable<ListadoDistribucionCanillasPromedioDiaDto> PromediosPorDia { get; set; } = new List<ListadoDistribucionCanillasPromedioDiaDto>(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class ListadoDistribucionGeneralResponseDto | ||||||
|  |     { | ||||||
|  |         public IEnumerable<ListadoDistribucionGeneralResumenDto> Resumen { get; set; } = new List<ListadoDistribucionGeneralResumenDto>(); | ||||||
|  |         public IEnumerable<ListadoDistribucionGeneralPromedioDiaDto> PromediosPorDia { get; set; } = new List<ListadoDistribucionGeneralPromedioDiaDto>(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,10 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class MovimientoBobinasPorEstadoResponseDto | ||||||
|  |     { | ||||||
|  |         public IEnumerable<MovimientoBobinaEstadoDetalleDto> Detalle { get; set; } = new List<MovimientoBobinaEstadoDetalleDto>(); | ||||||
|  |         public IEnumerable<MovimientoBobinaEstadoTotalDto> Totales { get; set; } = new List<MovimientoBobinaEstadoTotalDto>(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -2,6 +2,6 @@ namespace GestionIntegral.Api.Dtos.Reportes | |||||||
| { | { | ||||||
|     public class ObtenerCtrlDevolucionesDto |     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; } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -0,0 +1,14 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class ReporteCuentasDistribuidorResponseDto | ||||||
|  |     { | ||||||
|  |         public IEnumerable<BalanceCuentaDistDto> EntradasSalidas { get; set; } = new List<BalanceCuentaDistDto>(); | ||||||
|  |         public IEnumerable<BalanceCuentaDebCredDto> DebitosCreditos { get; set; } = new List<BalanceCuentaDebCredDto>(); | ||||||
|  |         public IEnumerable<BalanceCuentaPagosDto> Pagos { get; set; } = new List<BalanceCuentaPagosDto>(); | ||||||
|  |         public IEnumerable<SaldoDto> Saldos { get; set; } = new List<SaldoDto>(); // 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 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,16 @@ | |||||||
|  | using System.Collections.Generic; | ||||||
|  |  | ||||||
|  | namespace GestionIntegral.Api.Dtos.Reportes | ||||||
|  | { | ||||||
|  |     public class ReporteDistribucionCanillasResponseDto | ||||||
|  |     { | ||||||
|  |         public IEnumerable<DetalleDistribucionCanillaDto> Canillas { get; set; } = new List<DetalleDistribucionCanillaDto>(); | ||||||
|  |         public IEnumerable<DetalleDistribucionCanillaDto> CanillasAccionistas { get; set; } = new List<DetalleDistribucionCanillaDto>(); | ||||||
|  |         public IEnumerable<DetalleDistribucionCanillaAllDto> CanillasTodos { get; set; } = new List<DetalleDistribucionCanillaAllDto>(); | ||||||
|  |         public IEnumerable<DetalleDistribucionCanillaDto> CanillasLiquidadasOtraFecha { get; set; } = new List<DetalleDistribucionCanillaDto>(); | ||||||
|  |         public IEnumerable<DetalleDistribucionCanillaDto> CanillasAccionistasLiquidadasOtraFecha { get; set; } = new List<DetalleDistribucionCanillaDto>(); | ||||||
|  |         public IEnumerable<ObtenerCtrlDevolucionesDto> ControlDevolucionesRemitos { get; set; } = new List<ObtenerCtrlDevolucionesDto>(); | ||||||
|  |         public IEnumerable<ControlDevolucionesReporteDto> ControlDevolucionesDetalle { get; set; } = new List<ControlDevolucionesReporteDto>(); | ||||||
|  |         public IEnumerable<DevueltosOtrosDiasDto> ControlDevolucionesOtrosDias { get; set; } = new List<DevueltosOtrosDiasDto>(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -1,4 +1,3 @@ | |||||||
| // src/Services/Reportes/IReportesService.cs |  | ||||||
| using GestionIntegral.Api.Dtos.Reportes; | using GestionIntegral.Api.Dtos.Reportes; | ||||||
| using System; | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| @@ -33,10 +32,11 @@ namespace GestionIntegral.Api.Services.Reportes | |||||||
|             IEnumerable<DetalleDistribucionCanillaAllDto> CanillasAll, |             IEnumerable<DetalleDistribucionCanillaAllDto> CanillasAll, | ||||||
|             IEnumerable<DetalleDistribucionCanillaDto> CanillasFechaLiq, |             IEnumerable<DetalleDistribucionCanillaDto> CanillasFechaLiq, | ||||||
|             IEnumerable<DetalleDistribucionCanillaDto> CanillasAccFechaLiq, |             IEnumerable<DetalleDistribucionCanillaDto> CanillasAccFechaLiq, | ||||||
|             IEnumerable<ObtenerCtrlDevolucionesDto> CtrlDevoluciones, |             IEnumerable<ObtenerCtrlDevolucionesDto> CtrlDevolucionesRemitos, // Para SP_ObtenerCtrlDevoluciones | ||||||
|             IEnumerable<ControlDevolucionesReporteDto> CtrlDevolucionesParaDistCan, |             IEnumerable<ControlDevolucionesReporteDto> CtrlDevolucionesParaDistCan, // Para SP_DistCanillasCantidadEntradaSalida | ||||||
|  |             IEnumerable<DevueltosOtrosDiasDto> CtrlDevolucionesOtrosDias, // <--- NUEVO para SP_DistCanillasCantidadEntradaSalidaOtrosDias | ||||||
|             string? Error |             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) |         // Reporte Tiradas por Publicación y Secciones (RR008) | ||||||
|         Task<(IEnumerable<TiradasPublicacionesSeccionesDto> Data, string? Error)> ObtenerTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); |         Task<(IEnumerable<TiradasPublicacionesSeccionesDto> Data, string? Error)> ObtenerTiradasPublicacionesSeccionesAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta, int idPlanta); | ||||||
|   | |||||||
| @@ -1,4 +1,3 @@ | |||||||
| // src/Services/Reportes/ReportesService.cs |  | ||||||
| using GestionIntegral.Api.Data.Repositories.Reportes; | using GestionIntegral.Api.Data.Repositories.Reportes; | ||||||
| using GestionIntegral.Api.Dtos.Reportes; | using GestionIntegral.Api.Dtos.Reportes; | ||||||
| using Microsoft.Extensions.Logging; | using Microsoft.Extensions.Logging; | ||||||
| @@ -91,7 +90,8 @@ namespace GestionIntegral.Api.Services.Reportes | |||||||
|                 var detalle = await _reportesRepository.GetMovimientoBobinasEstadoDetalleAsync(fechaDesde.Date, fechaHasta.Date, idPlanta); |                 var detalle = await _reportesRepository.GetMovimientoBobinasEstadoDetalleAsync(fechaDesde.Date, fechaHasta.Date, idPlanta); | ||||||
|                 var totales = await _reportesRepository.GetMovimientoBobinasEstadoTotalesAsync(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); |                     d.FechaMovimiento = DateTime.SpecifyKind(d.FechaMovimiento, DateTimeKind.Utc); | ||||||
|                     return d; |                     return d; | ||||||
|                 }).ToList(); |                 }).ToList(); | ||||||
| @@ -214,8 +214,9 @@ namespace GestionIntegral.Api.Services.Reportes | |||||||
|     IEnumerable<DetalleDistribucionCanillaAllDto> CanillasAll, |     IEnumerable<DetalleDistribucionCanillaAllDto> CanillasAll, | ||||||
|     IEnumerable<DetalleDistribucionCanillaDto> CanillasFechaLiq, |     IEnumerable<DetalleDistribucionCanillaDto> CanillasFechaLiq, | ||||||
|     IEnumerable<DetalleDistribucionCanillaDto> CanillasAccFechaLiq, |     IEnumerable<DetalleDistribucionCanillaDto> CanillasAccFechaLiq, | ||||||
|             IEnumerable<ObtenerCtrlDevolucionesDto> CtrlDevoluciones, |     IEnumerable<ObtenerCtrlDevolucionesDto> CtrlDevolucionesRemitos, | ||||||
|     IEnumerable<ControlDevolucionesReporteDto> CtrlDevolucionesParaDistCan, |     IEnumerable<ControlDevolucionesReporteDto> CtrlDevolucionesParaDistCan, | ||||||
|  |     IEnumerable<DevueltosOtrosDiasDto> CtrlDevolucionesOtrosDias, | ||||||
|     string? Error |     string? Error | ||||||
| )> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa) | )> ObtenerReporteDistribucionCanillasAsync(DateTime fecha, int idEmpresa) | ||||||
|         { |         { | ||||||
| @@ -226,10 +227,16 @@ namespace GestionIntegral.Api.Services.Reportes | |||||||
|                 var canillasAllTask = _reportesRepository.GetDetalleDistribucionCanillasAllPubliAsync(fecha, idEmpresa); |                 var canillasAllTask = _reportesRepository.GetDetalleDistribucionCanillasAllPubliAsync(fecha, idEmpresa); | ||||||
|                 var canillasFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasPubliFechaLiqAsync(fecha, idEmpresa); |                 var canillasFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasPubliFechaLiqAsync(fecha, idEmpresa); | ||||||
|                 var canillasAccFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(fecha, idEmpresa); |                 var canillasAccFechaLiqTask = _reportesRepository.GetDetalleDistribucionCanillasAccPubliFechaLiqAsync(fecha, idEmpresa); | ||||||
|                 var ctrlDevolucionesTask = _reportesRepository.GetReporteObtenerCtrlDevolucionesAsync(fecha, idEmpresa); |                 var ctrlDevolucionesRemitosTask = _reportesRepository.GetReporteObtenerCtrlDevolucionesAsync(fecha, idEmpresa); // SP_ObtenerCtrlDevoluciones | ||||||
|                 var ctrlDevolucionesParaDistCanTask = _reportesRepository.GetReporteCtrlDevolucionesParaDistCanAsync(fecha, idEmpresa); |                 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<DetalleDistribucionCanillaDto>, IEnumerable<DetalleDistribucionCanillaDto>> toUtc = |                 Func<IEnumerable<DetalleDistribucionCanillaDto>, IEnumerable<DetalleDistribucionCanillaDto>> toUtc = | ||||||
|                     items => items?.Select(c => { if (c.Fecha.HasValue) c.Fecha = DateTime.SpecifyKind(c.Fecha.Value.Date, DateTimeKind.Utc); return c; }).ToList() |                     items => items?.Select(c => { if (c.Fecha.HasValue) c.Fecha = DateTime.SpecifyKind(c.Fecha.Value.Date, DateTimeKind.Utc); return c; }).ToList() | ||||||
| @@ -241,8 +248,9 @@ namespace GestionIntegral.Api.Services.Reportes | |||||||
|                     await canillasAllTask ?? Enumerable.Empty<DetalleDistribucionCanillaAllDto>(), |                     await canillasAllTask ?? Enumerable.Empty<DetalleDistribucionCanillaAllDto>(), | ||||||
|                     toUtc(await canillasFechaLiqTask), |                     toUtc(await canillasFechaLiqTask), | ||||||
|                     toUtc(await canillasAccFechaLiqTask), |                     toUtc(await canillasAccFechaLiqTask), | ||||||
|                     await ctrlDevolucionesTask ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>(), |                     await ctrlDevolucionesRemitosTask ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>(), | ||||||
|                     await ctrlDevolucionesParaDistCanTask ?? Enumerable.Empty<ControlDevolucionesReporteDto>(), |                     await ctrlDevolucionesParaDistCanTask ?? Enumerable.Empty<ControlDevolucionesReporteDto>(), | ||||||
|  |                     await ctrlDevolucionesOtrosDiasTask ?? Enumerable.Empty<DevueltosOtrosDiasDto>(), | ||||||
|                     null |                     null | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
| @@ -257,6 +265,7 @@ namespace GestionIntegral.Api.Services.Reportes | |||||||
|                     Enumerable.Empty<DetalleDistribucionCanillaDto>(), |                     Enumerable.Empty<DetalleDistribucionCanillaDto>(), | ||||||
|                     Enumerable.Empty<ObtenerCtrlDevolucionesDto>(), |                     Enumerable.Empty<ObtenerCtrlDevolucionesDto>(), | ||||||
|                     Enumerable.Empty<ControlDevolucionesReporteDto>(), |                     Enumerable.Empty<ControlDevolucionesReporteDto>(), | ||||||
|  |                     Enumerable.Empty<DevueltosOtrosDiasDto>(), | ||||||
|                     "Error interno al generar el reporte de distribución de canillas." |                     "Error interno al generar el reporte de distribución de canillas." | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("GestionIntegral.Api")] | [assembly: System.Reflection.AssemblyCompanyAttribute("GestionIntegral.Api")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [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.AssemblyProductAttribute("GestionIntegral.Api")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("GestionIntegral.Api")] | [assembly: System.Reflection.AssemblyTitleAttribute("GestionIntegral.Api")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -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":{}} | {"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":{}} | ||||||
| @@ -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":{}} | {"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":{}} | ||||||
| @@ -90,11 +90,6 @@ const MainLayoutWrapper: React.FC = () => ( | |||||||
|   </MainLayout> |   </MainLayout> | ||||||
| ); | ); | ||||||
|  |  | ||||||
| // Placeholder simple |  | ||||||
| const PlaceholderPage: React.FC<{ moduleName: string }> = ({ moduleName }) => ( |  | ||||||
|   <Typography variant="h5" sx={{ p: 2 }}>Página Principal del Módulo: {moduleName}</Typography> |  | ||||||
| ); |  | ||||||
|  |  | ||||||
| const AppRoutes = () => { | const AppRoutes = () => { | ||||||
|   return ( |   return ( | ||||||
|     <BrowserRouter> |     <BrowserRouter> | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user