using Elwig.Models.Entities; using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Elwig.Models.Dtos { public class DeliveryConfirmationDeliveryData : DataTable { private static readonly (string, string, string?, int)[] FieldNames = [ ("LsNr", "LsNr.", null, 26), ("DPNr", "Pos.", null, 8), ("Variety", "Sorte", null, 40), ("Attribute", "Attribut", null, 20), ("Modifiers", "Zu-/Abschläge", null, 30), ("QualityLevel", "Qualitätsstufe", null, 25), ("Gradation", "Gradation", "°Oe|°KMW", 32), ("Buckets", "Flächenbindung", "|kg", 36), ("Weight", "Gewicht", "kg", 16), ]; private readonly int MgNr; private DeliveryConfirmationDeliveryData(IEnumerable rows, int year, Member m) : base($"Anlieferungsbestätigung", $"Anlieferungsbestätigung {year} – {m.AdministrativeName}", rows, FieldNames) { MgNr = m.MgNr; } public static DeliveryConfirmationDeliveryData CreateEmpty(int year, Member m) { return new([], year, m); } public static async Task> ForSeason(DbSet table, int year) { return (await FromDbSet(table, year)) .GroupBy( p => p.Delivery.Member, p => new DeliveryConfirmationDeliveryRow(p), (k, g) => new DeliveryConfirmationDeliveryData(g, year, k) ).ToDictionary(d => d.MgNr, d => d); } public static async Task ForMember(DbSet table, int year, Member m) { return new DeliveryConfirmationDeliveryData((await FromDbSet(table, year, m.MgNr)).Select(p => new DeliveryConfirmationDeliveryRow(p)), year, m); } private static async Task> FromDbSet(DbSet table, int? year = null, int? mgnr = null) { var y = year?.ToString() ?? "NULL"; var m = mgnr?.ToString() ?? "NULL"; IQueryable q = table; if (year != null) q = q.Where(p => p.Year == year); if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr); await q .Include(p => p.Delivery) .Include(p => p.Variety) .Include(p => p.Attribute) .Include(p => p.Quality) .Include(p => p.Buckets) .Include(p => p.PartModifiers) .ThenInclude(m => m.Modifier) .LoadAsync(); return await table.FromSqlRaw($""" SELECT p.* FROM v_delivery v JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (v.year, v.did, v.dpnr) WHERE (p.year = {y} OR {y} IS NULL) AND (v.mgnr = {m} OR {m} IS NULL) ORDER BY p.year, v.mgnr, v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr """).ToListAsync(); } } public class DeliveryConfirmationDeliveryRow { public string LsNr; public int DPNr; public string Variety; public string? Attribute; public string? Cultivation; public string QualityLevel; public (double Oe, double Kmw) Gradation; public string[] Modifiers; public int Weight; public (string Name, int Value)[] Buckets; public DeliveryConfirmationDeliveryRow(DeliveryPart p) { var d = p.Delivery; LsNr = d.LsNr; DPNr = p.DPNr; Variety = p.Variety.Name; Attribute = p.Attribute?.Name; Cultivation = p.Cultivation?.Name; QualityLevel = p.Quality.Name; Gradation = (p.Oe, p.Kmw); Modifiers = p.Modifiers .Select(m => m.Name) .ToArray(); Weight = p.Weight; Buckets = p.Buckets .Where(b => b.Value > 0) .OrderByDescending(b => b.BktNr) .Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{b.Discr}", b.Value)) .ToArray(); } } }