Files
elwig/Elwig/Models/Dtos/OverUnderDeliveryData.cs

82 lines
3.4 KiB
C#

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Threading.Tasks;
namespace Elwig.Models.Dtos {
public class OverUnderDeliveryData : DataTable<OverUnderDeliveryRow> {
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),
("BusinessShares", "GA", null, 10),
("DeliveryObligation", "Lieferpflicht", "kg", 22),
("DeliveryRight", "Lieferrecht", "kg", 22),
("Weight", "Geliefert", "kg", 22),
("OverUnderDelivery", "Über-/Unterliefert", "kg", 35),
("Percent", "Prozent", "%", 16),
};
public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year) :
base($"Über-Unterlieferungen", $"Über- und Unterlieferungen laut gezeichneten Geschäftsanteilen {year}", rows, FieldNames) {
}
public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) {
var rows = await table.FromSqlRaw($"""
SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address, m.business_shares,
m.business_shares * s.min_kg_per_bs AS min_kg,
m.business_shares * s.max_kg_per_bs AS max_kg,
COALESCE(SUM(d.weight), 0) AS sum
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 season s ON s.year = {year}
LEFT JOIN v_delivery d ON d.mgnr = m.mgnr AND d.year = s.year
WHERE m.active = 1
GROUP BY d.year, m.mgnr
ORDER BY 100.0 * sum / max_kg, m.mgnr;
""").ToListAsync();
return new OverUnderDeliveryData(rows, year);
}
}
[Keyless]
public class OverUnderDeliveryRow {
[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 LocalityFull { get; set; }
[NotMapped]
public string Locality => LocalityFull.Split(",")[0];
[Column("business_shares")]
public int BusinessShares { get; set; }
[Column("min_kg")]
public int DeliveryObligation { get; set; }
[Column("max_kg")]
public int DeliveryRight { get; set; }
[Column("sum")]
public int Weight { get; set; }
[NotMapped]
public int? OverUnderDelivery =>
Weight < DeliveryObligation ? Weight - DeliveryObligation :
Weight > DeliveryRight ? Weight - DeliveryRight : null;
[NotMapped]
public double? Percent =>
Weight < DeliveryObligation ? Weight * 100.0 / DeliveryObligation - 100.0 :
Weight > DeliveryRight ? Weight * 100.0 / DeliveryRight - 100 : null;
}
}