diff --git a/Elwig/Helpers/Billing/Billing.cs b/Elwig/Helpers/Billing/Billing.cs
index 6b6a81d..545367b 100644
--- a/Elwig/Helpers/Billing/Billing.cs
+++ b/Elwig/Helpers/Billing/Billing.cs
@@ -55,7 +55,7 @@ namespace Elwig.Helpers.Billing {
COALESCE(LENGTH(attributes), 0) ASC, attribute_prio DESC, COALESCE(attributes, '~'),
kmw DESC, lsnr, dpnr
""";
- var reader = await cmd.ExecuteReaderAsync();
+ using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) {
deliveries.Add((
reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetString(3), reader.GetInt32(4),
@@ -125,7 +125,81 @@ namespace Elwig.Helpers.Billing {
await cmd.ExecuteNonQueryAsync();
}
- // TODO add second round to avoid under deliveries
+ if (!avoidUnderDeliveries)
+ return;
+
+ var underDeliveries = new Dictionary<(int, string), int>();
+ using (var cmd = cnx.CreateCommand()) {
+ cmd.CommandText = $"""
+ SELECT c.mgnr, c.bin, COALESCE(p.weight, 0) - c.min_kg AS diff
+ FROM v_area_commitment_bin c
+ LEFT JOIN v_payment_bin p ON (p.year, p.mgnr, p.bin) = (c.year, c.mgnr, c.bin)
+ WHERE c.year = {Year} AND LENGTH(c.bin) = 2 AND diff < 0
+ """;
+ using var reader = await cmd.ExecuteReaderAsync();
+ while (await reader.ReadAsync()) {
+ underDeliveries[(reader.GetInt32(0), reader.GetString(1))] = reader.GetInt32(2);
+ }
+ }
+
+ var fittingBins = new Dictionary<(int, string), int>();
+ using (var cmd = cnx.CreateCommand()) {
+ cmd.CommandText = $"""
+ SELECT c.mgnr, c.bin, COALESCE(p.weight, 0) - c.min_kg AS diff
+ FROM v_area_commitment_bin c
+ LEFT JOIN v_payment_bin p ON (p.year, p.mgnr, p.bin) = (c.year, c.mgnr, c.bin)
+ WHERE c.year = {Year} AND LENGTH(c.bin) = 3 AND diff > 0
+ """;
+ using var reader = await cmd.ExecuteReaderAsync();
+ while (await reader.ReadAsync()) {
+ fittingBins[(reader.GetInt32(0), reader.GetString(1))] = reader.GetInt32(2);
+ }
+ }
+
+ foreach (var item in fittingBins) {
+ var mgnr = item.Key.Item1;
+ var id = item.Key.Item2[..2];
+ var attr = item.Key.Item2[2..];
+ var available = item.Value;
+ var needed = -underDeliveries.GetValueOrDefault((mgnr, id), 0);
+ if (needed <= 0) continue;
+
+ var fittingDeliveries = new List<(int, int, int, int)>();
+ using (var cmd = cnx.CreateCommand()) {
+ cmd.CommandText = $"""
+ SELECT d.did, d.dpnr, d.weight, b.value
+ FROM v_delivery d
+ JOIN delivery_part_bin b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr) AND b.discr = '{attr}'
+ WHERE d.year = {Year} AND mgnr = {mgnr} AND sortid = '{id}' AND attributes = '{attr}'
+ ORDER BY kmw ASC, lsnr DESC, d.dpnr DESC
+ """;
+ using var reader = await cmd.ExecuteReaderAsync();
+ while (await reader.ReadAsync()) {
+ fittingDeliveries.Add((
+ reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3)
+ ));
+ }
+ }
+
+ var changes = new List<(int, int, int, int)>();
+ foreach (var (did, dpnr, _, w) in fittingDeliveries) {
+ int v = Math.Min(needed, w);
+ needed -= v;
+ changes.Add((did, dpnr, 1, v));
+ changes.Add((did, dpnr, 2, w - v));
+ if (needed == 0) break;
+ }
+
+ using (var cmd = cnx.CreateCommand()) {
+ cmd.CommandText = $"""
+ INSERT INTO delivery_part_bin (year, did, dpnr, binnr, discr, value)
+ VALUES {string.Join(",\n ", changes.Select(i => $"({Year}, {i.Item1}, {i.Item2}, {i.Item3}, '', {i.Item4})"))}
+ ON CONFLICT DO UPDATE
+ SET value = excluded.value
+ """;
+ await cmd.ExecuteNonQueryAsync();
+ }
+ }
}
}
}
diff --git a/Elwig/Windows/SeasonFinishWindow.xaml b/Elwig/Windows/SeasonFinishWindow.xaml
index b338edc..6f4e2f4 100644
--- a/Elwig/Windows/SeasonFinishWindow.xaml
+++ b/Elwig/Windows/SeasonFinishWindow.xaml
@@ -29,7 +29,7 @@
Margin="50,80,0,0"/>
-
Bei Lieferungen das Feld Gebunden berücksichtigen