185 lines
11 KiB
C#
185 lines
11 KiB
C#
using Elwig.Helpers;
|
||
using Elwig.Models.Entities;
|
||
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;
|
||
using System.Text.RegularExpressions;
|
||
|
||
namespace Elwig.Documents {
|
||
public class MemberDataSheet : BusinessDocument {
|
||
|
||
public new static string Name => "Stammdatenblatt";
|
||
|
||
public Season Season;
|
||
public Dictionary<string, MemberBucket> MemberBuckets;
|
||
public List<AreaCom> ActiveAreaCommitments;
|
||
|
||
public MemberDataSheet(Member m, AppDbContext ctx) : base($"{Name} {m.AdministrativeName}", m) {
|
||
DocumentId = $"{Name} {m.MgNr}";
|
||
Season = ctx.Seasons.ToList().MaxBy(s => s.Year) ?? throw new ArgumentException("invalid season");
|
||
MemberBuckets = ctx.GetMemberBuckets(Utils.CurrentYear, m.MgNr).GetAwaiter().GetResult();
|
||
ActiveAreaCommitments = [.. m.ActiveAreaCommitments(ctx)];
|
||
}
|
||
|
||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||
base.RenderBody(doc, pdf);
|
||
doc.Add(NewMemberData().SetMarginBottomMM(5));
|
||
doc.Add(NewBucketTable(Season, MemberBuckets, includeDelivery: false));
|
||
if (ActiveAreaCommitments.Count != 0) {
|
||
bool firstOnPage = false;
|
||
if (pdf.GetNumberOfPages() == 1) {
|
||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||
firstOnPage = true;
|
||
}
|
||
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 12, 0));
|
||
doc.Add(NewAreaComTable());
|
||
}
|
||
}
|
||
|
||
protected Cell NewDataHdr(string title, int colspan) {
|
||
return NewTd(title, 10, colspan: colspan, bold: true, italic: true, center: true, borderTop: true)
|
||
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0));
|
||
}
|
||
|
||
protected Cell NewDataTh(string text, float fontSize = 10, int colspan = 1) {
|
||
return NewTd(text, fontSize, colspan: colspan, italic: true)
|
||
.SetPaddingRightMM(0);
|
||
}
|
||
|
||
protected Table NewMemberData() {
|
||
var tbl = new Table(ColsMM(30.0, 51.5, 20.0, 12.0, 18.0, 31.5))
|
||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||
.SetBorder(new SolidBorder(BorderThickness));
|
||
|
||
tbl.AddCell(NewDataHdr("Persönliche Daten", 6));
|
||
if (Member.IsJuridicalPerson) {
|
||
tbl
|
||
.AddCell(NewDataTh("Name", 8, colspan: 3))
|
||
.AddCell(NewDataTh("Zu Handen", 8, colspan: 3))
|
||
.AddCell(NewTd(Member.Name, 12, colspan: 3))
|
||
.AddCell(NewTd(Member.ForTheAttentionOf, 12, colspan: 3));
|
||
} else {
|
||
tbl
|
||
.AddCell(NewDataTh("Titel (vorangestellt)", 8))
|
||
.AddCell(NewDataTh("Vorname", 8))
|
||
.AddCell(NewDataTh("Nachname", 8, colspan: 3))
|
||
.AddCell(NewDataTh("Titel (nachgestellt)", 8))
|
||
.AddCell(NewTd(Member.Prefix, 12))
|
||
.AddCell(NewTd($"{Member.GivenName} {Member.MiddleName}", 12))
|
||
.AddCell(NewTd(Member.Name, 12, colspan: 3))
|
||
.AddCell(NewTd(Member.Suffix, 12));
|
||
}
|
||
|
||
tbl
|
||
.AddCell(NewDataTh("Mitglieds-Nr.:")).AddCell(NewTd($"{Member.MgNr}"))
|
||
.AddCell(NewDataTh(Member.IsJuridicalPerson ? "Gründungsjahr/-tag:" : "Geburtsjahr/-tag:", colspan: 2))
|
||
.AddCell(NewTd(string.Join('.', Member.Birthday?.Split('-')?.Reverse() ?? []), colspan: 2))
|
||
.AddCell(NewDataTh("Adresse:")).AddCell(NewTd(Member.Address, colspan: 5))
|
||
.AddCell(NewDataTh("PLZ/Ort:"))
|
||
.AddCell(NewTd($"{Member.PostalDest.AtPlz?.Plz} {Member.PostalDest.AtPlz?.Dest} ({Member.PostalDest.AtPlz?.Ort.Name})", colspan: 5))
|
||
.AddCell(NewDataHdr("Rechnungsadresse (optional)", colspan: 6))
|
||
.AddCell(NewDataTh("Name:")).AddCell(NewTd(Member.BillingAddress?.FullName, colspan: 5))
|
||
.AddCell(NewDataTh("Adresse:")).AddCell(NewTd(Member.BillingAddress?.Address, colspan: 5))
|
||
.AddCell(NewDataTh("PLZ/Ort:"))
|
||
.AddCell(NewTd(Member.BillingAddress != null ? $"{Member.BillingAddress.PostalDest.AtPlz?.Plz} {Member.BillingAddress.PostalDest.AtPlz?.Dest} ({Member.BillingAddress.PostalDest.AtPlz?.Ort.Name})" : "", colspan: 5));
|
||
|
||
tbl.AddCell(NewDataHdr("Kontaktdaten", colspan: 3))
|
||
.AddCell(NewDataHdr("Bankverbindung", colspan: 3).SetBorderLeft(new SolidBorder(BorderThickness)));
|
||
List<string?[]> subTbl1 = [
|
||
.. Member.EmailAddresses.Select(a => new[] { "E-Mail-Adresse", a.Address }),
|
||
.. Member.TelephoneNumbers.Select(n => new[] { Utils.PhoneNrTypeToString(n.Type), n.Number, n.Comment }),
|
||
["Tel.-Nr./E-Mail-Adr.", null],
|
||
];
|
||
List<string?[]> subTbl2 = [
|
||
["IBAN", Member.Iban != null ? Utils.FormatIban(Member.Iban) : null],
|
||
["BIC", Member.Bic],
|
||
];
|
||
for (int i = 0; i < Math.Max(subTbl1.Count, subTbl2.Count); i++) {
|
||
tbl.AddCell(NewDataTh(i < subTbl1.Count ? subTbl1[i][0] + ":" : ""));
|
||
if (i < subTbl1.Count && subTbl1[i].Length >= 3 && subTbl1[i][2] != null) {
|
||
tbl.AddCell(NewTd(subTbl1[i][1])).AddCell(NewTd($"({subTbl1[i][2]})"));
|
||
} else {
|
||
tbl.AddCell(NewTd(i < subTbl1.Count ? subTbl1[i][1] : "", colspan: 2));
|
||
}
|
||
tbl.AddCell(NewDataTh(i < subTbl2.Count ? subTbl2[i][0] + ":" : "").SetBorderLeft(new SolidBorder(BorderThickness)))
|
||
.AddCell(NewTd(i < subTbl2.Count ? subTbl2[i][1] : "", colspan: 2));
|
||
}
|
||
|
||
tbl.AddCell(NewDataHdr("Betrieb", colspan: 6))
|
||
.AddCell(NewDataTh("Betriebs-Nr.:")).AddCell(NewTd(Member.LfbisNr))
|
||
.AddCell(NewDataTh("UID:", colspan: 2)).AddCell(NewTd(Member.UstIdNr, colspan: 2))
|
||
.AddCell(NewDataTh("Stammgemeinde:")).AddCell(NewTd(Member.DefaultKg?.Name))
|
||
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
||
.Add(Normal($"({(Member.IsBuchführend ? Season.VatNormal : Season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
||
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
||
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(Member.IsOrganic ? "Ja" : "Nein", colspan: 2))
|
||
.AddCell(NewDataHdr("Genossenschaft", colspan: 6))
|
||
.AddCell(NewDataTh("Status:")).AddCell(NewTd(new KernedParagraph(Member.IsActive ? "Aktiv " : "Nicht aktiv ", 10)
|
||
.Add(Normal("(" + (Member.ExitDate != null ? $"{Member.EntryDate:dd.MM.yyyy}\u2013{Member.ExitDate:dd.MM.yyyy}" : $"seit {Member.EntryDate:dd.MM.yyyy}") + ")", 8))))
|
||
.AddCell(NewDataTh("Geschäftsanteile:", colspan: 2)).AddCell(NewTd($"{Member.BusinessShares:N0}", colspan: 2))
|
||
.AddCell(NewDataTh("Stamm-Zweigstelle:")).AddCell(NewTd(Member.Branch?.Name))
|
||
.AddCell(NewDataTh("Volllieferant:", colspan: 2)).AddCell(NewTd(Member.IsVollLieferant ? "Ja" : "Nein", colspan: 2))
|
||
.AddCell(NewDataTh("Zusendungen per\u2026")).AddCell(NewTd(new KernedParagraph(10)
|
||
.Add(Italic("Post:")).Add(Normal(Member.ContactViaPost ? " Ja \u2013 " : " Nein \u2013 "))
|
||
.Add(Italic("E-Mail:")).Add(Normal(Member.ContactViaEmail ? " Ja" : " Nein"))))
|
||
.AddCell(NewDataTh("Funktionär:", colspan: 2)).AddCell(NewTd(Member.IsFunktionär ? "Ja" : "Nein", colspan: 2));
|
||
|
||
return tbl;
|
||
}
|
||
|
||
protected Table NewAreaComTable() {
|
||
var areaComs = ActiveAreaCommitments.GroupBy(a => a.AreaComType).Select(group => new {
|
||
Type = group.Key,
|
||
AreaComs = group.OrderBy(c => c.Kg.AtKg.Name).ToList(),
|
||
Size = group.Sum(c => c.Area)
|
||
}).OrderByDescending(a => a.Size).ToList();
|
||
|
||
var tbl = new Table(ColsMM(40, 30, 35, 15, 25, 20), true)
|
||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||
.SetBorder(Border.NO_BORDER)
|
||
.SetFontSize(10);
|
||
|
||
tbl.AddHeaderCell(NewTh("Katastralgemeinde", rowspan: 2, left: true))
|
||
.AddHeaderCell(NewTh("Ried", rowspan: 2, left: true))
|
||
.AddHeaderCell(NewTh("Parzelle(n)", rowspan: 2, left: true))
|
||
.AddHeaderCell(NewTh("Fläche"))
|
||
.AddHeaderCell(NewTh("Bewirt.", rowspan: 2))
|
||
.AddHeaderCell(NewTh("Laufzeit", rowspan: 2))
|
||
.AddHeaderCell(NewTh("[m²]"));
|
||
|
||
var lastContract = "";
|
||
foreach (var contractType in areaComs) {
|
||
tbl.AddCell(NewCell(new KernedParagraph(10).Add(BoldItalic($"{contractType.Type.WineVar.Name} {(contractType.Type.WineAttr != null ? "(" + contractType.Type.WineAttr + ")" : "")}")), colspan: 3)
|
||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER))
|
||
.AddCell(NewCell(new KernedParagraph(10).Add(Bold($"{contractType.Size:N0}")).SetTextAlignment(TextAlignment.RIGHT))
|
||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER))
|
||
.AddCell(NewCell(colspan: 2)
|
||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER));
|
||
|
||
foreach (var areaCom in contractType.AreaComs) {
|
||
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{areaCom.Kg.AtKg.Name} ")).Add(Normal($"({areaCom.Kg.AtKg.KgNr:00000})", 8))))
|
||
.AddCell(NewTd(areaCom.Rd?.Name))
|
||
.AddCell(NewTd(Regex.Replace(areaCom.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
||
.AddCell(NewTd($"{areaCom.Area:N0}", right: true))
|
||
.AddCell(NewTd(areaCom.WineCult?.Name, center: true))
|
||
.AddCell(NewTd(areaCom.YearTo == null ? (areaCom.YearFrom == null ? "unbefristet" : $"ab {areaCom.YearFrom}") : (areaCom.YearFrom == null ? $"bis {areaCom.YearTo}" : $"{areaCom.YearFrom}–{areaCom.YearTo}"), center: true));
|
||
lastContract = contractType.Type.DisplayName;
|
||
}
|
||
}
|
||
|
||
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||
tbl.AddCell(NewTd($"{ActiveAreaCommitments.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||
|
||
return tbl;
|
||
}
|
||
}
|
||
}
|