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 AreaComUnderDeliveryData : DataTable { private static readonly (string, string, string?, int)[] FieldNames = new[] { ("MgNr", "MgNr.", null, 12), ("Name", "Name", null, 40), ("GivenName", "Vorname", null, 40), ("Address", "Adresse", null, 60), ("Plz", "PLZ", null, 10), ("Locality", "Ort", null, 60), ("VtrgIds", "Vertrag", null, 14), ("Areas", "Fläche", "m²", 16), ("DeliveryObligations", "Lieferpflicht", "kg", 22), ("Weights", "Geliefert", "kg", 22), ("UnderDeliveries", "Unterliefert", "kg|%", 34), }; public AreaComUnderDeliveryData(IEnumerable rows, int year) : base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) { } public static async Task ForSeason(DbSet table, int year) { return new AreaComUnderDeliveryData( (await FromDbSet(table, year)).GroupBy( r => r.MgNr, (k, g) => new AreaComUnderDeliveryRow(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, c.bucket, c.area, u.min_kg, u.weight FROM member m LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest LEFT JOIN AT_ort o ON o.okz = p.okz LEFT JOIN v_area_commitment_bucket_strict c ON c.mgnr = m.mgnr AND c.year = {year} JOIN v_under_delivery u ON (u.mgnr, u.bucket, u.year) = (m.mgnr, c.bucket, c.year) WHERE m.active = 1 ORDER BY m.mgnr, c.bucket """).ToListAsync(); } } public class AreaComUnderDeliveryRow { public int MgNr; public string Name; public string GivenName; public string Address; public int Plz; public string Locality; public string[] VtrgIds; public int[] Areas; public int[] DeliveryObligations; public int[] Weights; public (int? Kg, double? Percent)[] UnderDeliveries => Weights.Zip(DeliveryObligations) .Select(v => v.First < v.Second ? ((int?, double?))(v.First - v.Second, v.First * 100.0 / v.Second - 100.0) : (null, null)) .ToArray(); public AreaComUnderDeliveryRow(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]; VtrgIds = rows.Select(r => r.VtrgId).ToArray(); Areas = rows.Select(r => r.Area).ToArray(); DeliveryObligations = rows.Select(r => r.DeliveryObligation).ToArray(); Weights = rows.Select(r => r.Weight).ToArray(); } } [Keyless] public class AreaComUnderDeliveryRowSingle { [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("min_kg")] public int DeliveryObligation { get; set; } [Column("weight")] public int Weight { get; set; } } }