Ajustes de reportes y controles.

Se implementan DataGrid a los reportes y se mejoran los controles de selección y presentación.
This commit is contained in:
2025-05-31 23:48:42 -03:00
parent 1182a4cdee
commit 99532b03f1
35 changed files with 4132 additions and 1363 deletions

View File

@@ -111,7 +111,7 @@ namespace GestionIntegral.Api.Controllers
{
LocalReport report = new LocalReport();
string rdlcPath = consolidado ? "Controllers/Reportes/RDLC/ReporteExistenciaPapelConsolidado.rdlc" : "Controllers/Reportes/RDLC/ReporteExistenciaPapel.rdlc";
using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
report.LoadReportDefinition(fs);
@@ -121,24 +121,28 @@ namespace GestionIntegral.Api.Controllers
var parameters = new List<ReportParameter>();
parameters.Add(new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")));
parameters.Add(new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")));
string nombrePlantaParam = "Consolidado";
if (!consolidado && idPlanta.HasValue)
{
var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value);
nombrePlantaParam = planta?.Nombre ?? "N/A";
} else if (consolidado) {
// Para el consolidado, el RDLC ReporteExistenciaPapelConsolidado.txt NO espera NomPlanta
}
else { // No consolidado pero idPlanta es NULL (aunque el servicio ya valida esto)
else if (consolidado)
{
// Para el consolidado, el RDLC ReporteExistenciaPapelConsolidado.txt NO espera NomPlanta
}
else
{ // No consolidado pero idPlanta es NULL (aunque el servicio ya valida esto)
nombrePlantaParam = "N/A";
}
// Solo añadir NomPlanta si NO es consolidado, porque el RDLC consolidado no lo tiene.
if (!consolidado) {
parameters.Add(new ReportParameter("NomPlanta", nombrePlantaParam));
if (!consolidado)
{
parameters.Add(new ReportParameter("NomPlanta", nombrePlantaParam));
}
report.SetParameters(parameters);
byte[] pdfBytes = report.Render("PDF");
@@ -165,7 +169,7 @@ namespace GestionIntegral.Api.Controllers
var (data, error) = await _reportesService.ObtenerMovimientoBobinasAsync(fechaDesde, fechaHasta, idPlanta); // <--- CORREGIDO
if (error != null) return BadRequest(new { message = error });
return Ok(data);
}
@@ -180,7 +184,7 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] int idPlanta)
{
if (!TienePermiso(PermisoVerReporteMovimientoBobinas)) return Forbid();
var (data, error) = await _reportesService.ObtenerMovimientoBobinasAsync(fechaDesde, fechaHasta, idPlanta); // <--- CORREGIDO
if (error != null) return BadRequest(new { message = error });
@@ -203,7 +207,7 @@ namespace GestionIntegral.Api.Controllers
parameters.Add(new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")));
parameters.Add(new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")));
parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A"));
report.SetParameters(parameters);
byte[] pdfBytes = report.Render("PDF");
@@ -233,10 +237,10 @@ namespace GestionIntegral.Api.Controllers
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." });
return NotFound(new { message = "No hay datos para el reporte de movimiento de bobinas por estado." });
}
var response = new MovimientoBobinasPorEstadoResponseDto
@@ -244,7 +248,7 @@ namespace GestionIntegral.Api.Controllers
Detalle = detalle ?? Enumerable.Empty<MovimientoBobinaEstadoDetalleDto>(),
Totales = totales ?? Enumerable.Empty<MovimientoBobinaEstadoTotalDto>()
};
return Ok(response);
}
@@ -265,9 +269,9 @@ namespace GestionIntegral.Api.Controllers
if (error != null) return BadRequest(new { message = error });
if ((detalle == null || !detalle.Any()) && (totales == null || !totales.Any()))
{
return NotFound(new { message = "No hay datos para generar el PDF del movimiento de bobinas por estado con los parámetros seleccionados." });
return NotFound(new { message = "No hay datos para generar el PDF del movimiento de bobinas por estado con los parámetros seleccionados." });
}
try
{
LocalReport report = new LocalReport();
@@ -275,15 +279,15 @@ namespace GestionIntegral.Api.Controllers
{
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSMovimientoBobinasEstado", detalle ?? new List<MovimientoBobinaEstadoDetalleDto>()));
report.DataSources.Add(new ReportDataSource("DSMovimientoBobinasEstadoTotales", totales ?? new List<MovimientoBobinaEstadoTotalDto>()));
report.DataSources.Add(new ReportDataSource("DSMovimientoBobinasEstado", detalle ?? new List<MovimientoBobinaEstadoDetalleDto>()));
report.DataSources.Add(new ReportDataSource("DSMovimientoBobinasEstadoTotales", totales ?? new List<MovimientoBobinaEstadoTotalDto>()));
var planta = await _plantaRepository.GetByIdAsync(idPlanta);
var parameters = new List<ReportParameter>();
parameters.Add(new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")));
parameters.Add(new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")));
parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A"));
report.SetParameters(parameters);
byte[] pdfBytes = report.Render("PDF");
@@ -305,7 +309,7 @@ namespace GestionIntegral.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetListadoDistribucionGeneral(
[FromQuery] int idPublicacion,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta)
{
if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid();
@@ -397,7 +401,7 @@ namespace GestionIntegral.Api.Controllers
{
return NotFound(new { message = "No hay datos para el listado de distribución de canillas." });
}
var response = new ListadoDistribucionCanillasResponseDto
{
DetalleSimple = simple ?? Enumerable.Empty<ListadoDistribucionCanillasSimpleDto>(),
@@ -478,10 +482,10 @@ namespace GestionIntegral.Api.Controllers
{
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)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
@@ -491,7 +495,7 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] int idPublicacion,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta,
[FromQuery] bool esAccionista)
[FromQuery] bool esAccionista)
{
if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid();
@@ -506,7 +510,7 @@ namespace GestionIntegral.Api.Controllers
try
{
LocalReport report = new LocalReport();
using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteListadoDistribucionCanImp.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteListadoDistribucionCanImp.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
report.LoadReportDefinition(fs);
}
@@ -518,10 +522,10 @@ namespace GestionIntegral.Api.Controllers
new ReportParameter("NomPubli", publicacion?.Nombre ?? "N/A"),
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy")),
new ReportParameter("CanAcc", esAccionista ? "1" : "0")
new ReportParameter("CanAcc", esAccionista ? "1" : "0")
};
report.SetParameters(parameters);
byte[] pdfBytes = report.Render("PDF");
string tipoVendedor = esAccionista ? "Accionistas" : "Canillitas";
string fileName = $"ListadoDistCanImp_Pub{idPublicacion}_{tipoVendedor}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf";
@@ -565,7 +569,7 @@ namespace GestionIntegral.Api.Controllers
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", data)); // Basado en el RDLC
report.SetParameters(new[] {
report.SetParameters(new[] {
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))
});
@@ -597,7 +601,7 @@ namespace GestionIntegral.Api.Controllers
var (data, error) = await _reportesService.ObtenerVentaMensualSecretariaElPlataAsync(fechaDesde, fechaHasta);
if (error != null) return BadRequest(new { message = error });
if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para el reporte." });
try
{
LocalReport report = new LocalReport();
@@ -606,7 +610,7 @@ namespace GestionIntegral.Api.Controllers
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", data)); // Basado en el RDLC
report.SetParameters(new[] {
report.SetParameters(new[] {
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))
});
@@ -630,7 +634,7 @@ namespace GestionIntegral.Api.Controllers
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<IActionResult> GetVentaMensualSecretariaTirDevoPdf([FromQuery] DateTime fechaDesde, [FromQuery] DateTime fechaHasta)
{
@@ -638,7 +642,7 @@ namespace GestionIntegral.Api.Controllers
var (data, error) = await _reportesService.ObtenerVentaMensualSecretariaTirDevoAsync(fechaDesde, fechaHasta);
if (error != null) return BadRequest(new { message = error });
if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para el reporte." });
try
{
LocalReport report = new LocalReport();
@@ -647,7 +651,7 @@ namespace GestionIntegral.Api.Controllers
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", data)); // Basado en el RDLC
report.SetParameters(new[] {
report.SetParameters(new[] {
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))
});
@@ -667,12 +671,12 @@ namespace GestionIntegral.Api.Controllers
{
if (!TienePermiso(PermisoVerComprobanteLiquidacionCanilla)) return Forbid();
var (canillas, canillasAcc, canillasAll, canillasFechaLiq, canillasAccFechaLiq,
ctrlDevolucionesRemitos, ctrlDevolucionesParaDistCan, ctrlDevolucionesOtrosDias, error) =
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()) &&
@@ -695,10 +699,10 @@ namespace GestionIntegral.Api.Controllers
ControlDevolucionesDetalle = ctrlDevolucionesParaDistCan ?? Enumerable.Empty<ControlDevolucionesReporteDto>(),
ControlDevolucionesOtrosDias = ctrlDevolucionesOtrosDias ?? Enumerable.Empty<DevueltosOtrosDiasDto>()
};
return Ok(response);
}
[HttpGet("distribucion-canillas/pdf")]
public async Task<IActionResult> GetReporteDistribucionCanillasPdf([FromQuery] DateTime fecha, [FromQuery] int idEmpresa, [FromQuery] bool soloTotales = false)
{
@@ -706,24 +710,24 @@ namespace GestionIntegral.Api.Controllers
// CORRECCIÓN AQUÍ: Añadir la variable para el nuevo elemento de la tupla
var (
canillas,
canillasAcc,
canillasAll,
canillasFechaLiq,
canillasAccFechaLiq,
canillas,
canillasAcc,
canillasAll,
canillasFechaLiq,
canillasAccFechaLiq,
ctrlDevolucionesRemitos, // Renombrado para claridad
ctrlDevolucionesParaDistCan,
_ , // Descartamos ctrlDevolucionesOtrosDias si no se usa aquí
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()) &&
(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()) &&
@@ -739,12 +743,12 @@ namespace GestionIntegral.Api.Controllers
{
LocalReport report = new LocalReport();
string rdlcPath = soloTotales ? "Controllers/Reportes/RDLC/ReporteDistribucionCanillasTotales.rdlc" : "Controllers/Reportes/RDLC/ReporteDistribucionCanillas.rdlc";
using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCan", canillas ?? new List<DetalleDistribucionCanillaDto>()));
report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanAcc", canillasAcc ?? new List<DetalleDistribucionCanillaDto>()));
report.DataSources.Add(new ReportDataSource("DSListadoDistribucionCanALL", canillasAll ?? new List<DetalleDistribucionCanillaAllDto>()));
@@ -796,7 +800,7 @@ namespace GestionIntegral.Api.Controllers
) = 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()) &&
@@ -811,18 +815,18 @@ namespace GestionIntegral.Api.Controllers
DevolucionesOtrosDias = ctrlDevolucionesOtrosDiasData ?? Enumerable.Empty<DevueltosOtrosDiasDto>(),
RemitosIngresados = ctrlDevolucionesRemitosData ?? Enumerable.Empty<ObtenerCtrlDevolucionesDto>()
};
return Ok(response);
}
[HttpGet("control-devoluciones/pdf")]
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 (
_, _, _, _, _,
_, _, _, _, _,
ctrlDevolucionesRemitosData, // Para DSObtenerCtrlDevoluciones
ctrlDevolucionesParaDistCanData, // Para DSCtrlDevoluciones
ctrlDevolucionesOtrosDiasData, // <--- NUEVO: Para DSCtrlDevolucionesOtrosDias
@@ -830,16 +834,16 @@ namespace GestionIntegral.Api.Controllers
) = await _reportesService.ObtenerReporteDistribucionCanillasAsync(fecha, idEmpresa);
if (error != null) return BadRequest(new { message = error });
// Ajustamos la condición para verificar los DataSets que realmente usa este reporte específico
if ((ctrlDevolucionesRemitosData == null || !ctrlDevolucionesRemitosData.Any()) &&
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." });
}
try
{
LocalReport report = new LocalReport();
@@ -847,13 +851,13 @@ namespace GestionIntegral.Api.Controllers
{
report.LoadReportDefinition(fs);
}
// DataSet que usa SP_DistCanillasCantidadEntradaSalida
report.DataSources.Add(new ReportDataSource("DSCtrlDevoluciones", ctrlDevolucionesParaDistCanData ?? new List<ControlDevolucionesReporteDto>()));
// 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>()));
@@ -891,15 +895,15 @@ namespace GestionIntegral.Api.Controllers
{
if (!TienePermiso(PermisoVerBalanceCuentas)) return Forbid();
var (entradasSalidas, debitosCreditos, pagos, saldos, error) =
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." });
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);
@@ -912,7 +916,7 @@ namespace GestionIntegral.Api.Controllers
NombreDistribuidor = distribuidor.Distribuidor?.Nombre,
NombreEmpresa = empresa?.Nombre
};
return Ok(response);
}
@@ -925,13 +929,13 @@ namespace GestionIntegral.Api.Controllers
{
if (!TienePermiso(PermisoVerBalanceCuentas)) return Forbid();
var (entradasSalidas, debitosCreditos, pagos, saldos, error) =
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." });
return NotFound(new { message = "No hay datos para generar el reporte de cuenta del distribuidor." });
}
try
@@ -946,7 +950,7 @@ namespace GestionIntegral.Api.Controllers
report.DataSources.Add(new ReportDataSource("DSDistribuidoresDebCred", debitosCreditos ?? new List<BalanceCuentaDebCredDto>()));
report.DataSources.Add(new ReportDataSource("DSDistribuidoresPagos", pagos ?? new List<BalanceCuentaPagosDto>()));
report.DataSources.Add(new ReportDataSource("DSDistribuidoresSaldos", saldos ?? new List<SaldoDto>()));
var parameters = new List<ReportParameter>
{
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
@@ -973,9 +977,9 @@ namespace GestionIntegral.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetReporteTiradasPublicacionesSeccionesData(
[FromQuery] int idPublicacion,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta,
[FromQuery] int? idPlanta,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta,
[FromQuery] int? idPlanta,
[FromQuery] bool consolidado = false)
{
if (!TienePermiso(PermisoVerReporteTiradas)) return Forbid();
@@ -992,7 +996,7 @@ namespace GestionIntegral.Api.Controllers
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." });
@@ -1002,9 +1006,9 @@ namespace GestionIntegral.Api.Controllers
[HttpGet("tiradas-publicaciones-secciones/pdf")]
public async Task<IActionResult> GetReporteTiradasPublicacionesSeccionesPdf(
[FromQuery] int idPublicacion,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta,
[FromQuery] int? idPlanta,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta,
[FromQuery] int? idPlanta,
[FromQuery] bool consolidado = false)
{
if (!TienePermiso(PermisoVerReporteTiradas)) return Forbid();
@@ -1021,15 +1025,15 @@ namespace GestionIntegral.Api.Controllers
if (!idPlanta.HasValue) return BadRequest(new { message = "Se requiere IdPlanta para reportes no consolidados." });
(data, errorMsg) = await _reportesService.ObtenerTiradasPublicacionesSeccionesAsync(idPublicacion, fechaDesde, fechaHasta, idPlanta.Value);
}
if (errorMsg != null) return BadRequest(new { message = errorMsg });
if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." });
try
{
LocalReport report = new LocalReport();
string rdlcPath = consolidado ?
"Controllers/Reportes/RDLC/ReporteTiradasPublicacionesSeccionesConsolidado.rdlc" :
string rdlcPath = consolidado ?
"Controllers/Reportes/RDLC/ReporteTiradasPublicacionesSeccionesConsolidado.rdlc" :
"Controllers/Reportes/RDLC/ReporteTiradasPublicacionesSecciones.rdlc";
using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
@@ -1041,7 +1045,7 @@ namespace GestionIntegral.Api.Controllers
var publicacion = await _publicacionRepository.GetByIdSimpleAsync(idPublicacion);
var parameters = new List<ReportParameter>
{
new ReportParameter("Mes", fechaDesde.ToString("MMMM yyyy")),
new ReportParameter("Mes", fechaDesde.ToString("MMMM yyyy")),
new ReportParameter("NomPubli", publicacion?.Nombre ?? "N/A")
};
if (!consolidado && idPlanta.HasValue)
@@ -1049,7 +1053,7 @@ namespace GestionIntegral.Api.Controllers
var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value);
parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A"));
}
report.SetParameters(parameters);
byte[] pdfBytes = report.Render("PDF");
@@ -1071,7 +1075,7 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] int? idPlanta,
[FromQuery] bool consolidado = false)
{
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
IEnumerable<ConsumoBobinasSeccionDto> data;
string? errorMsg;
@@ -1085,10 +1089,10 @@ namespace GestionIntegral.Api.Controllers
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);
}
@@ -1099,7 +1103,7 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] int? idPlanta,
[FromQuery] bool consolidado = false)
{
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
IEnumerable<ConsumoBobinasSeccionDto> data;
string? errorMsg;
@@ -1113,28 +1117,28 @@ namespace GestionIntegral.Api.Controllers
if (!idPlanta.HasValue) return BadRequest(new { message = "Se requiere IdPlanta para reportes no consolidados." });
(data, errorMsg) = await _reportesService.ObtenerConsumoBobinasPorSeccionAsync(fechaDesde, fechaHasta, idPlanta.Value);
}
if (errorMsg != null) return BadRequest(new { message = errorMsg });
if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." });
try
{
LocalReport report = new LocalReport();
string rdlcPath = consolidado ?
"Controllers/Reportes/RDLC/ReporteConsumoBobinasSeccionConsolidado.rdlc" :
"Controllers/Reportes/RDLC/ReporteConsumoBobinasSeccion.rdlc";
string rdlcPath = consolidado ?
"Controllers/Reportes/RDLC/ReporteConsumoBobinasSeccionConsolidado.rdlc" :
"Controllers/Reportes/RDLC/ReporteConsumoBobinasSeccion.rdlc";
using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSConsumoBobinasSeccion", data));
var parameters = new List<ReportParameter>
{
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))
};
if (!consolidado && idPlanta.HasValue)
if (!consolidado && idPlanta.HasValue)
{
var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value);
parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A"));
@@ -1158,10 +1162,10 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta)
{
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
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." });
@@ -1173,10 +1177,10 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta)
{
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
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." });
@@ -1188,7 +1192,7 @@ namespace GestionIntegral.Api.Controllers
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSConsumoBobinasPublicacion", data));
var parameters = new List<ReportParameter>
{
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
@@ -1215,7 +1219,7 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] int? idPlanta,
[FromQuery] bool consolidado = false)
{
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
IEnumerable<ComparativaConsumoBobinasDto> data;
string? errorMsg;
@@ -1229,7 +1233,7 @@ namespace GestionIntegral.Api.Controllers
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." });
@@ -1243,7 +1247,7 @@ namespace GestionIntegral.Api.Controllers
[FromQuery] int? idPlanta,
[FromQuery] bool consolidado = false)
{
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
if (!TienePermiso(PermisoVerReporteConsumoBobinas)) return Forbid();
IEnumerable<ComparativaConsumoBobinasDto> data;
string? errorMsg;
@@ -1257,15 +1261,15 @@ namespace GestionIntegral.Api.Controllers
if (!idPlanta.HasValue) return BadRequest(new { message = "Se requiere IdPlanta para reportes no consolidados." });
(data, errorMsg) = await _reportesService.ObtenerComparativaConsumoBobinasAsync(fechaInicioMesA, fechaFinMesA, fechaInicioMesB, fechaFinMesB, idPlanta.Value);
}
if (errorMsg != null) return BadRequest(new { message = errorMsg });
if (data == null || !data.Any()) return NotFound(new { message = "No hay datos para generar el reporte." });
try
{
LocalReport report = new LocalReport();
string rdlcPath = consolidado ?
"Controllers/Reportes/RDLC/ReporteConsumoBobinasMesesConsolidado.rdlc" :
string rdlcPath = consolidado ?
"Controllers/Reportes/RDLC/ReporteConsumoBobinasMesesConsolidado.rdlc" :
"Controllers/Reportes/RDLC/ReporteConsumoBobinasMeses.rdlc";
using (var fs = new FileStream(rdlcPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
@@ -1273,13 +1277,13 @@ namespace GestionIntegral.Api.Controllers
report.LoadReportDefinition(fs);
}
report.DataSources.Add(new ReportDataSource("DSConsumoBobinasMeses", data));
var parameters = new List<ReportParameter>
{
new ReportParameter("MesA", fechaInicioMesA.ToString("MMMM yyyy")),
new ReportParameter("MesB", fechaInicioMesB.ToString("MMMM yyyy"))
};
if (!consolidado && idPlanta.HasValue)
if (!consolidado && idPlanta.HasValue)
{
var planta = await _plantaRepository.GetByIdAsync(idPlanta.Value);
parameters.Add(new ReportParameter("NomPlanta", planta?.Nombre ?? "N/A"));
@@ -1292,5 +1296,93 @@ namespace GestionIntegral.Api.Controllers
}
catch (Exception ex) { _logger.LogError(ex, "Error PDF Comparativa Consumo Bobinas."); return StatusCode(500, "Error interno."); }
}
// GET: api/reportes/listado-distribucion-distribuidores
[HttpGet("listado-distribucion-distribuidores")]
[ProducesResponseType(typeof(ListadoDistribucionDistribuidoresResponseDto), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetListadoDistribucionDistribuidores(
[FromQuery] int idDistribuidor,
[FromQuery] int idPublicacion,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta)
{
if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid(); // RR002
(IEnumerable<ListadoDistribucionDistSimpleDto> simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> promedios, string? error) result =
await _reportesService.ObtenerListadoDistribucionDistribuidoresAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
if (result.error != null) return BadRequest(new { message = result.error });
if ((result.simple == null || !result.simple.Any()) && (result.promedios == null || !result.promedios.Any()))
{
return NotFound(new { message = "No hay datos para el listado de distribución de distribuidores." });
}
var response = new ListadoDistribucionDistribuidoresResponseDto
{
DetalleSimple = result.simple ?? Enumerable.Empty<ListadoDistribucionDistSimpleDto>(),
PromediosPorDia = result.promedios ?? Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>()
};
return Ok(response);
}
[HttpGet("listado-distribucion-distribuidores/pdf")]
[ProducesResponseType(typeof(FileContentResult), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<IActionResult> GetListadoDistribucionDistribuidoresPdf(
[FromQuery] int idDistribuidor,
[FromQuery] int idPublicacion,
[FromQuery] DateTime fechaDesde,
[FromQuery] DateTime fechaHasta)
{
if (!TienePermiso(PermisoVerListadoDistribucion)) return Forbid();
var (simple, promedios, error) = await _reportesService.ObtenerListadoDistribucionDistribuidoresAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
if (error != null) return BadRequest(new { message = error });
if ((simple == null || !simple.Any()) && (promedios == null || !promedios.Any()))
{
return NotFound(new { message = "No hay datos para generar el PDF." });
}
try
{
LocalReport report = new LocalReport();
// USAREMOS EL MISMO RDLC QUE PARA CANILLITAS, YA QUE TIENE LA MISMA ESTRUCTURA DE DATASOURCES
using (var fs = new FileStream("Controllers/Reportes/RDLC/ReporteListadoDistribucion.rdlc", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
report.LoadReportDefinition(fs);
}
// Nombres de DataSources deben coincidir con los del RDLC
report.DataSources.Add(new ReportDataSource("DSListadoDistribucion", simple ?? new List<ListadoDistribucionDistSimpleDto>()));
report.DataSources.Add(new ReportDataSource("DSListadoDistribucionAgDias", promedios ?? new List<ListadoDistribucionDistPromedioDiaDto>()));
var publicacionData = await _publicacionRepository.GetByIdAsync(idPublicacion);
var distribuidorData = await _distribuidorRepository.GetByIdAsync(idDistribuidor);
var parameters = new List<ReportParameter>
{
new ReportParameter("NomPubli", publicacionData.Publicacion?.Nombre ?? "N/A"),
new ReportParameter("NomDist", distribuidorData.Distribuidor?.Nombre ?? "N/A"), // Parámetro para el RDLC
new ReportParameter("FechaDesde", fechaDesde.ToString("dd/MM/yyyy")),
new ReportParameter("FechaHasta", fechaHasta.ToString("dd/MM/yyyy"))
};
report.SetParameters(parameters);
byte[] pdfBytes = report.Render("PDF");
string fileName = $"ListadoDistribucion_Dist{idDistribuidor}_Pub{idPublicacion}_{fechaDesde:yyyyMMdd}_{fechaHasta:yyyyMMdd}.pdf";
return File(pdfBytes, "application/pdf", fileName);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al generar PDF para Listado Distribucion (Distribuidores).");
return StatusCode(StatusCodes.Status500InternalServerError, "Error interno al generar el PDF del reporte.");
}
}
}
}

View File

@@ -11,8 +11,6 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes
Task<IEnumerable<MovimientoBobinasDto>> GetMovimientoBobinasAsync(DateTime fechaInicio, int diasPeriodo, int idPlanta);
Task<IEnumerable<MovimientoBobinaEstadoDetalleDto>> GetMovimientoBobinasEstadoDetalleAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta);
Task<IEnumerable<MovimientoBobinaEstadoTotalDto>> GetMovimientoBobinasEstadoTotalesAsync(DateTime fechaInicio, DateTime fechaFin, int idPlanta);
// --- MÉTODOS AÑADIDOS AQUÍ ---
Task<IEnumerable<ListadoDistribucionGeneralResumenDto>> GetListadoDistribucionGeneralResumenAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
Task<IEnumerable<ListadoDistribucionGeneralPromedioDiaDto>> GetListadoDistribucionGeneralPromedioDiaAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
Task<IEnumerable<ListadoDistribucionCanillasSimpleDto>> GetListadoDistribucionCanillasSimpleAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
@@ -40,5 +38,8 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes
Task<IEnumerable<BalanceCuentaDebCredDto>> GetBalanceCuentDistDebCredEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta);
Task<IEnumerable<BalanceCuentaPagosDto>> GetBalanceCuentDistPagosEmpresaAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta);
Task<IEnumerable<SaldoDto>> GetBalanceCuentSaldosEmpresasAsync(string destino, int idDestino, int idEmpresa);
Task<IEnumerable<ListadoDistribucionDistSimpleDto>> GetListadoDistribucionDistSimpleAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
Task<IEnumerable<ListadoDistribucionDistPromedioDiaDto>> GetListadoDistribucionDistPromedioDiaAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
Task<(IEnumerable<ListadoDistribucionDistSimpleDto> Simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionDistribuidoresAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
}
}

View File

@@ -132,7 +132,6 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes
}
}
// Implementaciones que faltaban
public async Task<IEnumerable<ListadoDistribucionGeneralResumenDto>> GetListadoDistribucionGeneralResumenAsync(int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
{
const string spName = "dbo.SP_DistObtenerResumenMensual";
@@ -419,5 +418,66 @@ namespace GestionIntegral.Api.Data.Repositories.Reportes
try { using var connection = _dbConnectionFactory.CreateConnection(); return await connection.QueryAsync<SaldoDto>(spName, parameters, commandType: CommandType.StoredProcedure); }
catch (Exception ex) { _logger.LogError(ex, "Error SP {SPName}", spName); return Enumerable.Empty<SaldoDto>(); }
}
public async Task<IEnumerable<ListadoDistribucionDistSimpleDto>> GetListadoDistribucionDistSimpleAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
{
const string spName = "dbo.SP_CantidadEntradaSalida";
var parameters = new DynamicParameters();
parameters.Add("@idDistribuidor", idDistribuidor, DbType.Int32);
parameters.Add("@idPublicacion", idPublicacion, DbType.Int32);
parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime);
parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime);
try
{
using var connection = _dbConnectionFactory.CreateConnection(); // <--- CORREGIDO AQUÍ
return await connection.QueryAsync<ListadoDistribucionDistSimpleDto>(spName, parameters, commandType: CommandType.StoredProcedure);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al ejecutar SP {SPName} para Listado Distribucion Distribuidores (Simple). Params: Dist={idDistribuidor}, Pub={idPublicacion}, Desde={fechaDesde}, Hasta={fechaHasta}", spName, idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
return Enumerable.Empty<ListadoDistribucionDistSimpleDto>();
}
}
public async Task<IEnumerable<ListadoDistribucionDistPromedioDiaDto>> GetListadoDistribucionDistPromedioDiaAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
{
const string spName = "dbo.SP_CantidadEntradaSalidaCPromAgDia";
var parameters = new DynamicParameters();
parameters.Add("@idDistribuidor", idDistribuidor, DbType.Int32);
parameters.Add("@idPublicacion", idPublicacion, DbType.Int32);
parameters.Add("@fechaDesde", fechaDesde, DbType.DateTime);
parameters.Add("@fechaHasta", fechaHasta, DbType.DateTime);
try
{
using var connection = _dbConnectionFactory.CreateConnection(); // <--- CORREGIDO AQUÍ
return await connection.QueryAsync<ListadoDistribucionDistPromedioDiaDto>(spName, parameters, commandType: CommandType.StoredProcedure);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error al ejecutar SP {SPName} para Listado Distribucion Distribuidores (Promedios). Params: Dist={idDistribuidor}, Pub={idPublicacion}, Desde={fechaDesde}, Hasta={fechaHasta}", spName, idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
return Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>();
}
}
public async Task<(IEnumerable<ListadoDistribucionDistSimpleDto> Simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionDistribuidoresAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
{
if (fechaDesde > fechaHasta)
return (Enumerable.Empty<ListadoDistribucionDistSimpleDto>(), Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
try
{
var simpleDataTask = this.GetListadoDistribucionDistSimpleAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
var promediosDataTask = this.GetListadoDistribucionDistPromedioDiaAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
await Task.WhenAll(simpleDataTask, promediosDataTask);
return (await simpleDataTask, await promediosDataTask, null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion (Distribuidores).");
return (Enumerable.Empty<ListadoDistribucionDistSimpleDto>(), Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>(), "Error interno al generar el reporte.");
}
}
}
}

View File

@@ -0,0 +1,14 @@
namespace GestionIntegral.Api.Dtos.Reportes
{
public class ListadoDistribucionDistPromedioDiaDto
{
public string Dia { get; set; } = string.Empty; // Nombre del día de la semana (Lunes, Martes, etc.)
public int? Cant { get; set; } // Cantidad de días con ese nombre en el período
public int? Llevados { get; set; }
public int? Devueltos { get; set; }
public int? Promedio_Llevados { get; set; }
public int? Promedio_Devueltos { get; set; }
public int? Promedio_Ventas { get; set; }
// public int Dia_Orden { get; set; } // Si el SP devuelve Dia_Orden para ordenar
}
}

View File

@@ -0,0 +1,9 @@
namespace GestionIntegral.Api.Dtos.Reportes
{
public class ListadoDistribucionDistSimpleDto
{
public int Dia { get; set; } // Día del mes
public int? Llevados { get; set; } // Nullable si el SP puede devolver NULL
public int? Devueltos { get; set; } // Nullable si el SP puede devolver NULL
}
}

View File

@@ -0,0 +1,8 @@
namespace GestionIntegral.Api.Dtos.Reportes
{
public class ListadoDistribucionDistribuidoresResponseDto
{
public IEnumerable<ListadoDistribucionDistSimpleDto> DetalleSimple { get; set; } = Enumerable.Empty<ListadoDistribucionDistSimpleDto>();
public IEnumerable<ListadoDistribucionDistPromedioDiaDto> PromediosPorDia { get; set; } = Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>();
}
}

View File

@@ -61,5 +61,7 @@ namespace GestionIntegral.Api.Services.Reportes
IEnumerable<SaldoDto> Saldos,
string? Error
)> ObtenerReporteCuentasDistribuidorAsync(int idDistribuidor, int idEmpresa, DateTime fechaDesde, DateTime fechaHasta);
Task<(IEnumerable<ListadoDistribucionDistSimpleDto> Simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionDistribuidoresAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta);
}
}

View File

@@ -427,5 +427,27 @@ namespace GestionIntegral.Api.Services.Reportes
);
}
}
public async Task<(IEnumerable<ListadoDistribucionDistSimpleDto> Simple, IEnumerable<ListadoDistribucionDistPromedioDiaDto> Promedios, string? Error)> ObtenerListadoDistribucionDistribuidoresAsync(int idDistribuidor, int idPublicacion, DateTime fechaDesde, DateTime fechaHasta)
{
if (fechaDesde > fechaHasta)
return (Enumerable.Empty<ListadoDistribucionDistSimpleDto>(), Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>(), "La fecha 'Desde' no puede ser mayor que la fecha 'Hasta'.");
try
{
// Llamar a los métodos específicos del repositorio
var simpleDataTask = _reportesRepository.GetListadoDistribucionDistSimpleAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
var promediosDataTask = _reportesRepository.GetListadoDistribucionDistPromedioDiaAsync(idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
await Task.WhenAll(simpleDataTask, promediosDataTask);
return (await simpleDataTask, await promediosDataTask, null);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error en ReportesService al obtener Listado Distribucion (Distribuidores). Params: Dist={idDistribuidor}, Pub={idPublicacion}, Desde={fechaDesde}, Hasta={fechaHasta}", idDistribuidor, idPublicacion, fechaDesde, fechaHasta);
return (Enumerable.Empty<ListadoDistribucionDistSimpleDto>(), Enumerable.Empty<ListadoDistribucionDistPromedioDiaDto>(), "Error interno al generar el reporte.");
}
}
}
}

View File

@@ -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+70fc84772161b499c8283a31b7a61246a6bcc46f")]
[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+1182a4cdee4fcdb55dc3f2dbfeeb2ec2187f2bea")]
[assembly: System.Reflection.AssemblyProductAttribute("GestionIntegral.Api")]
[assembly: System.Reflection.AssemblyTitleAttribute("GestionIntegral.Api")]
[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")]

View File

@@ -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=","RFpydTIMf9fxYfNnrif0YQNHLgrUW58SpaLEeCZ9nXg="],"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=","OZUau2FUwouOUoP6Eot2qiZlqRHSBBkSPL6vHtWUfGI="],"CachedAssets":{},"CachedCopyCandidates":{}}

View File

@@ -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=","RFpydTIMf9fxYfNnrif0YQNHLgrUW58SpaLEeCZ9nXg="],"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=","OZUau2FUwouOUoP6Eot2qiZlqRHSBBkSPL6vHtWUfGI="],"CachedAssets":{},"CachedCopyCandidates":{}}