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); } } }); }); } } }