Distribution_GL Initialization
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
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 5 (LKAS 7, full statement). Retrofit 2026-07-22:
|
||||
// no printed opening/closing cash balance (still in the Json/Csv data for the reconciliation
|
||||
// check, just not displayed here, matching the reference template); nonCashAdjustments and
|
||||
// workingCapitalChanges are combined and re-bucketed by sign at render time into "Additions
|
||||
// to Cash"/"Subtractions From Cash" rather than kept as two separate lists. Working-capital
|
||||
// lines now use the account's own Direction ("Increase"/"Decrease") for their wording, since
|
||||
// that's no longer derivable from ChangeAmount's sign alone (see the DTO's comment).
|
||||
public class CashFlowPdfDocument(string companyName, string currencyCode, CashFlowReportDto data) : IDocument
|
||||
{
|
||||
private record CashMovementLine(string Description, decimal Amount);
|
||||
|
||||
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
||||
|
||||
public void Compose(IDocumentContainer container)
|
||||
{
|
||||
var operating = data.OperatingActivities;
|
||||
var operatingProfitBeforeWorkingCapital = operating.ProfitForPeriod + operating.NonCashAdjustments.Sum(a => a.Amount);
|
||||
|
||||
var movements = operating.NonCashAdjustments
|
||||
.Select(a => new CashMovementLine(a.Description, a.Amount))
|
||||
.Concat(operating.WorkingCapitalChanges.Select(c => new CashMovementLine($"{c.Direction} in {c.AccountName}", c.ChangeAmount)))
|
||||
.ToList();
|
||||
var additions = movements.Where(m => m.Amount > 0).ToList();
|
||||
var subtractions = movements.Where(m => m.Amount <= 0).ToList();
|
||||
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Size(PageSizes.A4);
|
||||
page.Margin(2, Unit.Centimetre);
|
||||
ReportPageHeader.Compose(page, companyName, "Statement of Cash Flows", ReportPageHeader.RangePeriodLine(data.PeriodStart, data.PeriodEnd), currencyCode);
|
||||
|
||||
page.Content().PaddingTop(10).Column(column =>
|
||||
{
|
||||
column.Item().Text("Cash Flows from Operating Activities").Bold();
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text("Profit for the period");
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(operating.ProfitForPeriod));
|
||||
});
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text("Operating profit before working capital changes");
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(operatingProfitBeforeWorkingCapital));
|
||||
});
|
||||
|
||||
if (additions.Count > 0)
|
||||
{
|
||||
column.Item().PaddingTop(5).Text("Additions to Cash");
|
||||
foreach (var line in additions)
|
||||
{
|
||||
column.Item().PaddingLeft(10).Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text(line.Description);
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(line.Amount));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (subtractions.Count > 0)
|
||||
{
|
||||
column.Item().PaddingTop(5).Text("Subtractions From Cash");
|
||||
foreach (var line in subtractions)
|
||||
{
|
||||
column.Item().PaddingLeft(10).Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text(line.Description);
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(line.Amount));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
column.Item().PaddingTop(3).LineHorizontal(1);
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text("Net Cash from Operating Activities").Bold();
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(operating.NetCashFromOperatingActivities)).Bold();
|
||||
});
|
||||
|
||||
column.Item().PaddingTop(15).Text("Cash Flows from Investing Activities").Bold();
|
||||
foreach (var line in data.InvestingActivities.Lines)
|
||||
{
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text(line.AccountName);
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(line.Amount));
|
||||
});
|
||||
}
|
||||
column.Item().PaddingTop(3).LineHorizontal(1);
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
var label = data.InvestingActivities.NetCashFromInvestingActivities < 0 ? "Net Cash used in Investing Activities" : "Net Cash from Investing Activities";
|
||||
r.RelativeItem(4).Text(label).Bold();
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(data.InvestingActivities.NetCashFromInvestingActivities)).Bold();
|
||||
});
|
||||
|
||||
column.Item().PaddingTop(15).Text("Cash Flows from Financing Activities").Bold();
|
||||
foreach (var line in data.FinancingActivities.Lines)
|
||||
{
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
r.RelativeItem(4).Text(line.AccountName);
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(line.Amount));
|
||||
});
|
||||
}
|
||||
column.Item().PaddingTop(3).LineHorizontal(1);
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
var label = data.FinancingActivities.NetCashFromFinancingActivities < 0 ? "Net Cash used in Financing Activities" : "Net Cash from Financing Activities";
|
||||
r.RelativeItem(4).Text(label).Bold();
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(data.FinancingActivities.NetCashFromFinancingActivities)).Bold();
|
||||
});
|
||||
|
||||
column.Item().PaddingTop(15).LineHorizontal(1.5f);
|
||||
column.Item().Row(r =>
|
||||
{
|
||||
var label = data.NetIncreaseDecreaseInCash < 0 ? "Net Decrease in Cash and Cash Equivalents" : "Net Increase in Cash and Cash Equivalents";
|
||||
r.RelativeItem(4).Text(label).Bold();
|
||||
r.RelativeItem(1).AlignRight().Text(PdfFormatting.FormatAmount(data.NetIncreaseDecreaseInCash)).Bold();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user