using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Threading.Tasks; namespace Elwig.Models.Dtos { public class MemberDeliveryPerVariantData : DataTable { private static readonly (string, string, int)[] FieldNames = new[] { ("MgNr", "MgNr.", 12), ("Name", "Name", 40), ("GivenName", "Vorname", 40), ("Address", "Adresse", 60), ("Plz", "PLZ", 10), ("Locality", "Ort", 60), ("SortIds", "Sorte", 12), ("AttrIds", "Attribut", 16), ("Weights", "Geliefert", 22), ("Areas", "Fläche", 22), ("Yields", "Ertrag", 22), }; public MemberDeliveryPerVariantData(IEnumerable rows, int year) : base($"Liefermengen", $"Liefermengen pro Mitglied, Sorte und Attribut {year}", rows, FieldNames) { } public static async Task ForSeason(DbSet table, int year) { return new MemberDeliveryPerVariantData( (await FromDbSet(table, year)).GroupBy( r => r.MgNr, (k, g) => new MemberDeliveryPerVariantRow(g) ), year); } private static async Task> FromDbSet(DbSet table, int year) { return await table.FromSqlRaw($""" SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address, v.bucket, v.weight, v.area FROM ( SELECT c.year AS year, c.mgnr AS mgnr, c.bucket AS bucket, COALESCE(d.weight, 0) AS weight, COALESCE(c.area, 0) AS area FROM v_area_commitment_bucket_strict c LEFT JOIN v_delivery_bucket_strict d ON (d.year, d.mgnr, d.bucket) = (c.year, c.mgnr, c.bucket) WHERE c.year = {year} UNION SELECT d.year, d.mgnr, d.bucket, COALESCE(d.weight, 0), COALESCE(c.area, 0) FROM v_delivery_bucket_strict d LEFT JOIN v_area_commitment_bucket_strict c ON (c.year, c.mgnr, c.bucket) = (d.year, d.mgnr, d.bucket) WHERE d.year = {year} ) v LEFT JOIN member m ON m.mgnr = v.mgnr LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest LEFT JOIN AT_ort o ON o.okz = p.okz ORDER BY m.mgnr, v.bucket """).ToListAsync(); } } public class MemberDeliveryPerVariantRow { public int MgNr; public string Name; public string GivenName; public string Address; public int Plz; public string Locality; public string[] SortIds; public string[] AttrIds; public int[] Areas; public int[] Weights; public int?[] Yields => Weights.Zip(Areas).Select(i => i.Second > 0 ? (int?)i.First * 10_000 / i.Second : null).ToArray(); public MemberDeliveryPerVariantRow(IEnumerable rows) { var f = rows.First(); MgNr = f.MgNr; Name = f.Name; GivenName = f.GivenName; Address = f.Address; Plz = f.Plz; Locality = f.Locality.Split(",")[0]; SortIds = rows.Select(r => r.VtrgId[..2]).ToArray(); AttrIds = rows.Select(r => r.VtrgId[2..]).ToArray(); Areas = rows.Select(r => r.Area).ToArray(); Weights = rows.Select(r => r.Weight).ToArray(); } } [Keyless] public class MemberDeliveryPerVariantRowSingle { [Column("mgnr")] public int MgNr { get; set; } [Column("family_name")] public string Name { get; set; } [Column("given_name")] public string GivenName { get; set; } [Column("address")] public string Address { get; set; } [Column("plz")] public int Plz { get; set; } [Column("ort")] public string Locality { get; set; } [Column("bucket")] public string VtrgId { get; set; } [Column("area")] public int Area { get; set; } [Column("weight")] public int Weight { get; set; } } }