using General_Ledger_Service.DTOs.Reports; using QuestPDF.Fluent; using QuestPDF.Helpers; using QuestPDF.Infrastructure; namespace General_Ledger_Service.Services.PdfDocuments { // 05_LKAS_Report_PDF_Templates.md Section 3 (LKAS 1) - retrofit 2026-07-31, classified // presentation (Non-Current/Current split) driven by BalanceSheetReportDto's sections, // rather than the old rollup-by-depth-1 grouping. Each section is already leaf rows + a // server-computed Total (Accounting_System_Design_LKAS.md Section 11.3), so the renderer // just lists lines and prints the given totals - no rendering-layer arithmetic. public class BalanceSheetPdfDocument(string companyName, string currencyCode, DateOnly asOfDate, BalanceSheetReportDto data) : IDocument { public DocumentMetadata GetMetadata() => DocumentMetadata.Default; public void Compose(IDocumentContainer container) { container.Page(page => { page.Size(PageSizes.A4); page.Margin(2, Unit.Centimetre); ReportPageHeader.Compose(page, companyName, "Statement of Financial Position", ReportPageHeader.PointInTimePeriodLine(asOfDate), currencyCode); page.Content().PaddingTop(10).Column(column => { void RenderSection(string title, BalanceSheetSectionDto section, string totalLabel) { if (section.Lines.Count == 0) return; column.Item().PaddingTop(8).Text(title).Bold(); foreach (var line in section.Lines) { column.Item().Row(r => { r.RelativeItem(4).Text(line.AccountName).FontFamily(Fonts.Consolas); r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(line.Balance)); }); } column.Item().PaddingTop(2).LineHorizontal(0.75f); column.Item().Row(r => { r.RelativeItem(4).Text(totalLabel).Bold(); r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(section.Total)).Bold(); }); } column.Item().Text("ASSETS").Bold().FontSize(12); RenderSection("Non-Current Assets", data.NonCurrentAssets, "Total Non-Current Assets"); RenderSection("Current Assets", data.CurrentAssets, "Total Current Assets"); RenderSection("Unclassified Assets", data.UnclassifiedAssets, "Total Unclassified Assets"); column.Item().PaddingTop(3).LineHorizontal(1.5f); column.Item().Row(r => { r.RelativeItem(4).Text("TOTAL ASSETS").Bold(); r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(data.TotalAssets)).Bold(); }); column.Item().PaddingTop(15).Text("EQUITY AND LIABILITIES").Bold().FontSize(12); RenderSection("Equity", data.Equity, "Total Equity"); RenderSection("Non-Current Liabilities", data.NonCurrentLiabilities, "Total Non-Current Liabilities"); RenderSection("Current Liabilities", data.CurrentLiabilities, "Total Current Liabilities"); RenderSection("Unclassified Liabilities", data.UnclassifiedLiabilities, "Total Unclassified Liabilities"); column.Item().PaddingTop(3).LineHorizontal(1.5f); column.Item().Row(r => { r.RelativeItem(4).Text("TOTAL EQUITY AND LIABILITIES").Bold(); r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(data.TotalEquityAndLiabilities)).Bold(); }); }); }); } } }