Fix: Alinea cálculos del PDF y web en distribución de canillitas
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 4m16s
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 4m16s
Este commit soluciona varias inconsistencias de cálculo y visualización que existían entre el reporte de distribución para canillitas en la web y el PDF generado.
Los cambios principales incluyen:
- **Cálculo de Promedios Generales:** Se implementa un promedio ponderado utilizando división decimal y redondeo matemático (`MidpointRounding.AwayFromZero`) en el backend. Esto soluciona las diferencias numéricas en los totales ("Prom. Llevados", "Prom. Devueltos", etc.) que eran causadas por la división de enteros.
- **Corrección de % Devolución:** Se ajusta la fórmula en todo el reporte (web y PDF) para calcular correctamente el porcentaje de devolución (`Devueltos / Llevados`) en lugar del porcentaje de venta que se mostraba erróneamente.
- **Orden de Columnas en PDF:** Se corrige el orden de las columnas "Prom. Devueltos" y "Prom. Ventas" que estaban intercambiadas en la fila "General" del PDF.
- **Precisión en Redondeo Final:** Se refina el cálculo del "% Devolución General" para que se base en los totales sin redondear, eliminando una diferencia de 0.01% y logrando una paridad exacta con la interfaz web.
This commit is contained in:
@@ -148,7 +148,7 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
|
||||
foreach (var item in Model.PromediosPorDia.OrderBy(d => dayOrder.GetValueOrDefault(d.Dia, 99)))
|
||||
{
|
||||
var porcDevolucion = item.Llevados > 0 ? (decimal)item.Devueltos * 100 / item.Llevados : 0;
|
||||
var porcDevolucion = item.Promedio_Llevados > 0 ? (decimal)item.Promedio_Devueltos * 100 / item.Promedio_Llevados : 0;
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Cant.ToString("N0"));
|
||||
@@ -162,7 +162,6 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
var general = Model.PromedioGeneral;
|
||||
if (general != null)
|
||||
{
|
||||
var porcDevolucionGeneral = general.Promedio_Llevados > 0 ? (decimal)general.Promedio_Devueltos * 100 / general.Promedio_Llevados : 0;
|
||||
var boldStyle = TextStyle.Default.SemiBold();
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(text => text.Span(general.Dia).Style(boldStyle));
|
||||
@@ -170,7 +169,7 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Promedio_Llevados.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Promedio_Devueltos.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Promedio_Ventas.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(porcDevolucionGeneral.ToString("F2") + "%").Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.PorcentajeDevolucionGeneral.ToString("F2") + "%").Style(boldStyle));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace GestionIntegral.Api.Dtos.Reportes.ViewModels
|
||||
public string FechaDesde { get; set; } = string.Empty;
|
||||
public string FechaHasta { get; set; } = string.Empty;
|
||||
public string FechaReporte { get; set; } = DateTime.Now.ToString("dd/MM/yyyy");
|
||||
|
||||
|
||||
public ListadoDistribucionCanillasSimpleDto TotalesDetalleDiario
|
||||
{
|
||||
get
|
||||
@@ -29,7 +29,23 @@ namespace GestionIntegral.Api.Dtos.Reportes.ViewModels
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public decimal PorcentajeDevolucionGeneral
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PromediosPorDia == null || !PromediosPorDia.Any()) return 0;
|
||||
|
||||
var totalPonderadoLlevados = PromediosPorDia.Sum(p => p.Promedio_Llevados * p.Cant);
|
||||
var totalPonderadoDevueltos = PromediosPorDia.Sum(p => p.Promedio_Devueltos * p.Cant);
|
||||
|
||||
if (totalPonderadoLlevados == 0) return 0;
|
||||
|
||||
// Calculamos el porcentaje usando los totales ponderados para máxima precisión como lo hace el frontend.
|
||||
return (decimal)totalPonderadoDevueltos * 100 / totalPonderadoLlevados;
|
||||
}
|
||||
}
|
||||
|
||||
// --- PROPIEDAD PARA LA FILA "GENERAL" ---
|
||||
public ListadoDistribucionCanillasPromedioDiaDto? PromedioGeneral
|
||||
{
|
||||
@@ -37,20 +53,27 @@ namespace GestionIntegral.Api.Dtos.Reportes.ViewModels
|
||||
{
|
||||
if (PromediosPorDia == null || !PromediosPorDia.Any()) return null;
|
||||
|
||||
// Sumamos los totales, no promediamos los promedios
|
||||
var totalLlevados = PromediosPorDia.Sum(p => p.Llevados);
|
||||
var totalDevueltos = PromediosPorDia.Sum(p => p.Devueltos);
|
||||
// Sumamos los totales ponderados para cada columna
|
||||
var totalPonderadoLlevados = PromediosPorDia.Sum(p => p.Promedio_Llevados * p.Cant);
|
||||
var totalPonderadoDevueltos = PromediosPorDia.Sum(p => p.Promedio_Devueltos * p.Cant);
|
||||
var totalPonderadoVentas = PromediosPorDia.Sum(p => p.Promedio_Ventas * p.Cant);
|
||||
var totalDias = PromediosPorDia.Sum(p => p.Cant);
|
||||
|
||||
if (totalDias == 0) return null;
|
||||
|
||||
// Usamos Math.Round para un redondeo matemático estándar antes de la conversión.
|
||||
// MidpointRounding.AwayFromZero asegura que .5 se redondee hacia arriba, igual que en JavaScript.
|
||||
var promGeneralLlevados = (int)Math.Round((decimal)totalPonderadoLlevados / totalDias, MidpointRounding.AwayFromZero);
|
||||
var promGeneralDevueltos = (int)Math.Round((decimal)totalPonderadoDevueltos / totalDias, MidpointRounding.AwayFromZero);
|
||||
var promGeneralVentas = (int)Math.Round((decimal)totalPonderadoVentas / totalDias, MidpointRounding.AwayFromZero);
|
||||
|
||||
return new ListadoDistribucionCanillasPromedioDiaDto
|
||||
{
|
||||
Dia = "General",
|
||||
Cant = totalDias,
|
||||
Promedio_Llevados = totalLlevados / totalDias,
|
||||
Promedio_Devueltos = totalDevueltos / totalDias,
|
||||
Promedio_Ventas = (totalLlevados - totalDevueltos) / totalDias
|
||||
Promedio_Llevados = promGeneralLlevados,
|
||||
Promedio_Devueltos = promGeneralDevueltos,
|
||||
Promedio_Ventas = promGeneralVentas
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ builder.Services.AddCors(options =>
|
||||
policy =>
|
||||
{
|
||||
policy.WithOrigins(
|
||||
"http://localhost:5174", // Para desarrollo local
|
||||
"http://localhost:5173", // Para desarrollo local
|
||||
"https://gestion.eldiaservicios.com" // Para producción
|
||||
)
|
||||
.AllowAnyHeader()
|
||||
|
||||
Reference in New Issue
Block a user