DeliveryConfirmation: Add Statistics table

This commit is contained in:
2023-10-16 22:23:42 +02:00
parent 8c49cc8ef2
commit ff2968c989
8 changed files with 268 additions and 147 deletions

View File

@ -93,7 +93,60 @@
</tr>
</tbody>
</table>
<!-- TODO add Gesamtlieferung tabelle -->
<table class="delivery-confirmation-stats">
<colgroup>
<col style="width: 45mm;"/>
<col style="width: 17mm;"/>
<col style="width: 17mm;"/>
<col style="width: 17mm;"/>
<col style="width: 19mm;"/>
<col style="width: 16mm;"/>
<col style="width: 17mm;"/>
<col style="width: 17mm;"/>
</colgroup>
<thead>
<tr>
<th><b>Lese @Model.Year</b> per @($"{Model.Date:dd.MM.yyyy}") [kg]</th>
<th>Lieferpflicht</th>
<th>Lieferrecht</th>
<th>Unterliefert<br/>(bzgl. Zuget.)</th>
<th>Noch zu liefern<br/>(bzgl. Gelft.)</th>
<th>Überliefert<br/>(bzgl. Gelft.)</th>
<th>Zugeteilt</th>
<th>Geliefert</th>
</tr>
</thead>
<tbody>
@{
string FormatRow(int obligation, int right, int sum, int? payment = null) {
var isGa = payment == null;
payment ??= sum;
return $"<td>{obligation:N0}</td>" +
$"<td>{right:N0}</td>" +
$"<td>{(payment < obligation ? $"<b>{obligation - payment:N0}\x3c/b>" : "-")}</td>" +
$"<td>{(sum >= obligation && sum <= right ? $"{right - sum:N0}" : "-")}</td>" +
$"<td>{(obligation == 0 && right == 0 ? "-" : (sum > right ? ((isGa ? "<b>" : "") + $"{sum - right:N0}" + (isGa ? "</b>" : "")) : "-"))}</td>" +
$"<td>{(obligation == 0 && right == 0 ? "-" : $"{payment:N0}")}</td>" +
$"<td>{sum:N0}</td>";
}
}
<tr>
<th>Gesamtlieferung lt. gez. GA</th>
@Raw(FormatRow(Model.Member.DeliveryObligation, Model.Member.DeliveryRight, Model.Member.Deliveries.Where(d => d.Year == Model.Year).Sum(d => d.Weight)))
</tr>
<tr class="subheading">
<th>Flächenbindungen:</th>
</tr>
@foreach (var (id, (name, right, obligation, sum, payment)) in Model.MemberBins.OrderBy(b => b.Key)) {
if (right > 0 || obligation > 0 || sum > 0) {
<tr>
<th>@name</th>
@Raw(FormatRow(obligation, right, sum, payment))
</tr>
}
}
</tbody>
</table>
<div class="text" style="margin-top: 2em;">
@if (Model.Text != null) {
<p class="comment" style="white-space: pre-wrap; break-inside: avoid;">@Model.Text</p>

View File

@ -10,6 +10,7 @@ namespace Elwig.Documents {
public int Year;
public IEnumerable<DeliveryPart> Deliveries;
public string? Text = App.Client.TextDeliveryConfirmation;
public Dictionary<string, (string, int, int, int, int)> MemberBins;
public DeliveryConfirmation(AppDbContext ctx, int year, Member m) :
base($"Anlieferungsbestätigung {year} {((IAddress?)m.BillingAddress ?? m).Name}", m) {
@ -29,6 +30,7 @@ namespace Elwig.Documents {
v.kmw DESC, v.lsnr, v.dpnr
""")
.ToList();
MemberBins = ctx.GetMemberBins(Year, m.MgNr).GetAwaiter().GetResult();
}
}
}

View File

@ -76,61 +76,59 @@
<p class="comment">Amerkung zur Lieferung: @Model.Delivery.Comment</p>
}
@if (Model.DisplayStats > 0) {
<div id="delivery-stats">
<table class="delivery-stats @(Model.DisplayStats > 2 ? "expanded" : "")">
<colgroup>
<col style="width: 45mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
</colgroup>
<thead>
<tr>
<th><b>Lese @Model.Delivery.Year</b> per @($"{Model.Date:dd.MM.yyyy}") [kg]</th>
<th>Lieferpflicht</th>
<th>Lieferrecht</th>
<th>Unterliefert</th>
<th>Noch zu liefern</th>
<th>Überliefert</th>
<th>Geliefert</th>
</tr>
</thead>
<tbody>
@{
string FormatRow(int obligation, int right, int sum) {
return $"<td>{obligation:N0}</td>" +
$"<td>{right:N0}</td>" +
$"<td>{(sum < obligation ? $"{obligation - sum:N0}" : "-")}</td>" +
$"<td>{(sum >= obligation && sum <= right ? $"{right - sum:N0}" : "-")}</td>" +
$"<td>{(sum > right ? $"{sum - right:N0}" : "-")}</td>" +
$"<td>{sum:N0}</td>";
}
var sortids = Model.Delivery.Parts.Select(p => p.SortId).ToList();
var bins = Model.MemberBins.GroupBy(b => b.Item1[..2]).ToDictionary(g => g.Key, g => g.Count());
<table class="delivery-note-stats @(Model.DisplayStats > 2 ? "expanded" : "")">
<colgroup>
<col style="width: 45mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
<col style="width: 20mm;"/>
</colgroup>
<thead>
<tr>
<th><b>Lese @Model.Delivery.Year</b> per @($"{Model.Date:dd.MM.yyyy}") [kg]</th>
<th>Lieferpflicht</th>
<th>Lieferrecht</th>
<th>Unterliefert</th>
<th>Noch zu liefern</th>
<th>Überliefert</th>
<th>Geliefert</th>
</tr>
</thead>
<tbody>
@{
string FormatRow(int obligation, int right, int sum) {
return $"<td>{obligation:N0}</td>" +
$"<td>{right:N0}</td>" +
$"<td>{(sum < obligation ? $"{obligation - sum:N0}" : "-")}</td>" +
$"<td>{(sum >= obligation && sum <= right ? $"{right - sum:N0}" : "-")}</td>" +
$"<td>{(sum > right ? $"{sum - right:N0}" : "-")}</td>" +
$"<td>{sum:N0}</td>";
}
<tr>
<th>Gesamtlieferung lt. gez. GA</th>
@Raw(FormatRow(Model.Member.DeliveryObligation, Model.Member.DeliveryRight, Model.Member.Deliveries.Where(d => d.Year == Model.Delivery.Year).Sum(d => d.Weight)))
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());
}
<tr>
<th>Gesamtlieferung lt. gez. GA</th>
@Raw(FormatRow(Model.Member.DeliveryObligation, Model.Member.DeliveryRight, Model.Member.Deliveries.Where(d => d.Year == Model.Delivery.Year).Sum(d => d.Weight)))
</tr>
@if (Model.DisplayStats > 1) {
<tr class="subheading">
<th>Flächenbindungen:</th>
</tr>
@if (Model.DisplayStats > 1) {
<tr class="subheading">
<th>Flächenbindungen:</th>
</tr>
@foreach (var (id, name, right, obligation, sum) in Model.MemberBins.OrderBy(b => b.Item1)) {
if (right > 0 || obligation > 0 || (sum > 0 && bins[id[..2]] > 1 && !id.EndsWith('_'))) {
<tr class="@(sortids.Contains(id[..2]) ? "" : "optional")">
<th>@name</th>
@Raw(FormatRow(obligation, right, sum))
</tr>
}
@foreach (var (id, (name, right, obligation, sum, _)) in Model.MemberBins.OrderBy(b => b.Key)) {
if (right > 0 || obligation > 0 || (sum > 0 && bins[id[..2]] > 1 && !id.EndsWith('_'))) {
<tr class="@(sortids.Contains(id[..2]) ? "" : "optional")">
<th>@name</th>
@Raw(FormatRow(obligation, right, sum))
</tr>
}
}
</tbody>
</table>
</div>
}
</tbody>
</table>
}
</main>
@for (int i = 0; i < 2; i++) {

View File

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

View File

@ -1,6 +1,7 @@
table.delivery-confirmation {
font-size: 10pt;
margin-bottom: 5mm;
}
table.delivery-confirmation thead {
@ -68,3 +69,38 @@ table.delivery-confirmation tr.sum {
table.delivery-confirmation tr.sum td {
padding-top: 1mm;
}
table.delivery-confirmation-stats {
font-size: 10pt;
break-inside: avoid;
}
table.delivery-confirmation-stats th,
table.delivery-confirmation-stats td {
padding: 0.125mm 0;
}
table.delivery-confirmation-stats tr.subheading th {
text-align: left;
}
table.delivery-confirmation-stats thead th {
font-weight: normal;
font-style: italic;
text-align: right;
font-size: 8pt;
}
table.delivery-confirmation-stats thead th:first-child {
text-align: left;
}
table.delivery-confirmation-stats td {
text-align: right;
}
table.delivery-confirmation-stats tbody th {
font-weight: normal;
font-style: italic;
text-align: left;
}

View File

@ -52,45 +52,45 @@ table.delivery tr.sum td {
padding-top: 1mm;
}
table.delivery-stats {
table.delivery-note-stats {
font-size: 8pt;
break-inside: avoid;
break-after: avoid;
}
table.delivery-stats th,
table.delivery-stats td {
table.delivery-note-stats th,
table.delivery-note-stats td {
padding: 0.125mm 0;
}
table.delivery-stats:not(.expanded) tr.optional {
table.delivery-note-stats:not(.expanded) tr.optional {
display: none;
}
table.delivery-stats tr.subheading th {
table.delivery-note-stats tr.subheading th {
text-align: left;
}
table.delivery-stats.expanded tr.subheading:not(:has(~ tr)),
table.delivery-stats tr.subheading:not(:has(~ tr:not(.optional))) {
table.delivery-note-stats.expanded tr.subheading:not(:has(~ tr)),
table.delivery-note-stats tr.subheading:not(:has(~ tr:not(.optional))) {
display: none;
}
table.delivery-stats thead th {
table.delivery-note-stats thead th {
font-weight: normal;
font-style: italic;
text-align: right;
}
table.delivery-stats thead th:first-child {
table.delivery-note-stats thead th:first-child {
text-align: left;
}
table.delivery-stats td {
table.delivery-note-stats td {
text-align: right;
}
table.delivery-stats tbody th {
table.delivery-note-stats tbody th {
font-weight: normal;
font-style: italic;
text-align: left;