Bug was introduced by commit 9930e6173c
and shipped with v0.10.6 (2024-08-30)
		
	
		
			
				
	
	
		
			78 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			3.4 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.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
 | |
|                 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
 | |
|                 """).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);
 | |
|     }
 | |
| }
 |