QuestPdf Implementado en la totalidad de reportes.
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 7m55s
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 7m55s
This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ComparativaConsumoBobinasDocument : IDocument
|
||||
{
|
||||
public ComparativaConsumoBobinasViewModel Model { get; }
|
||||
|
||||
public ComparativaConsumoBobinasDocument(ComparativaConsumoBobinasViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("Reporte de Consumo de Bobinas - Comparativa Mensual").SemiBold().FontSize(14);
|
||||
|
||||
string subTitle = Model.EsConsolidado ? "Consolidado" : $"Planta: {Model.NombrePlanta}";
|
||||
column.Item().AlignCenter().Text(subTitle).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
// Le damos una proporción menor al texto de la izquierda (que es corto y fijo).
|
||||
row.RelativeItem(1).Text(text =>
|
||||
{
|
||||
text.Span("Fecha del Reporte: ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaReporte);
|
||||
});
|
||||
|
||||
// Le damos una proporción mayor al texto de la derecha (que es largo y variable).
|
||||
// El factor "2" significa que tendrá el doble de espacio disponible que el item con factor "1".
|
||||
row.RelativeItem(2).AlignRight().Text(text =>
|
||||
{
|
||||
text.Span("Meses: ").SemiBold().FontSize(12);
|
||||
text.Span($"{Model.MesA} (Mes A) contra {Model.MesB} (Mes B)").FontSize(12);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(3); // Tipo Bobina
|
||||
columns.RelativeColumn(1); columns.RelativeColumn(1); columns.RelativeColumn(1); // Grupo Cantidad
|
||||
columns.RelativeColumn(1); columns.RelativeColumn(1); columns.RelativeColumn(1); // Grupo Kilos
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
// Fila 1 del Encabezado
|
||||
header.Cell().RowSpan(2).Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignMiddle().Text("Tipo Bobina").SemiBold();
|
||||
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Cantidad Bobinas").SemiBold();
|
||||
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Kilos Utilizados").SemiBold();
|
||||
|
||||
// Fila 2 del Encabezado
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Mes A").SemiBold();
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Mes B").SemiBold();
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Diferencia").SemiBold();
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Kg Mes A").SemiBold();
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Kg Mes B").SemiBold();
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Diferencia").SemiBold();
|
||||
});
|
||||
|
||||
foreach (var item in Model.Detalles.OrderBy(x => x.TipoBobina))
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(item.TipoBobina);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.BobinasUtilizadasMesA.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.BobinasUtilizadasMesB.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.DiferenciaBobinasUtilizadas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.KilosUtilizadosMesA.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.KilosUtilizadosMesB.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.DiferenciaKilosUtilizados.ToString("N0"));
|
||||
}
|
||||
|
||||
// Fila de Totales
|
||||
var style = TextStyle.Default.SemiBold();
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span("Totales").Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.BobinasUtilizadasMesA).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.BobinasUtilizadasMesB).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.DiferenciaBobinasUtilizadas).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.KilosUtilizadosMesA).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.KilosUtilizadosMesB).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.DiferenciaKilosUtilizados).ToString("N0")).Style(style));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ConsumoBobinasPublicacionDocument : IDocument
|
||||
{
|
||||
public ConsumoBobinasPublicacionViewModel Model { get; }
|
||||
|
||||
public ConsumoBobinasPublicacionDocument(ConsumoBobinasPublicacionViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("Reporte de Consumo de Bobinas por Publicaciones").SemiBold().FontSize(14);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha del Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2); // Planta
|
||||
columns.RelativeColumn(3); // Publicación
|
||||
columns.RelativeColumn(1.5f); // Kilos
|
||||
columns.RelativeColumn(1.5f); // Cant. Bobinas
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Planta");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Publicación");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Kilos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Bobinas");
|
||||
});
|
||||
|
||||
var gruposPorPlanta = Model.Detalles.GroupBy(p => p.NombrePlanta);
|
||||
|
||||
foreach (var grupoPlanta in gruposPorPlanta)
|
||||
{
|
||||
var primeraFilaDePlanta = true;
|
||||
foreach (var detalle in grupoPlanta.OrderBy(d => d.NombrePublicacion))
|
||||
{
|
||||
// Celda de Planta (solo en la primera fila del grupo)
|
||||
if (primeraFilaDePlanta)
|
||||
{
|
||||
table.Cell().RowSpan((uint)grupoPlanta.Count()).Border(1).Padding(3).AlignTop().Text(grupoPlanta.Key).SemiBold();
|
||||
primeraFilaDePlanta = false;
|
||||
}
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(detalle.NombrePublicacion);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(detalle.TotalKilos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(detalle.CantidadBobinas.ToString("N0"));
|
||||
}
|
||||
}
|
||||
|
||||
// Fila de Totales Generales
|
||||
var totalGeneralKilos = Model.Detalles.Sum(d => d.TotalKilos);
|
||||
var totalGeneralBobinas = Model.Detalles.Sum(d => d.CantidadBobinas);
|
||||
|
||||
table.Cell().ColumnSpan(2).BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text("Totales").ExtraBold();
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text(t => t.Span(totalGeneralKilos.ToString("N0")).ExtraBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text(t => t.Span(totalGeneralBobinas.ToString("N0")).ExtraBold());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes;
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ConsumoBobinasSeccionDocument : IDocument
|
||||
{
|
||||
public ConsumoBobinasSeccionViewModel Model { get; }
|
||||
|
||||
public ConsumoBobinasSeccionDocument(ConsumoBobinasSeccionViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("Reporte de Consumo de Bobinas por Secciones").SemiBold().FontSize(14);
|
||||
|
||||
string subTitle = Model.EsConsolidado ? "Consolidado" : $"Planta: {Model.NombrePlanta}";
|
||||
column.Item().AlignCenter().Text(subTitle).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha del Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
|
||||
// Encabezado de la tabla principal
|
||||
column.Item().PaddingTop(10).BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).Row(row =>
|
||||
{
|
||||
row.RelativeItem(1.5f).Text("Publicación").SemiBold();
|
||||
row.RelativeItem(1.5f).Text("Sección").SemiBold();
|
||||
row.RelativeItem(3).Text("Bobina").SemiBold();
|
||||
row.RelativeItem(1).AlignRight().Text("Cant. Bobinas").SemiBold();
|
||||
row.RelativeItem(1).AlignRight().Text("Kilos").SemiBold();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
var gruposPorPublicacion = Model.Detalles.GroupBy(p => p.NombrePublicacion);
|
||||
|
||||
foreach (var grupoPub in gruposPorPublicacion)
|
||||
{
|
||||
column.Item().Element(c => ComposePublicacionSection(c, grupoPub));
|
||||
}
|
||||
|
||||
// Fila de Totales Generales al final
|
||||
var totalGeneralBobinas = Model.Detalles.Sum(d => d.CantidadBobinas);
|
||||
var totalGeneralKilos = Model.Detalles.Sum(d => d.TotalKilos);
|
||||
|
||||
column.Item().PaddingTop(10).Row(row =>
|
||||
{
|
||||
row.RelativeItem(6).AlignRight().Text("Total General").ExtraBold().FontSize(12);
|
||||
row.RelativeItem(1).AlignRight().Text(totalGeneralBobinas.ToString("N0")).ExtraBold().FontSize(12);
|
||||
row.RelativeItem(1).AlignRight().Text(totalGeneralKilos.ToString("N0")).ExtraBold().FontSize(12);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- COMPONENTE PARA UNA PUBLICACIÓN ENTERA ---
|
||||
void ComposePublicacionSection(IContainer container, IGrouping<string, ConsumoBobinasSeccionDto> grupoPub)
|
||||
{
|
||||
container.Row(row =>
|
||||
{
|
||||
// Columna 1: Nombre de la Publicación
|
||||
row.RelativeItem(1.5f).BorderBottom(1).BorderLeft(1).BorderRight(1).BorderColor(Colors.Grey.Medium).Padding(3).Text(grupoPub.Key).SemiBold();
|
||||
|
||||
// Columna 2: Contiene todas las sub-tablas de secciones
|
||||
row.RelativeItem(6.5f).Column(seccionesColumn =>
|
||||
{
|
||||
var gruposPorSeccion = grupoPub.GroupBy(s => s.NombreSeccion);
|
||||
foreach(var grupoSec in gruposPorSeccion)
|
||||
{
|
||||
seccionesColumn.Item().Element(c => ComposeSeccionTable(c, grupoSec));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- COMPONENTE PARA LA TABLA DE UNA SECCIÓN ---
|
||||
void ComposeSeccionTable(IContainer container, IGrouping<string, ConsumoBobinasSeccionDto> grupoSec)
|
||||
{
|
||||
container.Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(1.5f); // Sección
|
||||
columns.RelativeColumn(3); // Bobina
|
||||
columns.RelativeColumn(1); // Cantidad
|
||||
columns.RelativeColumn(1); // Kilos
|
||||
});
|
||||
|
||||
// Filas de detalle
|
||||
foreach (var detalle in grupoSec.OrderBy(d => d.NombreBobina))
|
||||
{
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).Text(grupoSec.Key);
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).Text(detalle.NombreBobina);
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(detalle.CantidadBobinas.ToString("N0"));
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(detalle.TotalKilos.ToString("N0"));
|
||||
}
|
||||
|
||||
// Fila de total de la sección
|
||||
var totalCantSeccion = grupoSec.Sum(d => d.CantidadBobinas);
|
||||
var totalKilosSeccion = grupoSec.Sum(d => d.TotalKilos);
|
||||
|
||||
table.Cell().ColumnSpan(2).Border(1).BorderColor(Colors.Grey.Medium).AlignRight().Padding(3).Text("Total Sección").SemiBold();
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(t => t.Span(totalCantSeccion.ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Medium).Padding(3).AlignRight().Text(t => t.Span(totalKilosSeccion.ToString("N0")).SemiBold());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ControlDevolucionesDocument : IDocument
|
||||
{
|
||||
public ControlDevolucionesViewModel Model { get; }
|
||||
|
||||
public ControlDevolucionesDocument(ControlDevolucionesViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(11));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Control de Devoluciones").SemiBold().FontSize(16);
|
||||
column.Item().AlignCenter().Text("Canillas / Accionistas").FontSize(13);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(15);
|
||||
|
||||
column.Item().Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text =>
|
||||
{
|
||||
text.Span("Fecha Consultada: ").SemiBold();
|
||||
text.Span(Model.FechaConsultada);
|
||||
});
|
||||
row.RelativeItem().AlignRight().Text(text =>
|
||||
{
|
||||
text.Span("Cantidad Canillas: ").SemiBold();
|
||||
text.Span(Model.CantidadCanillas.ToString());
|
||||
});
|
||||
});
|
||||
|
||||
column.Item().PaddingTop(5).Border(1).Background(Colors.Grey.Lighten3).AlignCenter().Padding(2).Text(Model.NombreEmpresa).SemiBold();
|
||||
|
||||
column.Item().Border(1).Padding(10).Column(innerCol =>
|
||||
{
|
||||
innerCol.Spacing(5);
|
||||
|
||||
// Fila de "Ingresados por Remito" con borde inferior sólido.
|
||||
innerCol.Item().BorderBottom(1, Unit.Point).BorderColor(Colors.Grey.Medium).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text("Ingresados por Remito:").SemiBold();
|
||||
row.RelativeItem().AlignRight().Text(Model.TotalIngresadosPorRemito.ToString("N0"));
|
||||
}); // <-- SOLUCIÓN: Borde sólido simple.
|
||||
|
||||
foreach (var item in Model.Detalles)
|
||||
{
|
||||
var totalSeccion = item.Devueltos - item.Llevados;
|
||||
innerCol.Item().PaddingTop(5).Row(row =>
|
||||
{
|
||||
row.ConstantItem(100).Text(item.Tipo).SemiBold();
|
||||
|
||||
row.RelativeItem().Column(sub =>
|
||||
{
|
||||
sub.Spacing(2);
|
||||
sub.Item().Row(r => {
|
||||
r.RelativeItem().Text("Llevados");
|
||||
r.RelativeItem().AlignRight().Text($"-{item.Llevados:N0}");
|
||||
});
|
||||
sub.Item().Row(r => {
|
||||
r.RelativeItem().Text("Devueltos");
|
||||
r.RelativeItem().AlignRight().Text($"{item.Devueltos:N0}");
|
||||
});
|
||||
sub.Item().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(2).Row(r => {
|
||||
r.RelativeItem().Text(t => t.Span("Total").SemiBold());
|
||||
r.RelativeItem().AlignRight().Text(t => t.Span(totalSeccion.ToString("N0")).SemiBold());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
column.Item().PaddingTop(10).Column(finalCol =>
|
||||
{
|
||||
finalCol.Spacing(2);
|
||||
|
||||
Action<RowDescriptor, string, string, bool> AddTotalRow = (row, label, value, isBold) =>
|
||||
{
|
||||
var text = row.RelativeItem().Text(label);
|
||||
if (isBold) text.SemiBold();
|
||||
|
||||
var valueText = row.ConstantItem(80).AlignRight().Text(value);
|
||||
if (isBold) valueText.SemiBold();
|
||||
};
|
||||
|
||||
// Usamos bordes superiores para separar las líneas de total
|
||||
finalCol.Item().BorderTop(2f).BorderColor(Colors.Black).PaddingTop(2).Row(row => AddTotalRow(row, "Total Devolución a la Fecha", Model.TotalDevolucionALaFecha.ToString("N0"), false));
|
||||
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(2).Row(row => AddTotalRow(row, "Total Devolución Días Anteriores", Model.TotalDevolucionDiasAnteriores.ToString("N0"), false));
|
||||
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(2).Row(row => AddTotalRow(row, "Total Devolución", Model.TotalDevolucionGeneral.ToString("N0"), false));
|
||||
finalCol.Item().BorderTop(2f).BorderColor(Colors.Black).PaddingTop(5).Row(row => AddTotalRow(row, "Sin Cargo", Model.TotalSinCargo.ToString("N0"), false));
|
||||
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(2).Row(row => AddTotalRow(row, "Sobrantes", $"-{Model.TotalSobrantes.ToString("N0")}", false));
|
||||
finalCol.Item().BorderTop(1).BorderColor(Colors.Grey.Lighten2).BorderBottom(1).BorderColor(Colors.Grey.Lighten2).PaddingTop(5).Row(row => AddTotalRow(row, "Diferencia", Model.DiferenciaFinal.ToString("N0"), true));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,260 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class CuentasDistribuidorDocument : IDocument
|
||||
{
|
||||
public CuentasDistribuidorViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR", false)
|
||||
{
|
||||
NumberFormat = { CurrencySymbol = "$" }
|
||||
};
|
||||
|
||||
public CuentasDistribuidorDocument(CuentasDistribuidorViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); x.Span(" de "); x.TotalPages(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text($"Fecha de Reporte {Model.FechaReporte}");
|
||||
row.RelativeItem().AlignCenter().Text("Cuenta De Distribuidor").SemiBold().FontSize(14);
|
||||
row.RelativeItem();
|
||||
});
|
||||
|
||||
column.Item().AlignCenter().Text(Model.NombreDistribuidor).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem(2);
|
||||
row.RelativeItem(8).AlignCenter().Text(text =>
|
||||
{
|
||||
text.Span("Fecha Consultada: Desde ").SemiBold();
|
||||
text.Span(Model.FechaDesde);
|
||||
text.Span(" Hasta ").SemiBold();
|
||||
text.Span(Model.FechaHasta);
|
||||
});
|
||||
row.RelativeItem(2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(20);
|
||||
|
||||
if (Model.Movimientos.Any()) column.Item().Element(ComposeMovimientosTable);
|
||||
if (Model.Pagos.Any()) column.Item().Element(ComposePagosTable);
|
||||
if (Model.DebitosCreditos.Any()) column.Item().Element(ComposeDebCredTable);
|
||||
|
||||
column.Item().Element(ComposeResumenPeriodo);
|
||||
column.Item().Element(ComposeSaldoFinal);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeMovimientosTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(5).Text("Movimientos").SemiBold().FontSize(11);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(60);
|
||||
columns.RelativeColumn(2);
|
||||
columns.ConstantColumn(50);
|
||||
columns.ConstantColumn(50);
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn(2);
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicacion");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Remito");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Cantidad");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Debe");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Haber");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||
});
|
||||
|
||||
decimal saldoAcumulado = 0; // Inicia en CERO
|
||||
foreach (var item in Model.Movimientos.OrderBy(m => m.Fecha))
|
||||
{
|
||||
saldoAcumulado += (item.Debe - item.Haber);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Fecha.ToString("dd/MM/yyyy"));
|
||||
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Remito);
|
||||
table.Cell().Border(1).Padding(2).AlignCenter().Text(item.Cantidad.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Debe.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Haber.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(saldoAcumulado.ToString("C", CultureAr));
|
||||
}
|
||||
|
||||
table.Cell().ColumnSpan(4).Border(1).AlignRight().Padding(2).Text(t => t.Span("Totales").SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Movimientos.Sum(x => x.Debe).ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Movimientos.Sum(x => x.Haber).ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(saldoAcumulado.ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposePagosTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(5).Text("Pagos").SemiBold().FontSize(12);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(60);
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.ConstantColumn(50);
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn(2);
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Recibo");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Debe");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Haber");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Detalle");
|
||||
});
|
||||
|
||||
decimal saldoAcumulado = Model.TotalMovimientos;
|
||||
foreach (var item in Model.Pagos.OrderBy(p => p.Fecha).ThenBy(p => p.Recibo))
|
||||
{
|
||||
saldoAcumulado += (item.Debe - item.Haber);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Fecha.ToString("dd/MM/yyyy"));
|
||||
table.Cell().Border(1).Padding(2).Text(item.Recibo.ToString());
|
||||
table.Cell().Border(1).Padding(2).Text(item.Tipo);
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Debe.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Haber.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(saldoAcumulado.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).Text(item.Detalle);
|
||||
}
|
||||
|
||||
table.Cell().ColumnSpan(3).Border(1).AlignRight().Padding(2).Text(t => t.Span("Totales").SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Pagos.Sum(x => x.Debe).ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.Pagos.Sum(x => x.Haber).ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(saldoAcumulado.ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeDebCredTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(5).Text("Débitos / Créditos").SemiBold().FontSize(12);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(65);
|
||||
columns.RelativeColumn(2);
|
||||
columns.RelativeColumn(1);
|
||||
columns.RelativeColumn(1);
|
||||
columns.RelativeColumn(2);
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Referencia");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Debe");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Haber");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Saldo");
|
||||
});
|
||||
|
||||
decimal saldoAcumulado = Model.TotalMovimientos + Model.TotalPagos;
|
||||
foreach (var item in Model.DebitosCreditos.OrderBy(dc => dc.Fecha))
|
||||
{
|
||||
saldoAcumulado += (item.Debe - item.Haber);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Fecha.ToString("dd/MM/yyyy"));
|
||||
table.Cell().Border(1).Padding(2).Text(item.Referencia);
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Debe.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.Haber.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(saldoAcumulado.ToString("C", CultureAr));
|
||||
}
|
||||
|
||||
table.Cell().ColumnSpan(2).Border(1).AlignRight().Padding(2).Text(t => t.Span("Totales").SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.DebitosCreditos.Sum(x => x.Debe).ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(Model.DebitosCreditos.Sum(x => x.Haber).ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().Border(1).AlignRight().Padding(2).Text(t => t.Span(saldoAcumulado.ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeResumenPeriodo(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).AlignLeft().Column(column =>
|
||||
{
|
||||
column.Item().Border(1).Padding(5).Width(300, Unit.Point).Column(col =>
|
||||
{
|
||||
col.Spacing(5);
|
||||
col.Item().Text("Datos totales del periodo consultado").SemiBold();
|
||||
Action<RowDescriptor, string, decimal> AddResumenRow = (row, label, value) =>
|
||||
{
|
||||
row.RelativeItem().Text(label);
|
||||
row.ConstantItem(120).AlignRight().Text(value.ToString("C", CultureAr));
|
||||
};
|
||||
col.Item().Row(row => AddResumenRow(row, "Movimientos", Model.TotalMovimientos));
|
||||
col.Item().Row(row => AddResumenRow(row, "Débitos/Créditos", Model.TotalDebitosCreditos));
|
||||
col.Item().Row(row => AddResumenRow(row, "Pagos", Model.TotalPagos));
|
||||
col.Item().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(5).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text("Total").SemiBold();
|
||||
row.ConstantItem(120).AlignRight().Text(t => t.Span(Model.TotalPeriodo.ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeSaldoFinal(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).AlignLeft().Text(text =>
|
||||
{
|
||||
text.Span($"Saldo Total del Distribuidor al {Model.FechaReporte} ").SemiBold().FontSize(12);
|
||||
text.Span(Model.SaldoDeCuenta.ToString("C", CultureAr)).SemiBold().FontSize(12);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
// --- REEMPLAZAR ARCHIVO: Controllers/Reportes/PdfTemplates/DistribucionCanillasDocument.cs ---
|
||||
using GestionIntegral.Api.Dtos.Reportes;
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class DistribucionCanillasDocument : IDocument
|
||||
{
|
||||
public DistribucionCanillasViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public DistribucionCanillasDocument(DistribucionCanillasViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().Row(row => {
|
||||
row.RelativeItem().Text("Listado de Distribución: Canillas / Accionistas").FontSize(12);
|
||||
row.RelativeItem().AlignRight().Text(text => {
|
||||
text.Span("Fecha Consultada ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaConsultada).FontSize(12);
|
||||
});
|
||||
});
|
||||
column.Item().PaddingTop(5).Row(row => {
|
||||
row.RelativeItem().Text(text => {
|
||||
text.Span("Fecha de Generación del Reporte ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaReporte);
|
||||
});
|
||||
row.RelativeItem().AlignRight().Text(text => {
|
||||
text.Span("Empresa ").SemiBold().FontSize(12);
|
||||
text.Span(Model.Empresa).FontSize(12);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(15);
|
||||
|
||||
if(Model.Canillas.Any())
|
||||
column.Item().Element(c => ComposeTablaDetallada(c, "Canillas", Model.Canillas));
|
||||
|
||||
if(Model.CanillasAccionistas.Any())
|
||||
column.Item().Element(c => ComposeTablaDetallada(c, "Accionistas", Model.CanillasAccionistas));
|
||||
|
||||
if(Model.CanillasLiquidadasOtraFecha.Any())
|
||||
column.Item().Element(c => ComposeTablaLiquidacion(c, "Liquidación de movimientos de otras fechas canillas", Model.CanillasLiquidadasOtraFecha));
|
||||
|
||||
if(Model.CanillasAccionistasLiquidadasOtraFecha.Any())
|
||||
column.Item().Element(c => ComposeTablaLiquidacion(c, "Liquidación de movimientos de otras fechas accionistas", Model.CanillasAccionistasLiquidadasOtraFecha));
|
||||
|
||||
if(Model.CanillasTodos.Any())
|
||||
column.Item().Element(c => ComposeTablaTotales(c, "Recuento de Publicaciones", Model.CanillasTodos));
|
||||
|
||||
if(Model.RemitoIngresado > 0)
|
||||
column.Item().Element(ComposeResumenDevoluciones);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeTablaDetallada(IContainer container, string title, IEnumerable<DetalleDistribucionCanillaDto> data)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(4).Text(title).SemiBold().FontSize(11);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(3); columns.RelativeColumn(3);
|
||||
columns.RelativeColumn(1); columns.RelativeColumn(1);
|
||||
columns.RelativeColumn(1); columns.RelativeColumn(1.2f);
|
||||
});
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Vendedor");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||
});
|
||||
foreach (var grupoCanilla in data.GroupBy(c => c.Canilla))
|
||||
{
|
||||
var primeraFila = true;
|
||||
// El RowSpan es el número de publicaciones + la fila de total
|
||||
var totalFilasGrupo = grupoCanilla.Count() + 1;
|
||||
foreach (var item in grupoCanilla.OrderBy(p => p.Publicacion))
|
||||
{
|
||||
if (primeraFila)
|
||||
{
|
||||
table.Cell().RowSpan((uint)totalFilasGrupo).Border(1).Padding(2).AlignTop().Text(item.Canilla);
|
||||
primeraFila = false;
|
||||
}
|
||||
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida - item.TotalCantEntrada).ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||
}
|
||||
// Subtotal por canilla
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text("Totales").SemiBold();
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalCantSalida).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalCantEntrada).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(t => t.Span(grupoCanilla.Sum(i => i.TotalRendir).ToString("C", CultureAr)).SemiBold());
|
||||
}
|
||||
|
||||
var boldStyle = TextStyle.Default.ExtraBold();
|
||||
table.Cell().ColumnSpan(2).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total " + title).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeTablaLiquidacion(IContainer container, string title, IEnumerable<DetalleDistribucionCanillaDto> data)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(4).Text(title).SemiBold().FontSize(11);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(3); columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn(3); columns.RelativeColumn(1);
|
||||
columns.RelativeColumn(1); columns.RelativeColumn(1);
|
||||
columns.RelativeColumn(1.2f);
|
||||
});
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Vendedor");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Fecha");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||
});
|
||||
foreach(var item in data.OrderBy(d => d.Canilla).ThenBy(d => d.Fecha))
|
||||
{
|
||||
table.Cell().Border(1).Padding(2).Text(item.Canilla);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Fecha?.ToString("dd/MM/yyyy") ?? "");
|
||||
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida - item.TotalCantEntrada).ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||
}
|
||||
var boldStyle = TextStyle.Default.ExtraBold();
|
||||
table.Cell().ColumnSpan(3).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total").Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeTablaTotales(IContainer container, string title, IEnumerable<DetalleDistribucionCanillaAllDto> data)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(4).Text(title).SemiBold().FontSize(11);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2); columns.RelativeColumn(3);
|
||||
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.2f);
|
||||
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.5f);
|
||||
});
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo Vendedor");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||
});
|
||||
foreach(var item in data.OrderBy(d => d.TipoVendedor).ThenBy(d => d.Publicacion))
|
||||
{
|
||||
table.Cell().Border(1).Padding(2).Text(item.TipoVendedor);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida-item.TotalCantEntrada).ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||
}
|
||||
var boldStyle = TextStyle.Default.ExtraBold();
|
||||
table.Cell().ColumnSpan(2).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total General").Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(data.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeResumenDevoluciones(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5).Column(column => {
|
||||
column.Item().Row(row => {
|
||||
row.Spacing(15);
|
||||
row.AutoItem().Text(text => { text.Span("Remito: ").SemiBold().FontSize(11); text.Span(Model.RemitoIngresado.ToString("N0")).FontSize(11); });
|
||||
row.AutoItem().Text(text => { text.Span("Devolución: ").SemiBold().FontSize(11); text.Span(Model.DevolucionTotal.ToString("N0")).FontSize(11); });
|
||||
row.AutoItem().Text(text => { text.Span("Venta: ").SemiBold().FontSize(11); text.Span(Model.VentaTotal.ToString("N0")).FontSize(11); });
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class DistribucionCanillasTotalesDocument : IDocument
|
||||
{
|
||||
public DistribucionCanillasViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public DistribucionCanillasTotalesDocument(DistribucionCanillasViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().Row(row => {
|
||||
row.RelativeItem().Text("Listado de Distribución: Canillas / Accionistas (Totales)").FontSize(12);
|
||||
row.RelativeItem().AlignRight().Text(text => {
|
||||
text.Span("Fecha Consultada ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaConsultada).FontSize(12);
|
||||
});
|
||||
});
|
||||
column.Item().PaddingTop(5).Row(row => {
|
||||
row.RelativeItem().Text(text => {
|
||||
text.Span("Fecha de Generación del Reporte ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaReporte).FontSize(12);
|
||||
});
|
||||
row.RelativeItem().AlignRight().Text(text => {
|
||||
text.Span("Empresa ").SemiBold().FontSize(12);
|
||||
text.Span(Model.Empresa).FontSize(12);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(15);
|
||||
|
||||
if(Model.CanillasTodos.Any())
|
||||
column.Item().Element(ComposeTablaTotales);
|
||||
|
||||
if(Model.RemitoIngresado > 0)
|
||||
column.Item().Element(ComposeResumenDevoluciones);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeTablaTotales(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(4).Text("Recuento de Publicaciones").SemiBold().FontSize(11);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2); columns.RelativeColumn(3);
|
||||
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.2f);
|
||||
columns.RelativeColumn(1.2f); columns.RelativeColumn(1.5f);
|
||||
});
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo Vendedor");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).Text("Publicación");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("Vendidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(2).AlignRight().Text("A Rendir");
|
||||
});
|
||||
foreach(var item in Model.CanillasTodos.OrderBy(d => d.TipoVendedor).ThenBy(d => d.Publicacion))
|
||||
{
|
||||
table.Cell().Border(1).Padding(2).Text(item.TipoVendedor);
|
||||
table.Cell().Border(1).Padding(2).Text(item.Publicacion);
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text((item.TotalCantSalida-item.TotalCantEntrada).ToString("N0"));
|
||||
table.Cell().Border(1).Padding(2).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||
}
|
||||
var boldStyle = TextStyle.Default.ExtraBold();
|
||||
table.Cell().ColumnSpan(2).BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span("Total General").Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalCantSalida).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalCantSalida - i.TotalCantEntrada).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).Padding(2).AlignRight().Text(t => t.Span(Model.CanillasTodos.Sum(i => i.TotalRendir).ToString("C", CultureAr)).Style(boldStyle));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeResumenDevoluciones(IContainer container)
|
||||
{
|
||||
container.PaddingTop(10).Column(column => {
|
||||
column.Item().Row(row => {
|
||||
row.Spacing(15);
|
||||
row.AutoItem().Text(text => { text.Span("Remito: ").SemiBold(); text.Span(Model.RemitoIngresado.ToString("N0")); });
|
||||
row.AutoItem().Text(text => { text.Span("Devolución: ").SemiBold(); text.Span(Model.DevolucionTotal.ToString("N0")); });
|
||||
row.AutoItem().Text(text => { text.Span("Venta: ").SemiBold(); text.Span(Model.VentaTotal.ToString("N0")); });
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
container
|
||||
.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.PageColor(Colors.White);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(10));
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
container
|
||||
.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.PageColor(Colors.White);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(10));
|
||||
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class LiquidacionCanillaDocument : IDocument
|
||||
{
|
||||
public LiquidacionCanillaViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public LiquidacionCanillaDocument(LiquidacionCanillaViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
// CORRECCIÓN: El método GetSettings ya no es necesario para este diseño.
|
||||
// La configuración por defecto es suficiente.
|
||||
// public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Size(PageSizes.A5);
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().Text("EL DIA S.A.I.C. y F.");
|
||||
column.Item().Text(text =>
|
||||
{
|
||||
text.Span("Liquidación venta de diarios del: ");
|
||||
text.Span(Model.FechaLiquidacion);
|
||||
});
|
||||
column.Item().PaddingTop(5).Text($"Vendedor: {Model.NombreVendedor}").SemiBold();
|
||||
column.Item().PaddingTop(10);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(15);
|
||||
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2);
|
||||
columns.RelativeColumn(2);
|
||||
columns.RelativeColumn(1);
|
||||
});
|
||||
|
||||
foreach (var item in Model.Detalles.OrderBy(d => d.Publicacion))
|
||||
{
|
||||
var vendidos = item.TotalCantSalida - item.TotalCantEntrada;
|
||||
|
||||
table.Cell().ColumnSpan(3).Text(item.Publicacion).SemiBold();
|
||||
|
||||
table.Cell();
|
||||
table.Cell().Text("Retirados");
|
||||
table.Cell().AlignRight().Text(item.TotalCantSalida.ToString("N0"));
|
||||
|
||||
table.Cell();
|
||||
table.Cell().Text("Devueltos");
|
||||
table.Cell().AlignRight().Text(item.TotalCantEntrada.ToString("N0"));
|
||||
|
||||
table.Cell();
|
||||
table.Cell().Text("Vendidos");
|
||||
table.Cell().AlignRight().Text(vendidos.ToString("N0"));
|
||||
|
||||
table.Cell();
|
||||
table.Cell().Text("Precio Unitario");
|
||||
table.Cell().AlignRight().Text(item.PrecioEjemplar.ToString("C", CultureAr));
|
||||
|
||||
table.Cell();
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(2).Text(t => t.Span("Importe Vendido").SemiBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(2).AlignRight().Text(t => t.Span(item.TotalRendir.ToString("C", CultureAr)).SemiBold());
|
||||
}
|
||||
});
|
||||
|
||||
column.Item().BorderTop(2).BorderColor(Colors.Black).PaddingTop(4).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text("Total A Rendir").SemiBold().FontSize(10);
|
||||
row.RelativeItem().AlignRight().Text(text => text.Span(Model.TotalARendir.ToString("C", CultureAr)).SemiBold().FontSize(10));
|
||||
});
|
||||
|
||||
if (!Model.EsAccionista && Model.Ganancias.Any())
|
||||
{
|
||||
column.Item().PaddingTop(10).Element(ComposeGananciasTable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeGananciasTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().Text("Comisiones Acreditadas").SemiBold().FontSize(11);
|
||||
|
||||
column.Item().PaddingTop(5).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2);
|
||||
columns.RelativeColumn(1);
|
||||
});
|
||||
|
||||
foreach (var item in Model.Ganancias)
|
||||
{
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Lighten2).Padding(3).Text(item.Publicacion);
|
||||
table.Cell().Border(1).BorderColor(Colors.Grey.Lighten2).Padding(3).AlignRight().Text(item.TotalRendir.ToString("C", CultureAr));
|
||||
}
|
||||
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).Text("Total Comisiones").SemiBold();
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).Padding(3).AlignRight().Text(t => t.Span(Model.TotalComisiones.ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ListadoDistCanMensualDiariosDocument : IDocument
|
||||
{
|
||||
public ListadoDistCanMensualDiariosViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public ListadoDistCanMensualDiariosDocument(ListadoDistCanMensualDiariosViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text($"Ventas por {Model.TipoDestinatario} desde el {Model.FechaDesde} hasta el {Model.FechaHasta}").SemiBold().FontSize(12);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
// APLICAMOS LA SOLUCIÓN AQUÍ: .AlignTop()
|
||||
container.PaddingTop(1, Unit.Centimetre).AlignTop().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(3); // Nombre
|
||||
columns.ConstantColumn(50); // El Día
|
||||
columns.ConstantColumn(50); // El Plata
|
||||
columns.ConstantColumn(60); // Vendidos
|
||||
columns.RelativeColumn(1.5f); // Imp. El Día
|
||||
columns.RelativeColumn(1.5f); // Imp. El Plata
|
||||
columns.RelativeColumn(1.5f); // Importe Total
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).Text("Nombre").SemiBold();
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignCenter().Text("El Día").SemiBold();
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignCenter().Text("El Plata").SemiBold();
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignCenter().Text("Vendidos").SemiBold();
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignRight().Text("Imp. El Día").SemiBold();
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignRight().Text("Imp. El Plata").SemiBold();
|
||||
header.Cell().BorderBottom(1).BorderColor(Colors.Grey.Medium).Padding(4).AlignRight().Text("Importe Total").SemiBold();
|
||||
});
|
||||
|
||||
foreach (var item in Model.Detalles.OrderBy(d => d.Canilla))
|
||||
{
|
||||
table.Cell().Padding(3).PaddingRight(10).Text(item.Canilla);
|
||||
table.Cell().Padding(3).AlignCenter().Text(item.ElDia?.ToString("N0") ?? "0");
|
||||
table.Cell().Padding(3).AlignCenter().Text(item.ElPlata?.ToString("N0") ?? "0");
|
||||
table.Cell().Padding(3).AlignCenter().Text(item.Vendidos?.ToString("N0") ?? "0");
|
||||
table.Cell().Padding(3).AlignRight().Text(item.ImporteElDia?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||
table.Cell().Padding(3).AlignRight().Text(item.ImporteElPlata?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||
table.Cell().Padding(3).AlignRight().Text(item.ImporteTotal?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||
}
|
||||
|
||||
// Fila de Totales
|
||||
var totalElDia = Model.Detalles.Sum(x => x.ElDia ?? 0);
|
||||
var totalElPlata = Model.Detalles.Sum(x => x.ElPlata ?? 0);
|
||||
var totalVendidos = Model.Detalles.Sum(x => x.Vendidos ?? 0);
|
||||
var totalImpElDia = Model.Detalles.Sum(x => x.ImporteElDia ?? 0);
|
||||
var totalImpElPlata = Model.Detalles.Sum(x => x.ImporteElPlata ?? 0);
|
||||
var totalImpTotal = Model.Detalles.Sum(x => x.ImporteTotal ?? 0);
|
||||
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).Text("Totales").SemiBold();
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignCenter().Text(t => t.Span(totalElDia.ToString("N0")).SemiBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignCenter().Text(t => t.Span(totalElPlata.ToString("N0")).SemiBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignCenter().Text(t => t.Span(totalVendidos.ToString("N0")).SemiBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignRight().Text(t => t.Span(totalImpElDia.ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignRight().Text(t => t.Span(totalImpElPlata.ToString("C", CultureAr)).SemiBold());
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).PaddingTop(4).AlignRight().Text(t => t.Span(totalImpTotal.ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ListadoDistCanMensualDocument : IDocument
|
||||
{
|
||||
public ListadoDistCanMensualViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public ListadoDistCanMensualDocument(ListadoDistCanMensualViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Listado de Distribución Mensual").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text(Model.TipoDestinatario).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(10);
|
||||
|
||||
// Agrupamos los datos por Canilla
|
||||
var gruposPorCanilla = Model.Detalles.GroupBy(d => d.Canilla);
|
||||
|
||||
// Creamos una tabla principal que contendrá todo
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2.5f); // Canilla / Publicación
|
||||
columns.RelativeColumn(); // Llevados
|
||||
columns.RelativeColumn(); // Devueltos
|
||||
columns.RelativeColumn(1.2f); // Importe
|
||||
});
|
||||
|
||||
// Encabezado principal de la tabla
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).Text("Canilla / Publicación").SemiBold();
|
||||
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Llevados").SemiBold();
|
||||
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Devueltos").SemiBold();
|
||||
header.Cell().BorderBottom(1.5f).BorderColor(Colors.Black).Padding(4).AlignRight().Text("Importe").SemiBold();
|
||||
});
|
||||
|
||||
// Iteramos sobre cada grupo de canilla
|
||||
foreach (var grupo in gruposPorCanilla)
|
||||
{
|
||||
// Fila del nombre del Canilla
|
||||
table.Cell().ColumnSpan(4).PaddingTop(8).Text(grupo.Key).SemiBold();
|
||||
|
||||
// Filas de detalle para ese canilla
|
||||
foreach (var detalle in grupo)
|
||||
{
|
||||
table.Cell().PaddingLeft(15).Padding(2).Text(detalle.Publicacion);
|
||||
table.Cell().Padding(2).AlignRight().Text(detalle.TotalCantSalida?.ToString("N0") ?? "0");
|
||||
table.Cell().Padding(2).AlignRight().Text(detalle.TotalCantEntrada?.ToString("N0") ?? "0");
|
||||
table.Cell().Padding(2).AlignRight().Text(detalle.TotalRendir?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||
}
|
||||
|
||||
// Fila de total por canilla
|
||||
var totalRendirCanilla = grupo.Sum(d => d.TotalRendir ?? 0);
|
||||
table.Cell().ColumnSpan(3).BorderTop(1.5f).BorderColor(Colors.Black).AlignRight().Padding(2).Text("A Rendir").SemiBold();
|
||||
table.Cell().BorderTop(1.5f).BorderColor(Colors.Black).AlignRight().Padding(2).Text(t => t.Span(totalRendirCanilla.ToString("C", CultureAr)).SemiBold());
|
||||
}
|
||||
|
||||
// --- Fila de TOTALES GENERALES ---
|
||||
var totalGeneralLlevados = Model.Detalles.Sum(d => d.TotalCantSalida ?? 0);
|
||||
var totalGeneralDevueltos = Model.Detalles.Sum(d => d.TotalCantEntrada ?? 0);
|
||||
var totalGeneralRendir = Model.Detalles.Sum(d => d.TotalRendir ?? 0);
|
||||
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).Text("TOTALES").ExtraBold();
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralLlevados.ToString("N0")).ExtraBold());
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralDevueltos.ToString("N0")).ExtraBold());
|
||||
table.Cell().BorderTop(2).BorderColor(Colors.Black).PaddingTop(5).AlignRight().Text(t => t.Span(totalGeneralRendir.ToString("C", CultureAr)).ExtraBold());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ListadoDistCanillasImporteDocument : IDocument
|
||||
{
|
||||
public ListadoDistCanillasImporteViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public ListadoDistCanillasImporteDocument(ListadoDistCanillasImporteViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Listado de Distribución con Importes").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text(Model.TipoDestinatario).FontSize(12);
|
||||
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(); // Fecha
|
||||
columns.RelativeColumn(); // Llevados
|
||||
columns.RelativeColumn(); // Devueltos
|
||||
columns.RelativeColumn(); // Vendidos
|
||||
columns.RelativeColumn(1.5f); // Importe Publicación
|
||||
columns.RelativeColumn(1.5f); // A Rendir
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Fecha");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Vendidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Imp. Publicación");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("A Rendir");
|
||||
});
|
||||
|
||||
foreach (var item in Model.Detalles)
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(item.Fecha);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Llevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Devueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Vendidos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalRendirPublicacion.ToString("C", CultureAr));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalRendirGeneral.ToString("C", CultureAr));
|
||||
}
|
||||
|
||||
// Fila de Totales
|
||||
var totalLlevados = Model.Detalles.Sum(x => x.Llevados);
|
||||
var totalDevueltos = Model.Detalles.Sum(x => x.Devueltos);
|
||||
var totalVendidos = Model.Detalles.Sum(x => x.Vendidos);
|
||||
var totalRendirPub = Model.Detalles.Sum(x => x.TotalRendirPublicacion);
|
||||
var totalRendirGral = Model.Detalles.Sum(x => x.TotalRendirGeneral);
|
||||
|
||||
var boldStyle = TextStyle.Default.SemiBold();
|
||||
|
||||
table.Cell().Border(1).Padding(3); // Celda vacía
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalLlevados.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalDevueltos.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalVendidos.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalRendirPub.ToString("C", CultureAr)).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(totalRendirGral.ToString("C", CultureAr)).Style(boldStyle));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ListadoDistribucionCanillasDocument : IDocument
|
||||
{
|
||||
public ListadoDistribucionCanillasViewModel Model { get; }
|
||||
|
||||
public ListadoDistribucionCanillasDocument(ListadoDistribucionCanillasViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Listado de Distribución - Canillitas").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(8, Unit.Millimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(15);
|
||||
|
||||
column.Item().Text("Distribución").SemiBold().FontSize(12);
|
||||
column.Item().Element(ComposeDetalleDiarioTable);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre);
|
||||
|
||||
column.Item().Text("Promedios").SemiBold().FontSize(12);
|
||||
column.Item().Element(ComposePromediosTable);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeDetalleDiarioTable(IContainer container)
|
||||
{
|
||||
container.Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(50); // Día
|
||||
columns.RelativeColumn(); // Llevados
|
||||
columns.RelativeColumn(); // Devueltos
|
||||
columns.RelativeColumn(); // Venta Neta
|
||||
columns.RelativeColumn(2); // Promedio (columna vacía en el original)
|
||||
columns.RelativeColumn(2); // % Devolución
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Venta Neta");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Promedio");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||
});
|
||||
|
||||
decimal ventaNetaAcumulada = 0;
|
||||
int conteoDias = 0;
|
||||
|
||||
foreach (var item in Model.DetalleDiario.OrderBy(x => x.Dia))
|
||||
{
|
||||
var ventaNetaDia = item.Llevados - item.Devueltos;
|
||||
ventaNetaAcumulada += ventaNetaDia;
|
||||
conteoDias++;
|
||||
var promedio = ventaNetaAcumulada / conteoDias;
|
||||
var porcDevolucion = item.Llevados > 0 ? (decimal)item.Devueltos * 100 / item.Llevados : 0;
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(item.Dia.ToString());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Llevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Devueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(ventaNetaDia.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(promedio.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2"));
|
||||
}
|
||||
|
||||
var totalVentaNeta = Model.TotalesDetalleDiario.Llevados - Model.TotalesDetalleDiario.Devueltos;
|
||||
var totalPorcDevolucion = Model.TotalesDetalleDiario.Llevados > 0 ? (decimal)Model.TotalesDetalleDiario.Devueltos * 100 / Model.TotalesDetalleDiario.Llevados : 0;
|
||||
|
||||
table.Cell().Border(1).Padding(3); // Celda vacía
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.TotalesDetalleDiario.Llevados.ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.TotalesDetalleDiario.Devueltos.ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalVentaNeta.ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span((ventaNetaAcumulada / (conteoDias > 0 ? conteoDias : 1)).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalPorcDevolucion.ToString("F2")).SemiBold());
|
||||
});
|
||||
}
|
||||
|
||||
void ComposePromediosTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingBottom(5).Text("Promedios por Día de Semana").SemiBold().FontSize(11);
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(1.5f);
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn(1.2f);
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día Semana");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Días");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Ventas");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||
});
|
||||
|
||||
var dayOrder = new Dictionary<string, int> { { "Lunes", 1 }, { "Martes", 2 }, { "Miércoles", 3 }, { "Jueves", 4 }, { "Viernes", 5 }, { "Sábado", 6 }, { "Domingo", 7 } };
|
||||
|
||||
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;
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Cant.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Llevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Devueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Ventas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2") + "%");
|
||||
}
|
||||
|
||||
// --- SECCIÓN AÑADIDA PARA LA FILA "GENERAL" ---
|
||||
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));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.Cant.ToString("N0")).Style(boldStyle));
|
||||
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));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ListadoDistribucionDistribuidoresDocument : IDocument
|
||||
{
|
||||
public ListadoDistribucionDistribuidoresViewModel Model { get; }
|
||||
|
||||
public ListadoDistribucionDistribuidoresDocument(ListadoDistribucionDistribuidoresViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Listado de Distribución").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text(Model.NombreDistribuidor).FontSize(12);
|
||||
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(11);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(8, Unit.Millimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(15);
|
||||
column.Item().Text("Distribución").SemiBold().FontSize(12);
|
||||
column.Item().Element(ComposeDetalleDiarioTable);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre);
|
||||
|
||||
column.Item().Text("Promedios").SemiBold().FontSize(12);
|
||||
column.Item().Element(ComposePromediosTable);
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeDetalleDiarioTable(IContainer container)
|
||||
{
|
||||
container.Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(50); columns.RelativeColumn();
|
||||
columns.RelativeColumn(); columns.RelativeColumn();
|
||||
columns.RelativeColumn(2); columns.RelativeColumn(2);
|
||||
});
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Venta Neta");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Promedio");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||
});
|
||||
|
||||
decimal ventaNetaAcumulada = 0;
|
||||
int conteoDias = 0;
|
||||
|
||||
foreach (var item in Model.DetalleDiario.OrderBy(x => x.Dia))
|
||||
{
|
||||
var llevados = item.Llevados ?? 0;
|
||||
var devueltos = item.Devueltos ?? 0;
|
||||
var ventaNetaDia = llevados - devueltos;
|
||||
if(llevados > 0)
|
||||
{
|
||||
ventaNetaAcumulada += ventaNetaDia;
|
||||
conteoDias++;
|
||||
}
|
||||
var promedio = conteoDias > 0 ? ventaNetaAcumulada / conteoDias : 0;
|
||||
var porcDevolucion = llevados > 0 ? (decimal)devueltos * 100 / llevados : 0;
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(item.Dia.ToString());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(llevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(devueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(ventaNetaDia.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(promedio.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2") + "%");
|
||||
}
|
||||
|
||||
var totalLlevados = Model.DetalleDiario.Sum(i => i.Llevados ?? 0);
|
||||
var totalDevueltos = Model.DetalleDiario.Sum(i => i.Devueltos ?? 0);
|
||||
var totalVentaNeta = totalLlevados - totalDevueltos;
|
||||
var totalPorcDevolucion = totalLlevados > 0 ? (decimal)totalDevueltos * 100 / totalLlevados : 0;
|
||||
|
||||
var boldStyle = TextStyle.Default.SemiBold();
|
||||
table.Cell().Border(1).Padding(3);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalLlevados.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalDevueltos.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalVentaNeta.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span((ventaNetaAcumulada / (conteoDias > 0 ? conteoDias : 1)).ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(totalPorcDevolucion.ToString("F2") + "%").Style(boldStyle));
|
||||
});
|
||||
}
|
||||
|
||||
void ComposePromediosTable(IContainer container)
|
||||
{
|
||||
var dayOrder = new Dictionary<string, int> { { "Lunes", 1 }, { "Martes", 2 }, { "Miércoles", 3 }, { "Jueves", 4 }, { "Viernes", 5 }, { "Sábado", 6 }, { "Domingo", 7 }};
|
||||
|
||||
container.Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(1.5f); columns.RelativeColumn();
|
||||
columns.RelativeColumn(); columns.RelativeColumn();
|
||||
columns.RelativeColumn(); columns.RelativeColumn(1.2f);
|
||||
});
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Días");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Ventas");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("% Devolución");
|
||||
});
|
||||
foreach (var item in Model.PromediosPorDia.Where(p => p.Dia != "General").OrderBy(d => dayOrder.GetValueOrDefault(d.Dia, 99)))
|
||||
{
|
||||
var llevados = item.Promedio_Llevados ?? 0;
|
||||
var devueltos = item.Promedio_Devueltos ?? 0;
|
||||
var porcDevolucion = llevados > 0 ? (decimal)devueltos * 100 / llevados : 0;
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Cant?.ToString("N0") ?? "0");
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(llevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(devueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Promedio_Ventas?.ToString("N0") ?? "0");
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(porcDevolucion.ToString("F2") + "%");
|
||||
}
|
||||
|
||||
// --- FILA GENERAL ---
|
||||
var general = Model.PromedioGeneral;
|
||||
if (general != null)
|
||||
{
|
||||
var boldStyle = TextStyle.Default.SemiBold();
|
||||
var llevadosGeneral = general.Llevados ?? 0; // Usamos el total para el %
|
||||
var devueltosGeneral = general.Devueltos ?? 0; // Usamos el total para el %
|
||||
var porcDevolucionGeneral = llevadosGeneral > 0 ? (decimal)devueltosGeneral * 100 / llevadosGeneral : 0;
|
||||
|
||||
table.Cell().Border(1).Padding(3).Text(t => t.Span(general.Dia).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Cant?.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Promedio_Llevados?.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Promedio_Devueltos?.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(general.Promedio_Ventas?.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(porcDevolucionGeneral.ToString("F2") + "%").Style(boldStyle));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class ListadoDistribucionGeneralDocument : IDocument
|
||||
{
|
||||
public ListadoDistribucionGeneralViewModel Model { get; }
|
||||
|
||||
public ListadoDistribucionGeneralDocument(ListadoDistribucionGeneralViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Listado de Distribución General Mensual").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text(Model.NombrePublicacion).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(1, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Mes Consultado: ").SemiBold(); text.Span(Model.MesConsultado); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Millimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(20);
|
||||
|
||||
if (Model.ResumenMensual.Any())
|
||||
{
|
||||
column.Item().Element(ComposeResumenTable);
|
||||
}
|
||||
if (Model.PromediosPorDia.Any())
|
||||
{
|
||||
column.Item().Element(ComposePromediosTable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeResumenTable(IContainer container)
|
||||
{
|
||||
container.Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(40);
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Tirada");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Sin Cargo");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Perdidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Vendidos");
|
||||
});
|
||||
|
||||
foreach (var item in Model.ResumenMensual.OrderBy(x => x.Fecha))
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(item.Fecha.Day.ToString());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.CantidadTirada.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.SinCargo.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Perdidos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Llevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Devueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.Vendidos.ToString("N0"));
|
||||
}
|
||||
|
||||
table.Cell().Border(1).Padding(3);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.CantidadTirada).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.SinCargo).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Perdidos).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Llevados).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Devueltos).ToString("N0")).SemiBold());
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(t => t.Span(Model.ResumenMensual.Sum(x => x.Vendidos).ToString("N0")).SemiBold());
|
||||
});
|
||||
}
|
||||
|
||||
void ComposePromediosTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
// --- TÍTULO DE LA TABLA DE PROMEDIOS ---
|
||||
column.Item().PaddingBottom(5).AlignCenter().Text("Promedios Diarios de Distribución").SemiBold();
|
||||
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(1.2f);
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
columns.RelativeColumn();
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Día");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Días");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Tirada");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Sin Cargo");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Perdidos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Llevados");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Devueltos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Vendidos");
|
||||
});
|
||||
|
||||
var dayOrder = new Dictionary<string, int> { { "Lunes", 1 }, { "Martes", 2 }, { "Miércoles", 3 }, { "Jueves", 4 }, { "Viernes", 5 }, { "Sábado", 6 }, { "Domingo", 7 } };
|
||||
|
||||
// Mostramos los promedios por día de la semana
|
||||
foreach (var item in Model.PromediosPorDia.OrderBy(d => dayOrder.GetValueOrDefault(d.Dia, 99)))
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(item.Dia);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.CantidadDias.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioTirada.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioSinCargo.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioPerdidos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioLlevados.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioDevueltos.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioVendidos.ToString("N0"));
|
||||
}
|
||||
|
||||
// --- FILA GENERAL CON DATOS CALCULADOS DEL VIEWMODEL ---
|
||||
var general = Model.PromedioGeneral;
|
||||
if (general != null)
|
||||
{
|
||||
var boldStyle = TextStyle.Default.SemiBold();
|
||||
table.Cell().Border(1).Padding(3).Text(text => text.Span(general.Dia).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.CantidadDias.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioTirada.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioSinCargo.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioPerdidos.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioLlevados.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioDevueltos.ToString("N0")).Style(boldStyle));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(general.PromedioVendidos.ToString("N0")).Style(boldStyle));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class MovimientoBobinasDocument : IDocument
|
||||
{
|
||||
public MovimientoBobinasViewModel Model { get; }
|
||||
|
||||
public MovimientoBobinasDocument(MovimientoBobinasViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container
|
||||
.Page(page =>
|
||||
{
|
||||
// Configuramos la página en modo apaisado (landscape)
|
||||
page.Size(PageSizes.A4.Landscape());
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(9)); // Un poco más pequeño por la cantidad de columnas
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
|
||||
page.Footer()
|
||||
.AlignCenter()
|
||||
.Text(x =>
|
||||
{
|
||||
x.Span("Página ");
|
||||
x.CurrentPageNumber();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("Reporte de Movimiento de Bobinas").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text($"Planta: {Model.NombrePlanta}").FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Column(col =>
|
||||
{
|
||||
col.Item().Text(text =>
|
||||
{
|
||||
text.Span("Fecha del Reporte: ").SemiBold();
|
||||
text.Span(Model.FechaReporte);
|
||||
});
|
||||
col.Item().Text($"Periodo Consultado: Desde {Model.FechaDesde} Hasta {Model.FechaHasta}");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Table(table =>
|
||||
{
|
||||
// Definimos 11 columnas. Usamos una combinación de relativas y constantes
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2.5f); // Tipo
|
||||
columns.ConstantColumn(50); // Cant. Inicial
|
||||
columns.ConstantColumn(60); // Kg Iniciales
|
||||
columns.ConstantColumn(50); // Compradas
|
||||
columns.ConstantColumn(60); // Kg Comprados
|
||||
columns.ConstantColumn(50); // Consumidas
|
||||
columns.ConstantColumn(60); // Kg Consumidos
|
||||
columns.ConstantColumn(50); // Dañadas
|
||||
columns.ConstantColumn(60); // Kg Dañados
|
||||
columns.ConstantColumn(50); // Cant. Final
|
||||
columns.ConstantColumn(60); // Kg Final
|
||||
});
|
||||
|
||||
// Encabezado de la tabla
|
||||
table.Header(header =>
|
||||
{
|
||||
// Celda por celda para control total
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).Text("Tipo");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Cant. Inicial");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Inicial");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Compradas");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Comprados");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Consumidas");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Consumidos");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Dañadas");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Dañados");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Cant. Final");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(2).AlignCenter().Text("Kg Final");
|
||||
});
|
||||
|
||||
// Filas de datos
|
||||
foreach (var item in Model.Movimientos)
|
||||
{
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).Text(item.TipoBobina);
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasIniciales.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosIniciales.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasCompradas.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosComprados.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasConsumidas.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosConsumidos.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasDaniadas.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosDaniados.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.BobinasFinales.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(2).AlignCenter().Text(item.KilosFinales.ToString("N0"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class MovimientoBobinasEstadoDocument : IDocument
|
||||
{
|
||||
public MovimientoBobinasEstadoViewModel Model { get; }
|
||||
|
||||
public MovimientoBobinasEstadoDocument(MovimientoBobinasEstadoViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
public DocumentSettings GetSettings() => DocumentSettings.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container
|
||||
.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Roboto").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
|
||||
page.Footer()
|
||||
.AlignCenter()
|
||||
.Text(x =>
|
||||
{
|
||||
x.Span("Página ");
|
||||
x.CurrentPageNumber();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("Reporte de Movimiento de Bobinas por Estados").SemiBold().FontSize(14);
|
||||
column.Item().AlignCenter().Text($"Planta: {Model.NombrePlanta}").FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(2, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Column(col =>
|
||||
{
|
||||
col.Item().Text(text =>
|
||||
{
|
||||
text.Span("Fecha del Reporte: ").SemiBold();
|
||||
text.Span(Model.FechaReporte);
|
||||
});
|
||||
col.Item().Text($"Periodo Consultado: Desde {Model.FechaDesde} Hasta {Model.FechaHasta}");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||
{
|
||||
// Primera tabla: Detalle de Movimientos
|
||||
column.Item().Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(3); // Tipo Bobina
|
||||
columns.RelativeColumn(2); // Remito
|
||||
columns.ConstantColumn(80); // Fecha
|
||||
columns.ConstantColumn(60); // Cantidad
|
||||
columns.RelativeColumn(2); // Tipo Movimiento
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo Bobina");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("N° Remito");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Fecha Mov.");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cantidad");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo Movimiento");
|
||||
});
|
||||
|
||||
foreach (var item in Model.Detalles)
|
||||
{
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoBobina);
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.NumeroRemito);
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignCenter().Text(item.FechaMovimiento.ToString("dd/MM/yyyy"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.Cantidad.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoMovimiento);
|
||||
}
|
||||
});
|
||||
|
||||
// Espacio entre tablas
|
||||
column.Item().PaddingTop(1, Unit.Centimetre);
|
||||
|
||||
// Segunda tabla: Totales
|
||||
column.Item().AlignLeft().Table(table => // Alineamos la tabla a la izquierda para que no ocupe todo el ancho
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(120); // Tipo Movimiento
|
||||
columns.ConstantColumn(80); // Total Bobinas
|
||||
columns.ConstantColumn(80); // Total Kilos
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Totales por Movimiento");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Bobinas");
|
||||
header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Kilos");
|
||||
});
|
||||
|
||||
foreach (var total in Model.Totales)
|
||||
{
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(total.TipoMovimiento);
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(total.TotalBobinas.ToString("N0"));
|
||||
table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(total.TotalKilos.ToString("N0"));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class NovedadesCanillasDocument : IDocument
|
||||
{
|
||||
public NovedadesCanillasViewModel Model { get; }
|
||||
private static readonly CultureInfo CultureAr = new CultureInfo("es-AR");
|
||||
|
||||
public NovedadesCanillasDocument(NovedadesCanillasViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1.5f, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(10));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("Listado de Novedades - Canillas").SemiBold().FontSize(16);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha de Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Periodo: ").SemiBold(); text.Span($"{Model.FechaDesde} - {Model.FechaHasta}"); });
|
||||
});
|
||||
|
||||
column.Item().PaddingTop(5).Border(1).Background(Colors.Grey.Lighten3).AlignCenter().Padding(2).Text(Model.NombreEmpresa).SemiBold();
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(1, Unit.Centimetre).Column(column =>
|
||||
{
|
||||
column.Spacing(20);
|
||||
|
||||
if (Model.ResumenCanillas.Any())
|
||||
{
|
||||
column.Item().Element(ComposeResumenTable);
|
||||
}
|
||||
|
||||
if (Model.DetallesNovedades.Any())
|
||||
{
|
||||
column.Item().Element(ComposeDetallesNovedadesTable);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeResumenTable(IContainer container)
|
||||
{
|
||||
container.Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(3); // Canilla
|
||||
columns.RelativeColumn(1); // Legajo
|
||||
columns.RelativeColumn(1); // Faltas
|
||||
columns.RelativeColumn(1); // Francos
|
||||
columns.RelativeColumn(1.5f); // Comisiones
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Canilla");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Legajo");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Faltas");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Francos");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Comisiones");
|
||||
});
|
||||
|
||||
foreach (var item in Model.ResumenCanillas.OrderBy(x => x.Canilla))
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(item.Canilla);
|
||||
table.Cell().Border(1).Padding(3).Text(item.Legajo?.ToString() ?? "-");
|
||||
table.Cell().Border(1).Padding(3).AlignCenter().Text(item.Faltas?.ToString("N0") ?? "0");
|
||||
table.Cell().Border(1).Padding(3).AlignCenter().Text(item.Francos?.ToString("N0") ?? "0");
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalRendir?.ToString("C", CultureAr) ?? "$ 0.00");
|
||||
}
|
||||
|
||||
// Fila de Totales
|
||||
table.Cell().ColumnSpan(4).Border(1).Padding(3).AlignRight().Text("Total").SemiBold();
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.ResumenCanillas.Sum(x => x.TotalRendir ?? 0).ToString("C", CultureAr)).SemiBold());
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeDetallesNovedadesTable(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().PaddingTop(10).Text("Otras Novedades").SemiBold().FontSize(12);
|
||||
column.Item().PaddingTop(5).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2); // Nombre
|
||||
columns.ConstantColumn(80); // Fecha
|
||||
columns.RelativeColumn(4); // Detalle
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Nombre");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Fecha");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Detalle");
|
||||
});
|
||||
|
||||
// Agrupamos por canillita para mostrar su nombre una sola vez
|
||||
foreach (var grupo in Model.DetallesNovedades.GroupBy(x => x.NomApe))
|
||||
{
|
||||
// Celda con el nombre del canillita, abarcando todas las filas de sus novedades
|
||||
table.Cell().RowSpan((uint)grupo.Count()).Border(1).Padding(3).Text(grupo.Key);
|
||||
|
||||
// Iteramos sobre las novedades del grupo
|
||||
foreach (var detalle in grupo.OrderBy(d => d.Fecha))
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(detalle.Fecha.ToString("dd/MM/yyyy"));
|
||||
table.Cell().Border(1).Padding(3).Text(detalle.Detalle);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class TiradasPublicacionesSeccionesDocument : IDocument
|
||||
{
|
||||
public TiradasPublicacionesSeccionesViewModel Model { get; }
|
||||
|
||||
public TiradasPublicacionesSeccionesDocument(TiradasPublicacionesSeccionesViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(9));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("Reporte de Tiradas por Publicación Mensual").SemiBold().FontSize(14);
|
||||
|
||||
// Título secundario dinámico
|
||||
string subTitle = Model.EsConsolidado
|
||||
? $"Consolidado - Publicación: {Model.NombrePublicacion}"
|
||||
: $"Planta: {Model.NombrePlanta} - Publicación: {Model.NombrePublicacion}";
|
||||
column.Item().AlignCenter().Text(subTitle).FontSize(12);
|
||||
|
||||
column.Item().PaddingTop(5, Unit.Millimetre).Row(row =>
|
||||
{
|
||||
row.RelativeItem().Text(text => { text.Span("Fecha del Reporte: ").SemiBold(); text.Span(Model.FechaReporte); });
|
||||
row.RelativeItem().AlignRight().Text(text => { text.Span("Mes Consultado: ").SemiBold(); text.Span(Model.MesConsultado); });
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.RelativeColumn(2.5f); // Nombre Seccion
|
||||
columns.RelativeColumn(1.5f); // Páginas Impresas
|
||||
columns.RelativeColumn(1); // Total Ediciones
|
||||
columns.RelativeColumn(1.5f); // Pág. Por Edición
|
||||
columns.RelativeColumn(1.2f); // Total Ejemplares
|
||||
columns.RelativeColumn(1.5f); // Pág. Ejemplar
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).Text("Nombre Sección");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Páginas Impresas");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Ediciones");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Pág/Edición");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Total Ejemplares");
|
||||
header.Cell().Border(1).Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Prom. Pág/Ejemplar");
|
||||
});
|
||||
|
||||
foreach (var item in Model.Detalles.OrderBy(x => x.NombreSeccion))
|
||||
{
|
||||
table.Cell().Border(1).Padding(3).Text(item.NombreSeccion);
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalPaginasImpresas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.CantidadTiradas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalPaginasEjemplares.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.TotalEjemplares.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(item.PromedioPaginasPorEjemplar.ToString("N0"));
|
||||
}
|
||||
|
||||
// Fila de Totales
|
||||
var style = TextStyle.Default.SemiBold();
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span("Totales").Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.TotalPaginasImpresas).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.CantidadTiradas).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.TotalPaginasEjemplares).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.TotalEjemplares).ToString("N0")).Style(style));
|
||||
table.Cell().Border(1).Padding(3).AlignRight().Text(text => text.Span(Model.Detalles.Sum(x => x.PromedioPaginasPorEjemplar).ToString("N0")).Style(style));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class VentaMensualSecretariaElDiaDocument : IDocument
|
||||
{
|
||||
public VentaMensualSecretariaElDiaViewModel Model { get; }
|
||||
|
||||
public VentaMensualSecretariaElDiaDocument(VentaMensualSecretariaElDiaViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(11));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("VENTA DIARIO EL DÍA").SemiBold().FontSize(16);
|
||||
|
||||
column.Item().AlignCenter().Text(text =>
|
||||
{
|
||||
text.Span("Fecha Consultada: Desde ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaDesde).FontSize(12);
|
||||
text.Span(" Hasta ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaHasta).FontSize(12);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(50); // Día
|
||||
columns.RelativeColumn(); // Canillas
|
||||
columns.RelativeColumn(); // Tirajes
|
||||
columns.RelativeColumn(); // Ventas
|
||||
columns.RelativeColumn(); // Accionistas
|
||||
columns.RelativeColumn(); // Total Coop.
|
||||
columns.RelativeColumn(); // Total Gral.
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("DÍA").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("CANILLAS").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TIRAJES").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("VENTAS").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("ACCIONISTAS").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TOTAL COOPERATIVA").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TOTAL").FontColor(Colors.White).SemiBold());
|
||||
});
|
||||
|
||||
foreach (var item in Model.VentasDiarias.OrderBy(x => x.Dia))
|
||||
{
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Dia.ToString());
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.CantidadCanillas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Tirajes.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Ventas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Accionistas.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TotalCooperativa.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.TotalGeneral.ToString("N0")).SemiBold());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class VentaMensualSecretariaElPlataDocument : IDocument
|
||||
{
|
||||
public VentaMensualSecretariaElPlataViewModel Model { get; }
|
||||
|
||||
public VentaMensualSecretariaElPlataDocument(VentaMensualSecretariaElPlataViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(11));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Spacing(5);
|
||||
column.Item().AlignCenter().Text("VENTA DIARIO EL PLATA").SemiBold().FontSize(16);
|
||||
|
||||
column.Item().AlignCenter().Text(text =>
|
||||
{
|
||||
text.Span("Fecha Consultada: Desde ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaDesde).FontSize(12);
|
||||
text.Span(" Hasta ").SemiBold().FontSize(12);
|
||||
text.Span(Model.FechaHasta).FontSize(12);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(50); // Día
|
||||
columns.RelativeColumn(); // Tirada Coop
|
||||
columns.RelativeColumn(); // Devolución Coop
|
||||
columns.RelativeColumn(); // Venta Coop
|
||||
columns.RelativeColumn(); // Tirada Canillas
|
||||
columns.RelativeColumn(); // Venta Canillas
|
||||
columns.RelativeColumn(); // Total
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("DÍA").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TIRADA COOP.").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("DEVOLUCIÓN COOP.").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("VENTA COOP.").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TIRADA CANILLAS").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("VENTA CANILLAS (TOTAL)").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().Background(Colors.Black).Border(1).BorderColor(Colors.White).Padding(4).AlignCenter().Text(text => text.Span("TOTAL").FontColor(Colors.White).SemiBold());
|
||||
});
|
||||
|
||||
foreach (var item in Model.VentasDiarias.OrderBy(x => x.Dia))
|
||||
{
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Dia.ToString());
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaCoop.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionCoop.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.VentaCoop.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaCan.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.VentaCan.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.Total.ToString("N0")).SemiBold());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using GestionIntegral.Api.Dtos.Reportes.ViewModels;
|
||||
using QuestPDF.Elements.Table;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using System.Linq;
|
||||
|
||||
namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates
|
||||
{
|
||||
public class VentaMensualSecretariaTirDevoDocument : IDocument
|
||||
{
|
||||
public VentaMensualSecretariaTirDevoViewModel Model { get; }
|
||||
|
||||
public VentaMensualSecretariaTirDevoDocument(VentaMensualSecretariaTirDevoViewModel model)
|
||||
{
|
||||
Model = model;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
// CORRECCIÓN: Se aplica Landscape() al tamaño de página.
|
||||
page.Size(PageSizes.A4.Landscape());
|
||||
page.Margin(1, Unit.Centimetre);
|
||||
page.DefaultTextStyle(x => x.FontFamily("Arial").FontSize(12));
|
||||
|
||||
page.Header().Element(ComposeHeader);
|
||||
page.Content().Element(ComposeContent);
|
||||
page.Footer().AlignCenter().Text(x => { x.Span("Página "); x.CurrentPageNumber(); });
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeHeader(IContainer container)
|
||||
{
|
||||
container.Column(column =>
|
||||
{
|
||||
column.Item().AlignCenter().Text("TIRADA Y DEVOLUCIÓN").SemiBold().FontSize(18);
|
||||
column.Item().AlignCenter().Text(text =>
|
||||
{
|
||||
text.Span("Fecha Consultada: Desde ").SemiBold().FontSize(14);
|
||||
text.Span(Model.FechaDesde).FontSize(14);
|
||||
text.Span(" Hasta ").SemiBold().FontSize(14);
|
||||
text.Span(Model.FechaHasta).FontSize(14);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void ComposeContent(IContainer container)
|
||||
{
|
||||
container.PaddingTop(5, Unit.Millimetre).Table(table =>
|
||||
{
|
||||
table.ColumnsDefinition(columns =>
|
||||
{
|
||||
columns.ConstantColumn(40);
|
||||
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // EL DÍA
|
||||
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // POPULAR
|
||||
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // CLARÍN
|
||||
columns.RelativeColumn(); columns.RelativeColumn(); columns.RelativeColumn(); // LA NACIÓN
|
||||
});
|
||||
|
||||
table.Header(header =>
|
||||
{
|
||||
// CORRECCIÓN: La sintaxis de VerticalAlign es un método.
|
||||
header.Cell().RowSpan(2).Border(1).Background(Colors.Black).AlignCenter().AlignMiddle().Text(text => text.Span("Día").FontColor(Colors.White).SemiBold());
|
||||
|
||||
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("EL DÍA").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("POPULAR").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("CLARÍN").FontColor(Colors.White).SemiBold());
|
||||
header.Cell().ColumnSpan(3).Border(1).Background(Colors.Black).AlignCenter().Text(text => text.Span("LA NACIÓN").FontColor(Colors.White).SemiBold());
|
||||
|
||||
// CORRECCIÓN: Se define una función local para crear y estilizar las celdas del sub-encabezado.
|
||||
// Esto evita el error de "multiple child elements".
|
||||
void SubHeaderCell(ITableCellContainer cell, string text)
|
||||
{
|
||||
cell.Border(1)
|
||||
.Background(Colors.Black)
|
||||
.AlignCenter()
|
||||
.Text(txt => txt.Span(text).FontColor(Colors.White).SemiBold());
|
||||
}
|
||||
|
||||
foreach (var _ in Enumerable.Range(0, 4))
|
||||
{
|
||||
SubHeaderCell(header.Cell(), "TIRADA");
|
||||
SubHeaderCell(header.Cell(), "DEVOLUC");
|
||||
SubHeaderCell(header.Cell(), "VENTA");
|
||||
}
|
||||
});
|
||||
|
||||
// Filas de datos (sin cambios)
|
||||
foreach (var item in Model.VentasDiarias.OrderBy(x => x.Dia))
|
||||
{
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.Dia.ToString());
|
||||
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaCoop.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionCoop.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaCoop.ToString("N0")).SemiBold());
|
||||
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaPopular.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionPopular.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaPopular.ToString("N0")).SemiBold());
|
||||
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaClarin.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionClarin.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaClarin.ToString("N0")).SemiBold());
|
||||
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.TiradaNacion.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(item.DevolucionNacion.ToString("N0"));
|
||||
table.Cell().Border(1).Padding(4).AlignCenter().Text(t => t.Span(item.VentaNacion.ToString("N0")).SemiBold());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user