[#23] DeliveryConfirmation: Add Sortenaufteilung table
This commit is contained in:
@ -35,8 +35,49 @@ namespace Elwig.Documents {
|
||||
}
|
||||
}
|
||||
|
||||
public string PrintSortenaufteilung(int year, Dictionary<string, MemberBucket> buckets) {
|
||||
return "";
|
||||
private static string GetColGroup(IEnumerable<double> cols) {
|
||||
return "<colgroup>\n" + string.Join("\n", cols.Select(g => $"<col style=\"width: {g}mm;\"/>")) + "\n</colgroup>\n";
|
||||
}
|
||||
|
||||
public static string PrintSortenaufteilung(Dictionary<string, MemberBucket> buckets) {
|
||||
List<string> attributes = ["_", ""];
|
||||
List<string> names = ["kein Qual.Wein", "ohne Attribut"];
|
||||
List<(string, string)> bucketAttrs = [
|
||||
.. buckets
|
||||
.Where(b => b.Key.Length > 2 && b.Key[2] != '_' && b.Value.DeliveryStrict > 0)
|
||||
.Select(b => (b.Key[2..], b.Value.Name.Split("(")[1][..^1]))
|
||||
.Distinct()
|
||||
.OrderBy(v => v.Item1)
|
||||
];
|
||||
names.AddRange(bucketAttrs.Select(b => b.Item2));
|
||||
names.Add("Gesamt");
|
||||
attributes.AddRange(bucketAttrs.Select(b => b.Item1));
|
||||
|
||||
List<double> cols = [40];
|
||||
cols.AddRange(names.Select(_ => 125.0 / names.Count));
|
||||
string tbl = GetColGroup(cols);
|
||||
tbl += "<thead><tr>" +
|
||||
$"<th><b>Sortenaufteilung</b> [kg]</th>" +
|
||||
string.Join("", names.Select(c => $"<th>{c}</th>")) +
|
||||
"</tr></thead>";
|
||||
|
||||
tbl += string.Join("\n", buckets
|
||||
.GroupBy(b => (b.Key[..2], b.Value.Name.Split("(")[0].Trim()))
|
||||
.Where(g => g.Sum(a => a.Value.DeliveryStrict) > 0)
|
||||
.OrderBy(g => g.Key.Item1)
|
||||
.Select(g => {
|
||||
var dict = g.ToDictionary(a => a.Key[2..], a => a.Value);
|
||||
var vals = attributes.Select(a => dict.TryGetValue(a, out MemberBucket value) ? value.DeliveryStrict : 0).ToList();
|
||||
return $"<tr><th>{g.Key.Item2}</th>" + string.Join("", vals.Select(v => "<td class=\"number\">" + (v == 0 ? "-" : $"{v:N0}") + "</td>")) +
|
||||
$"<td class=\"number\">{dict.Values.Select(v => v.DeliveryStrict).Sum():N0}</td></tr>";
|
||||
})
|
||||
);
|
||||
var totalDict = buckets.GroupBy(b => b.Key[2..]).ToDictionary(g => g.Key, g => g.Sum(a => a.Value.DeliveryStrict));
|
||||
var totals = attributes.Select(a => totalDict.TryGetValue(a, out int value) ? value : 0);
|
||||
tbl += "<tr class=\"sum\"><td></td>" + string.Join("", totals.Select(v => $"<td class=\"number\">{v:N0}</td>")) +
|
||||
$"<td class=\"number\">{totalDict.Values.Sum():N0}</td></tr>";
|
||||
|
||||
return "<table class=\"small number cohere\">" + tbl + "</table>";
|
||||
}
|
||||
|
||||
private static string FormatRow(int obligation, int right, int delivery, int? payment = null, bool isGa = false, bool showPayment = false) {
|
||||
@ -56,8 +97,7 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
public string PrintBucketTable(Season season, Dictionary<string, MemberBucket> buckets, bool includePayment = false, bool isTiny = false, IEnumerable<string>? filter = null) {
|
||||
int[] colGroups = includePayment ? [45, 17, 17, 17, 19, 16, 17, 17] : [45, 20, 20, 20, 20, 20, 20];
|
||||
string tbl = "<colgroup>\n" + string.Join("\n", colGroups.Select(g => $"<col style=\"width: {g}mm;\"/>")) + "\n</colgroup>\n";
|
||||
string tbl = GetColGroup(includePayment ? [45, 17, 17, 17, 19, 16, 17, 17] : [45, 20, 20, 20, 20, 20, 20]);
|
||||
tbl += $"""
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -1,3 +1,4 @@
|
||||
@using Elwig.Documents
|
||||
@using RazorLight
|
||||
@inherits TemplatePage<Elwig.Documents.DeliveryConfirmation>
|
||||
@model Elwig.Documents.DeliveryConfirmation
|
||||
@ -89,6 +90,7 @@
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
@Raw(BusinessDocument.PrintSortenaufteilung(Model.MemberBuckets))
|
||||
@Raw(Model.PrintBucketTable(Model.Season, Model.MemberBuckets, includePayment: true))
|
||||
<div class="text" style="margin-top: 2em;">
|
||||
@if (Model.Text != null) {
|
||||
|
@ -14,7 +14,7 @@ using Elwig.Models.Dtos;
|
||||
namespace Elwig.Helpers {
|
||||
|
||||
public record struct AreaComBucket(int Area, int Obligation, int Right);
|
||||
public record struct MemberBucket(string Name, int Area, int Obligation, int Right, int Delivery, int Payment);
|
||||
public record struct MemberBucket(string Name, int Area, int Obligation, int Right, int Delivery, int DeliveryStrict, int Payment);
|
||||
|
||||
public class AppDbContext : DbContext {
|
||||
|
||||
@ -66,6 +66,7 @@ namespace Elwig.Helpers {
|
||||
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = new();
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = new();
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = new();
|
||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = new();
|
||||
|
||||
public AppDbContext() {
|
||||
@ -242,6 +243,24 @@ namespace Elwig.Helpers {
|
||||
_memberDeliveryBuckets[year] = buckets;
|
||||
}
|
||||
|
||||
private async Task FetchMemberDeliveryBucketsStrict(int year, SqliteConnection? cnx = null) {
|
||||
var ownCnx = cnx == null;
|
||||
cnx ??= await ConnectAsync();
|
||||
var buckets = new Dictionary<int, Dictionary<string, int>>();
|
||||
using (var cmd = cnx.CreateCommand()) {
|
||||
cmd.CommandText = $"SELECT mgnr, bucket, weight FROM v_delivery_bucket_strict WHERE year = {year}";
|
||||
using var reader = await cmd.ExecuteReaderAsync();
|
||||
while (await reader.ReadAsync()) {
|
||||
var mgnr = reader.GetInt32(0);
|
||||
var bucket = reader.GetString(1);
|
||||
if (!buckets.ContainsKey(mgnr)) buckets[mgnr] = new();
|
||||
buckets[mgnr][bucket] = reader.GetInt32(2);
|
||||
}
|
||||
}
|
||||
if (ownCnx) await cnx.DisposeAsync();
|
||||
_memberDeliveryBucketsStrict[year] = buckets;
|
||||
}
|
||||
|
||||
private async Task FetchMemberPaymentBuckets(int year, SqliteConnection? cnx = null) {
|
||||
var ownCnx = cnx == null;
|
||||
cnx ??= await ConnectAsync();
|
||||
@ -272,6 +291,12 @@ namespace Elwig.Helpers {
|
||||
return _memberDeliveryBuckets[year].GetValueOrDefault(mgnr, new());
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, int>> GetMemberDeliveryBucketsStrict(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||
if (!_memberDeliveryBucketsStrict.ContainsKey(year))
|
||||
await FetchMemberDeliveryBucketsStrict(year, cnx);
|
||||
return _memberDeliveryBucketsStrict[year].GetValueOrDefault(mgnr, new());
|
||||
}
|
||||
|
||||
public async Task<Dictionary<string, int>> GetMemberPaymentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||
if (!_memberPaymentBuckets.ContainsKey(year))
|
||||
await FetchMemberPaymentBuckets(year, cnx);
|
||||
@ -283,6 +308,7 @@ namespace Elwig.Helpers {
|
||||
cnx ??= await ConnectAsync();
|
||||
var rightsAndObligations = await GetMemberAreaCommitmentBuckets(year, mgnr, cnx);
|
||||
var deliveryBuckets = await GetMemberDeliveryBuckets(year, mgnr, cnx);
|
||||
var deliveryBucketsStrict = await GetMemberDeliveryBucketsStrict(year, mgnr, cnx);
|
||||
var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
|
||||
if (ownCnx) await cnx.DisposeAsync();
|
||||
|
||||
@ -297,6 +323,7 @@ namespace Elwig.Helpers {
|
||||
rightsAndObligations.GetValueOrDefault(id).Obligation,
|
||||
rightsAndObligations.GetValueOrDefault(id).Right,
|
||||
deliveryBuckets.GetValueOrDefault(id),
|
||||
deliveryBucketsStrict.GetValueOrDefault(id),
|
||||
paymentBuckets.GetValueOrDefault(id)
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user