using Elwig.Helpers; using Elwig.Models; using Elwig.Models.Entities; using System.Collections.Generic; using System.Globalization; using System.Linq; namespace Elwig.Documents { public abstract class BusinessDocument : Document { public Member Member; public string? Location; public bool IncludeSender = false; public bool UseBillingAddress = false; public bool ShowDateAndLocation = false; public string Aside; public BusinessDocument(string title, Member m, bool includeSender = false) : base(title) { Member = m; Location = App.BranchLocation; IncludeSender = includeSender; var uid = (m.UstIdNr ?? "-") + (m.IsBuchführend ? "" : " (pauschaliert)"); Aside = $"" + $"" + $"" + $"" + $"" + $"
Mitglied
Mitglieds-Nr.:{m.MgNr}
Betriebs-Nr.:{m.LfbisNr}
UID:{uid}
"; } public string Address { get { IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member; var plz = addr.PostalDest.AtPlz; return string.Join("\n", ((string?[])[Member.BillingAddress?.FullName, Member.AdministrativeName, Member.ForTheAttentionOf, addr.Address, $"{plz?.Plz} {plz?.Ort.Name.Split(",")[0]}", addr.PostalDest.Country.Name]).Where(s => !string.IsNullOrWhiteSpace(s))); } } private static string GetColGroup(IEnumerable cols) { return "\n" + string.Join("\n", cols.Select(g => $"")) + "\n\n"; } public static string PrintSortenaufteilung(List stats) { List discrs = [""]; List names = ["ohne Attr./Bewirt."]; List bucketAttrs = [ .. stats .Select(s => s.Discr) .Distinct() .Where(s => s.Length > 0) .Order() ]; names.AddRange(bucketAttrs); names.Add("Gesamt"); discrs.AddRange(bucketAttrs); List cols = [40]; cols.AddRange(names.Select(_ => 125.0 / names.Count)); string tbl = GetColGroup(cols); tbl += "" + $"Sortenaufteilung [kg]" + string.Join("", names.Select(c => $"{c}")) + ""; tbl += string.Join("\n", stats .GroupBy(b => b.Variety) .OrderBy(b => b.Key) .Select(g => { var dict = g.ToDictionary(a => a.Discr, a => a.Weight); var vals = discrs.Select(a => dict.GetValueOrDefault(a, 0)).ToList(); return $"{g.Key}" + string.Join("", vals.Select(v => "" + (v == 0 ? "-" : $"{v:N0}") + "")) + $"{dict.Values.Sum():N0}"; }) ); var totalDict = stats.GroupBy(s => s.Discr).ToDictionary(g => g.Key, g => g.Sum(a => a.Weight)); var totals = discrs.Select(a => totalDict.TryGetValue(a, out int value) ? value : 0); tbl += "" + string.Join("", totals.Select(v => $"{v:N0}")) + $"{totalDict.Values.Sum():N0}"; return "" + tbl + "
"; } private static string FormatRow( int obligation, int right, int delivery, int? totalDelivery = null, int? payment = null, int? area = null, bool isGa = false, bool showPayment = false, bool showArea = false ) { totalDelivery ??= delivery; payment ??= delivery; if (showArea) { return $"{(area == null ? "" : $"{area:N0}")}" + $"{obligation:N0}" + $"{right:N0}"; } return $"{(obligation == 0 ? "-" : $"{obligation:N0}")}" + $"{(right == 0 ? "-" : $"{right:N0}")}" + $"{(totalDelivery < obligation ? $"{obligation - totalDelivery:N0}" : "-")}" + $"{(delivery <= right ? $"{right - delivery:N0}" : "-")}" + $"{(obligation == 0 && right == 0 ? "-" : (delivery > right ? ((isGa ? "" : "") + $"{delivery - right:N0}" + (isGa ? "" : "")) : "-"))}" + (showPayment ? $"{(isGa ? "" : obligation == 0 && right == 0 ? "-" : $"{payment:N0}")}" : "") + $"{totalDelivery:N0}"; } private static string FormatRow(MemberBucket bucket, bool isGa = false, bool showPayment = false, bool showArea = false) { return FormatRow(bucket.Obligation, bucket.Right, bucket.Delivery, bucket.DeliveryTotal, bucket.Payment, bucket.Area, isGa, showPayment, showArea); } public string PrintBucketTable( Season season, Dictionary buckets, bool includeDelivery = true, bool includePayment = false, bool isTiny = false, IEnumerable? filter = null ) { includePayment = includePayment && includeDelivery; string tbl = GetColGroup(!includeDelivery ? [105, 20, 20, 20] : includePayment ? [45, 17, 17, 17, 19, 16, 17, 17] : [45, 20, 20, 20, 20, 20, 20]); tbl += $""" {(includeDelivery ? "Lese " + season.Year : "Zusammengefasste Flächenbindungen")} per {Date:dd.MM.yyyy} {(includeDelivery ? "[kg]" : "")} {(!includeDelivery ? "Fläche" : "")} Lieferpflicht Lieferrecht {(includeDelivery ? "Unterliefert" : "")} {(includeDelivery ? "Noch lieferbar" : "")} {(includeDelivery ? "Überliefert" : "")} {(includePayment ? "Zugeteilt" : "")} {(includeDelivery ? "Geliefert" : "")} {(!includeDelivery ? "[m²][kg][kg]" : "")} """; var mBuckets = buckets .Where(b => ((!includeDelivery && b.Value.Area > 0) || (includeDelivery && (b.Value.Right > 0 || b.Value.Obligation > 0 || b.Value.Delivery > 0))) && (filter == null || filter.Contains(b.Key[..2]))) .ToList(); var fbVars = mBuckets .Where(b => b.Value.Right > 0 || b.Value.Obligation > 0) .Select(b => b.Key.Replace("_", "")) .Order() .ToArray(); var fbs = mBuckets .Where(b => fbVars.Contains(b.Key) && b.Key.Length == 2) .OrderBy(b => b.Value.Name); var vtr = mBuckets .Where(b => fbVars.Contains(b.Key) && b.Key.Length > 2) .OrderBy(b => b.Value.Name); var rem = mBuckets .Where(b => !fbVars.Contains(b.Key)) .OrderBy(b => b.Value.Name); tbl += "\n\n"; tbl += $"Gesamtlieferung lt. gez. GA{FormatRow( Member.BusinessShares * season.MinKgPerBusinessShare, Member.BusinessShares * season.MaxKgPerBusinessShare, season.Deliveries.Where(d => d.MgNr == Member.MgNr).Sum(d => d.Weight), isGa: true, showPayment: includePayment, showArea: !includeDelivery )}"; if (fbs.Any()) { tbl += $"" + $"Flächenbindungen{(vtr.Any() ? " (inkl. Verträge)" : "")}:"; foreach (var (id, b) in fbs) { tbl += $"{b.Name}{FormatRow(b, showPayment: includePayment, showArea: !includeDelivery)}"; } } if (vtr.Any()) { tbl += $"" + "Verträge:"; foreach (var (id, b) in vtr) { tbl += $"{b.Name}{FormatRow(b, showPayment: includePayment, showArea: !includeDelivery)}"; } } tbl += "\n\n"; return $"\n" + tbl + "\n
"; } } }