126 lines
6.4 KiB
C#
126 lines
6.4 KiB
C#
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<string, string> 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;
|
|
}
|
|
}
|
|
}
|