Billing: Rename bins to buckets

This commit is contained in:
2023-11-02 13:06:32 +01:00
parent 9f67448b72
commit eebddf0527
11 changed files with 88 additions and 88 deletions

View File

@ -10,7 +10,7 @@ namespace Elwig.Documents {
public Credit Credit; public Credit Credit;
public string? Text; public string? Text;
public string CurrencySymbol; public string CurrencySymbol;
public string[] BinNames; public string[] BucketNames;
public int Precision; public int Precision;
public IEnumerable<DeliveryPart> Parts; public IEnumerable<DeliveryPart> Parts;
@ -27,7 +27,7 @@ namespace Elwig.Documents {
Text = App.Client.TextDeliveryNote; Text = App.Client.TextDeliveryNote;
DocumentId = $"Tr.-Gutschr. {c.TgId}"; DocumentId = $"Tr.-Gutschr. {c.TgId}";
CurrencySymbol = c.Payment.Variant.Season.Currency.Symbol ?? c.Payment.Variant.Season.Currency.Code; CurrencySymbol = c.Payment.Variant.Season.Currency.Symbol ?? c.Payment.Variant.Season.Currency.Code;
BinNames = new string[0]; // FIXME BucketNames = new string[0]; // FIXME
Precision = c.Payment.Variant.Season.Precision; Precision = c.Payment.Variant.Season.Precision;
Parts = ctx.DeliveryParts.FromSql($""" Parts = ctx.DeliveryParts.FromSql($"""
SELECT p.* SELECT p.*

View File

@ -4,7 +4,7 @@
@{ Layout = "BusinessDocument"; } @{ Layout = "BusinessDocument"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\CreditNote.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\CreditNote.css"/>
@{ @{
var binNum = Model.BinNames.Length; var bucketNum = Model.BucketNames.Length;
} }
<main> <main>
<h1>@Model.Title</h1> <h1>@Model.Title</h1>
@ -30,7 +30,7 @@
<th rowspan="3" style="text-align: left;">Attribut</th> <th rowspan="3" style="text-align: left;">Attribut</th>
<th rowspan="2" colspan="2">Gradation</th> <th rowspan="2" colspan="2">Gradation</th>
<th colspan="2">Zu-/Abschläge</th> <th colspan="2">Zu-/Abschläge</th>
<th colspan="2">@Raw(string.Join("<br/>", Model.BinNames))</th> <th colspan="2">@Raw(string.Join("<br/>", Model.BucketNames))</th>
<th rowspan="2">Betrag</th> <th rowspan="2">Betrag</th>
</tr> </tr>
<tr> <tr>
@ -61,23 +61,23 @@
var pmt = part.Payment; var pmt = part.Payment;
var abs = pmt?.ModAbs == null || pmt?.ModAbs == 0 ? "-" : pmt?.ModAbs.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision))); var abs = pmt?.ModAbs == null || pmt?.ModAbs == 0 ? "-" : pmt?.ModAbs.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision)));
var rel = pmt?.ModRel == null || pmt?.ModRel == 0 ? "-" : $"{pmt?.ModRel * 100:0.00##}"; var rel = pmt?.ModRel == null || pmt?.ModRel == 0 ? "-" : $"{pmt?.ModRel * 100:0.00##}";
<tr class="first @(binNum <= 1 ? "last" : "") @(last != null && last != part.SortId ? "new" : "")"> <tr class="first @(bucketNum <= 1 ? "last" : "") @(last != null && last != part.SortId ? "new" : "")">
<td rowspan="@binNum" class="lsnr">@part.Delivery.LsNr</td> <td rowspan="@bucketNum" class="lsnr">@part.Delivery.LsNr</td>
<td rowspan="@binNum" class="dpnr">@part.DPNr</td> <td rowspan="@bucketNum" class="dpnr">@part.DPNr</td>
<td rowspan="@binNum" class="variant">@part.Variant.Name</td> <td rowspan="@bucketNum" class="variant">@part.Variant.Name</td>
<td rowspan="@binNum" class="attribute">@part.Attribute?.Name</td> <td rowspan="@bucketNum" class="attribute">@part.Attribute?.Name</td>
<td rowspan="@binNum" class="oe">@($"{part.Oe:N0}")</td> <td rowspan="@bucketNum" class="oe">@($"{part.Oe:N0}")</td>
<td rowspan="@binNum" class="kmw">@($"{part.Kmw:N1}")</td> <td rowspan="@bucketNum" class="kmw">@($"{part.Kmw:N1}")</td>
<td rowspan="@binNum" class="abs">@abs</td> <td rowspan="@bucketNum" class="abs">@abs</td>
<td rowspan="@binNum" class="rel">@rel</td> <td rowspan="@bucketNum" class="rel">@rel</td>
<!--FIXME price--> <!--FIXME price-->
@Raw(FormatRow(pmt?.DeliveryPart.Bins?.ElementAtOrDefault(0)?.Value, 0)) @Raw(FormatRow(pmt?.DeliveryPart.Buckets?.ElementAtOrDefault(0)?.Value, 0))
<td rowspan="@binNum" class="amount sum">@($"{pmt?.Amount:N2}")</td> <td rowspan="@bucketNum" class="amount sum">@($"{pmt?.Amount:N2}")</td>
</tr> </tr>
@for (int i = 1; i < binNum; i++) { @for (int i = 1; i < bucketNum; i++) {
<tr class="@(i == binNum - 1 ? "last" : "")"> <tr class="@(i == bucketNum - 1 ? "last" : "")">
<!--FIXME price--> <!--FIXME price-->
@Raw(FormatRow(pmt?.DeliveryPart.Bins?.ElementAtOrDefault(i)?.Value, 0)) @Raw(FormatRow(pmt?.DeliveryPart.Buckets?.ElementAtOrDefault(i)?.Value, 0))
</tr> </tr>
} }
last = part.SortId; last = part.SortId;

View File

@ -11,7 +11,7 @@ namespace Elwig.Documents {
public Season Season; public Season Season;
public IEnumerable<DeliveryPart> Deliveries; public IEnumerable<DeliveryPart> Deliveries;
public string? Text = App.Client.TextDeliveryConfirmation; public string? Text = App.Client.TextDeliveryConfirmation;
public Dictionary<string, (string, int, int, int, int)> MemberBins; public Dictionary<string, (string, int, int, int, int)> MemberBuckets;
public DeliveryConfirmation(AppDbContext ctx, int year, Member m, IEnumerable<DeliveryPart>? deliveries = null) : public DeliveryConfirmation(AppDbContext ctx, int year, Member m, IEnumerable<DeliveryPart>? deliveries = null) :
base($"Anlieferungsbestätigung {year}", m) { base($"Anlieferungsbestätigung {year}", m) {
@ -28,7 +28,7 @@ namespace Elwig.Documents {
ORDER BY v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr ORDER BY v.sortid, v.abgewertet ASC, v.attribute_prio DESC, COALESCE(v.attrid, '~'), v.kmw DESC, v.lsnr, v.dpnr
""") """)
.ToList(); .ToList();
MemberBins = ctx.GetMemberBins(Season.Year, m.MgNr).GetAwaiter().GetResult(); MemberBuckets = ctx.GetMemberBuckets(Season.Year, m.MgNr).GetAwaiter().GetResult();
} }
} }
} }

View File

@ -44,11 +44,11 @@
var lastSortId = ""; var lastSortId = "";
} }
@foreach (var p in Model.Deliveries) { @foreach (var p in Model.Deliveries) {
var bins = p.Bins.Where(b => b.Value > 0).OrderByDescending(b => b.BktNr).ToArray(); var buckets = p.Buckets.Where(b => b.Value > 0).OrderByDescending(b => b.BktNr).ToArray();
var rowsBins = bins.Length; var rowsBuckets = buckets.Length;
var mods = p.Modifiers.Select(m => m.Name).ToArray(); var mods = p.Modifiers.Select(m => m.Name).ToArray();
var rowsMod = mods.Length + 1; var rowsMod = mods.Length + 1;
var rows = Math.Max(rowsBins, rowsMod); var rows = Math.Max(rowsBuckets, rowsMod);
var first = true; var first = true;
@for (int i = 0; i < rows; i++) { @for (int i = 0; i < rows; i++) {
<tr class="@(first ? "first" : "") @(p.SortId != lastSortId && lastSortId != "" ? "new": "") @(rows > i + 1 ? "trailing" : "")"> <tr class="@(first ? "first" : "") @(p.SortId != lastSortId && lastSortId != "" ? "new": "") @(rows > i + 1 ? "trailing" : "")">
@ -66,14 +66,14 @@
} else if (i > 0) { } else if (i > 0) {
<td colspan="3"></td> <td colspan="3"></td>
} }
@if (i < bins.Length) { @if (i < buckets.Length) {
var bin = bins[i]; var bucket = buckets[i];
<td class="geb">@(bin.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{bin.Discr}"):</td> <td class="geb">@(bucket.Discr == "_" ? "ungeb." : $"geb. {p.SortId}{bucket.Discr}"):</td>
<td class="weight">@($"{bin.Value:N0}")</td> <td class="weight">@($"{bucket.Value:N0}")</td>
} else { } else {
<td colspan="2"></td> <td colspan="2"></td>
} }
@if (i == bins.Length - 1) { @if (i == buckets.Length - 1) {
<td class="weight">@($"{p.Weight:N0}")</td> <td class="weight">@($"{p.Weight:N0}")</td>
} else { } else {
<td></td> <td></td>
@ -129,11 +129,11 @@
$"<td>{(mode != 2 ? "" : obligation == 0 && right == 0 ? "-" : $"{payment:N0}")}</td>" + $"<td>{(mode != 2 ? "" : obligation == 0 && right == 0 ? "-" : $"{payment:N0}")}</td>" +
$"<td>{sum:N0}</td>"; $"<td>{sum:N0}</td>";
} }
var mBins = Model.MemberBins.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0 || b.Value.Item4 > 0).ToList(); var mBuckets = Model.MemberBuckets.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0 || b.Value.Item4 > 0).ToList();
var fbVars = mBins.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0).Select(b => b.Key.Replace("_", "")).Order().ToArray(); var fbVars = mBuckets.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0).Select(b => b.Key.Replace("_", "")).Order().ToArray();
var fbs = mBins.Where(b => fbVars.Contains(b.Key) && b.Key.Length == 2).OrderBy(b => b.Value.Item1); var fbs = mBuckets.Where(b => fbVars.Contains(b.Key) && b.Key.Length == 2).OrderBy(b => b.Value.Item1);
var vtr = mBins.Where(b => fbVars.Contains(b.Key) && b.Key.Length > 2).OrderBy(b => b.Value.Item1); var vtr = mBuckets.Where(b => fbVars.Contains(b.Key) && b.Key.Length > 2).OrderBy(b => b.Value.Item1);
var rem = mBins.Where(b => !fbVars.Contains(b.Key)).OrderBy(b => b.Value.Item1); var rem = mBuckets.Where(b => !fbVars.Contains(b.Key)).OrderBy(b => b.Value.Item1);
} }
<tr> <tr>
<th>Gesamtlieferung lt. gez. GA</th> <th>Gesamtlieferung lt. gez. GA</th>

View File

@ -7,7 +7,7 @@ namespace Elwig.Documents {
public Delivery Delivery; public Delivery Delivery;
public string? Text; public string? Text;
public Dictionary<string, (string, int, int, int, int)> MemberBins; public Dictionary<string, (string, int, int, int, int)> MemberBuckets;
// 0 - none // 0 - none
// 1 - GA only // 1 - GA only
@ -27,7 +27,7 @@ namespace Elwig.Documents {
$"</tbody></table>"; $"</tbody></table>";
Text = App.Client.TextDeliveryNote; Text = App.Client.TextDeliveryNote;
DocumentId = d.LsNr; DocumentId = d.LsNr;
MemberBins = ctx.GetMemberBins(d.Year, d.Member.MgNr).GetAwaiter().GetResult(); MemberBuckets = ctx.GetMemberBuckets(d.Year, d.Member.MgNr).GetAwaiter().GetResult();
} }
} }
} }

View File

@ -108,7 +108,7 @@
$"<td>{sum:N0}</td>"; $"<td>{sum:N0}</td>";
} }
var sortids = Model.Delivery.Parts.Select(p => p.SortId).ToList(); var sortids = Model.Delivery.Parts.Select(p => p.SortId).ToList();
var bins = Model.MemberBins.GroupBy(b => b.Key[..2]).ToDictionary(g => g.Key, g => g.Count()); var buckets = Model.MemberBuckets.GroupBy(b => b.Key[..2]).ToDictionary(g => g.Key, g => g.Count());
} }
<tr> <tr>
<th>Gesamtlieferung lt. gez. GA</th> <th>Gesamtlieferung lt. gez. GA</th>
@ -122,8 +122,8 @@
<tr class="subheading"> <tr class="subheading">
<th>Flächenbindungen:</th> <th>Flächenbindungen:</th>
</tr> </tr>
@foreach (var (id, (name, right, obligation, sum, _)) in Model.MemberBins.OrderBy(b => b.Key)) { @foreach (var (id, (name, right, obligation, sum, _)) in Model.MemberBuckets.OrderBy(b => b.Key)) {
if (right > 0 || obligation > 0 || (sum > 0 && bins[id[..2]] > 1 && !id.EndsWith('_'))) { if (right > 0 || obligation > 0 || (sum > 0 && buckets[id[..2]] > 1 && !id.EndsWith('_'))) {
<tr class="@(sortids.Contains(id[..2]) ? "" : "optional")"> <tr class="@(sortids.Contains(id[..2]) ? "" : "optional")">
<th>@name</th> <th>@name</th>
@Raw(FormatRow(obligation, right, sum)) @Raw(FormatRow(obligation, right, sum))

View File

@ -53,8 +53,8 @@ namespace Elwig.Helpers {
public static string ConnectionString => $"Data Source=\"{App.Config.DatabaseFile}\"; Foreign Keys=True; Mode=ReadWrite; Cache=Default"; public static string ConnectionString => $"Data Source=\"{App.Config.DatabaseFile}\"; Foreign Keys=True; Mode=ReadWrite; Cache=Default";
private readonly Dictionary<int, Dictionary<int, Dictionary<string, (int, int)>>> _memberRightsAndObligations = new(); private readonly Dictionary<int, Dictionary<int, Dictionary<string, (int, int)>>> _memberRightsAndObligations = new();
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBins = new(); private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = new();
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBins = new(); private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = new();
public AppDbContext() { public AppDbContext() {
if (App.Config.DatabaseLog != null) { if (App.Config.DatabaseLog != null) {
@ -190,55 +190,55 @@ namespace Elwig.Helpers {
private async Task FetchMemberRightsAndObligations(int year, SqliteConnection? cnx = null) { private async Task FetchMemberRightsAndObligations(int year, SqliteConnection? cnx = null) {
var ownCnx = cnx == null; var ownCnx = cnx == null;
cnx ??= await ConnectAsync(); cnx ??= await ConnectAsync();
var bins = new Dictionary<int, Dictionary<string, (int, int)>>(); var buckets = new Dictionary<int, Dictionary<string, (int, int)>>();
using (var cmd = cnx.CreateCommand()) { using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"SELECT mgnr, bucket, min_kg, max_kg FROM v_area_commitment_bucket WHERE year = {year}"; cmd.CommandText = $"SELECT mgnr, bucket, min_kg, max_kg FROM v_area_commitment_bucket WHERE year = {year}";
using var reader = await cmd.ExecuteReaderAsync(); using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) { while (await reader.ReadAsync()) {
var mgnr = reader.GetInt32(0); var mgnr = reader.GetInt32(0);
var vtrgid = reader.GetString(1); var vtrgid = reader.GetString(1);
if (!bins.ContainsKey(mgnr)) bins[mgnr] = new(); if (!buckets.ContainsKey(mgnr)) buckets[mgnr] = new();
bins[mgnr][vtrgid] = (reader.GetInt32(3), reader.GetInt32(2)); buckets[mgnr][vtrgid] = (reader.GetInt32(3), reader.GetInt32(2));
} }
} }
if (ownCnx) await cnx.DisposeAsync(); if (ownCnx) await cnx.DisposeAsync();
_memberRightsAndObligations[year] = bins; _memberRightsAndObligations[year] = buckets;
} }
private async Task FetchMemberDeliveryBins(int year, SqliteConnection? cnx = null) { private async Task FetchMemberDeliveryBuckets(int year, SqliteConnection? cnx = null) {
var ownCnx = cnx == null; var ownCnx = cnx == null;
cnx ??= await ConnectAsync(); cnx ??= await ConnectAsync();
var bins = new Dictionary<int, Dictionary<string, int>>(); var buckets = new Dictionary<int, Dictionary<string, int>>();
using (var cmd = cnx.CreateCommand()) { using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"SELECT mgnr, bucket, weight FROM v_delivery_bucket WHERE year = {year}"; cmd.CommandText = $"SELECT mgnr, bucket, weight FROM v_delivery_bucket WHERE year = {year}";
using var reader = await cmd.ExecuteReaderAsync(); using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) { while (await reader.ReadAsync()) {
var mgnr = reader.GetInt32(0); var mgnr = reader.GetInt32(0);
var bin = reader.GetString(1); var bucket = reader.GetString(1);
if (!bins.ContainsKey(mgnr)) bins[mgnr] = new(); if (!buckets.ContainsKey(mgnr)) buckets[mgnr] = new();
bins[mgnr][bin] = reader.GetInt32(2); buckets[mgnr][bucket] = reader.GetInt32(2);
} }
} }
if (ownCnx) await cnx.DisposeAsync(); if (ownCnx) await cnx.DisposeAsync();
_memberDeliveryBins[year] = bins; _memberDeliveryBuckets[year] = buckets;
} }
private async Task FetchMemberPaymentBins(int year, SqliteConnection? cnx = null) { private async Task FetchMemberPaymentBuckets(int year, SqliteConnection? cnx = null) {
var ownCnx = cnx == null; var ownCnx = cnx == null;
cnx ??= await ConnectAsync(); cnx ??= await ConnectAsync();
var bins = new Dictionary<int, Dictionary<string, int>>(); var buckets = new Dictionary<int, Dictionary<string, int>>();
using (var cmd = cnx.CreateCommand()) { using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"SELECT mgnr, bucket, weight FROM v_payment_bucket WHERE year = {year}"; cmd.CommandText = $"SELECT mgnr, bucket, weight FROM v_payment_bucket WHERE year = {year}";
using var reader = await cmd.ExecuteReaderAsync(); using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) { while (await reader.ReadAsync()) {
var mgnr = reader.GetInt32(0); var mgnr = reader.GetInt32(0);
var bin = reader.GetString(1); var bucket = reader.GetString(1);
if (!bins.ContainsKey(mgnr)) bins[mgnr] = new(); if (!buckets.ContainsKey(mgnr)) buckets[mgnr] = new();
bins[mgnr][bin] = reader.GetInt32(2); buckets[mgnr][bucket] = reader.GetInt32(2);
} }
} }
if (ownCnx) await cnx.DisposeAsync(); if (ownCnx) await cnx.DisposeAsync();
_memberPaymentBins[year] = bins; _memberPaymentBuckets[year] = buckets;
} }
public async Task<Dictionary<string, (int, int)>> GetMemberRightsAndObligations(int year, int mgnr, SqliteConnection? cnx = null) { public async Task<Dictionary<string, (int, int)>> GetMemberRightsAndObligations(int year, int mgnr, SqliteConnection? cnx = null) {
@ -247,41 +247,41 @@ namespace Elwig.Helpers {
return _memberRightsAndObligations[year].GetValueOrDefault(mgnr, new()); return _memberRightsAndObligations[year].GetValueOrDefault(mgnr, new());
} }
public async Task<Dictionary<string, int>> GetMemberDeliveryBins(int year, int mgnr, SqliteConnection? cnx = null) { public async Task<Dictionary<string, int>> GetMemberDeliveryBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
if (!_memberDeliveryBins.ContainsKey(year)) if (!_memberDeliveryBuckets.ContainsKey(year))
await FetchMemberDeliveryBins(year, cnx); await FetchMemberDeliveryBuckets(year, cnx);
return _memberDeliveryBins[year].GetValueOrDefault(mgnr, new()); return _memberDeliveryBuckets[year].GetValueOrDefault(mgnr, new());
} }
public async Task<Dictionary<string, int>> GetMemberPaymentBins(int year, int mgnr, SqliteConnection? cnx = null) { public async Task<Dictionary<string, int>> GetMemberPaymentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
if (!_memberPaymentBins.ContainsKey(year)) if (!_memberPaymentBuckets.ContainsKey(year))
await FetchMemberPaymentBins(year, cnx); await FetchMemberPaymentBuckets(year, cnx);
return _memberPaymentBins[year].GetValueOrDefault(mgnr, new()); return _memberPaymentBuckets[year].GetValueOrDefault(mgnr, new());
} }
public async Task<Dictionary<string, (string, int, int, int, int)>> GetMemberBins(int year, int mgnr, SqliteConnection? cnx = null) { public async Task<Dictionary<string, (string, int, int, int, int)>> GetMemberBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
var ownCnx = cnx == null; var ownCnx = cnx == null;
cnx ??= await ConnectAsync(); cnx ??= await ConnectAsync();
var rightsAndObligations = await GetMemberRightsAndObligations(year, mgnr, cnx); var rightsAndObligations = await GetMemberRightsAndObligations(year, mgnr, cnx);
var deliveryBins = await GetMemberDeliveryBins(year, mgnr, cnx); var deliveryBuckets = await GetMemberDeliveryBuckets(year, mgnr, cnx);
var paymentBins = await GetMemberPaymentBins(year, mgnr, cnx); var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
if (ownCnx) await cnx.DisposeAsync(); if (ownCnx) await cnx.DisposeAsync();
var bins = new Dictionary<string, (string, int, int, int, int)>(); var buckets = new Dictionary<string, (string, int, int, int, int)>();
foreach (var id in rightsAndObligations.Keys.Union(deliveryBins.Keys).Union(paymentBins.Keys)) { foreach (var id in rightsAndObligations.Keys.Union(deliveryBuckets.Keys).Union(paymentBuckets.Keys)) {
var variety = await WineVarieties.FindAsync(id[..2]); var variety = await WineVarieties.FindAsync(id[..2]);
var attrIds = id[2..]; var attrIds = id[2..];
var attrs = await WineAttributes.Where(a => attrIds.Contains(a.AttrId)).ToListAsync(); var attrs = await WineAttributes.Where(a => attrIds.Contains(a.AttrId)).ToListAsync();
var name = (variety?.Name ?? "") + (attrIds == "_" ? " (kein Qual.Wein)" : attrs.Count > 0 ? $" ({string.Join(" / ", attrs.Select(a => a.Name))})" : ""); var name = (variety?.Name ?? "") + (attrIds == "_" ? " (kein Qual.Wein)" : attrs.Count > 0 ? $" ({string.Join(" / ", attrs.Select(a => a.Name))})" : "");
bins[id] = ( buckets[id] = (
name, name,
rightsAndObligations.GetValueOrDefault(id).Item1, rightsAndObligations.GetValueOrDefault(id).Item1,
rightsAndObligations.GetValueOrDefault(id).Item2, rightsAndObligations.GetValueOrDefault(id).Item2,
deliveryBins.GetValueOrDefault(id), deliveryBuckets.GetValueOrDefault(id),
paymentBins.GetValueOrDefault(id) paymentBuckets.GetValueOrDefault(id)
); );
} }
return bins; return buckets;
} }
} }
} }

View File

@ -38,7 +38,7 @@ namespace Elwig.Helpers.Billing {
} }
} }
public async Task CalculateBins(bool allowAttrsIntoLowerBins, bool avoidUnderDeliveries, bool honorGebunden) { public async Task CalculateBuckets(bool allowAttrsIntoLower, bool avoidUnderDeliveries, bool honorGebunden) {
var attrVals = Context.WineAttributes.ToDictionary(a => a.AttrId, a => (a.IsStrict, a.FillLower)); var attrVals = Context.WineAttributes.ToDictionary(a => a.AttrId, a => (a.IsStrict, a.FillLower));
var attrForced = attrVals.Where(a => a.Value.IsStrict && a.Value.FillLower == 0).Select(a => a.Key).ToArray(); var attrForced = attrVals.Where(a => a.Value.IsStrict && a.Value.FillLower == 0).Select(a => a.Key).ToArray();
using var cnx = await AppDbContext.ConnectAsync(); using var cnx = await AppDbContext.ConnectAsync();
@ -103,7 +103,7 @@ namespace Elwig.Helpers.Billing {
inserts.Add((did, dpnr, i, key[2..], v)); inserts.Add((did, dpnr, i, key[2..], v));
w -= v; w -= v;
} }
if (w == 0 || (!allowAttrsIntoLowerBins && isStrict)) break; if (w == 0 || (!allowAttrsIntoLower && isStrict)) break;
} }
inserts.Add((did, dpnr, 0, "_", w)); inserts.Add((did, dpnr, 0, "_", w));
lastMgNr = mgnr; lastMgNr = mgnr;
@ -138,7 +138,7 @@ namespace Elwig.Helpers.Billing {
} }
} }
var fittingBins = new Dictionary<(int, string), int>(); var fittingBuckets = new Dictionary<(int, string), int>();
using (var cmd = cnx.CreateCommand()) { using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $""" cmd.CommandText = $"""
SELECT c.mgnr, c.bucket, COALESCE(p.weight, 0) - c.min_kg AS diff SELECT c.mgnr, c.bucket, COALESCE(p.weight, 0) - c.min_kg AS diff
@ -148,11 +148,11 @@ namespace Elwig.Helpers.Billing {
"""; """;
using var reader = await cmd.ExecuteReaderAsync(); using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) { while (await reader.ReadAsync()) {
fittingBins[(reader.GetInt32(0), reader.GetString(1))] = reader.GetInt32(2); fittingBuckets[(reader.GetInt32(0), reader.GetString(1))] = reader.GetInt32(2);
} }
} }
foreach (var item in fittingBins) { foreach (var item in fittingBuckets) {
var mgnr = item.Key.Item1; var mgnr = item.Key.Item1;
var id = item.Key.Item2[..2]; var id = item.Key.Item2[..2];
var attr = item.Key.Item2[2..]; var attr = item.Key.Item2[2..];

View File

@ -115,6 +115,6 @@ namespace Elwig.Models {
public string OriginString => Origin.OriginString + "\n" + (Kg?.Gl != null ? $" / {Kg.Gl.Name}" : "") + (Kg != null ? $" / {Kg.AtKg.Gem.Name} / KG {Kg.AtKg.Name}" : "") + (Rd != null ? $" / Ried {Rd.Name}" : ""); public string OriginString => Origin.OriginString + "\n" + (Kg?.Gl != null ? $" / {Kg.Gl.Name}" : "") + (Kg != null ? $" / {Kg.AtKg.Gem.Name} / KG {Kg.AtKg.Name}" : "") + (Rd != null ? $" / Ried {Rd.Name}" : "");
[InverseProperty("Part")] [InverseProperty("Part")]
public virtual ISet<DeliveryPartBucket> Bins { get; private set; } public virtual ISet<DeliveryPartBucket> Buckets { get; private set; }
} }
} }

View File

@ -24,10 +24,10 @@
Margin="110,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="110,40,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
ValueChanged="SeasonInput_ValueChanged"/> ValueChanged="SeasonInput_ValueChanged"/>
<Button x:Name="CalculateBinsButton" Content="Aufteilung Berechnen" <Button x:Name="CalculateBucketsButton" Content="Aufteilung Berechnen"
Click="CalculateBinsButton_Click" Click="CalculateBucketsButton_Click"
Margin="50,80,0,0"/> Margin="50,80,0,0"/>
<CheckBox x:Name="AllowAttrIntoLowerBinsInput" Content="Erlauben Lieferungen auch auf (konfigurierte) &quot;schlechtere&quot; Flächenbindungen aufzuteilen" <CheckBox x:Name="AllowAttrIntoLowerInput" Content="Erlauben Lieferungen auch auf (konfigurierte) &quot;schlechtere&quot; Flächenbindungen aufzuteilen"
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="255,68,0,0"/> VerticalAlignment="Top" HorizontalAlignment="Left" Margin="255,68,0,0"/>
<CheckBox x:Name="AvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei &quot;besseren&quot; Flächenbindungen vermeiden" <CheckBox x:Name="AvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei &quot;besseren&quot; Flächenbindungen vermeiden"
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="255,88,0,0"/> VerticalAlignment="Top" HorizontalAlignment="Left" Margin="255,88,0,0"/>

View File

@ -28,24 +28,24 @@ namespace Elwig.Windows {
var s1 = await Context.Seasons.FindAsync(SeasonInput.Value + 1); var s1 = await Context.Seasons.FindAsync(SeasonInput.Value + 1);
var valid = (s0 != null); var valid = (s0 != null);
var last = (s1 == null); var last = (s1 == null);
CalculateBinsButton.IsEnabled = valid && last; CalculateBucketsButton.IsEnabled = valid && last;
DeliveryConfirmationButton.IsEnabled = valid; DeliveryConfirmationButton.IsEnabled = valid;
OverUnderDeliveryButton.IsEnabled = valid; OverUnderDeliveryButton.IsEnabled = valid;
} }
private async void CalculateBinsButton_Click(object sender, RoutedEventArgs evt) { private async void CalculateBucketsButton_Click(object sender, RoutedEventArgs evt) {
if (SeasonInput.Value is not int year) if (SeasonInput.Value is not int year)
return; return;
CalculateBinsButton.IsEnabled = false; CalculateBucketsButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.AppStarting;
var b = new Billing(year); var b = new Billing(year);
await b.FinishSeason(); await b.FinishSeason();
await b.CalculateBins( await b.CalculateBuckets(
AllowAttrIntoLowerBinsInput.IsChecked ?? false, AllowAttrIntoLowerInput.IsChecked ?? false,
AvoidUnderDeliveriesInput.IsChecked ?? false, AvoidUnderDeliveriesInput.IsChecked ?? false,
HonorGebundenInput.IsChecked ?? false); HonorGebundenInput.IsChecked ?? false);
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
CalculateBinsButton.IsEnabled = true; CalculateBucketsButton.IsEnabled = true;
} }
private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) { private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) {