[#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) {
|
private static string GetColGroup(IEnumerable<double> cols) {
|
||||||
return "";
|
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) {
|
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) {
|
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 = GetColGroup(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";
|
|
||||||
tbl += $"""
|
tbl += $"""
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@using Elwig.Documents
|
||||||
@using RazorLight
|
@using RazorLight
|
||||||
@inherits TemplatePage<Elwig.Documents.DeliveryConfirmation>
|
@inherits TemplatePage<Elwig.Documents.DeliveryConfirmation>
|
||||||
@model Elwig.Documents.DeliveryConfirmation
|
@model Elwig.Documents.DeliveryConfirmation
|
||||||
@ -89,6 +90,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@Raw(BusinessDocument.PrintSortenaufteilung(Model.MemberBuckets))
|
||||||
@Raw(Model.PrintBucketTable(Model.Season, Model.MemberBuckets, includePayment: true))
|
@Raw(Model.PrintBucketTable(Model.Season, Model.MemberBuckets, includePayment: true))
|
||||||
<div class="text" style="margin-top: 2em;">
|
<div class="text" style="margin-top: 2em;">
|
||||||
@if (Model.Text != null) {
|
@if (Model.Text != null) {
|
||||||
|
@ -14,7 +14,7 @@ using Elwig.Models.Dtos;
|
|||||||
namespace Elwig.Helpers {
|
namespace Elwig.Helpers {
|
||||||
|
|
||||||
public record struct AreaComBucket(int Area, int Obligation, int Right);
|
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 {
|
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, AreaComBucket>>> _memberAreaCommitmentBuckets = new();
|
||||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = 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();
|
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = new();
|
||||||
|
|
||||||
public AppDbContext() {
|
public AppDbContext() {
|
||||||
@ -242,6 +243,24 @@ namespace Elwig.Helpers {
|
|||||||
_memberDeliveryBuckets[year] = buckets;
|
_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) {
|
private async Task FetchMemberPaymentBuckets(int year, SqliteConnection? cnx = null) {
|
||||||
var ownCnx = cnx == null;
|
var ownCnx = cnx == null;
|
||||||
cnx ??= await ConnectAsync();
|
cnx ??= await ConnectAsync();
|
||||||
@ -272,6 +291,12 @@ namespace Elwig.Helpers {
|
|||||||
return _memberDeliveryBuckets[year].GetValueOrDefault(mgnr, new());
|
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) {
|
public async Task<Dictionary<string, int>> GetMemberPaymentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||||
if (!_memberPaymentBuckets.ContainsKey(year))
|
if (!_memberPaymentBuckets.ContainsKey(year))
|
||||||
await FetchMemberPaymentBuckets(year, cnx);
|
await FetchMemberPaymentBuckets(year, cnx);
|
||||||
@ -283,6 +308,7 @@ namespace Elwig.Helpers {
|
|||||||
cnx ??= await ConnectAsync();
|
cnx ??= await ConnectAsync();
|
||||||
var rightsAndObligations = await GetMemberAreaCommitmentBuckets(year, mgnr, cnx);
|
var rightsAndObligations = await GetMemberAreaCommitmentBuckets(year, mgnr, cnx);
|
||||||
var deliveryBuckets = await GetMemberDeliveryBuckets(year, mgnr, cnx);
|
var deliveryBuckets = await GetMemberDeliveryBuckets(year, mgnr, cnx);
|
||||||
|
var deliveryBucketsStrict = await GetMemberDeliveryBucketsStrict(year, mgnr, cnx);
|
||||||
var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
|
var paymentBuckets = await GetMemberPaymentBuckets(year, mgnr, cnx);
|
||||||
if (ownCnx) await cnx.DisposeAsync();
|
if (ownCnx) await cnx.DisposeAsync();
|
||||||
|
|
||||||
@ -297,6 +323,7 @@ namespace Elwig.Helpers {
|
|||||||
rightsAndObligations.GetValueOrDefault(id).Obligation,
|
rightsAndObligations.GetValueOrDefault(id).Obligation,
|
||||||
rightsAndObligations.GetValueOrDefault(id).Right,
|
rightsAndObligations.GetValueOrDefault(id).Right,
|
||||||
deliveryBuckets.GetValueOrDefault(id),
|
deliveryBuckets.GetValueOrDefault(id),
|
||||||
|
deliveryBucketsStrict.GetValueOrDefault(id),
|
||||||
paymentBuckets.GetValueOrDefault(id)
|
paymentBuckets.GetValueOrDefault(id)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user