using GestionIntegral.Api.Dtos.Reportes.ViewModels; using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; using System.Linq; namespace GestionIntegral.Api.Controllers.Reportes.PdfTemplates { // Usamos una clase parcial para organizar mejor el código, aunque no es estrictamente necesario aquí. public class ExistenciaPapelDocument : IDocument { // Usamos una propiedad pública con 'init' en lugar de un campo privado. // Esto es más limpio y funciona mejor con el análisis de código. public ExistenciaPapelViewModel Model { get; } public ExistenciaPapelDocument(ExistenciaPapelViewModel model) { Model = model; } public DocumentMetadata GetMetadata() => DocumentMetadata.Default; public DocumentSettings GetSettings() => DocumentSettings.Default; public void Compose(IDocumentContainer container) { container .Page(page => { page.Margin(1.5f, Unit.Centimetre); page.PageColor(Colors.White); 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(); }); }); } // Ahora los métodos usan 'Model' (la propiedad pública) en lugar de '_model'. void ComposeHeader(IContainer container) { container.Column(column => { column.Spacing(5); column.Item().AlignCenter().Text("Reporte de Existencias de Papel").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 => { table.ColumnsDefinition(columns => { columns.RelativeColumn(); columns.ConstantColumn(65); columns.ConstantColumn(70); columns.ConstantColumn(85); columns.ConstantColumn(65); columns.ConstantColumn(80); }); table.Header(header => { header.Cell().Background(Colors.Grey.Lighten3).Padding(4).Text("Tipo de Bobina"); header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Cant. Stock"); header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Kg. Stock"); header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Consumo (Kg)"); header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignRight().Text("Días Disp."); header.Cell().Background(Colors.Grey.Lighten3).Padding(4).AlignCenter().Text("Fin Estimado"); }); foreach (var item in Model.Existencias) { table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).Text(item.TipoBobina); table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.BobinasEnStock?.ToString("N0") ?? "0"); table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.TotalKilosEnStock?.ToString("N0") ?? "0"); table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.ConsumoAcumulado?.ToString("N0") ?? "0"); table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(item.PromedioDiasDisponibles?.ToString("N0") ?? "N/A"); table.Cell().BorderBottom(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignCenter().Text(item.FechaEstimacionFinStock?.ToString("dd/MM/yyyy") ?? "N/A"); } var totalBobinas = Model.Existencias.Sum(e => e.BobinasEnStock ?? 0); var totalKilos = Model.Existencias.Sum(e => e.TotalKilosEnStock ?? 0); var totalConsumo = Model.Existencias.Sum(e => e.ConsumoAcumulado ?? 0); table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span("Totales").SemiBold()); table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalBobinas.ToString("N0")).SemiBold()); table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalKilos.ToString("N0")).SemiBold()); table.Cell().BorderTop(1).BorderColor(Colors.Grey.Lighten2).Padding(4).AlignRight().Text(t => t.Span(totalConsumo.ToString("N0")).SemiBold()); table.Cell().ColumnSpan(2).BorderTop(1).BorderColor(Colors.Grey.Lighten2); }); } } }