using Elwig.Helpers; using Elwig.Models.Entities; using System; using System.Collections.Generic; using System.Linq; namespace Elwig.Models.Dtos { public class MemberMovementData : DataTable { private static readonly (string, string, string?, int)[] FieldNames = [ ("Type", "\u2026 durch", null, 30), ("MgNr", "MgNr.", null, 12), ("Name1", "Name", null, 40), ("Name2", "Vorname", null, 25), ("Address", "Adresse", null, 50), ("Plz", "PLZ", null, 10), ("Locality", "Ort", null, 50), ("Date", "Datum", null, 20), ("SharesOld", "GA\nalt", null, 10), ("SharesDiff", "GA\nDiff.", null, 10), ("SharesNew", "GA\nneu", null, 10), ("Costs", "Kosten", "€", 15), ]; private MemberMovementData(string name, IEnumerable<(string? Name, IEnumerable Rows)> sections) : base("Mitgl.-Bewegungen", name, sections, FieldNames) { } public static MemberMovementData FromMemberHistory(string name, IEnumerable rows, Dictionary> history) { (string? Name, List Rows)[] sections = [ ("Beitritt", []), ("Nachzeichnung (GA)", []), ("Überschreibung", []), ("Kündigung (GA)", []), ("Austritt", []), ]; foreach (var h in rows.OrderBy(r => r.DateNotice).ThenBy(r => r.ToMgNr).ThenBy(r => r.FromMgNr)) { int cat; if (h.ToMgNr == h.FromMgNr) { // Umwandlung if (h.ToType == BusinessShareType.Dormant) { // Kündigung (GA) cat = 3; } else if (h.FromType == h.ToType) { // Überschreibung cat = 2; } else { throw new NotImplementedException(); } } else if (h.DateNotice <= h.ToMember?.EntryDate && h.DateNotice >= h.FromMember?.ExitDate) { // Überschreibung cat = 2; } else if (h.DateNotice <= h.ToMember?.EntryDate) { // Beitritt cat = 0; } else if (h.DateNotice >= h.FromMember?.ExitDate) { // Austritt cat = 4; } else if (h.ToMember == null) { // Auszahlung continue; } else { // Nachzeichnung (GA) cat = 1; } Member a; Member? b = null; if (h.FromMember != null && h.ToMember != null) { if (cat <= 1) { a = h.ToMember; b = h.FromMember; } else { a = h.FromMember; b = h.ToMember; } } else if (h.FromMember != null) { a = h.FromMember; } else if (h.ToMember != null) { a = h.ToMember; } else { throw new ArgumentException(); } var oldA = history[a.MgNr].GetValueOrDefault(h.DateNotice); var d = new MemberMovementDataRow { Type = [h.ReasonPretty], MgNr = [a.MgNr], Name1 = [a.Name], Name2 = [a.AdministrativeName2], Address = [a.Address], Plz = [a.PostalDest.AtPlz!.Plz], Locality = [a.PostalDest.AtPlz.Ort.Name], Date = h.DateNotice, SharesOld = [oldA.Shares + oldA.SharesRed + oldA.SharesWhite], SharesDiff = [cat != 3 && a == h.ToMember ? h.Shares : -h.Shares], Costs = [h.FromMember == null ? h.TotalValue : null], }; d.SharesNew = [d.SharesOld[^1] + (h.FromMgNr == h.ToMgNr ? 0 : d.SharesDiff[^1])]; if (b != null) { var oldB = history[b.MgNr].GetValueOrDefault(h.DateNotice); d.Type = [..d.Type, "\u2026 " + (cat <= 1 ? "von" : "an")]; d.MgNr = [.. d.MgNr, b.MgNr]; d.Name1 = [.. d.Name1, b.Name]; d.Name2 = [.. d.Name2, b.AdministrativeName2]; d.Address = [.. d.Address, b.Address]; d.Plz = [.. d.Plz, b.PostalDest.AtPlz!.Plz]; d.Locality = [.. d.Locality, b.PostalDest.AtPlz.Ort.Name]; d.SharesOld = [.. d.SharesOld, oldB.Shares + oldB.SharesRed + oldB.SharesWhite]; d.SharesDiff = [.. d.SharesDiff, b == h.ToMember ? h.Shares : -h.Shares]; d.SharesNew = [.. d.SharesNew, d.SharesOld[^1] + d.SharesDiff[^1]]; } sections[cat].Rows.Add(d); } return new MemberMovementData($"Mitglieder-Bewegungen {name}", sections.Select(s => (s.Name, (IEnumerable)s.Rows))); } } public class MemberMovementDataRow { public string[] Type = []; public int[] MgNr = []; public string[] Name1 = []; public string?[] Name2 = []; public string[] Address = []; public int[] Plz = []; public string[] Locality = []; public DateOnly Date; public int?[] SharesOld = []; public int[] SharesDiff = []; public int?[] SharesNew = []; public decimal?[] Costs = []; } }