79 lines
3.5 KiB
C#
79 lines
3.5 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
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 = [
|
|
("MgNr", "MgNr.", null, 12),
|
|
("Name1", "Name", null, 40),
|
|
("Name2", "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|%", 34),
|
|
];
|
|
|
|
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.name AS name_1,
|
|
COALESCE(m.prefix || ' ', '') || m.given_name ||
|
|
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
|
|
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 v_delivery d
|
|
LEFT JOIN member m ON m.mgnr = d.mgnr
|
|
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 = d.year
|
|
WHERE s.year = {year} AND (m.active = TRUE OR d.weight > 0)
|
|
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("name_1")]
|
|
public required string Name1 { get; set; }
|
|
[Column("name_2")]
|
|
public string? Name2 { get; set; }
|
|
[Column("address")]
|
|
public required string Address { get; set; }
|
|
[Column("plz")]
|
|
public int Plz { get; set; }
|
|
[Column("ort")]
|
|
public required 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? Kg, double? Percent) OverUnderDelivery =>
|
|
Weight < DeliveryObligation ? (Weight - DeliveryObligation, Weight * 100.0 / DeliveryObligation - 100.0) :
|
|
Weight > DeliveryRight ? (Weight - DeliveryRight, Weight * 100.0 / DeliveryRight - 100.0) : (null, null);
|
|
}
|
|
}
|