[#32] PaymentVariantSummary: Add summary header

This commit is contained in:
2024-05-09 19:12:27 +02:00
parent 602c237fa0
commit 4bd378e048
8 changed files with 180 additions and 16 deletions

View File

@ -165,6 +165,7 @@ main table th.narrow {
padding-right: 0; padding-right: 0;
} }
main table .tborder {border-top: var(--border-thickness) solid black;}
main table .lborder {border-left: var(--border-thickness) solid black;} main table .lborder {border-left: var(--border-thickness) solid black;}
main table .rborder {border-right: var(--border-thickness) solid black;} main table .rborder {border-right: var(--border-thickness) solid black;}

View File

@ -1,5 +1,7 @@
using Elwig.Models.Dtos; using Elwig.Helpers.Billing;
using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using System.Linq;
namespace Elwig.Documents { namespace Elwig.Documents {
public class PaymentVariantSummary : Document { public class PaymentVariantSummary : Document {
@ -8,12 +10,21 @@ namespace Elwig.Documents {
public PaymentVariantSummaryData Data; public PaymentVariantSummaryData Data;
public PaymentVar Variant; public PaymentVar Variant;
public BillingData BillingData;
public string CurrencySymbol; public string CurrencySymbol;
public int MemberNum;
public int DeliveryNum;
public int DeliveryPartNum;
public PaymentVariantSummary(PaymentVar v, PaymentVariantSummaryData data) : base(v.Name) { public PaymentVariantSummary(PaymentVar v, PaymentVariantSummaryData data) :
base($"{Name} {v.Year} - {v.Name}") {
Variant = v; Variant = v;
BillingData = BillingData.FromJson(v.Data);
Data = data; Data = data;
CurrencySymbol = v.Season.Currency.Symbol ?? v.Season.Currency.Code; CurrencySymbol = v.Season.Currency.Symbol ?? v.Season.Currency.Code;
MemberNum = v.Credits.Count;
DeliveryNum = v.DeliveryPartPayments.DistinctBy(p => p.DeliveryPart.Delivery).Count();
DeliveryPartNum = v.DeliveryPartPayments.Count;
} }
} }
} }

View File

@ -5,10 +5,157 @@
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\PaymentVariantSummary.css" /> <link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\PaymentVariantSummary.css" />
<main> <main>
<h1>Auszahlungsvariante</h1> <h1>Auszahlungsvariante Lese @Model.Variant.Year</h1>
<h2>@Model.Variant.Name</h2> <h2>@Model.Variant.Name</h2>
<!-- TODO --> <table class="payment-variant border">
<table class="payment-variant"> <colgroup>
<col style="width: 20.0mm;"/>
<col style="width: 30.0mm;"/>
<col style="width: 4.5mm;"/>
<col style="width: 28.0mm;"/>
<col style="width: 47.5mm;"/>
<col style="width: 15.0mm;"/>
<col style="width: 20.0mm;"/>
</colgroup>
@{
//var sum1 = Model.Variant.DeliveryPartPayments.Sum(p => p.NetAmount);
//var sum2 = Model.Variant.Credits.Sum(p => p.); //Model.Variant.MemberPayments.Sum(p => p.Amount);
var modifiers = Model.Variant.DeliveryPartPayments.Sum(p => p.Amount - p.NetAmount);
var sum2 = Model.Variant.Credits.Sum(p => p.NetAmount);
var sum1 = sum2 - modifiers;
var payed = -Model.Variant.Credits.Sum(p => p.PrevNetAmount ?? 0m);
var netSum = Model.Variant.Credits.Sum(p => p.NetAmount) - Model.Variant.Credits.Sum(p => p.PrevNetAmount ?? 0m);
var vat = Model.Variant.Credits.Sum(p => p.VatAmount);
var grossSum = Model.Variant.Credits.Sum(p => p.GrossAmount);
var totalMods = Model.Variant.Credits.Sum(p => p.Modifiers ?? 0m);
var considered = -Model.Variant.Credits.Sum(p => p.PrevModifiers ?? 0m);
var totalSum = Model.Variant.Credits.Sum(p => p.Amount);
}
<tbody>
<tr class="sectionheading">
<th colspan="4">Allgemein</th>
<th colspan="3" class="lborder">Berücksichtigt</th>
</tr>
<tr>
<th>Name:</th>
<td colspan="3">@Model.Variant.Name</td>
<th colspan="2" class="lborder">Zu-/Abschläge bei Lieferungen:</th>
<td class="center">@(Model.BillingData.ConsiderDelieryModifiers ? "Ja" : "Nein")</td>
</tr>
<tr>
<th>Beschr.:</th>
<td colspan="3">@Model.Variant.Comment</td>
<th colspan="2" class="lborder">Pönalen bei Unterlieferungen (FB):</th>
<td class="center">@(Model.BillingData.ConsiderContractPenalties ? "Ja" : "Nein")</td>
</tr>
<tr>
<th>Datum:</th>
<td colspan="3">@($"{Model.Variant.Date:dd.MM.yyyy}")</td>
<th colspan="2" class="lborder">Strafen bei Unterlieferungen (GA):</th>
<td class="center">@(Model.BillingData.ConsiderTotalPenalty ? "Ja" : "Nein")</td>
</tr>
<tr>
<th>Überw.:</th>
<td colspan="3">@($"{Model.Variant.TransferDate:dd.MM.yyyy}")</td>
<th colspan="2" class="lborder">Automatische Nachzeichnung der GA:</th>
<td class="center">@(Model.BillingData.ConsiderAutoBusinessShares ? "Ja" : "Nein")</td>
</tr>
<tr class="sectionheading">
<th colspan="4">Beträge</th>
<th colspan="3" class="lborder">Statistik</th>
</tr>
<tr>
<th colspan="2">Zwischensumme:</th>
<td></td>
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{sum1:N2}")</td>
<th class="lborder">Lieferanten:</th>
<td colspan="2" class="number">@($"{Model.MemberNum:N0}")</td>
</tr>
<tr>
<th colspan="2">Zu-/Abschläge (Lieferungen):</th>
<td class="number">@Utils.GetSign(modifiers)</td>
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(modifiers):N2}")</td>
<th class="lborder">Lieferungen:</th>
<td colspan="2" class="number">@($"{Model.DeliveryNum:N0}")</td>
</tr>
<tr>
<th colspan="2">Gesamtsumme:</th>
<td class="number tborder"></td>
<td class="number tborder"><span class="fleft">@Model.CurrencySymbol</span>@($"{sum2:N2}")</td>
<th class="lborder">Teillieferungen:</th>
<td colspan="2" class="number">@($"{Model.DeliveryPartNum:N0}")</td>
</tr>
<tr>
<th colspan="2">Bisher ausgezahlt:</th>
<td class="number">@Utils.GetSign(payed)</td>
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(payed):N2}")</td>
<th class="lborder"></th>
<td colspan="2"></td>
</tr>
<tr>
<th colspan="2">Nettosumme:</th>
<td class="number tborder"></td>
<td class="number tborder"><span class="fleft">@Model.CurrencySymbol</span>@($"{netSum:N2}")</td>
@{
var weiRows = Model.Data.Rows.Where(r => r.QualityLevel == "Wein");
var minWei = weiRows.Min(r => r.Ungeb.Price);
var maxWei = weiRows.Max(r => r.Ungeb.Price);
}
<th class="lborder tborder">Preis (abgewertet):</th>
<td colspan="2" class="center tborder">@(minWei != maxWei ? $"{minWei:N4}~{maxWei:N4}" : $"{minWei:N4}") @Model.CurrencySymbol/kg</td>
</tr>
<tr>
<th colspan="2">Mehrwertsteuer:</th>
<td class="number">@Utils.GetSign(vat)</td>
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(vat):N2}")</td>
@{
var quwRows = Model.Data.Rows.Where(r => r.QualityLevel != "Wein");
var minPrice = quwRows.Min(r => r.Ungeb.Price);
var maxPrice = quwRows.Max(r => r.Ungeb.Price);
}
<th class="lborder">Preis (ungeb., nicht abgew.):</th>
<td colspan="2" class="center">@(minPrice != maxPrice ? $"{minPrice:N4}~{maxPrice:N4}" : $"{minPrice:N4}") @Model.CurrencySymbol/kg</td>
</tr>
<tr>
<th colspan="2">Bruttosumme:</th>
<td class="number tborder"></td>
<td class="number tborder"><span class="fleft">@Model.CurrencySymbol</span>@($"{grossSum:N2}")</td>
@{
var gebRows = Model.Data.Rows
.Where(r => r.Geb.Price != null && r.Ungeb.Price != null)
.Select(r => r.Geb.Price - r.Ungeb.Price);
var minGeb = gebRows.Min();
var maxGeb = gebRows.Max();
}
<th class="lborder">Gebunden-Zuschlag:</th>
<td colspan="2" class="center">
@(minGeb != maxGeb ? $"{minGeb:N4}~{maxGeb:N4} {Model.CurrencySymbol}/kg" : minGeb == 0 ? "-" : $"{minGeb:N4} {Model.CurrencySymbol}/kg")
</td>
</tr>
<tr>
<th colspan="2">Abzüge (Strafen/Pönalen, GA, ...):</th>
<td class="number">@Utils.GetSign(totalMods)</td>
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(totalMods):N2}")</td>
<th class="lborder tborder">Menge (ungebunden):</th>
<td colspan="2" class="number tborder">@($"{Model.Data.Rows.Sum(r => r.Ungeb.Weight):N0}") kg</td>
</tr>
<tr>
<th colspan="2">Bereits berücksichtigte Abzüge:</th>
<td class="number">@Utils.GetSign(considered)</td>
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(considered):N2}")</td>
<th class="lborder">Menge (gebunden):</th>
<td colspan="2" class="number">@($"{Model.Data.Rows.Sum(r => r.Geb.Weight):N0}") kg</td>
</tr>
<tr>
<th colspan="2">Auszahlungsbetrag:</th>
<td class="number tborder"></td>
<td class="number tborder"><span class="fleft">@Model.CurrencySymbol</span>@($"{totalSum:N2}")</td>
<th class="lborder">Gesamtmenge:</th>
<td colspan="2" class="number tborder">@($"{Model.Data.Rows.Sum(r => r.Ungeb.Weight + r.Geb.Weight):N0}") kg</td>
</tr>
</tbody>
</table>
<table class="payment-variant-data">
<colgroup> <colgroup>
<col style="width: 30mm;"/> <col style="width: 30mm;"/>
<col style="width: 20mm;"/> <col style="width: 20mm;"/>
@ -45,7 +192,7 @@
var rows = Model.Data.Rows var rows = Model.Data.Rows
.Where(r => r.Variety == row.Variety && r.Attribute == row.Attribute && r.Cultivation == row.Cultivation) .Where(r => r.Variety == row.Variety && r.Attribute == row.Attribute && r.Cultivation == row.Cultivation)
.ToList(); .ToList();
<tr class="subheading @(hdr != lastHdr && lastHdr != null ? "new" : "")"> <tr class="subheading @(lastHdr != null ? "new" : "")">
<th colspan="2">@hdr</th> <th colspan="2">@hdr</th>
<td class="number">@($"{rows.Sum(r => r.Ungeb.Weight):N0}")</td> <td class="number">@($"{rows.Sum(r => r.Ungeb.Weight):N0}")</td>
<td></td> <td></td>

View File

@ -13,5 +13,9 @@ h2 {
} }
table.payment-variant { table.payment-variant {
margin-top: 10mm;
}
table.payment-variant-data {
break-before: page; break-before: page;
} }

View File

@ -36,7 +36,7 @@ namespace Elwig.Models.Dtos {
); );
public PaymentVariantSummaryData(PaymentVar v, IEnumerable<PaymentRow> rows) : public PaymentVariantSummaryData(PaymentVar v, IEnumerable<PaymentRow> rows) :
base(PaymentVariantSummary.Name, PaymentVariantSummary.Name, v.Name, rows, FieldNames) { base($"{PaymentVariantSummary.Name} {v.Year}", $"{PaymentVariantSummary.Name} Lese {v.Year}", v.Name, rows, FieldNames) {
} }
public static async Task<PaymentVariantSummaryData> ForPaymentVariant(PaymentVar v, DbSet<PaymentVariantSummaryRow> table) { public static async Task<PaymentVariantSummaryData> ForPaymentVariant(PaymentVar v, DbSet<PaymentVariantSummaryRow> table) {

View File

@ -192,6 +192,7 @@ namespace Elwig.Windows {
PaymentSum.Text = $"- {sym}"; PaymentSum.Text = $"- {sym}";
} else { } else {
// all values in the credit table are stored with precision 2! // all values in the credit table are stored with precision 2!
TotalSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.NetAmountValue), 2):N2} {sym}";
VatSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.VatAmountValue), 2):N2} {sym}"; VatSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.VatAmountValue), 2):N2} {sym}";
DeductionSum.Text = $"{-Utils.DecFromDb(await credits.SumAsync(c => c.ModifiersValue ?? 0), 2):N2} {sym}"; DeductionSum.Text = $"{-Utils.DecFromDb(await credits.SumAsync(c => c.ModifiersValue ?? 0), 2):N2} {sym}";
PaymentSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.AmountValue), 2):N2} {sym}"; PaymentSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.AmountValue), 2):N2} {sym}";
@ -353,7 +354,7 @@ namespace Elwig.Windows {
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows); var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var doc = new PaymentVariantSummary(v, data); using var doc = new PaymentVariantSummary((await ctx.PaymentVariants.FindAsync(v.Year, v.AvNr))!, data);
await Utils.ExportDocument(doc, mode); await Utils.ExportDocument(doc, mode);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);

View File

@ -13,17 +13,17 @@ namespace Tests.DocumentTests {
var v = (await ctx.PaymentVariants.FindAsync(2020, 1))!; var v = (await ctx.PaymentVariants.FindAsync(2020, 1))!;
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows); var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var doc = new PaymentVariantSummary(v, data); using var doc = new PaymentVariantSummary(v, data);
var text = await Utils.GeneratePdfText(doc, true); var text = await Utils.GeneratePdfText(doc);
var table = text.Split('\n').Select(l => Regex.Split(l.Trim(), "[ ]{2,}")).Where(l => l.Length > 2).ToArray(); var table = text.Split('\n').Select(l => Regex.Split(l.Trim(), "[ ]{2,}")).Where(l => l.Length > 2).ToArray();
Assert.Multiple(() => { Assert.Multiple(() => {
Assert.That(text, Contains.Substring("Auszahlungsvariante")); Assert.That(text, Contains.Substring("Auszahlungsvariante"));
Assert.That(text, Contains.Substring(v.Name)); Assert.That(text, Contains.Substring(v.Name));
Assert.That(table, Is.EqualTo(new string[][] { Assert.That(text, Contains.Substring("""
[ "Gradation", "ungebunden", "gebunden", "Gesamt" ], Gradation ungebunden gebunden Gesamt
[ "[°Oe]", "[kg]", "[/kg]", "[kg]", "[/kg]", "[]" ], [°Oe] [kg] [/kg] [kg] [/kg] []
["Grüner Veltliner", "3 219", "0", "1 609,50"], Grüner Veltliner 3 219 0 1 609,50
["Qualitätswein", "73", "3 219", "0,5000", "-", "-", "1 609,50"], Qualitätswein 73 3 219 0,5000 - - 1 609,50
})); """));
}); });
} }
} }

View File

@ -61,7 +61,7 @@ INSERT INTO delivery_part_bucket (year, did, dpnr, bktnr, discr, value) VALUES
(2020, 5, 2, 0, '_', 2190); (2020, 5, 2, 0, '_', 2190);
INSERT INTO payment_variant (year, avnr, name, date, transfer_date, test_variant, calc_time, comment, data) VALUES INSERT INTO payment_variant (year, avnr, name, date, transfer_date, test_variant, calc_time, comment, data) VALUES
(2020, 1, 'Probevariante', '2021-01-15', '2021-01-15', TRUE, NULL, NULL, '{}'); (2020, 1, 'Probevariante', '2021-01-15', '2021-01-15', TRUE, NULL, NULL, '{"mode":"elwig","version":1,"payment":0.5,"curves":[]}');
INSERT INTO payment_delivery_part_bucket (year, did, dpnr, bktnr, avnr, price, amount) VALUES INSERT INTO payment_delivery_part_bucket (year, did, dpnr, bktnr, avnr, price, amount) VALUES
(2020, 1, 1, 0, 1, 5000, 16095000); (2020, 1, 1, 0, 1, 5000, 16095000);