[#20][#80] Elwig: Update member_history and add different types of shares
Test / Run tests (push) Successful in 2m0s

This commit is contained in:
2026-07-01 11:01:15 +02:00
parent 4ebe07f579
commit feee6ad1ec
37 changed files with 858 additions and 264 deletions
+79 -16
View File
@@ -13,33 +13,72 @@ namespace Elwig.Models.Dtos {
("Address", "Adresse", null, 60),
("Plz", "PLZ", null, 10),
("Locality", "Ort", null, 60),
("BusinessShares", "GA", null, 10),
("Shares", "GA", null, 10),
("DeliveryObligation", "Lieferpflicht", "kg", 22),
("DeliveryRight", "Lieferrecht", "kg", 22),
("Weight", "Geliefert", "kg", 22),
("WeightTotal", "Geliefert", "kg", 22),
("OverUnderDelivery", "Über-/Unterliefert", "kg|%", 34),
];
private static readonly (string, string, string?, int)[] FieldNamesRed = [
("MgNr", "MgNr.", null, 12),
("Name1", "Name", null, 40),
("Name2", "Vorname", null, 40),
("Address", "Adresse", null, 60),
("Plz", "PLZ", null, 10),
("Locality", "Ort", null, 60),
("SharesRed", "GA", null, 10),
("DeliveryObligationRed", "Lieferpflicht", "kg", 22),
("DeliveryRightRed", "Lieferrecht", "kg", 22),
("WeightRed", "Geliefert", "kg", 22),
("OverUnderDeliveryRed", "Über-/Unterliefert", "kg|%", 34),
];
private static readonly (string, string, string?, int)[] FieldNamesWhite = [
("MgNr", "MgNr.", null, 12),
("Name1", "Name", null, 40),
("Name2", "Vorname", null, 40),
("Address", "Adresse", null, 60),
("Plz", "PLZ", null, 10),
("Locality", "Ort", null, 60),
("SharesWhite", "GA", null, 10),
("DeliveryObligationWhite", "Lieferpflicht", "kg", 22),
("DeliveryRightWhite", "Lieferrecht", "kg", 22),
("WeightWhite", "Geliefert", "kg", 22),
("OverUnderDeliveryWhite", "Ü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 OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year, string mode) :
base($"Über-Unterlieferungen", $"Über- und Unterlieferungen laut gezeichneten Geschäftsanteilen {(mode == "R" ? "rot" : "weiß")} {year}", rows,
mode == "R" ? FieldNamesRed : FieldNamesWhite) {
}
public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) {
var rows = await table.FromSql($"""
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
p.plz, o.name AS ort, m.address, h.shares, h.shares_red, h.shares_white,
h.shares * COALESCE(s.min_kg_per_share, 0) AS min_kg,
h.shares * COALESCE(s.max_kg_per_share, 0) AS max_kg,
h.shares_red * COALESCE(s.min_kg_per_share_red, s.min_kg_per_share, 0) AS min_kg_red,
h.shares_red * COALESCE(s.max_kg_per_share_red, s.max_kg_per_share, 0) AS max_kg_red,
h.shares_white * COALESCE(s.min_kg_per_share_white, s.min_kg_per_share, 0) AS min_kg_white,
h.shares_white * COALESCE(s.max_kg_per_share_white, s.max_kg_per_share, 0) AS max_kg_white,
COALESCE(d.weight_total, 0) AS weight_total,
COALESCE(d.weight_red, 0) AS weight_red,
COALESCE(d.weight_white, 0) AS weight_white
FROM season s, 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_delivery d ON (d.year, d.mgnr) = (s.year, m.mgnr)
WHERE s.year = {year} AND (m.active = TRUE OR d.weight > 0)
GROUP BY s.year, m.mgnr
ORDER BY 100.0 * sum / max_kg, m.mgnr
LEFT JOIN v_member_history h ON (h.year, h.mgnr) = (s.year, m.mgnr)
LEFT JOIN v_stat_member d ON (d.year, d.mgnr) = (s.year, m.mgnr)
WHERE s.year = {year} AND (m.active = TRUE OR d.weight_total > 0)
ORDER BY 100.0 * weight_total / (max_kg + max_kg_red + max_kg_white), m.mgnr
""").ToListAsync();
return new OverUnderDeliveryData(rows, year);
}
@@ -61,17 +100,41 @@ namespace Elwig.Models.Dtos {
public required string LocalityFull { get; set; }
[NotMapped]
public string Locality => LocalityFull.Split(",")[0];
[Column("business_shares")]
public int BusinessShares { get; set; }
[Column("shares")]
public int Shares { get; set; }
[Column("shares_red")]
public int SharesRed { get; set; }
[Column("shares_white")]
public int SharesWhite { 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);
WeightTotal < DeliveryObligation ? (WeightTotal - DeliveryObligation, WeightTotal * 100.0 / DeliveryObligation - 100.0) :
WeightTotal > DeliveryRight ? (WeightTotal - DeliveryRight, WeightTotal * 100.0 / DeliveryRight - 100.0) : (null, null);
[Column("min_kg_red")]
public int DeliveryObligationRed { get; set; }
[Column("max_kg_red")]
public int DeliveryRightRed { get; set; }
[NotMapped]
public (int? Kg, double? Percent) OverUnderDeliveryRed =>
WeightRed < DeliveryObligationRed ? (WeightRed - DeliveryObligationRed, WeightRed * 100.0 / DeliveryObligationRed - 100.0) :
WeightRed > DeliveryRightRed ? (WeightRed - DeliveryRightRed, WeightRed * 100.0 / DeliveryRightRed - 100.0) : (null, null);
[Column("min_kg_white")]
public int DeliveryObligationWhite { get; set; }
[Column("max_kg_white")]
public int DeliveryRightWhite { get; set; }
[NotMapped]
public (int? Kg, double? Percent) OverUnderDeliveryWhite =>
WeightWhite < DeliveryObligationWhite ? (WeightWhite - DeliveryObligationWhite, WeightWhite * 100.0 / DeliveryObligationWhite - 100.0) :
WeightWhite > DeliveryRightWhite ? (WeightWhite - DeliveryRightWhite, WeightWhite * 100.0 / DeliveryRightWhite - 100.0) : (null, null);
[Column("weight_total")]
public int WeightTotal { get; set; }
[Column("weight_red")]
public int WeightRed { get; set; }
[Column("weight_white")]
public int WeightWhite { get; set; }
}
}