358 lines
21 KiB
C#
358 lines
21 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 Microsoft.EntityFrameworkCore;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text.RegularExpressions;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace Elwig.Documents {
|
||
public class MemberDataSheet : BusinessDocument {
|
||
|
||
public new static string Name => "Stammdatenblatt";
|
||
|
||
public Season? Season;
|
||
public int MemberDeliveredWeightRed;
|
||
public int MemberDeliveredWeightWhite;
|
||
public List<MemberHistory> MemberHistory = [];
|
||
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||
public List<AreaCom> ActiveAreaCommitments = [];
|
||
|
||
public MemberDataSheet(Member m) :
|
||
base($"{Name} {m.AdministrativeName}", m, DateOnly.FromDateTime(m.ModifiedAt)) {
|
||
ShowDateAndLocation = true;
|
||
DocumentId = $"{Name} {m.MgNr}";
|
||
}
|
||
|
||
public static async Task<MemberDataSheet> Initialize(int mgnr) {
|
||
using var ctx = new AppDbContext();
|
||
return new MemberDataSheet(await ctx.FetchMembers(mgnr, includeContactInfo: true).SingleAsync());
|
||
}
|
||
|
||
protected override async Task LoadData(AppDbContext ctx) {
|
||
await base.LoadData(ctx);
|
||
Season = await ctx.FetchSeasons().FirstOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||
MemberHistory = await ctx.MemberHistory
|
||
.Where(h => h.FromMgNr == Member.MgNr || h.ToMgNr == Member.MgNr)
|
||
.OrderBy(h => h.DateString).ThenBy(h => h.HistNr)
|
||
.ToListAsync();
|
||
MemberBuckets = await ctx.GetMemberBuckets(Utils.CurrentYear, Member.MgNr);
|
||
ActiveAreaCommitments = await Member.ActiveAreaCommitments(ctx)
|
||
.Include(c => c.Contract).ThenInclude(c => c.Revisions)
|
||
.ToListAsync();
|
||
var weights = await ctx.Deliveries
|
||
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
|
||
.SelectMany(d => d.Parts)
|
||
.GroupBy(p => p.Variety.Type)
|
||
.ToDictionaryAsync(g => g.Key, g => g.Sum(p => p.Weight));
|
||
MemberDeliveredWeightRed = weights.GetValueOrDefault("R", 0);
|
||
MemberDeliveredWeightWhite = weights.GetValueOrDefault("W", 0);
|
||
}
|
||
|
||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||
if (Season == null) throw new Exception("Call LoadData before RenderBody");
|
||
base.RenderBody(doc, pdf);
|
||
doc.Add(NewMemberData(Season).SetMarginBottomMM(5));
|
||
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeightRed, MemberDeliveredWeightWhite, 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, 6, 0));
|
||
doc.Add(NewAreaComTable(ActiveAreaCommitments));
|
||
}
|
||
if (App.Client.EnableMemberHistory) {
|
||
bool firstOnPage = false;
|
||
if (pdf.GetNumberOfPages() == 1) {
|
||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||
firstOnPage = true;
|
||
}
|
||
doc.Add(new KernedParagraph(12).Add(Bold($"Verlauf der Geschäftsanteile per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 6, 0));
|
||
doc.Add(NewMemberBusinessSharesTable(MemberHistory));
|
||
}
|
||
}
|
||
|
||
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(Season season) {
|
||
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));
|
||
}
|
||
|
||
var shares = (Member.Shares != 0 || (Member.SharesRed == 0 && Member.SharesWhite == 0) ? $"{Member.Shares:N0}" : "") +
|
||
(Member.SharesRed != 0 || Member.SharesWhite != 0 ? (Member.Shares != 0 ? " / " : "") + $"{Member.SharesRed:N0} (rot) / {Member.SharesWhite:N0} (weiß)" : "") +
|
||
(Member.SharesDormant != 0 ? $" / {Member.SharesDormant:N0} (ruhend)" : "");
|
||
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(shares, 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(IEnumerable<AreaCom> activeAreaComs) {
|
||
var areaComs = activeAreaComs.GroupBy(a => a.AreaComType).Select(group => new {
|
||
Type = group.Key,
|
||
AreaComs = group.OrderBy(c => c.Contract.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) {
|
||
var c = areaCom.Contract;
|
||
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{c.Kg.AtKg.Name} ")).Add(Normal($"({c.Kg.AtKg.KgNr:00000})", 8))))
|
||
.AddCell(NewTd(c.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(c.YearTo == null ? (c.YearFrom == null ? "unbefristet" : $"ab {c.YearFrom}") : (c.YearFrom == null ? $"bis {c.YearTo}" : $"{c.YearFrom}–{c.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($"{activeAreaComs.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;
|
||
}
|
||
|
||
protected Cell[] NewBusinessSharesCells(MemberHistoryPoint p, bool isDiff = true) {
|
||
if (App.Client.HasRedWhite) {
|
||
return [
|
||
NewTd(isDiff ? (p.SharesRed == 0 ? "" : p.SharesRed < 0 ? $"–{-p.SharesRed:N0}" : $"+{p.SharesRed:N0}") : $"{p.SharesRed:N0}",
|
||
right: true, bold: !isDiff, borderTop: !isDiff),
|
||
NewTd(isDiff ? (p.SharesWhite == 0 ? "" : p.SharesWhite < 0 ? $"–{-p.SharesWhite:N0}" : $"+{p.SharesWhite:N0}") : $"{p.SharesWhite:N0}",
|
||
right: true, bold: !isDiff, borderTop: !isDiff),
|
||
NewTd(isDiff ? (p.SharesDormant == 0 ? "" : p.SharesDormant < 0 ? $"–{-p.SharesDormant:N0}" : $"+{p.SharesDormant:N0}") : $"{p.SharesDormant:N0}",
|
||
right: true, bold: !isDiff, borderTop: !isDiff),
|
||
];
|
||
} else {
|
||
return [
|
||
NewTd(isDiff ? (p.Shares == 0 ? "" : p.Shares < 0 ? $"–{-p.Shares:N0}" : $"+{p.Shares:N0}") : $"{p.Shares:N0}",
|
||
right: true, bold: !isDiff, borderTop: !isDiff),
|
||
NewTd(isDiff ? (p.SharesDormant == 0 ? "" : p.SharesDormant < 0 ? $"–{-p.SharesDormant:N0}" : $"+{p.SharesDormant:N0}") : $"{p.SharesDormant:N0}",
|
||
right : true, bold: !isDiff, borderTop: !isDiff),
|
||
];
|
||
}
|
||
}
|
||
|
||
protected Table NewMemberBusinessSharesTable(IEnumerable<MemberHistory> history) {
|
||
var tbl = new Table(ColsMM(18, 111, 12, 12, 12), true)
|
||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||
.SetBorder(Border.NO_BORDER)
|
||
.SetFontSize(10);
|
||
|
||
var tw = App.Client.HasRedWhite ? 1 : 2;
|
||
tbl.AddHeaderCell(NewTh("Datum", rowspan: 2))
|
||
.AddHeaderCell(NewTh("Text", rowspan: 2, colspan: tw, left: true))
|
||
.AddHeaderCell(NewTh("Geschäftsanteile", colspan: App.Client.HasRedWhite ? 3 : 2));
|
||
if (App.Client.HasRedWhite) {
|
||
tbl.AddHeaderCell(NewTh("rot"))
|
||
.AddHeaderCell(NewTh("weiß"))
|
||
.AddHeaderCell(NewTh("ruhend"));
|
||
} else {
|
||
tbl.AddHeaderCell(NewTh("normal"))
|
||
.AddHeaderCell(NewTh("ruhend"));
|
||
}
|
||
|
||
if (!history.Any() || Member.EntryDate <= history.First().Date) {
|
||
tbl.AddCell(NewTd($"{Member.EntryDate:dd.MM.yyyy}"))
|
||
.AddCell(NewTd("Eintritt", colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(new()));
|
||
}
|
||
|
||
var recorded = history.Aggregate(new MemberHistoryPoint(), (s, h) => new(
|
||
s.Shares + (h.ToMgNr == Member.MgNr && h.ToType == 1 ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == 1 ? h.Shares : 0),
|
||
s.SharesRed + (h.ToMgNr == Member.MgNr && h.ToType == 2 ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == 2 ? h.Shares : 0),
|
||
s.SharesWhite + (h.ToMgNr == Member.MgNr && h.ToType == 3 ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == 3 ? h.Shares : 0),
|
||
s.SharesDormant + (h.ToMgNr == Member.MgNr && h.ToType == 9 ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == 9 ? h.Shares : 0)));
|
||
var cur = new MemberHistoryPoint(Member.Shares - recorded.Shares, Member.SharesRed - recorded.SharesRed, Member.SharesWhite - recorded.SharesWhite, Member.SharesDormant - recorded.SharesDormant);
|
||
|
||
if (cur.Shares != 0 || cur.SharesRed != 0 || cur.SharesWhite != 0 || cur.SharesDormant != 0) {
|
||
tbl.AddCell(NewTd())
|
||
.AddCell(NewTd("Nicht erfasst", colspan: tw, italic: true))
|
||
.AddCells(NewBusinessSharesCells(cur));
|
||
if (history.Any()) {
|
||
tbl.AddCell(NewTd(borderTop: true))
|
||
.AddCell(NewTd($"Bis Lese {history.First().Date.Year - 1}", borderTop: true, colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(cur, isDiff: false));
|
||
}
|
||
}
|
||
|
||
DateOnly? lastDate = null;
|
||
foreach (var row in history) {
|
||
int s = 0, r = 0, w = 0, d = 0;
|
||
if (row.FromMgNr == Member.MgNr) {
|
||
switch (row.FromType) {
|
||
case 1: s -= row.Shares; break;
|
||
case 2: r -= row.Shares; break;
|
||
case 3: w -= row.Shares; break;
|
||
case 9: d -= row.Shares; break;
|
||
}
|
||
}
|
||
if (row.ToMgNr == Member.MgNr) {
|
||
switch (row.ToType) {
|
||
case 1: s += row.Shares; break;
|
||
case 2: r += row.Shares; break;
|
||
case 3: w += row.Shares; break;
|
||
case 9: d += row.Shares; break;
|
||
}
|
||
}
|
||
if (lastDate < Member.EntryDate && row.Date <= Member.EntryDate) {
|
||
tbl.AddCell(NewTd($"{Member.EntryDate:dd.MM.yyyy}"))
|
||
.AddCell(NewTd("Eintritt", colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(new()));
|
||
}
|
||
if (lastDate != null && row.Date.Year != lastDate?.Year) {
|
||
tbl.AddCell(NewTd(borderTop: true))
|
||
.AddCell(NewTd(lastDate?.Year == row.Date.Year - 1 ? $"Lese {lastDate?.Year}" : $"Lese {lastDate?.Year}–{row.Date.Year - 1}", borderTop: true, colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(cur, isDiff: false));
|
||
}
|
||
if (lastDate < Member.ExitDate && row.Date <= Member.ExitDate) {
|
||
tbl.AddCell(NewTd($"{Member.ExitDate:dd.MM.yyyy}"))
|
||
.AddCell(NewTd("Austritt", colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(new()));
|
||
}
|
||
cur = new(cur.Shares + s, cur.SharesRed + r, cur.SharesWhite + w, cur.SharesDormant + d);
|
||
|
||
var reason = row.Reason;
|
||
if (reason == "auto") {
|
||
reason = "Automatische Nachzeichnung";
|
||
} else if (reason == "transfer") {
|
||
if (row.ToMgNr == Member.MgNr) {
|
||
reason = $"Übertragen von {row.FromMember.AdministrativeName} (MgNr. {row.FromMgNr})";
|
||
} else {
|
||
reason = $"Übertragen an {row.ToMember.AdministrativeName} (MgNr. {row.ToMgNr})";
|
||
}
|
||
}
|
||
|
||
tbl.AddCell(NewTd($"{row.Date:dd.MM.yyyy}"))
|
||
.AddCell(NewTd(reason, colspan: tw))
|
||
.AddCells(NewBusinessSharesCells(new(s, r, w, d)));
|
||
lastDate = row.Date;
|
||
}
|
||
|
||
if (Member.ExitDate != null && (!history.Any() || Member.ExitDate > history.Last().Date)) {
|
||
tbl.AddCell(NewTd($"{Member.ExitDate:dd.MM.yyyy}"))
|
||
.AddCell(NewTd("Austritt", colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(new()));
|
||
}
|
||
|
||
tbl.AddCell(NewTd(borderTop: true))
|
||
.AddCell(NewTd(lastDate == null ? "Aktuell" : $"Ab Lese {lastDate?.Year}", borderTop: true, colspan: tw, bold: true))
|
||
.AddCells(NewBusinessSharesCells(cur, isDiff: false));
|
||
|
||
return tbl;
|
||
}
|
||
}
|
||
}
|