using Elwig.Helpers; using Elwig.Models.Dtos; using iText.Kernel.Colors; using iText.Kernel.Pdf; using iText.Layout.Borders; using iText.Layout.Element; using iText.Layout.Properties; using System; using System.Collections.Generic; using System.Linq; namespace Elwig.Documents { public class WineQualityStatistics : Document { public new static string Name => "Qualitätsstatistik"; public readonly string[][] QualIds = [["WEI"], ["RSW", "LDW"], ["QUW"], ["KAB"]]; public readonly Dictionary QualityLevels = new() { ["WEI"] = "Wein", ["RSW"] = "Rebsortenwein", ["LDW"] = "Landwein", ["QUW"] = "Qualitätswein", ["KAB"] = "Kabinett", }; public string Filter; public WineQualityStatisticsData Data; public bool UseOe => Data.UseOe; public WineQualityStatistics(string filter, WineQualityStatisticsData data) : base($"{Name} {filter}") { Filter = filter; Data = data; } protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { base.RenderBody(doc, pdf); doc.Add(new KernedParagraph(Name, 24) .SetTextAlignment(TextAlignment.CENTER).SetFont(BF) .SetMarginBottomMM(2)); doc.Add(new KernedParagraph(Filter, 14) .SetTextAlignment(TextAlignment.CENTER).SetFont(BF) .SetMarginBottomMM(10)); foreach (var sec in Data.Sections) { doc.Add(NewQualitySectionTable(sec).SetMarginBottomMM(5)); } } protected Table NewQualityColumnTable(string[] qualIds, WineQualityStatisticsData.QualitySection sec) { var tbl = new Table(ColsMM(9.5, 10, 19.5)) .SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout() .SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE) .SetMarginsMM(1, 0, 1, 0) .AddCell(NewCell(new KernedParagraph(UseOe ? "[°Oe]" : "[°KMW]", 8) .SetTextAlignment(TextAlignment.CENTER).SetFont(IF)).SetPaddingsMM(1, 1, 1, 2)) .AddCell(NewCell(new KernedParagraph("[#]", 8) .SetTextAlignment(TextAlignment.CENTER).SetFont(IF)).SetPaddingsMM(1, 1, 1, 1)) .AddCell(NewCell(new KernedParagraph("[kg]", 8) .SetTextAlignment(TextAlignment.CENTER).SetFont(IF)).SetPaddingsMM(1, 2, 1, 1)); foreach (var qualId in qualIds) { tbl.AddCell(NewCell(new KernedParagraph(QualityLevels.GetValueOrDefault(qualId, qualId), 10) .SetFont(BI).SetTextAlignment(TextAlignment.CENTER), colspan: 3) .SetPaddingsMM(2, 0, 2, 0)); foreach (var (grad, avgKmw, num, weight) in sec.Data.GetValueOrDefault(qualId, Array.Empty<(double, double, int, int)>())) { tbl.AddCell(NewCell(new KernedParagraph(UseOe ? $"{grad:N0}" : $"{grad:N1}", 10) .SetTextAlignment(TextAlignment.CENTER)).SetPaddingsMM(0, 0, 0, 2)) .AddCell(NewCell(new KernedParagraph($"{num:N0}", 10) .SetTextAlignment(TextAlignment.RIGHT)).SetPaddingsMM(0, 0, 0, 0)) .AddCell(NewCell(new KernedParagraph($"{weight:N0}", 10) .SetTextAlignment(TextAlignment.RIGHT)).SetPaddingsMM(0, 2, 0, 0)); } } return tbl; } protected Table NewQualitySumTable(double kmw, int num, int weight) { return new Table(ColsMM(9.5, 10, 19.5)) .SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout() .SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE) .SetMarginsMM(1, 0, 1, 0) .AddCell(NewCell(new KernedParagraph(weight == 0 ? "-" : UseOe ? $"{Utils.KmwToOe(kmw):N0}" : $"{kmw:N1}", 10) .SetTextAlignment(TextAlignment.CENTER).SetFont(BF)).SetPaddingsMM(0, 0, 0, 2)) .AddCell(NewCell(new KernedParagraph($"{num:N0}", 10) .SetTextAlignment(TextAlignment.RIGHT).SetFont(BF)).SetPaddingsMM(0, 0, 0, 0)) .AddCell(NewCell(new KernedParagraph($"{weight:N0}", 10) .SetTextAlignment(TextAlignment.RIGHT).SetFont(BF)).SetPaddingsMM(0, 2, 0, 0)); } protected Table NewQualitySectionTable(WineQualityStatisticsData.QualitySection sec) { var tbl = new Table(4) .SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout() .SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE) .SetBorder(new SolidBorder(BorderThickness)) .SetKeepTogether(true); var bgColor = sec.Type == "R" ? new DeviceRgb(0xff, 0xc0, 0xc0) : sec.Type == "W" ? new DeviceRgb(0xc0, 0xff, 0xc0) : new DeviceRgb(0xe0, 0xe0, 0xe0); tbl.AddCell(NewCell(new KernedParagraph(sec.Name, 14).SetFont(BF), colspan: 4) .SetBackgroundColor(bgColor).SetPaddingsMM(1, 2, 1, 2)); foreach (var qualIds in QualIds) { tbl.AddCell(NewCell().SetPadding(0).Add(NewQualityColumnTable(qualIds, sec)) .SetBorder(new SolidBorder(BorderThickness))); } foreach (var qualIds in QualIds) { var quals = qualIds.Select(q => sec.Data.GetValueOrDefault(q, Array.Empty<(double Grad, double AvgKmw, int Num, int Weight)>())); var weight = quals.Sum(q => q.Sum(kv => kv.Weight)); var num = quals.Sum(q => q.Sum(kv => kv.Num)); var kmw = quals.Sum(q => q.Sum(kv => kv.AvgKmw * kv.Weight)) / weight; tbl.AddCell(NewCell().SetPaddingsMM(0.5f, 0, 0.5f, 0).Add(NewQualitySumTable(kmw, num, weight)) .SetBorder(new SolidBorder(BorderThickness))); } var totalWeight = sec.Data.Values.Sum(q => q.Sum(kv => kv.Weight)); var totalNum = sec.Data.Values.Sum(q => q.Sum(kv => kv.Num)); var totalKmw = sec.Data.Values.Sum(q => q.Sum(kv => kv.AvgKmw * kv.Weight)) / totalWeight; tbl.AddCell(NewCell(colspan: 3).SetBackgroundColor(bgColor)) .AddCell(NewCell().SetPadding(0).Add(NewQualitySumTable(totalKmw, totalNum, totalWeight)) .SetBackgroundColor(bgColor)); return tbl; } } }