Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
c6cd9d7c73 | |||
1b28752f4c | |||
e0bdbee2ae | |||
ff3bd5cea5 | |||
116d88d3d6 | |||
6bcb2fb406 | |||
8665c93702 | |||
62496a0770 | |||
8678a02318 | |||
9de7fad139 | |||
85c8783f7e | |||
75e02751f0 | |||
ef1c3b25cf | |||
255953a658 | |||
9470b26aec | |||
3a2bf81bd9 | |||
d3aca196dd | |||
519e903d1c | |||
dd568b81e8 | |||
31b0ae245d | |||
46498ce337 | |||
0fff698a5d | |||
a71c6685f0 |
@ -119,6 +119,11 @@ main h1 {
|
|||||||
font-size: 10pt;
|
font-size: 10pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-wrapper p.custom {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
break-inside: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
.main-wrapper .hidden {
|
.main-wrapper .hidden {
|
||||||
break-before: avoid;
|
break-before: avoid;
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
public PaymentMember? Payment;
|
public PaymentMember? Payment;
|
||||||
public Credit? Credit;
|
public Credit? Credit;
|
||||||
public CreditNoteData Data;
|
public CreditNoteDeliveryData Data;
|
||||||
public string? Text;
|
public string? Text;
|
||||||
public string CurrencySymbol;
|
public string CurrencySymbol;
|
||||||
public int Precision;
|
public int Precision;
|
||||||
@ -20,7 +20,7 @@ namespace Elwig.Documents {
|
|||||||
public decimal MemberTotalUnderDelivery;
|
public decimal MemberTotalUnderDelivery;
|
||||||
public decimal MemberAutoBusinessShares;
|
public decimal MemberAutoBusinessShares;
|
||||||
|
|
||||||
public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteData data, Dictionary<string, UnderDelivery>? underDeliveries = null) :
|
public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteDeliveryData data, Dictionary<string, UnderDelivery>? underDeliveries = null) :
|
||||||
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} – {p.Variant.Name}", p.Member) {
|
base($"{Name} {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr:000}" : p.Member.Name)} – {p.Variant.Name}", p.Member) {
|
||||||
UseBillingAddress = true;
|
UseBillingAddress = true;
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
@ -50,18 +50,18 @@ namespace Elwig.Documents {
|
|||||||
$"<tr><th>Überw. am</th><td>{p.Variant.TransferDate:dd.MM.yyyy}</td></tr>" +
|
$"<tr><th>Überw. am</th><td>{p.Variant.TransferDate:dd.MM.yyyy}</td></tr>" +
|
||||||
$"<tr><th>Datum/Zeit</th><td>{p.Credit?.ModifiedTimestamp:dd.MM.yyyy} / {p.Credit?.ModifiedTimestamp:HH:mm}</td></tr>" +
|
$"<tr><th>Datum/Zeit</th><td>{p.Credit?.ModifiedTimestamp:dd.MM.yyyy} / {p.Credit?.ModifiedTimestamp:HH:mm}</td></tr>" +
|
||||||
$"</tbody></table>";
|
$"</tbody></table>";
|
||||||
Text = App.Client.TextDeliveryNote;
|
Text = App.Client.TextCreditNote;
|
||||||
DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : p.MgNr);
|
DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr:000}" : p.MgNr);
|
||||||
CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
|
CurrencySymbol = season.Currency.Symbol ?? season.Currency.Code;
|
||||||
Precision = season.Precision;
|
Precision = season.Precision;
|
||||||
|
|
||||||
var variants = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
||||||
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
||||||
var comTypes = ctx.AreaCommitmentTypes.ToDictionary(t => t.VtrgId, t => t);
|
var comTypes = ctx.AreaCommitmentTypes.ToDictionary(t => t.VtrgId, t => t);
|
||||||
MemberUnderDeliveries = underDeliveries?
|
MemberUnderDeliveries = underDeliveries?
|
||||||
.OrderBy(u => u.Key)
|
.OrderBy(u => u.Key)
|
||||||
.Select(u => (
|
.Select(u => (
|
||||||
variants[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
varieties[u.Key[..2]].Name + (u.Key.Length > 2 ? " " + attributes[u.Key[2..]].Name : ""),
|
||||||
u.Value.Diff,
|
u.Value.Diff,
|
||||||
u.Value.Diff * (comTypes[u.Key].PenaltyPerKg ?? 0)
|
u.Value.Diff * (comTypes[u.Key].PenaltyPerKg ?? 0)
|
||||||
- (comTypes[u.Key].PenaltyAmount ?? 0)
|
- (comTypes[u.Key].PenaltyAmount ?? 0)
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
@if (i == 0) {
|
@if (i == 0) {
|
||||||
<td rowspan="@rows">@p.LsNr</td>
|
<td rowspan="@rows">@p.LsNr</td>
|
||||||
<td rowspan="@rows">@p.DPNr</td>
|
<td rowspan="@rows">@p.DPNr</td>
|
||||||
<td class="small">@p.Variant</td>
|
<td class="small">@p.Variety</td>
|
||||||
<td class="small">@p.Attribute</td>
|
<td class="small">@p.Attribute</td>
|
||||||
<td rowspan="@rows" class="center">@($"{p.Gradation.Oe:N0}")</td>
|
<td rowspan="@rows" class="center">@($"{p.Gradation.Oe:N0}")</td>
|
||||||
<td rowspan="@rows" class="center">@($"{p.Gradation.Kmw:N1}")</td>
|
<td rowspan="@rows" class="center">@($"{p.Gradation.Kmw:N1}")</td>
|
||||||
@ -158,4 +158,10 @@
|
|||||||
}
|
}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<p>Überweisung erfolgt auf Konto @(Elwig.Helpers.Utils.FormatIban(Model.Member.Iban ?? "-")).</p>
|
||||||
|
<div style="margin-top: 1em;">
|
||||||
|
@if (Model.Text != null) {
|
||||||
|
<p class="custom">@Model.Text</p>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -10,11 +10,11 @@ namespace Elwig.Documents {
|
|||||||
public new static string Name => "Anlieferungsbestätigung";
|
public new static string Name => "Anlieferungsbestätigung";
|
||||||
|
|
||||||
public Season Season;
|
public Season Season;
|
||||||
public DeliveryConfirmationData Data;
|
public DeliveryConfirmationDeliveryData Data;
|
||||||
public string? Text = App.Client.TextDeliveryConfirmation;
|
public string? Text = App.Client.TextDeliveryConfirmation;
|
||||||
public Dictionary<string, MemberBucket> MemberBuckets;
|
public Dictionary<string, MemberBucket> MemberBuckets;
|
||||||
|
|
||||||
public DeliveryConfirmation(AppDbContext ctx, int year, Member m, DeliveryConfirmationData data) :
|
public DeliveryConfirmation(AppDbContext ctx, int year, Member m, DeliveryConfirmationDeliveryData data) :
|
||||||
base($"{Name} {year}", m) {
|
base($"{Name} {year}", m) {
|
||||||
Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("invalid season");
|
Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("invalid season");
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
|
@ -42,17 +42,17 @@
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@{
|
@{
|
||||||
var lastVariant = "";
|
var lastVariety = "";
|
||||||
}
|
}
|
||||||
@foreach (var p in Model.Data.Rows) {
|
@foreach (var p in Model.Data.Rows) {
|
||||||
var rows = Math.Max(p.Buckets.Length, p.Modifiers.Length + 1);
|
var rows = Math.Max(p.Buckets.Length, p.Modifiers.Length + 1);
|
||||||
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.Variant != lastVariant && lastVariant != "" ? "new": "") @(rows > i + 1 ? "last" : "")">
|
<tr class="@(first ? "first" : "") @(p.Variety != lastVariety && lastVariety != "" ? "new": "") @(rows > i + 1 ? "last" : "")">
|
||||||
@if (first) {
|
@if (first) {
|
||||||
<td rowspan="@rows">@p.LsNr</td>
|
<td rowspan="@rows">@p.LsNr</td>
|
||||||
<td rowspan="@rows">@p.DPNr</td>
|
<td rowspan="@rows">@p.DPNr</td>
|
||||||
<td class="small">@p.Variant</td>
|
<td class="small">@p.Variety</td>
|
||||||
<td class="small">@p.Attribute</td>
|
<td class="small">@p.Attribute</td>
|
||||||
<td class="small">@p.QualityLevel</td>
|
<td class="small">@p.QualityLevel</td>
|
||||||
<td rowspan="@rows" class="center">@($"{p.Gradation.Oe:N0}")</td>
|
<td rowspan="@rows" class="center">@($"{p.Gradation.Oe:N0}")</td>
|
||||||
@ -80,7 +80,7 @@
|
|||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
lastVariant = p.Variant;
|
lastVariety = p.Variety;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<tr class="sum bold">
|
<tr class="sum bold">
|
||||||
@ -92,9 +92,9 @@
|
|||||||
</table>
|
</table>
|
||||||
@Raw(BusinessDocument.PrintSortenaufteilung(Model.MemberBuckets))
|
@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 style="margin-top: 2em;">
|
||||||
@if (Model.Text != null) {
|
@if (Model.Text != null) {
|
||||||
<p class="comment" style="white-space: pre-wrap; break-inside: avoid;">@Model.Text</p>
|
<p class="custom comment">@Model.Text</p>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
@ -19,7 +19,7 @@ namespace Elwig.Documents {
|
|||||||
public DeliveryJournal(string filter, IQueryable<DeliveryPart> deliveries) :
|
public DeliveryJournal(string filter, IQueryable<DeliveryPart> deliveries) :
|
||||||
this(filter, deliveries
|
this(filter, deliveries
|
||||||
.Include(p => p.Delivery).ThenInclude(d => d.Member)
|
.Include(p => p.Delivery).ThenInclude(d => d.Member)
|
||||||
.Include(p => p.Variant)
|
.Include(p => p.Variety)
|
||||||
.ToList()) { }
|
.ToList()) { }
|
||||||
|
|
||||||
public DeliveryJournal(AppDbContext ctx, DateOnly date) :
|
public DeliveryJournal(AppDbContext ctx, DateOnly date) :
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
<td class="small">@($"{p.Delivery.Time:HH:mm}")</td>
|
<td class="small">@($"{p.Delivery.Time:HH:mm}")</td>
|
||||||
<td class="number">@p.Delivery.Member.MgNr</td>
|
<td class="number">@p.Delivery.Member.MgNr</td>
|
||||||
<td class="small">@p.Delivery.Member.AdministrativeName</td>
|
<td class="small">@p.Delivery.Member.AdministrativeName</td>
|
||||||
<td class="small">@p.Variant.Name</td>
|
<td class="small">@p.Variety.Name</td>
|
||||||
<td class="center">@($"{p.Oe:N0}")</td>
|
<td class="center">@($"{p.Oe:N0}")</td>
|
||||||
<td class="center">@($"{p.Kmw:N1}")</td>
|
<td class="center">@($"{p.Kmw:N1}")</td>
|
||||||
<td class="number">@($"{p.Weight:N0}")</td>
|
<td class="number">@($"{p.Weight:N0}")</td>
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
@foreach (var part in Model.Delivery.Parts.OrderBy(p => p.DPNr)) {
|
@foreach (var part in Model.Delivery.Parts.OrderBy(p => p.DPNr)) {
|
||||||
<tr class="main">
|
<tr class="main">
|
||||||
<td class="center">@part.DPNr</td>
|
<td class="center">@part.DPNr</td>
|
||||||
<td colspan="2">@part.Variant.Name</td>
|
<td colspan="2">@part.Variety.Name</td>
|
||||||
<td colspan="2">@part.Attribute?.Name</td>
|
<td colspan="2">@part.Attribute?.Name</td>
|
||||||
<td>@part.Quality.Name</td>
|
<td>@part.Quality.Name</td>
|
||||||
<td class="center">@($"{part.Oe:N0}")</td>
|
<td class="center">@($"{part.Oe:N0}")</td>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>0.6.1</Version>
|
<Version>0.6.3</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ namespace Elwig.Helpers {
|
|||||||
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
||||||
public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
|
public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
|
||||||
public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
||||||
|
public DbSet<CreditNoteDeliveryRowSingle> CreditNoteDeliveryRows { get; private set; }
|
||||||
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
||||||
|
|
||||||
private readonly StreamWriter? LogFile = null;
|
private readonly StreamWriter? LogFile = null;
|
||||||
|
@ -9,7 +9,7 @@ namespace Elwig.Helpers {
|
|||||||
public static class AppDbUpdater {
|
public static class AppDbUpdater {
|
||||||
|
|
||||||
// Don't forget to update value in Tests/fetch-resources.bat!
|
// Don't forget to update value in Tests/fetch-resources.bat!
|
||||||
public static readonly int RequiredSchemaVersion = 13;
|
public static readonly int RequiredSchemaVersion = 14;
|
||||||
|
|
||||||
private static int VersionOffset = 0;
|
private static int VersionOffset = 0;
|
||||||
|
|
||||||
|
@ -150,31 +150,31 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static Dictionary<string, JsonValue> GetSelection(JsonNode value, IEnumerable<string> attributeVariants) {
|
protected static Dictionary<string, JsonValue> GetSelection(JsonNode value, IEnumerable<string> vaributes) {
|
||||||
if (value is JsonValue flatRate) {
|
if (value is JsonValue flatRate) {
|
||||||
return attributeVariants.ToDictionary(e => e, _ => flatRate);
|
return vaributes.ToDictionary(e => e, _ => flatRate);
|
||||||
} if (value is not JsonObject data) {
|
} if (value is not JsonObject data) {
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
Dictionary<string, JsonValue> dict;
|
Dictionary<string, JsonValue> dict;
|
||||||
if (data["default"] is JsonValue def) {
|
if (data["default"] is JsonValue def) {
|
||||||
dict = attributeVariants.ToDictionary(e => e, _ => def);
|
dict = vaributes.ToDictionary(e => e, _ => def);
|
||||||
} else {
|
} else {
|
||||||
dict = [];
|
dict = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
var variants = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length == 2);
|
var varieties = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length == 2);
|
||||||
var attributes = data.Where(p => p.Key.StartsWith('/'));
|
var attributes = data.Where(p => p.Key.StartsWith('/'));
|
||||||
var others = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length > 2 && p.Key != "default");
|
var others = data.Where(p => !p.Key.StartsWith('/') && p.Key.Length > 2 && p.Key != "default");
|
||||||
foreach (var (idx, v) in variants) {
|
foreach (var (idx, v) in varieties) {
|
||||||
var curve = v?.AsValue() ?? throw new InvalidOperationException();
|
var curve = v?.AsValue() ?? throw new InvalidOperationException();
|
||||||
foreach (var i in attributeVariants.Where(e => e.StartsWith(idx[..^1]))) {
|
foreach (var i in vaributes.Where(e => e.StartsWith(idx[..^1]))) {
|
||||||
dict[i] = curve;
|
dict[i] = curve;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var (idx, v) in attributes) {
|
foreach (var (idx, v) in attributes) {
|
||||||
var curve = v?.AsValue() ?? throw new InvalidOperationException();
|
var curve = v?.AsValue() ?? throw new InvalidOperationException();
|
||||||
foreach (var i in attributeVariants.Where(e => e[2..] == idx[1..])) {
|
foreach (var i in vaributes.Where(e => e[2..] == idx[1..])) {
|
||||||
dict[i] = curve;
|
dict[i] = curve;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return curve;
|
return curve;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void CollapsePaymentData(JsonObject data, IEnumerable<string> attributeVariants) {
|
protected static void CollapsePaymentData(JsonObject data, IEnumerable<string> vaributes, bool useDefault = true) {
|
||||||
Dictionary<string, List<string>> rev1 = [];
|
Dictionary<string, List<string>> rev1 = [];
|
||||||
Dictionary<decimal, List<string>> rev2 = [];
|
Dictionary<decimal, List<string>> rev2 = [];
|
||||||
foreach (var (k, v) in data) {
|
foreach (var (k, v) in data) {
|
||||||
@ -273,18 +273,18 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
if (!data.ContainsKey("default")) {
|
if (!data.ContainsKey("default")) {
|
||||||
foreach (var (v, ks) in rev1) {
|
foreach (var (v, ks) in rev1) {
|
||||||
if (ks.Count >= attributeVariants.Count() / 2.0) {
|
if ((ks.Count >= vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) {
|
||||||
foreach (var k in ks) data.Remove(k);
|
foreach (var k in ks) data.Remove(k);
|
||||||
data["default"] = v;
|
data["default"] = v;
|
||||||
CollapsePaymentData(data, attributeVariants);
|
CollapsePaymentData(data, vaributes, useDefault);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var (v, ks) in rev2) {
|
foreach (var (v, ks) in rev2) {
|
||||||
if (ks.Count >= attributeVariants.Count() / 2.0) {
|
if ((ks.Count >= vaributes.Count() * 0.5 && useDefault) || ks.Count == vaributes.Count()) {
|
||||||
foreach (var k in ks) data.Remove(k);
|
foreach (var k in ks) data.Remove(k);
|
||||||
data["default"] = v;
|
data["default"] = v;
|
||||||
CollapsePaymentData(data, attributeVariants);
|
CollapsePaymentData(data, vaributes, useDefault);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,17 +296,17 @@ namespace Elwig.Helpers.Billing {
|
|||||||
.Distinct()
|
.Distinct()
|
||||||
.ToList();
|
.ToList();
|
||||||
foreach (var idx in attributes) {
|
foreach (var idx in attributes) {
|
||||||
var len = attributeVariants.Count(e => e.EndsWith(idx));
|
var len = vaributes.Count(e => e.EndsWith(idx));
|
||||||
foreach (var (v, ks) in rev1) {
|
foreach (var (v, ks) in rev1) {
|
||||||
var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
|
var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
|
||||||
if (myKs.Count > 1 && myKs.Count >= len / 2.0) {
|
if (myKs.Count > 1 && ((myKs.Count >= len * 0.5 && useDefault) || myKs.Count == len)) {
|
||||||
foreach (var k in myKs) data.Remove(k);
|
foreach (var k in myKs) data.Remove(k);
|
||||||
data[idx] = v;
|
data[idx] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var (v, ks) in rev2) {
|
foreach (var (v, ks) in rev2) {
|
||||||
var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
|
var myKs = ks.Where(k => k.EndsWith(idx)).ToList();
|
||||||
if (myKs.Count > 1 && myKs.Count >= len / 2.0) {
|
if (myKs.Count > 1 && ((myKs.Count >= len * 0.5 && useDefault) || myKs.Count == len)) {
|
||||||
foreach (var k in myKs) data.Remove(k);
|
foreach (var k in myKs) data.Remove(k);
|
||||||
data[idx] = v;
|
data[idx] = v;
|
||||||
}
|
}
|
||||||
@ -314,7 +314,13 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JsonObject FromGraphEntries(IEnumerable<GraphEntry> graphEntries, BillingData? origData = null, IEnumerable<string>? attributeVariants = null) {
|
public static JsonObject FromGraphEntries(
|
||||||
|
IEnumerable<GraphEntry> graphEntries,
|
||||||
|
BillingData? origData = null,
|
||||||
|
IEnumerable<string>? vaributes = null,
|
||||||
|
bool useDefaultPayment = true,
|
||||||
|
bool useDefaultQuality = true
|
||||||
|
) {
|
||||||
var payment = new JsonObject();
|
var payment = new JsonObject();
|
||||||
var qualityWei = new JsonObject();
|
var qualityWei = new JsonObject();
|
||||||
var curves = new JsonArray();
|
var curves = new JsonArray();
|
||||||
@ -331,7 +337,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
} else {
|
} else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach (var c in entry.Contracts) {
|
foreach (var c in entry.Vaributes) {
|
||||||
if (entry.Abgewertet) {
|
if (entry.Abgewertet) {
|
||||||
qualityWei[$"{c.Variety?.SortId}/{c.Attribute?.AttrId}"] = node.DeepClone();
|
qualityWei[$"{c.Variety?.SortId}/{c.Attribute?.AttrId}"] = node.DeepClone();
|
||||||
} else {
|
} else {
|
||||||
@ -340,8 +346,8 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CollapsePaymentData(payment, attributeVariants ?? payment.Select(e => e.Key).ToList());
|
CollapsePaymentData(payment, vaributes ?? payment.Select(e => e.Key).ToList(), useDefaultPayment);
|
||||||
CollapsePaymentData(qualityWei, attributeVariants ?? qualityWei.Select(e => e.Key).ToList());
|
CollapsePaymentData(qualityWei, vaributes ?? qualityWei.Select(e => e.Key).ToList(), useDefaultQuality);
|
||||||
|
|
||||||
var data = new JsonObject {
|
var data = new JsonObject {
|
||||||
["mode"] = "elwig",
|
["mode"] = "elwig",
|
||||||
@ -359,16 +365,16 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
if (payment.Count == 0) {
|
if (payment.Count == 0) {
|
||||||
data["payment"] = 0;
|
data["payment"] = 0;
|
||||||
} else if (payment.Count == 1) {
|
} else if (payment.Count == 1 && payment.First().Key == "default") {
|
||||||
data["payment"] = payment.Single().Value?.DeepClone();
|
data["payment"] = payment.Single().Value?.DeepClone();
|
||||||
} else {
|
} else {
|
||||||
data["payment"] = payment;
|
data["payment"] = payment;
|
||||||
}
|
}
|
||||||
if (qualityWei.Count == 1) {
|
if (qualityWei.Count == 1 && qualityWei.First().Key == "default") {
|
||||||
data["quality"] = new JsonObject() {
|
data["quality"] = new JsonObject() {
|
||||||
["WEI"] = qualityWei.Single().Value?.DeepClone()
|
["WEI"] = qualityWei.Single().Value?.DeepClone()
|
||||||
};
|
};
|
||||||
} else if (qualityWei.Count > 1) {
|
} else if (qualityWei.Count >= 1) {
|
||||||
data["quality"] = new JsonObject() {
|
data["quality"] = new JsonObject() {
|
||||||
["WEI"] = qualityWei
|
["WEI"] = qualityWei
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public BillingVariant(int year, int avnr) : base(year) {
|
public BillingVariant(int year, int avnr) : base(year) {
|
||||||
AvNr = avnr;
|
AvNr = avnr;
|
||||||
PaymentVariant = Context.PaymentVariants.Find(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
PaymentVariant = Context.PaymentVariants.Find(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
||||||
Data = PaymentBillingData.FromJson(PaymentVariant.Data, Utils.GetAttributeVarieties(Context, Year));
|
Data = PaymentBillingData.FromJson(PaymentVariant.Data, Utils.GetVaributes(Context, Year, onlyDelivered: false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Calculate() {
|
public async Task Calculate() {
|
||||||
@ -24,9 +24,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
await DeleteInDb(cnx);
|
await DeleteInDb(cnx);
|
||||||
await SetCalcTime(cnx);
|
await SetCalcTime(cnx);
|
||||||
await CalculatePrices(cnx);
|
await CalculatePrices(cnx);
|
||||||
if (Data.ConsiderDelieryModifiers)
|
if (Data.ConsiderDelieryModifiers) {
|
||||||
await CalculateDeliveryModifiers(cnx);
|
await CalculateDeliveryModifiers(cnx);
|
||||||
await CalculateMemberModifiers(cnx);
|
await CalculateMemberModifiers(cnx);
|
||||||
|
}
|
||||||
await tx.CommitAsync();
|
await tx.CommitAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,11 +43,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
|
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
|
||||||
ROUND(lp.amount / POW(10, s.precision - 2)) AS prev_amount,
|
ROUND(lp.amount / POW(10, s.precision - 2)) AS prev_amount,
|
||||||
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
|
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
|
||||||
ROUND(
|
ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) +
|
||||||
IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0) / POW(10, 4 - 2), 0) +
|
ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) +
|
||||||
IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) +
|
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2))
|
||||||
IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.business_shares * s.bs_value, 0), 0) / POW(10, s.precision - 2)
|
AS modifiers,
|
||||||
) AS modifiers,
|
|
||||||
lc.modifiers AS prev_modifiers
|
lc.modifiers AS prev_modifiers
|
||||||
FROM season s
|
FROM season s
|
||||||
JOIN payment_variant v ON v.year = s.year
|
JOIN payment_variant v ON v.year = s.year
|
||||||
@ -62,26 +62,9 @@ namespace Elwig.Helpers.Billing {
|
|||||||
LEFT JOIN payment_member lp ON (lp.year, lp.avnr, lp.mgnr) = (l.year, l.avnr, m.mgnr)
|
LEFT JOIN payment_member lp ON (lp.year, lp.avnr, lp.mgnr) = (l.year, l.avnr, m.mgnr)
|
||||||
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (v.year, v.avnr, m.mgnr)
|
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (v.year, v.avnr, m.mgnr)
|
||||||
LEFT JOIN credit lc ON (lc.year, lc.avnr, lc.mgnr) = (l.year, l.avnr, m.mgnr)
|
LEFT JOIN credit lc ON (lc.year, lc.avnr, lc.mgnr) = (l.year, l.avnr, m.mgnr)
|
||||||
LEFT JOIN (SELECT year, mgnr,
|
LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
||||||
SUM(COALESCE(IIF(u.weight = 0, -t.penalty_none, 0), 0) +
|
LEFT JOIN v_penalty_business_shares b ON (b.year, b.mgnr) = (s.year, m.mgnr)
|
||||||
COALESCE(IIF(u.diff < 0, -t.penalty_amount, 0), 0) +
|
LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr)
|
||||||
COALESCE(u.diff * t.penalty_per_kg, 0)) AS total_penalty
|
|
||||||
FROM v_under_delivery u
|
|
||||||
JOIN area_commitment_type t ON t.vtrgid = u.bucket
|
|
||||||
GROUP BY year, mgnr) u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
|
||||||
LEFT JOIN (SELECT s.year, u.mgnr,
|
|
||||||
(COALESCE(IIF(u.weight = 0, -s.penalty_none, 0), 0) +
|
|
||||||
COALESCE(IIF(u.diff < 0, -s.penalty_amount, 0), 0) +
|
|
||||||
COALESCE(u.diff * s.penalty_per_kg, 0)
|
|
||||||
) / POW(10, s.precision - 2) AS total_penalty
|
|
||||||
FROM v_total_under_delivery u
|
|
||||||
JOIN season s ON s.year = u.year
|
|
||||||
WHERE u.diff < 0) b ON (b.year, b.mgnr) = (s.year, m.mgnr)
|
|
||||||
LEFT JOIN (SELECT h.mgnr, h.business_shares
|
|
||||||
FROM member_history h
|
|
||||||
WHERE type = 'auto' AND
|
|
||||||
date >= '{Year}-06-01' AND
|
|
||||||
date < '{Year + 1}-06-01') a ON a.mgnr = m.mgnr
|
|
||||||
WHERE s.year = {Year} AND v.avnr = {AvNr};
|
WHERE s.year = {Year} AND v.avnr = {AvNr};
|
||||||
|
|
||||||
UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr});
|
UPDATE payment_variant SET test_variant = FALSE WHERE (year, avnr) = ({Year}, {AvNr});
|
||||||
|
@ -7,15 +7,15 @@ using System.Text.Json.Nodes;
|
|||||||
namespace Elwig.Helpers.Billing {
|
namespace Elwig.Helpers.Billing {
|
||||||
public class EditBillingData : BillingData {
|
public class EditBillingData : BillingData {
|
||||||
|
|
||||||
protected readonly IEnumerable<string> AttributeVariants;
|
protected readonly IEnumerable<string> Vaributes;
|
||||||
|
|
||||||
public EditBillingData(JsonObject data, IEnumerable<string> attributeVariants) :
|
public EditBillingData(JsonObject data, IEnumerable<string> vaributes) :
|
||||||
base(data) {
|
base(data) {
|
||||||
AttributeVariants = attributeVariants;
|
Vaributes = vaributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EditBillingData FromJson(string json, IEnumerable<string> attributeVariants) {
|
public static EditBillingData FromJson(string json, IEnumerable<string> vaributes) {
|
||||||
return new(ParseJson(json), attributeVariants);
|
return new(ParseJson(json), vaributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private (Dictionary<int, Curve>, Dictionary<int, List<string>>) GetGraphEntries(JsonNode root) {
|
private (Dictionary<int, Curve>, Dictionary<int, List<string>>) GetGraphEntries(JsonNode root) {
|
||||||
@ -56,7 +56,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Dictionary<int, List<string>> dict3 = curves.ToDictionary(c => c.Key, _ => new List<string>());
|
Dictionary<int, List<string>> dict3 = curves.ToDictionary(c => c.Key, _ => new List<string>());
|
||||||
foreach (var (selector, value) in GetSelection(root, AttributeVariants)) {
|
foreach (var (selector, value) in GetSelection(root, Vaributes)) {
|
||||||
int? idx = null;
|
int? idx = null;
|
||||||
if (value.TryGetValue<decimal>(out var val)) {
|
if (value.TryGetValue<decimal>(out var val)) {
|
||||||
idx = Array.IndexOf(virtCurves, val) + virtOffset;
|
idx = Array.IndexOf(virtCurves, val) + virtOffset;
|
||||||
@ -70,12 +70,16 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return (curves, dict3);
|
return (curves, dict3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<GraphEntry> CreateGraphEntries(AppDbContext ctx, int precision, Dictionary<int, Curve> curves, Dictionary<int, List<string>> entries) {
|
private static List<GraphEntry> CreateGraphEntries(
|
||||||
|
AppDbContext ctx, int precision,
|
||||||
|
Dictionary<int, Curve> curves,
|
||||||
|
Dictionary<int, List<string>> entries
|
||||||
|
) {
|
||||||
var vars = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
var vars = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
||||||
var attrs = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
var attrs = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
||||||
return entries
|
return entries
|
||||||
.Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value
|
.Select(e => new GraphEntry(e.Key, precision, curves[e.Key], e.Value
|
||||||
.Select(s => new ContractSelection(vars[s[..2]], s.Length > 2 ? attrs[s[2..]] : null))
|
.Select(s => new Varibute(vars[s[..2]], s.Length > 2 ? attrs[s[2..]] : null))
|
||||||
.ToList()))
|
.ToList()))
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
@ -83,7 +87,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public IEnumerable<GraphEntry> GetPaymentGraphEntries(AppDbContext ctx, Season season) {
|
public IEnumerable<GraphEntry> GetPaymentGraphEntries(AppDbContext ctx, Season season) {
|
||||||
var root = GetPaymentEntry();
|
var root = GetPaymentEntry();
|
||||||
var (curves, entries) = GetGraphEntries(root);
|
var (curves, entries) = GetGraphEntries(root);
|
||||||
return CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Contracts.Count > 0);
|
return CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Vaributes.Count > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<GraphEntry> GetQualityGraphEntries(AppDbContext ctx, Season season, int idOffset = 0) {
|
public IEnumerable<GraphEntry> GetQualityGraphEntries(AppDbContext ctx, Season season, int idOffset = 0) {
|
||||||
@ -91,7 +95,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
if (root == null || root["WEI"] is not JsonNode qualityWei)
|
if (root == null || root["WEI"] is not JsonNode qualityWei)
|
||||||
return [];
|
return [];
|
||||||
var (curves, entries) = GetGraphEntries(qualityWei);
|
var (curves, entries) = GetGraphEntries(qualityWei);
|
||||||
var list = CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Contracts.Count > 0);
|
var list = CreateGraphEntries(ctx, season.Precision, curves, entries).Where(e => e.Vaributes.Count > 0);
|
||||||
foreach (var e in list) {
|
foreach (var e in list) {
|
||||||
e.Id += idOffset;
|
e.Id += idOffset;
|
||||||
e.Abgewertet = true;
|
e.Abgewertet = true;
|
||||||
|
@ -7,7 +7,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
public const int MinX = 50;
|
public const int MinX = 50;
|
||||||
public const int MinXGeb = 73;
|
public const int MinXGeb = 73;
|
||||||
public const int MaxX = 140;
|
public const int MaxX = 120;
|
||||||
|
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
public BillingData.CurveMode Mode { get; set; }
|
public BillingData.CurveMode Mode { get; set; }
|
||||||
@ -36,10 +36,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ContractSelection> Contracts { get; set; }
|
public List<Varibute> Vaributes { get; set; }
|
||||||
public string ContractsStringSimple => (Abgewertet ? "Abgew.: " : "") + (Contracts.Count != 0 ? (Contracts.Count >= 25 ? "Restliche Sorten" : string.Join(", ", Contracts.Select(c => c.Listing))) : "-");
|
public string VaributeStringSimple => (Abgewertet ? "Abgew.: " : "") + (Vaributes.Count != 0 ? (Vaributes.Count >= 25 ? "Restliche Sorten" : string.Join(", ", Vaributes.Select(c => c.Listing))) : "-");
|
||||||
public string ContractsString => Contracts.Count != 0 ? string.Join("\n", Contracts.Select(c => c.FullName)) : "-";
|
public string VaributeString => Vaributes.Count != 0 ? string.Join("\n", Vaributes.Select(c => c.FullName)) : "-";
|
||||||
public string ContractsStringChange => (Abgewertet ? "A." : "") + string.Join(",", Contracts.Select(c => c.Listing));
|
public string VaributeStringChange => (Abgewertet ? "A." : "") + string.Join(",", Vaributes.Select(c => c.Listing));
|
||||||
private readonly int Precision;
|
private readonly int Precision;
|
||||||
|
|
||||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode) {
|
public GraphEntry(int id, int precision, BillingData.CurveMode mode) {
|
||||||
@ -47,7 +47,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
Precision = precision;
|
Precision = precision;
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
DataGraph = new Graph(precision, MinX, MaxX); ;
|
DataGraph = new Graph(precision, MinX, MaxX); ;
|
||||||
Contracts = [];
|
Vaributes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden) :
|
public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden) :
|
||||||
@ -56,21 +56,21 @@ namespace Elwig.Helpers.Billing {
|
|||||||
if (gebunden != null) GebundenGraph = new Graph(gebunden, precision, MinXGeb, MaxX);
|
if (gebunden != null) GebundenGraph = new Graph(gebunden, precision, MinXGeb, MaxX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphEntry(int id, int precision, BillingData.Curve curve, List<ContractSelection> contracts) :
|
public GraphEntry(int id, int precision, BillingData.Curve curve, List<Varibute> vaributes) :
|
||||||
this(id, precision, curve.Mode) {
|
this(id, precision, curve.Mode) {
|
||||||
DataGraph = new Graph(curve.Normal, precision, MinX, MaxX);
|
DataGraph = new Graph(curve.Normal, precision, MinX, MaxX);
|
||||||
if (curve.Gebunden != null)
|
if (curve.Gebunden != null)
|
||||||
GebundenGraph = new Graph(curve.Gebunden, precision, MinXGeb, MaxX);
|
GebundenGraph = new Graph(curve.Gebunden, precision, MinXGeb, MaxX);
|
||||||
Contracts = contracts;
|
Vaributes = vaributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, List<ContractSelection> contracts) {
|
private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, List<Varibute> vaributes) {
|
||||||
Id = id;
|
Id = id;
|
||||||
Precision = precision;
|
Precision = precision;
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
DataGraph = dataGraph;
|
DataGraph = dataGraph;
|
||||||
GebundenGraph = gebundenGraph;
|
GebundenGraph = gebundenGraph;
|
||||||
Contracts = contracts;
|
Vaributes = vaributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddGebundenGraph() {
|
public void AddGebundenGraph() {
|
||||||
|
@ -9,24 +9,24 @@ namespace Elwig.Helpers.Billing {
|
|||||||
protected readonly Dictionary<int, Curve> Curves;
|
protected readonly Dictionary<int, Curve> Curves;
|
||||||
protected readonly Dictionary<string, Curve> PaymentData;
|
protected readonly Dictionary<string, Curve> PaymentData;
|
||||||
protected readonly Dictionary<string, Curve> QualityData;
|
protected readonly Dictionary<string, Curve> QualityData;
|
||||||
protected readonly IEnumerable<string> AttributeVariants;
|
protected readonly IEnumerable<string> Vaributes;
|
||||||
|
|
||||||
public PaymentBillingData(JsonObject data, IEnumerable<string> attributeVariants) :
|
public PaymentBillingData(JsonObject data, IEnumerable<string> vaributes) :
|
||||||
base(data) {
|
base(data) {
|
||||||
if (attributeVariants.Any(e => e.Any(c => c < 'A' || c > 'Z')))
|
if (vaributes.Any(e => e.Any(c => c < 'A' || c > 'Z')))
|
||||||
throw new ArgumentException("Invalid attributeVariants");
|
throw new ArgumentException("Invalid vaributes");
|
||||||
AttributeVariants = attributeVariants;
|
Vaributes = vaributes;
|
||||||
Curves = GetCurves();
|
Curves = GetCurves();
|
||||||
PaymentData = GetPaymentData();
|
PaymentData = GetPaymentData();
|
||||||
QualityData = GetQualityData();
|
QualityData = GetQualityData();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static PaymentBillingData FromJson(string json, IEnumerable<string> attributeVariants) {
|
public static PaymentBillingData FromJson(string json, IEnumerable<string> vaributes) {
|
||||||
return new(ParseJson(json), attributeVariants);
|
return new(ParseJson(json), vaributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Dictionary<string, Curve> GetData(JsonNode data) {
|
private Dictionary<string, Curve> GetData(JsonNode data) {
|
||||||
return GetSelection(data, AttributeVariants).ToDictionary(e => e.Key, e => LookupCurve(e.Value));
|
return GetSelection(data, Vaributes).ToDictionary(e => e.Key, e => LookupCurve(e.Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Dictionary<string, Curve> GetPaymentData() {
|
protected Dictionary<string, Curve> GetPaymentData() {
|
||||||
|
@ -2,14 +2,17 @@
|
|||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Billing {
|
namespace Elwig.Helpers.Billing {
|
||||||
public class ContractSelection : IComparable<ContractSelection> {
|
public class Varibute : IComparable<Varibute> {
|
||||||
|
|
||||||
public WineVar? Variety { get; }
|
public WineVar? Variety { get; }
|
||||||
public WineAttr? Attribute { get; }
|
public WineAttr? Attribute { get; }
|
||||||
|
public int? AssignedGraphId { get; set; }
|
||||||
|
public int? AssignedAbgewGraphId { get; set; }
|
||||||
|
|
||||||
public string Listing => $"{Variety?.SortId}{Attribute?.AttrId}";
|
public string Listing => $"{Variety?.SortId}{Attribute?.AttrId}";
|
||||||
public string FullName => $"{Variety?.Name}" + (Variety != null && Attribute != null ? " " : "") + $"{Attribute?.Name}";
|
public string FullName => $"{Variety?.Name}" + (Variety != null && Attribute != null ? " " : "") + $"{Attribute?.Name}";
|
||||||
|
|
||||||
public ContractSelection(WineVar? var, WineAttr? attr) {
|
public Varibute(WineVar? var, WineAttr? attr) {
|
||||||
Variety = var;
|
Variety = var;
|
||||||
Attribute = attr;
|
Attribute = attr;
|
||||||
}
|
}
|
||||||
@ -18,7 +21,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return Listing;
|
return Listing;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo(ContractSelection? other) {
|
public int CompareTo(Varibute? other) {
|
||||||
return Listing.CompareTo(other?.Listing);
|
return Listing.CompareTo(other?.Listing);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -60,6 +60,7 @@ namespace Elwig.Helpers {
|
|||||||
|
|
||||||
public string? TextDeliveryNote;
|
public string? TextDeliveryNote;
|
||||||
public string? TextDeliveryConfirmation;
|
public string? TextDeliveryConfirmation;
|
||||||
|
public string? TextCreditNote;
|
||||||
|
|
||||||
public ClientParameters(AppDbContext ctx) : this(ctx.ClientParameters.ToDictionary(e => e.Param, e => e.Value)) { }
|
public ClientParameters(AppDbContext ctx) : this(ctx.ClientParameters.ToDictionary(e => e.Param, e => e.Value)) { }
|
||||||
|
|
||||||
@ -99,6 +100,8 @@ namespace Elwig.Helpers {
|
|||||||
if (TextDeliveryNote == "") TextDeliveryNote = null;
|
if (TextDeliveryNote == "") TextDeliveryNote = null;
|
||||||
TextDeliveryConfirmation = parameters.GetValueOrDefault("TEXT_DELIVERYCONFIRMATION");
|
TextDeliveryConfirmation = parameters.GetValueOrDefault("TEXT_DELIVERYCONFIRMATION");
|
||||||
if (TextDeliveryConfirmation == "") TextDeliveryConfirmation = null;
|
if (TextDeliveryConfirmation == "") TextDeliveryConfirmation = null;
|
||||||
|
TextCreditNote = parameters.GetValueOrDefault("TEXT_CREDITNOTE");
|
||||||
|
if (TextCreditNote == "") TextCreditNote = null;
|
||||||
} catch {
|
} catch {
|
||||||
throw new KeyNotFoundException();
|
throw new KeyNotFoundException();
|
||||||
}
|
}
|
||||||
@ -133,6 +136,7 @@ namespace Elwig.Helpers {
|
|||||||
("DOCUMENT_SENDER", Sender2),
|
("DOCUMENT_SENDER", Sender2),
|
||||||
("TEXT_DELIVERYNOTE", TextDeliveryNote),
|
("TEXT_DELIVERYNOTE", TextDeliveryNote),
|
||||||
("TEXT_DELIVERYCONFIRMATION", TextDeliveryConfirmation),
|
("TEXT_DELIVERYCONFIRMATION", TextDeliveryConfirmation),
|
||||||
|
("TEXT_CREDITNOTE", TextCreditNote),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,19 +108,19 @@ namespace Elwig.Helpers.Export {
|
|||||||
<style:paragraph-properties fo:text-align="center"/>
|
<style:paragraph-properties fo:text-align="center"/>
|
||||||
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
||||||
</style:style>
|
</style:style>
|
||||||
<number:number-style style:name="NN0"><number:number number:decimal-places="0" number:min-decimal-places="0" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN0"><number:number number:decimal-places="0" number:min-decimal-places="0" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N0" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN0"/>
|
<style:style style:name="N0" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN0"/>
|
||||||
<number:number-style style:name="NN1"><number:number number:decimal-places="1" number:min-decimal-places="1" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN1"><number:number number:decimal-places="1" number:min-decimal-places="1" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N1" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN1"/>
|
<style:style style:name="N1" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN1"/>
|
||||||
<number:number-style style:name="NN2"><number:number number:decimal-places="2" number:min-decimal-places="2" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN2"><number:number number:decimal-places="2" number:min-decimal-places="2" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N2" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN2"/>
|
<style:style style:name="N2" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN2"/>
|
||||||
<number:number-style style:name="NN3"><number:number number:decimal-places="3" number:min-decimal-places="3" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN3"><number:number number:decimal-places="3" number:min-decimal-places="3" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N3" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN3"/>
|
<style:style style:name="N3" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN3"/>
|
||||||
<number:number-style style:name="NN4"><number:number number:decimal-places="4" number:min-decimal-places="4" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN4"><number:number number:decimal-places="4" number:min-decimal-places="4" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N4" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN4"/>
|
<style:style style:name="N4" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN4"/>
|
||||||
<number:number-style style:name="NN5"><number:number number:decimal-places="5" number:min-decimal-places="5" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN5"><number:number number:decimal-places="5" number:min-decimal-places="5" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N5" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN5"/>
|
<style:style style:name="N5" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN5"/>
|
||||||
<number:number-style style:name="NN6"><number:number number:decimal-places="6" number:min-decimal-places="6" number:min-integer-digits="1"/></number:number-style>
|
<number:number-style style:name="NN6"><number:number number:decimal-places="6" number:min-decimal-places="6" number:min-integer-digits="1" number:grouping="true"/></number:number-style>
|
||||||
<style:style style:name="N6" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN6"/>
|
<style:style style:name="N6" style:family="table-cell" style:parent-style-name="default" style:data-style-name="NN6"/>
|
||||||
</office:automatic-styles>
|
</office:automatic-styles>
|
||||||
<office:body>
|
<office:body>
|
||||||
@ -262,13 +262,14 @@ namespace Elwig.Helpers.Export {
|
|||||||
string c;
|
string c;
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
c = $"<{ct}{add}/>";
|
c = $"<{ct}{add}/>";
|
||||||
} else if (data is float || data is double || data is byte || data is char ||
|
} else if (data is decimal || data is float || data is double || data is byte || data is char ||
|
||||||
data is short || data is ushort || data is int || data is uint || data is long || data is ulong) {
|
data is short || data is ushort || data is int || data is uint || data is long || data is ulong) {
|
||||||
double v = double.Parse(data?.ToString() ?? "0"); // use default culture for ToString and Parse()!
|
double v = double.Parse(data?.ToString() ?? "0"); // use default culture for ToString and Parse()!
|
||||||
if (units != null && units.Length > 0) {
|
if (units != null && units.Length > 0) {
|
||||||
int n = -1;
|
int n = -1;
|
||||||
switch (units[0]) {
|
switch (units[0]) {
|
||||||
case "%": n = 1; data = $"{v:N1}"; break;
|
case "%": n = 1; data = $"{v:N1}"; break;
|
||||||
|
case "€": n = 2; data = $"{v:N2}"; break;
|
||||||
case "°KMW": n = 1; data = $"{v:N1}"; break;
|
case "°KMW": n = 1; data = $"{v:N1}"; break;
|
||||||
case "°Oe": n = 0; data = $"{v:N0}"; break;
|
case "°Oe": n = 0; data = $"{v:N0}"; break;
|
||||||
}
|
}
|
||||||
|
@ -74,12 +74,16 @@ namespace Elwig.Helpers.Printing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task Print(string path, int copies = 1) {
|
public static async Task Print(string path, int copies = 1) {
|
||||||
var p = new Process() { StartInfo = new() { FileName = PdfToPrinter } };
|
try {
|
||||||
p.StartInfo.ArgumentList.Add(path);
|
var p = new Process() { StartInfo = new() { FileName = PdfToPrinter } };
|
||||||
p.StartInfo.ArgumentList.Add("/s");
|
p.StartInfo.ArgumentList.Add(path);
|
||||||
p.StartInfo.ArgumentList.Add($"copies={copies}");
|
p.StartInfo.ArgumentList.Add("/s");
|
||||||
p.Start();
|
p.StartInfo.ArgumentList.Add($"copies={copies}");
|
||||||
await p.WaitForExitAsync();
|
p.Start();
|
||||||
|
await p.WaitForExitAsync();
|
||||||
|
} catch (Exception e) {
|
||||||
|
MessageBox.Show("Beim Drucken ist ein Fehler aufgetreten:\n\n" + e.Message, "Fehler beim Drucken");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +163,7 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static string FormatIban(string iban) {
|
public static string FormatIban(string iban) {
|
||||||
return Regex.Replace(iban, ".{4}", "$0 ");
|
return Regex.Replace(iban.Trim(), ".{4}", "$0 ").Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RunBackground(string title, Func<Task> a) {
|
public static void RunBackground(string title, Func<Task> a) {
|
||||||
@ -362,25 +362,21 @@ namespace Elwig.Helpers {
|
|||||||
return output.OrderByDescending(l => l.Count());
|
return output.OrderByDescending(l => l.Count());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<string> GetAttributeVarieties(AppDbContext ctx, int year, bool withSlash = false) {
|
public static List<string> GetVaributes(AppDbContext ctx, int year, bool withSlash = false, bool onlyDelivered = true) {
|
||||||
return ctx.DeliveryParts
|
var varieties = ctx.WineVarieties.Select(v => v.SortId).ToList();
|
||||||
|
var delivered = ctx.DeliveryParts
|
||||||
.Where(d => d.Year == year)
|
.Where(d => d.Year == year)
|
||||||
.Select(d => $"{d.SortId}{(withSlash ? "/" : "")}{d.AttrId}")
|
.Select(d => $"{d.SortId}{(withSlash ? "/" : "")}{d.AttrId}")
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.ToList()
|
|
||||||
.Union(ctx.WineVarieties.Select(v => v.SortId))
|
|
||||||
.ToList();
|
.ToList();
|
||||||
|
return [.. (onlyDelivered ? delivered : delivered.Union(varieties)).Order()];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<ContractSelection> GetContractsForYear(AppDbContext ctx, int year) {
|
public static List<Varibute> GetVaributeList(AppDbContext ctx, int year, bool onlyDelivered = true) {
|
||||||
return ctx.DeliveryParts
|
var varieties = ctx.WineVarieties.ToDictionary(v => v.SortId, v => v);
|
||||||
.Where(p => p.Year == year)
|
var attributes = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => a);
|
||||||
.Select(d => new ContractSelection(d.Variant, d.Attribute))
|
return GetVaributes(ctx, year, false, onlyDelivered)
|
||||||
.Distinct()
|
.Select(s => new Varibute(varieties[s[..2]], s.Length > 2 ? attributes[s[2..]] : null))
|
||||||
.ToList()
|
|
||||||
.Union(ctx.WineVarieties.Select(v => new ContractSelection(v, null)))
|
|
||||||
.DistinctBy(c => c.Listing)
|
|
||||||
.Order()
|
|
||||||
.ToList();
|
.ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -8,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
|
public class AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = new[] {
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
("Name", "Name", null, 40),
|
("Name", "Name", null, 40),
|
||||||
("GivenName", "Vorname", null, 40),
|
("GivenName", "Vorname", null, 40),
|
||||||
@ -20,7 +19,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
("DeliveryObligations", "Lieferpflicht", "kg", 22),
|
("DeliveryObligations", "Lieferpflicht", "kg", 22),
|
||||||
("Weights", "Geliefert", "kg", 22),
|
("Weights", "Geliefert", "kg", 22),
|
||||||
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
||||||
};
|
];
|
||||||
|
|
||||||
public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
|
public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
|
||||||
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
||||||
|
@ -1,162 +1,180 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using Elwig.Helpers.Billing;
|
using Elwig.Helpers.Billing;
|
||||||
using Elwig.Models.Entities;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Data.Entity.Core.Common.CommandTrees.ExpressionBuilder;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class CreditNoteData : DataTable<CreditNoteRow> {
|
public class CreditNoteData : DataTable<CreditNoteRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?)[] FieldNames = new[] {
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("", "", (string?)null), // TODO
|
("MgNr", "MgNr.", null, 12),
|
||||||
};
|
("Name", "Name", null, 40),
|
||||||
|
("GivenName", "Vorname", null, 40),
|
||||||
|
("Address", "Adresse", null, 60),
|
||||||
|
("Plz", "PLZ", null, 10),
|
||||||
|
("Locality", "Ort", null, 60),
|
||||||
|
("Iban", "IBAN", null, 45),
|
||||||
|
("TgNr", "TG-Nr.", null, 20),
|
||||||
|
("Sum", "Zwischens.", "€", 20),
|
||||||
|
("Surcharge", "Zuschlag", "€", 20),
|
||||||
|
("Total", "Gesamt", "€", 20),
|
||||||
|
("ConsideredSum", "Berückstgt.", "€", 20),
|
||||||
|
("Net", "Netto", "€", 20),
|
||||||
|
("Vat1", "10% MwSt.", "€", 20),
|
||||||
|
("Vat2", "13% MwSt.", "€", 20),
|
||||||
|
("Gross", "Brutto", "€", 20),
|
||||||
|
("Penalties", "Pönalen FB", "€", 20),
|
||||||
|
("Penalty", "Unterl. GA", "€", 20),
|
||||||
|
("AutoBs", "GA Nachz.", "€", 20),
|
||||||
|
("Others", "Sonstige", "€", 20),
|
||||||
|
("Considered", "Berückstgt.", "€", 20),
|
||||||
|
("Amount", "Betrag", "€", 20),
|
||||||
|
];
|
||||||
|
|
||||||
private readonly int Year;
|
public CreditNoteData(IEnumerable<CreditNoteRow> rows, int year, string name) :
|
||||||
private readonly int? TgNr;
|
base($"Buchungsliste", $"Buchungsliste {name} {year}", rows, FieldNames) {
|
||||||
private readonly int? AvNr;
|
|
||||||
private readonly int? MgNr;
|
|
||||||
|
|
||||||
private CreditNoteData(IEnumerable<CreditNoteRow> rows, int year, int? tgnr, int? avnr = null, int? mgnr = null) :
|
|
||||||
base($"Traubengutschrift {year}/{tgnr}", rows, FieldNames) {
|
|
||||||
Year = year;
|
|
||||||
TgNr = tgnr;
|
|
||||||
AvNr = avnr;
|
|
||||||
MgNr = mgnr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IDictionary<int, CreditNoteData>> ForPaymentVariant(DbSet<CreditNoteRowSingle> table, DbSet<Season> seasons, int year, int avnr) {
|
public static async Task<CreditNoteData> ForPaymentVariant(AppDbContext ctx, int year, int avnr) {
|
||||||
return (await FromDbSet(table, year, avnr))
|
var variant = await ctx.PaymentVariants.FindAsync(year, avnr);
|
||||||
.GroupBy(
|
var name = variant!.Name;
|
||||||
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
var data = BillingData.FromJson(variant!.Data);
|
||||||
(k, g) => new CreditNoteRow(g, seasons))
|
var rows = (await FromDbSet(ctx.CreditNoteRows, year, avnr)).Select(r => new CreditNoteRow(r, data)).ToList();
|
||||||
.GroupBy(
|
return new CreditNoteData(rows, year, name);
|
||||||
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr },
|
|
||||||
(k, g) => new CreditNoteData(g, k.Year, k.TgNr, mgnr: k.MgNr))
|
|
||||||
.ToDictionary(d => d.MgNr ?? 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
|
private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int year, int avnr) {
|
||||||
var y = year?.ToString() ?? "NULL";
|
return await table.FromSql($"""
|
||||||
var v = avnr?.ToString() ?? "NULL";
|
SELECT m.mgnr, m.family_name, m.given_name, p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision,
|
||||||
var m = mgnr?.ToString() ?? "NULL";
|
p.amount - p.net_amount AS surcharge,
|
||||||
return await table.FromSqlRaw($"""
|
c.net_amount, c.prev_net_amount, c.vat, c.vat_amount, c.gross_amount, c.modifiers, c.prev_modifiers, c.amount,
|
||||||
SELECT d.year, c.tgnr, v.avnr, d.mgnr, d.did, d.lsnr, d.dpnr, d.weight, d.modifiers,
|
ROUND(COALESCE(u.total_penalty, 0) / POW(10, 4 - 2)) AS fb_penalty,
|
||||||
b.bktnr, d.sortid, b.discr, b.value, pb.price, pb.amount, p.net_amount, p.amount AS total_amount,
|
ROUND(COALESCE(b.total_penalty, 0) / POW(10, s.precision - 2)) AS bs_penalty,
|
||||||
s.name AS variant, a.name AS attribute, q.name AS quality_level, d.oe, d.kmw
|
ROUND(COALESCE(a.total_amount, 0) / POW(10, s.precision - 2)) AS auto_bs
|
||||||
FROM v_delivery d
|
FROM credit c
|
||||||
JOIN wine_variety s ON s.sortid = d.sortid
|
LEFT JOIN member m ON m.mgnr = c.mgnr
|
||||||
LEFT JOIN wine_attribute a ON a.attrid = d.attrid
|
LEFT JOIN payment_member p ON (p.year, p.avnr, p.mgnr) = (c.year, c.avnr, c.mgnr)
|
||||||
JOIN wine_quality_level q ON q.qualid = d.qualid
|
LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
|
||||||
LEFT JOIN delivery_part_bucket b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr)
|
LEFT JOIN AT_ort o ON o.okz = p.okz
|
||||||
LEFT JOIN payment_variant v ON v.year = d.year
|
LEFT JOIN season s ON s.year = c.year
|
||||||
LEFT JOIN payment_delivery_part p ON (p.year, p.did, p.dpnr, p.avnr) = (d.year, d.did, d.dpnr, v.avnr)
|
LEFT JOIN v_penalty_area_commitments u ON (u.year, u.mgnr) = (s.year, m.mgnr)
|
||||||
LEFT JOIN payment_delivery_part_bucket pb ON (pb.year, pb.did, pb.dpnr, pb.bktnr, pb.avnr) = (b.year, b.did, b.dpnr, b.bktnr, v.avnr)
|
LEFT JOIN v_penalty_business_shares b ON (b.year, b.mgnr) = (s.year, m.mgnr)
|
||||||
LEFT JOIN credit c ON (c.year, c.avnr, c.mgnr) = (d.year, v.avnr, d.mgnr)
|
LEFT JOIN v_auto_business_shares a ON (a.year, a.mgnr) = (s.year, m.mgnr)
|
||||||
WHERE b.value > 0 AND (d.year = {y} OR {y} IS NULL) AND (v.avnr = {v} OR {v} IS NULL) AND (d.mgnr = {m} OR {m} IS NULL)
|
WHERE c.year = {year} AND c.avnr = {avnr}
|
||||||
ORDER BY d.year, v.avnr, d.mgnr, d.lsnr, d.dpnr
|
ORDER BY m.mgnr
|
||||||
""").ToListAsync();
|
""").ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CreditNoteRow {
|
public class CreditNoteRow {
|
||||||
|
|
||||||
public int Year;
|
|
||||||
public int? TgNr;
|
|
||||||
public int AvNr;
|
|
||||||
public int MgNr;
|
public int MgNr;
|
||||||
|
public string Name;
|
||||||
|
public string GivenName;
|
||||||
|
public string Address;
|
||||||
|
public int Plz;
|
||||||
|
public string Locality;
|
||||||
|
public string Iban;
|
||||||
|
public string TgNr;
|
||||||
|
public decimal Sum;
|
||||||
|
public decimal? Surcharge;
|
||||||
|
public decimal Total;
|
||||||
|
public decimal? ConsideredSum;
|
||||||
|
public decimal Net;
|
||||||
|
public decimal? Vat1, Vat2;
|
||||||
|
public decimal Gross;
|
||||||
|
public decimal? Penalties;
|
||||||
|
public decimal? Penalty;
|
||||||
|
public decimal? AutoBs;
|
||||||
|
public decimal? Others;
|
||||||
|
public decimal? Considered;
|
||||||
|
public decimal Amount;
|
||||||
|
|
||||||
public string LsNr;
|
public CreditNoteRow(CreditNoteRowSingle row, BillingData data) {
|
||||||
public int DPNr;
|
byte prec1 = 2, prec2 = row.Precision;
|
||||||
public string Variant;
|
MgNr = row.MgNr;
|
||||||
public string? Attribute;
|
Name = row.Name;
|
||||||
public string[] Modifiers;
|
GivenName = row.GivenName;
|
||||||
public string QualityLevel;
|
Address = row.Address;
|
||||||
public (double Oe, double Kmw) Gradation;
|
Plz = row.Plz;
|
||||||
public (string Name, int Value, decimal? Price, decimal? Amount)[] Buckets;
|
Locality = row.Locality;
|
||||||
public decimal? TotalModifiers;
|
Iban = Utils.FormatIban(row.Iban);
|
||||||
public decimal? Amount;
|
TgNr = $"{row.Year}/{row.TgNr}";
|
||||||
|
Total = Utils.DecFromDb(row.NetAmount, prec1);
|
||||||
public CreditNoteRow(IEnumerable<CreditNoteRowSingle> rows, DbSet<Season> seasons) {
|
Surcharge = (row.Surcharge == null || row.Surcharge == 0) ? null : Utils.DecFromDb((long)row.Surcharge, prec2);
|
||||||
var f = rows.First();
|
Sum = Total - (Surcharge ?? 0);
|
||||||
Year = f.Year;
|
ConsideredSum = (row.PrevNetAmount == null ||row.PrevNetAmount == 0) ? null : -Utils.DecFromDb((long)row.PrevNetAmount, prec1);
|
||||||
TgNr = f.TgNr;
|
Net = Total + (ConsideredSum ?? 0);
|
||||||
MgNr = f.MgNr;
|
if (row.Vat == 0.10) {
|
||||||
var season = seasons.Find(Year);
|
Vat1 = Utils.DecFromDb(row.VatAmount, prec1);
|
||||||
|
} else if (row.Vat == 0.13) {
|
||||||
LsNr = f.LsNr;
|
Vat2 = Utils.DecFromDb(row.VatAmount, prec1);
|
||||||
DPNr = f.DPNr;
|
}
|
||||||
Variant = f.Variant;
|
decimal mod = (row.Modifiers == null) ? 0 : Utils.DecFromDb((long)row.Modifiers, prec1);
|
||||||
Attribute = f.Attribute;
|
if (data.ConsiderContractPenalties)
|
||||||
var modifiers = (IEnumerable<Modifier>)(f.Modifiers ?? "").Split(',')
|
Penalties = (row.FbPenalty == null || row.FbPenalty == 0) ? null : Utils.DecFromDb((long)row.FbPenalty, prec1);
|
||||||
.Select(m => season?.Modifiers.FirstOrDefault(s => s.ModId == m))
|
if (data.ConsiderTotalPenalty)
|
||||||
.Where(m => m != null)
|
Penalty = (row.BsPealty == null || row.BsPealty == 0) ? null : Utils.DecFromDb((long)row.BsPealty, prec1);
|
||||||
.OrderBy(m => m.Ordering)
|
if (data.ConsiderAutoBusinessShares)
|
||||||
.ToList();
|
AutoBs = (row.AutoBs == null || row.AutoBs == 0) ? null : -Utils.DecFromDb((long)row.AutoBs, prec1);
|
||||||
Modifiers = modifiers.Select(m => m.Name).ToArray();
|
mod -= (Penalties ?? 0) + (Penalty ?? 0) + (AutoBs ?? 0);
|
||||||
QualityLevel = f.QualityLevel;
|
Others = (mod == 0) ? null : mod;
|
||||||
Gradation = (f.Oe, f.Kmw);
|
Gross = Utils.DecFromDb(row.GrossAmount, prec1);
|
||||||
Buckets = rows
|
Considered = (row.PrevModifiers == null || row.PrevModifiers == 0) ? null : -Utils.DecFromDb((long)row.PrevModifiers, prec1);
|
||||||
.Where(b => b.Value > 0)
|
Amount = Utils.DecFromDb(row.Amount, prec1);
|
||||||
.OrderByDescending(b => b.BktNr)
|
|
||||||
.Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {f.SortId}{b.Discr}", b.Value,
|
|
||||||
b.Price != null ? season?.DecFromDb((long)b.Price) : null,
|
|
||||||
b.Amount != null ? season?.DecFromDb((long)b.Amount) : null))
|
|
||||||
.ToArray();
|
|
||||||
Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null;
|
|
||||||
var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null;
|
|
||||||
TotalModifiers = Amount - netAmount;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Keyless]
|
[Keyless]
|
||||||
public class CreditNoteRowSingle {
|
public class CreditNoteRowSingle {
|
||||||
[Column("year")]
|
|
||||||
public int Year { get; set; }
|
|
||||||
[Column("tgnr")]
|
|
||||||
public int? TgNr { get; set; }
|
|
||||||
[Column("avnr")]
|
|
||||||
public int? AvNr { get; set; }
|
|
||||||
[Column("mgnr")]
|
[Column("mgnr")]
|
||||||
public int MgNr { get; set; }
|
public int MgNr { get; set; }
|
||||||
[Column("did")]
|
[Column("family_name")]
|
||||||
public int DId { get; set; }
|
public string Name { get; set; }
|
||||||
[Column("lsnr")]
|
[Column("given_name")]
|
||||||
public string LsNr { get; set; }
|
public string GivenName { get; set; }
|
||||||
[Column("dpnr")]
|
[Column("address")]
|
||||||
public int DPNr { get; set; }
|
public string Address { get; set; }
|
||||||
[Column("weight")]
|
[Column("plz")]
|
||||||
public int Weight { get; set; }
|
public int Plz { get; set; }
|
||||||
[Column("modifiers")]
|
[Column("ort")]
|
||||||
public string? Modifiers { get; set; }
|
public string LocalityFull { get; set; }
|
||||||
[Column("bktnr")]
|
[NotMapped]
|
||||||
public int BktNr { get; set; }
|
public string Locality => LocalityFull.Split(",")[0];
|
||||||
[Column("sortid")]
|
[Column("iban")]
|
||||||
public string SortId { get; set; }
|
public string Iban { get; set; }
|
||||||
[Column("discr")]
|
[Column("year")]
|
||||||
public string Discr { get; set; }
|
public int Year { get; set; }
|
||||||
[Column("value")]
|
[Column("precision")]
|
||||||
public int Value { get; set; }
|
public byte Precision { get; set; }
|
||||||
[Column("price")]
|
[Column("tgnr")]
|
||||||
public long? Price { get; set; }
|
public string TgNr { get; set; }
|
||||||
[Column("amount")]
|
[Column("surcharge")]
|
||||||
public long? Amount { get; set; }
|
public long? Surcharge { get; set; }
|
||||||
[Column("net_amount")]
|
[Column("net_amount")]
|
||||||
public long? NetAmount { get; set; }
|
public long NetAmount { get; set; }
|
||||||
[Column("total_amount")]
|
[Column("prev_net_amount")]
|
||||||
public long? TotalAmount { get; set; }
|
public long? PrevNetAmount { get; set; }
|
||||||
[Column("variant")]
|
[Column("vat")]
|
||||||
public string Variant { get; set; }
|
public double Vat { get; set; }
|
||||||
[Column("attribute")]
|
[Column("vat_amount")]
|
||||||
public string? Attribute { get; set; }
|
public long VatAmount { get; set; }
|
||||||
[Column("quality_level")]
|
[Column("gross_amount")]
|
||||||
public string QualityLevel { get; set; }
|
public long GrossAmount { get; set; }
|
||||||
[Column("oe")]
|
[Column("modifiers")]
|
||||||
public double Oe { get; set; }
|
public long? Modifiers { get; set; }
|
||||||
[Column("kmw")]
|
[Column("prev_modifiers")]
|
||||||
public double Kmw { get; set; }
|
public long? PrevModifiers { get; set; }
|
||||||
|
[Column("amount")]
|
||||||
|
public long Amount { get; set; }
|
||||||
|
[Column("fb_penalty")]
|
||||||
|
public long? FbPenalty { get; set; }
|
||||||
|
[Column("bs_penalty")]
|
||||||
|
public long? BsPealty { get; set; }
|
||||||
|
[Column("auto_bs")]
|
||||||
|
public long? AutoBs { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
159
Elwig/Models/Dtos/CreditNoteDeliveryData.cs
Normal file
159
Elwig/Models/Dtos/CreditNoteDeliveryData.cs
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
using Elwig.Models.Entities;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Elwig.Models.Dtos {
|
||||||
|
public class CreditNoteDeliveryData : DataTable<CreditNoteDeliveryRow> {
|
||||||
|
|
||||||
|
private static readonly (string, string, string?)[] FieldNames = [
|
||||||
|
("", "", null), // TODO
|
||||||
|
];
|
||||||
|
|
||||||
|
private readonly int Year;
|
||||||
|
private readonly int? TgNr;
|
||||||
|
private readonly int? AvNr;
|
||||||
|
private readonly int? MgNr;
|
||||||
|
|
||||||
|
private CreditNoteDeliveryData(IEnumerable<CreditNoteDeliveryRow> rows, int year, int? tgnr, int? avnr = null, int? mgnr = null) :
|
||||||
|
base($"Traubengutschrift {year}/{tgnr}", rows, FieldNames) {
|
||||||
|
Year = year;
|
||||||
|
TgNr = tgnr;
|
||||||
|
AvNr = avnr;
|
||||||
|
MgNr = mgnr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<Season> seasons, int year, int avnr) {
|
||||||
|
return (await FromDbSet(table, year, avnr))
|
||||||
|
.GroupBy(
|
||||||
|
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
|
||||||
|
(k, g) => new CreditNoteDeliveryRow(g, seasons))
|
||||||
|
.GroupBy(
|
||||||
|
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr },
|
||||||
|
(k, g) => new CreditNoteDeliveryData(g, k.Year, k.TgNr, mgnr: k.MgNr))
|
||||||
|
.ToDictionary(d => d.MgNr ?? 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<IEnumerable<CreditNoteDeliveryRowSingle>> FromDbSet(DbSet<CreditNoteDeliveryRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
|
||||||
|
var y = year?.ToString() ?? "NULL";
|
||||||
|
var v = avnr?.ToString() ?? "NULL";
|
||||||
|
var m = mgnr?.ToString() ?? "NULL";
|
||||||
|
return await table.FromSqlRaw($"""
|
||||||
|
SELECT d.year, c.tgnr, v.avnr, d.mgnr, d.did, d.lsnr, d.dpnr, d.weight, d.modifiers,
|
||||||
|
b.bktnr, d.sortid, b.discr, b.value, pb.price, pb.amount, p.net_amount, p.amount AS total_amount,
|
||||||
|
s.name AS variety, a.name AS attribute, q.name AS quality_level, d.oe, d.kmw
|
||||||
|
FROM v_delivery d
|
||||||
|
JOIN wine_variety s ON s.sortid = d.sortid
|
||||||
|
LEFT JOIN wine_attribute a ON a.attrid = d.attrid
|
||||||
|
JOIN wine_quality_level q ON q.qualid = d.qualid
|
||||||
|
LEFT JOIN delivery_part_bucket b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr)
|
||||||
|
LEFT JOIN payment_variant v ON v.year = d.year
|
||||||
|
LEFT JOIN payment_delivery_part p ON (p.year, p.did, p.dpnr, p.avnr) = (d.year, d.did, d.dpnr, v.avnr)
|
||||||
|
LEFT JOIN payment_delivery_part_bucket pb ON (pb.year, pb.did, pb.dpnr, pb.bktnr, pb.avnr) = (b.year, b.did, b.dpnr, b.bktnr, v.avnr)
|
||||||
|
LEFT JOIN credit c ON (c.year, c.avnr, c.mgnr) = (d.year, v.avnr, d.mgnr)
|
||||||
|
WHERE b.value > 0 AND (d.year = {y} OR {y} IS NULL) AND (v.avnr = {v} OR {v} IS NULL) AND (d.mgnr = {m} OR {m} IS NULL)
|
||||||
|
ORDER BY d.year, v.avnr, d.mgnr, d.lsnr, d.dpnr
|
||||||
|
""").ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CreditNoteDeliveryRow {
|
||||||
|
|
||||||
|
public int Year;
|
||||||
|
public int? TgNr;
|
||||||
|
public int AvNr;
|
||||||
|
public int MgNr;
|
||||||
|
|
||||||
|
public string LsNr;
|
||||||
|
public int DPNr;
|
||||||
|
public string Variety;
|
||||||
|
public string? Attribute;
|
||||||
|
public string[] Modifiers;
|
||||||
|
public string QualityLevel;
|
||||||
|
public (double Oe, double Kmw) Gradation;
|
||||||
|
public (string Name, int Value, decimal? Price, decimal? Amount)[] Buckets;
|
||||||
|
public decimal? TotalModifiers;
|
||||||
|
public decimal? Amount;
|
||||||
|
|
||||||
|
public CreditNoteDeliveryRow(IEnumerable<CreditNoteDeliveryRowSingle> rows, DbSet<Season> seasons) {
|
||||||
|
var f = rows.First();
|
||||||
|
Year = f.Year;
|
||||||
|
TgNr = f.TgNr;
|
||||||
|
MgNr = f.MgNr;
|
||||||
|
var season = seasons.Find(Year);
|
||||||
|
|
||||||
|
LsNr = f.LsNr;
|
||||||
|
DPNr = f.DPNr;
|
||||||
|
Variety = f.Variety;
|
||||||
|
Attribute = f.Attribute;
|
||||||
|
var modifiers = (IEnumerable<Modifier>)(f.Modifiers ?? "").Split(',')
|
||||||
|
.Select(m => season?.Modifiers.FirstOrDefault(s => s.ModId == m))
|
||||||
|
.Where(m => m != null)
|
||||||
|
.OrderBy(m => m.Ordering)
|
||||||
|
.ToList();
|
||||||
|
Modifiers = modifiers.Select(m => m.Name).ToArray();
|
||||||
|
QualityLevel = f.QualityLevel;
|
||||||
|
Gradation = (f.Oe, f.Kmw);
|
||||||
|
Buckets = rows
|
||||||
|
.Where(b => b.Value > 0)
|
||||||
|
.OrderByDescending(b => b.BktNr)
|
||||||
|
.Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {f.SortId}{b.Discr}", b.Value,
|
||||||
|
b.Price != null ? season?.DecFromDb((long)b.Price) : null,
|
||||||
|
b.Amount != null ? season?.DecFromDb((long)b.Amount) : null))
|
||||||
|
.ToArray();
|
||||||
|
Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null;
|
||||||
|
var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null;
|
||||||
|
TotalModifiers = Amount - netAmount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Keyless]
|
||||||
|
public class CreditNoteDeliveryRowSingle {
|
||||||
|
[Column("year")]
|
||||||
|
public int Year { get; set; }
|
||||||
|
[Column("tgnr")]
|
||||||
|
public int? TgNr { get; set; }
|
||||||
|
[Column("avnr")]
|
||||||
|
public int? AvNr { get; set; }
|
||||||
|
[Column("mgnr")]
|
||||||
|
public int MgNr { get; set; }
|
||||||
|
[Column("did")]
|
||||||
|
public int DId { get; set; }
|
||||||
|
[Column("lsnr")]
|
||||||
|
public string LsNr { get; set; }
|
||||||
|
[Column("dpnr")]
|
||||||
|
public int DPNr { get; set; }
|
||||||
|
[Column("weight")]
|
||||||
|
public int Weight { get; set; }
|
||||||
|
[Column("modifiers")]
|
||||||
|
public string? Modifiers { get; set; }
|
||||||
|
[Column("bktnr")]
|
||||||
|
public int BktNr { get; set; }
|
||||||
|
[Column("sortid")]
|
||||||
|
public string SortId { get; set; }
|
||||||
|
[Column("discr")]
|
||||||
|
public string Discr { get; set; }
|
||||||
|
[Column("value")]
|
||||||
|
public int Value { get; set; }
|
||||||
|
[Column("price")]
|
||||||
|
public long? Price { get; set; }
|
||||||
|
[Column("amount")]
|
||||||
|
public long? Amount { get; set; }
|
||||||
|
[Column("net_amount")]
|
||||||
|
public long? NetAmount { get; set; }
|
||||||
|
[Column("total_amount")]
|
||||||
|
public long? TotalAmount { get; set; }
|
||||||
|
[Column("variety")]
|
||||||
|
public string Variety { get; set; }
|
||||||
|
[Column("attribute")]
|
||||||
|
public string? Attribute { get; set; }
|
||||||
|
[Column("quality_level")]
|
||||||
|
public string QualityLevel { get; set; }
|
||||||
|
[Column("oe")]
|
||||||
|
public double Oe { get; set; }
|
||||||
|
[Column("kmw")]
|
||||||
|
public double Kmw { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -5,42 +5,42 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class DeliveryConfirmationData : DataTable<DeliveryConfirmationRow> {
|
public class DeliveryConfirmationDeliveryData : DataTable<DeliveryConfirmationDeliveryRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = new[] {
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("LsNr", "LsNr.", null, 26),
|
("LsNr", "LsNr.", null, 26),
|
||||||
("DPNr", "Pos.", null, 8),
|
("DPNr", "Pos.", null, 8),
|
||||||
("Variant", "Sorte", null, 40),
|
("Variety", "Sorte", null, 40),
|
||||||
("Attribute", "Attribut", null, 20),
|
("Attribute", "Attribut", null, 20),
|
||||||
("Modifiers", "Zu-/Abschläge", null, 30),
|
("Modifiers", "Zu-/Abschläge", null, 30),
|
||||||
("QualityLevel", "Qualitätsstufe", null, 25),
|
("QualityLevel", "Qualitätsstufe", null, 25),
|
||||||
("Gradation", "Gradation", "°Oe|°KMW", 32),
|
("Gradation", "Gradation", "°Oe|°KMW", 32),
|
||||||
("Buckets", "Flächenbindung", "|kg", 36),
|
("Buckets", "Flächenbindung", "|kg", 36),
|
||||||
("Weight", "Gewicht", "kg", 16),
|
("Weight", "Gewicht", "kg", 16),
|
||||||
};
|
];
|
||||||
|
|
||||||
private readonly int MgNr;
|
private readonly int MgNr;
|
||||||
|
|
||||||
private DeliveryConfirmationData(IEnumerable<DeliveryConfirmationRow> rows, int year, Member m) :
|
private DeliveryConfirmationDeliveryData(IEnumerable<DeliveryConfirmationDeliveryRow> rows, int year, Member m) :
|
||||||
base($"Anlieferungsbestätigung", $"Anlieferungsbestätigung {year} – {m.AdministrativeName}", rows, FieldNames) {
|
base($"Anlieferungsbestätigung", $"Anlieferungsbestätigung {year} – {m.AdministrativeName}", rows, FieldNames) {
|
||||||
MgNr = m.MgNr;
|
MgNr = m.MgNr;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DeliveryConfirmationData CreateEmpty(int year, Member m) {
|
public static DeliveryConfirmationDeliveryData CreateEmpty(int year, Member m) {
|
||||||
return new([], year, m);
|
return new([], year, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<IDictionary<int, DeliveryConfirmationData>> ForSeason(DbSet<DeliveryPart> table, int year) {
|
public static async Task<IDictionary<int, DeliveryConfirmationDeliveryData>> ForSeason(DbSet<DeliveryPart> table, int year) {
|
||||||
return (await FromDbSet(table, year))
|
return (await FromDbSet(table, year))
|
||||||
.GroupBy(
|
.GroupBy(
|
||||||
p => p.Delivery.Member,
|
p => p.Delivery.Member,
|
||||||
p => new DeliveryConfirmationRow(p),
|
p => new DeliveryConfirmationDeliveryRow(p),
|
||||||
(k, g) => new DeliveryConfirmationData(g, year, k)
|
(k, g) => new DeliveryConfirmationDeliveryData(g, year, k)
|
||||||
).ToDictionary(d => d.MgNr, d => d);
|
).ToDictionary(d => d.MgNr, d => d);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<DeliveryConfirmationData> ForMember(DbSet<DeliveryPart> table, int year, Member m) {
|
public static async Task<DeliveryConfirmationDeliveryData> ForMember(DbSet<DeliveryPart> table, int year, Member m) {
|
||||||
return new DeliveryConfirmationData((await FromDbSet(table, year, m.MgNr)).Select(p => new DeliveryConfirmationRow(p)), year, m);
|
return new DeliveryConfirmationDeliveryData((await FromDbSet(table, year, m.MgNr)).Select(p => new DeliveryConfirmationDeliveryRow(p)), year, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<DeliveryPart>> FromDbSet(DbSet<DeliveryPart> table, int? year = null, int? mgnr = null) {
|
private static async Task<IEnumerable<DeliveryPart>> FromDbSet(DbSet<DeliveryPart> table, int? year = null, int? mgnr = null) {
|
||||||
@ -51,7 +51,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr);
|
if (mgnr != null) q = q.Where(p => p.Delivery.MgNr == mgnr);
|
||||||
await q
|
await q
|
||||||
.Include(p => p.Delivery)
|
.Include(p => p.Delivery)
|
||||||
.Include(p => p.Variant)
|
.Include(p => p.Variety)
|
||||||
.Include(p => p.Attribute)
|
.Include(p => p.Attribute)
|
||||||
.Include(p => p.Quality)
|
.Include(p => p.Quality)
|
||||||
.Include(p => p.Buckets)
|
.Include(p => p.Buckets)
|
||||||
@ -68,10 +68,10 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DeliveryConfirmationRow {
|
public class DeliveryConfirmationDeliveryRow {
|
||||||
public string LsNr;
|
public string LsNr;
|
||||||
public int DPNr;
|
public int DPNr;
|
||||||
public string Variant;
|
public string Variety;
|
||||||
public string? Attribute;
|
public string? Attribute;
|
||||||
public string QualityLevel;
|
public string QualityLevel;
|
||||||
public (double Oe, double Kmw) Gradation;
|
public (double Oe, double Kmw) Gradation;
|
||||||
@ -79,11 +79,11 @@ namespace Elwig.Models.Dtos {
|
|||||||
public int Weight;
|
public int Weight;
|
||||||
public (string Name, int Value)[] Buckets;
|
public (string Name, int Value)[] Buckets;
|
||||||
|
|
||||||
public DeliveryConfirmationRow(DeliveryPart p) {
|
public DeliveryConfirmationDeliveryRow(DeliveryPart p) {
|
||||||
var d = p.Delivery;
|
var d = p.Delivery;
|
||||||
LsNr = d.LsNr;
|
LsNr = d.LsNr;
|
||||||
DPNr = p.DPNr;
|
DPNr = p.DPNr;
|
||||||
Variant = p.Variant.Name;
|
Variety = p.Variety.Name;
|
||||||
Attribute = p.Attribute?.Name;
|
Attribute = p.Attribute?.Name;
|
||||||
QualityLevel = p.Quality.Name;
|
QualityLevel = p.Quality.Name;
|
||||||
Gradation = (p.Oe, p.Kmw);
|
Gradation = (p.Oe, p.Kmw);
|
@ -8,7 +8,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class MemberDeliveryPerVariantData : DataTable<MemberDeliveryPerVariantRow> {
|
public class MemberDeliveryPerVariantData : DataTable<MemberDeliveryPerVariantRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = new[] {
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
("Name", "Name", null, 40),
|
("Name", "Name", null, 40),
|
||||||
("GivenName", "Vorname", null, 40),
|
("GivenName", "Vorname", null, 40),
|
||||||
@ -20,7 +20,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
("Weights", "Geliefert", "kg", 22),
|
("Weights", "Geliefert", "kg", 22),
|
||||||
("Areas", "Fläche", "m²", 22),
|
("Areas", "Fläche", "m²", 22),
|
||||||
("Yields", "Ertrag", "kg/ha", 22),
|
("Yields", "Ertrag", "kg/ha", 22),
|
||||||
};
|
];
|
||||||
|
|
||||||
|
|
||||||
public MemberDeliveryPerVariantData(IEnumerable<MemberDeliveryPerVariantRow> rows, int year) :
|
public MemberDeliveryPerVariantData(IEnumerable<MemberDeliveryPerVariantRow> rows, int year) :
|
||||||
|
@ -7,7 +7,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class OverUnderDeliveryData : DataTable<OverUnderDeliveryRow> {
|
public class OverUnderDeliveryData : DataTable<OverUnderDeliveryRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = new[] {
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
("Name", "Name", null, 40),
|
("Name", "Name", null, 40),
|
||||||
("GivenName", "Vorname", null, 40),
|
("GivenName", "Vorname", null, 40),
|
||||||
@ -19,7 +19,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
("DeliveryRight", "Lieferrecht", "kg", 22),
|
("DeliveryRight", "Lieferrecht", "kg", 22),
|
||||||
("Weight", "Geliefert", "kg", 22),
|
("Weight", "Geliefert", "kg", 22),
|
||||||
("OverUnderDelivery", "Über-/Unterliefert", "kg|%", 34),
|
("OverUnderDelivery", "Über-/Unterliefert", "kg|%", 34),
|
||||||
};
|
];
|
||||||
|
|
||||||
public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year) :
|
public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year) :
|
||||||
base($"Über-Unterlieferungen", $"Über- und Unterlieferungen laut gezeichneten Geschäftsanteilen {year}", rows, FieldNames) {
|
base($"Über-Unterlieferungen", $"Über- und Unterlieferungen laut gezeichneten Geschäftsanteilen {year}", rows, FieldNames) {
|
||||||
|
@ -23,7 +23,7 @@ namespace Elwig.Models.Entities {
|
|||||||
public string SortId { get; set; }
|
public string SortId { get; set; }
|
||||||
|
|
||||||
[ForeignKey("SortId")]
|
[ForeignKey("SortId")]
|
||||||
public virtual WineVar Variant { get; private set; }
|
public virtual WineVar Variety { get; private set; }
|
||||||
|
|
||||||
[Column("attrid")]
|
[Column("attrid")]
|
||||||
public string? AttrId { get; set; }
|
public string? AttrId { get; set; }
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
-- schema version 11 to 12
|
-- schema version 12 to 13
|
||||||
|
|
||||||
ALTER TABLE season ADD COLUMN bs_value INTEGER;
|
ALTER TABLE season ADD COLUMN bs_value INTEGER;
|
||||||
|
|
||||||
|
33
Elwig/Resources/Sql/13-14.sql
Normal file
33
Elwig/Resources/Sql/13-14.sql
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
-- schema version 13 to 14
|
||||||
|
|
||||||
|
CREATE VIEW v_penalty_area_commitments AS
|
||||||
|
SELECT year, mgnr,
|
||||||
|
SUM(COALESCE(IIF(u.weight = 0, -t.penalty_none, 0), 0) +
|
||||||
|
COALESCE(IIF(u.diff < 0, -t.penalty_amount, 0), 0) +
|
||||||
|
COALESCE(u.diff * t.penalty_per_kg, 0)
|
||||||
|
) AS total_penalty
|
||||||
|
FROM v_under_delivery u
|
||||||
|
JOIN area_commitment_type t ON t.vtrgid = u.bucket
|
||||||
|
GROUP BY year, mgnr
|
||||||
|
HAVING total_penalty < 0
|
||||||
|
ORDER BY year, mgnr;
|
||||||
|
|
||||||
|
CREATE VIEW v_penalty_business_shares AS
|
||||||
|
SELECT s.year, u.mgnr,
|
||||||
|
(COALESCE(IIF(u.weight = 0, -s.penalty_none, 0), 0) +
|
||||||
|
COALESCE(IIF(u.diff < 0, -s.penalty_amount, 0), 0) +
|
||||||
|
COALESCE(u.diff * s.penalty_per_kg, 0)
|
||||||
|
) AS total_penalty
|
||||||
|
FROM v_total_under_delivery u
|
||||||
|
JOIN season s ON s.year = u.year
|
||||||
|
WHERE u.diff < 0 AND total_penalty < 0
|
||||||
|
ORDER BY s.year, u.mgnr;
|
||||||
|
|
||||||
|
CREATE VIEW v_auto_business_shares AS
|
||||||
|
SELECT s.year, h.mgnr,
|
||||||
|
SUM(h.business_shares) AS business_shares,
|
||||||
|
SUM(h.business_shares) * s.bs_value AS total_amount
|
||||||
|
FROM member_history h, season s
|
||||||
|
WHERE h.type = 'auto' AND h.date >= s.year || '-01-01' AND h.date <= s.year || '-12-31'
|
||||||
|
GROUP BY s.year, h.mgnr
|
||||||
|
ORDER BY s.year, h.mgnr;
|
@ -535,15 +535,18 @@
|
|||||||
</GroupBox>
|
</GroupBox>
|
||||||
<GroupBox Header="Anlieferungsbestätigung" Margin="10,10,10,10" Height="250">
|
<GroupBox Header="Anlieferungsbestätigung" Margin="10,10,10,10" Height="250">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
|
||||||
<ColumnDefinition Width="*"/>
|
|
||||||
</Grid.ColumnDefinitions>
|
|
||||||
|
|
||||||
<TextBox x:Name="TextElementDeliveryConfirmation" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
|
<TextBox x:Name="TextElementDeliveryConfirmation" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
|
||||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,10,10" Height="Auto"
|
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,10,10" Height="Auto"
|
||||||
TextChanged="TextBox_TextChanged"/>
|
TextChanged="TextBox_TextChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
<GroupBox Header="Traubengutschrift" Margin="10,10,10,10" Height="250">
|
||||||
|
<Grid>
|
||||||
|
<TextBox x:Name="TextElementCreditNote" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
|
||||||
|
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,10,10" Height="Auto"
|
||||||
|
TextChanged="TextBox_TextChanged"/>
|
||||||
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</ScrollViewer>
|
</ScrollViewer>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
|
@ -12,11 +12,11 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
public BaseDataWindow() {
|
public BaseDataWindow() {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
RequiredInputs = new Control[] {
|
RequiredInputs = [
|
||||||
ClientNameInput, ClientNameTypeInput, ClientNameTokenInput, ClientNameShortInput,
|
ClientNameInput, ClientNameTypeInput, ClientNameTokenInput, ClientNameShortInput,
|
||||||
ClientAddressInput, ClientPlzInput, ClientOrtInput,
|
ClientAddressInput, ClientPlzInput, ClientOrtInput,
|
||||||
};
|
];
|
||||||
ExemptInputs = new Control[] {
|
ExemptInputs = [
|
||||||
ClientNameFull,
|
ClientNameFull,
|
||||||
BranchIdInput, BranchNameInput, BranchPlzInput, BranchOrtInput,
|
BranchIdInput, BranchNameInput, BranchPlzInput, BranchOrtInput,
|
||||||
BranchAddressInput, BranchPhoneNrInput, BranchFaxNrInput, BranchMobileNrInput,
|
BranchAddressInput, BranchPhoneNrInput, BranchFaxNrInput, BranchMobileNrInput,
|
||||||
@ -30,7 +30,7 @@ namespace Elwig.Windows {
|
|||||||
SeasonMinKgPerBsInput.TextBox, SeasonMaxKgPerBsInput.TextBox, SeasonBsValueInput.TextBox,
|
SeasonMinKgPerBsInput.TextBox, SeasonMaxKgPerBsInput.TextBox, SeasonBsValueInput.TextBox,
|
||||||
SeasonPenaltyPerKgInput.TextBox, SeasonPenaltyInput.TextBox, SeasonPenaltyNoneInput.TextBox,
|
SeasonPenaltyPerKgInput.TextBox, SeasonPenaltyInput.TextBox, SeasonPenaltyNoneInput.TextBox,
|
||||||
SeasonModifierIdInput, SeasonModifierNameInput, SeasonModifierRelInput.TextBox, SeasonModifierAbsInput.TextBox,
|
SeasonModifierIdInput, SeasonModifierNameInput, SeasonModifierRelInput.TextBox, SeasonModifierAbsInput.TextBox,
|
||||||
};
|
];
|
||||||
WineAttributeFillLowerInput.Visibility = Visibility.Hidden;
|
WineAttributeFillLowerInput.Visibility = Visibility.Hidden;
|
||||||
WineAttributeFillLowerLabel.Visibility = Visibility.Hidden;
|
WineAttributeFillLowerLabel.Visibility = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
@ -297,6 +297,7 @@ namespace Elwig.Windows {
|
|||||||
case 3: ModeDeliveryNoteFull.IsChecked = true; break;
|
case 3: ModeDeliveryNoteFull.IsChecked = true; break;
|
||||||
}
|
}
|
||||||
TextElementDeliveryConfirmation.Text = p.TextDeliveryConfirmation;
|
TextElementDeliveryConfirmation.Text = p.TextDeliveryConfirmation;
|
||||||
|
TextElementCreditNote.Text = p.TextCreditNote;
|
||||||
|
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
}
|
}
|
||||||
@ -322,6 +323,7 @@ namespace Elwig.Windows {
|
|||||||
p.TextDeliveryNote = TextElementDeliveryNote.Text.Length > 0 ? TextElementDeliveryNote.Text : null;
|
p.TextDeliveryNote = TextElementDeliveryNote.Text.Length > 0 ? TextElementDeliveryNote.Text : null;
|
||||||
p.ModeDeliveryNoteStats = (ModeDeliveryNoteNone.IsChecked == true) ? 0 : (ModeDeliveryNoteGaOnly.IsChecked == true) ? 1 : (ModeDeliveryNoteShort.IsChecked == true) ? 2 : (ModeDeliveryNoteFull.IsChecked == true) ? 3 : 2;
|
p.ModeDeliveryNoteStats = (ModeDeliveryNoteNone.IsChecked == true) ? 0 : (ModeDeliveryNoteGaOnly.IsChecked == true) ? 1 : (ModeDeliveryNoteShort.IsChecked == true) ? 2 : (ModeDeliveryNoteFull.IsChecked == true) ? 3 : 2;
|
||||||
p.TextDeliveryConfirmation = TextElementDeliveryConfirmation.Text.Length > 0 ? TextElementDeliveryConfirmation.Text : null;
|
p.TextDeliveryConfirmation = TextElementDeliveryConfirmation.Text.Length > 0 ? TextElementDeliveryConfirmation.Text : null;
|
||||||
|
p.TextCreditNote = TextElementCreditNote.Text.Length > 0 ? TextElementCreditNote.Text : null;
|
||||||
|
|
||||||
await p.UpdateValues();
|
await p.UpdateValues();
|
||||||
}
|
}
|
||||||
|
@ -61,14 +61,17 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Label Content="Für:" Margin="10,-2,0,0" FontSize="14" Grid.Column="0" VerticalAlignment="Center"/>
|
<Label Content="Für:" Margin="10,-2,0,0" FontSize="14" Grid.Column="0" VerticalAlignment="Center"/>
|
||||||
<xctk:CheckComboBox x:Name="ContractInput" Margin="50,0,0,0" Grid.Column="0"
|
<xctk:CheckComboBox x:Name="VaributeInput" Margin="50,0,0,0" Grid.Column="0" Width="500" Height="25" HorizontalAlignment="Left"
|
||||||
Delimiter=", " AllItemsSelectedContent="Alle" IsEnabled="False" ItemSelectionChanged="ContractInput_Changed"
|
IsSelectAllActive="True" SelectAllContent="Alle Sorten" Delimiter=", " AllItemsSelectedContent="Alle Sorten"
|
||||||
Width="500" Height="25" HorizontalAlignment="Left">
|
IsEnabled="False" ItemSelectionChanged="VaributeInput_Changed">
|
||||||
<xctk:CheckComboBox.ItemTemplate>
|
<xctk:CheckComboBox.ItemTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Variety.Name}" Width="150"/>
|
<TextBlock Text="{Binding Variety.Name}" Width="150"/>
|
||||||
<TextBlock Text="{Binding Attribute.Name}"/>
|
<TextBlock Text="{Binding Variety.Type}" Width="30"/>
|
||||||
|
<TextBlock Text="{Binding Attribute.Name}" Width="120"/>
|
||||||
|
<TextBlock Text="{Binding AssignedGraphId}" Width="30"/>
|
||||||
|
<TextBlock Text="{Binding AssignedAbgewGraphId}" Width="30"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</xctk:CheckComboBox.ItemTemplate>
|
</xctk:CheckComboBox.ItemTemplate>
|
||||||
@ -83,7 +86,7 @@
|
|||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Id}" Width="30"/>
|
<TextBlock Text="{Binding Id}" Width="30"/>
|
||||||
<TextBlock Text="{Binding ContractsStringSimple}" ToolTip="{Binding ContractsString}"/>
|
<TextBlock Text="{Binding VaributeStringSimple}" ToolTip="{Binding VaributeString}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</ListBox.ItemTemplate>
|
</ListBox.ItemTemplate>
|
||||||
|
@ -33,14 +33,28 @@ namespace Elwig.Windows {
|
|||||||
private Marker PrimaryMarkedPointPlot;
|
private Marker PrimaryMarkedPointPlot;
|
||||||
private Marker SecondaryMarkedPointPlot;
|
private Marker SecondaryMarkedPointPlot;
|
||||||
private Text TooltipPlot;
|
private Text TooltipPlot;
|
||||||
private LegendItem UngebundenLegend;
|
|
||||||
private LegendItem GebundenLegend;
|
|
||||||
private LegendItem LDWLegend;
|
|
||||||
private LegendItem QUWLegend;
|
|
||||||
private LegendItem KABLegend;
|
|
||||||
|
|
||||||
private (Graph? graph, int index) LastHighlighted = (null, -1);
|
private static readonly LegendItem
|
||||||
private (Graph? graph, int index) Highlighted = (null, -1);
|
UngebundenLegend = new() {
|
||||||
|
Label = "Ungebunden", LineWidth = 1, LineColor = ColorUngebunden,
|
||||||
|
Marker = new(MarkerShape.FilledCircle, 5, ColorUngebunden)
|
||||||
|
},
|
||||||
|
GebundenLegend = new() {
|
||||||
|
Label = "Gebunden", LineWidth = 1, LineColor = ColorGebunden,
|
||||||
|
Marker = new(MarkerShape.FilledCircle, 5, ColorGebunden)
|
||||||
|
},
|
||||||
|
LdwLegend = new() {
|
||||||
|
Label = "68 °Oe (LDW)", LineWidth = 2, LineColor = Colors.Red, Marker = MarkerStyle.None
|
||||||
|
},
|
||||||
|
QuwLegend = new() {
|
||||||
|
Label = "73 °Oe (QUW)", LineWidth = 2, LineColor = Colors.Orange, Marker = MarkerStyle.None
|
||||||
|
},
|
||||||
|
KabLegend = new() {
|
||||||
|
Label = "84 °Oe (KAB)", LineWidth = 2, LineColor = Colors.Green, Marker = MarkerStyle.None
|
||||||
|
};
|
||||||
|
|
||||||
|
private (Graph? Graph, int Index) LastHighlighted = (null, -1);
|
||||||
|
private (Graph? Graph, int Index) Highlighted = (null, -1);
|
||||||
private Graph? ActiveGraph = null;
|
private Graph? ActiveGraph = null;
|
||||||
private int PrimaryMarkedPoint = -1;
|
private int PrimaryMarkedPoint = -1;
|
||||||
private int SecondaryMarkedPoint = -1;
|
private int SecondaryMarkedPoint = -1;
|
||||||
@ -50,6 +64,9 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private List<GraphEntry> GraphEntries = [];
|
private List<GraphEntry> GraphEntries = [];
|
||||||
private GraphEntry? SelectedGraphEntry => (GraphEntry)GraphList.SelectedItem;
|
private GraphEntry? SelectedGraphEntry => (GraphEntry)GraphList.SelectedItem;
|
||||||
|
private List<Varibute> Vaributes = [];
|
||||||
|
private bool AllVaributesAssigned => Vaributes.All(v => v.AssignedGraphId != null);
|
||||||
|
private bool AllVaributesAssignedAbgew => Vaributes.All(v => v.AssignedAbgewGraphId != null);
|
||||||
|
|
||||||
public ChartWindow(int year, int avnr) {
|
public ChartWindow(int year, int avnr) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -84,18 +101,29 @@ namespace Elwig.Windows {
|
|||||||
PaymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
PaymentVar = await Context.PaymentVariants.FindAsync(Year, AvNr) ?? throw new ArgumentException("PaymentVar not found");
|
||||||
Season = await Context.Seasons.FindAsync(Year) ?? throw new ArgumentException("Season not found");
|
Season = await Context.Seasons.FindAsync(Year) ?? throw new ArgumentException("Season not found");
|
||||||
|
|
||||||
var data = EditBillingData.FromJson(PaymentVar.Data, Utils.GetAttributeVarieties(Context, Year));
|
var data = EditBillingData.FromJson(PaymentVar.Data, Utils.GetVaributes(Context, Year));
|
||||||
var paymentEntries = data.GetPaymentGraphEntries(Context, Season);
|
var paymentEntries = data.GetPaymentGraphEntries(Context, Season);
|
||||||
GraphEntries = [
|
GraphEntries = [
|
||||||
..paymentEntries,
|
..paymentEntries,
|
||||||
..data.GetQualityGraphEntries(Context, Season, paymentEntries.Max(e => e.Id))
|
..data.GetQualityGraphEntries(Context, Season, paymentEntries.Any() ? paymentEntries.Max(e => e.Id) : 0)
|
||||||
];
|
];
|
||||||
|
Vaributes = Utils.GetVaributeList(Context, Year);
|
||||||
|
GraphEntries.ForEach(e => {
|
||||||
|
e.Vaributes.ForEach(v => {
|
||||||
|
var found = Vaributes.Find(a => a.Attribute?.AttrId == v.Attribute?.AttrId && a.Variety?.SortId == v.Variety?.SortId);
|
||||||
|
if (found == null) return;
|
||||||
|
if (e.Abgewertet) {
|
||||||
|
found.AssignedAbgewGraphId = e.Id;
|
||||||
|
} else {
|
||||||
|
found.AssignedGraphId = e.Id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var contracts = Utils.GetContractsForYear(Context, Year);
|
|
||||||
FillingInputs = true;
|
FillingInputs = true;
|
||||||
ControlUtils.RenewItemsSource(ContractInput, contracts, g => (g as ContractSelection)?.Listing);
|
ControlUtils.RenewItemsSource(VaributeInput, Vaributes, v => (v as Varibute)?.Listing);
|
||||||
FillingInputs = false;
|
FillingInputs = false;
|
||||||
ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.ContractsStringChange, GraphList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(GraphList, GraphEntries, g => (g as GraphEntry)?.VaributeStringChange, GraphList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||||
|
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
}
|
}
|
||||||
@ -108,7 +136,7 @@ namespace Elwig.Windows {
|
|||||||
GebundenTypeFixed.IsEnabled = true;
|
GebundenTypeFixed.IsEnabled = true;
|
||||||
GebundenTypeGraph.IsEnabled = true;
|
GebundenTypeGraph.IsEnabled = true;
|
||||||
GebundenTypeNone.IsEnabled = true;
|
GebundenTypeNone.IsEnabled = true;
|
||||||
ContractInput.IsEnabled = true;
|
VaributeInput.IsEnabled = true;
|
||||||
AbgewertetInput.IsEnabled = true;
|
AbgewertetInput.IsEnabled = true;
|
||||||
EnableOptionButtons();
|
EnableOptionButtons();
|
||||||
FillInputs();
|
FillInputs();
|
||||||
@ -127,7 +155,7 @@ namespace Elwig.Windows {
|
|||||||
GebundenTypeFixed.IsEnabled = false;
|
GebundenTypeFixed.IsEnabled = false;
|
||||||
GebundenTypeGraph.IsEnabled = false;
|
GebundenTypeGraph.IsEnabled = false;
|
||||||
GebundenTypeNone.IsEnabled = false;
|
GebundenTypeNone.IsEnabled = false;
|
||||||
ContractInput.IsEnabled = false;
|
VaributeInput.IsEnabled = false;
|
||||||
AbgewertetInput.IsEnabled = false;
|
AbgewertetInput.IsEnabled = false;
|
||||||
}
|
}
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
@ -148,7 +176,7 @@ namespace Elwig.Windows {
|
|||||||
GebundenFlatBonus.Text = "";
|
GebundenFlatBonus.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlUtils.SelectCheckComboBoxItems(ContractInput, SelectedGraphEntry?.Contracts ?? [], i => (i as ContractSelection)?.Listing);
|
ControlUtils.SelectCheckComboBoxItems(VaributeInput, SelectedGraphEntry?.Vaributes ?? [], i => (i as Varibute)?.Listing);
|
||||||
|
|
||||||
InitPlot();
|
InitPlot();
|
||||||
OechslePricePlot.IsEnabled = true;
|
OechslePricePlot.IsEnabled = true;
|
||||||
@ -160,41 +188,6 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void InitPlot() {
|
private void InitPlot() {
|
||||||
UngebundenLegend = new LegendItem() {
|
|
||||||
Label = "Ungebunden",
|
|
||||||
LineWidth = 1,
|
|
||||||
LineColor = ColorUngebunden,
|
|
||||||
Marker = new MarkerStyle(MarkerShape.FilledCircle, 5, ColorUngebunden)
|
|
||||||
};
|
|
||||||
|
|
||||||
GebundenLegend = new LegendItem() {
|
|
||||||
Label = "Gebunden",
|
|
||||||
LineWidth = 1,
|
|
||||||
LineColor = ColorGebunden,
|
|
||||||
Marker = new MarkerStyle(MarkerShape.FilledCircle, 5, ColorGebunden)
|
|
||||||
};
|
|
||||||
|
|
||||||
LDWLegend = new LegendItem() {
|
|
||||||
Label = "68 °Oe (LDW)",
|
|
||||||
LineWidth = 2,
|
|
||||||
LineColor = Colors.Red,
|
|
||||||
Marker = MarkerStyle.None
|
|
||||||
};
|
|
||||||
|
|
||||||
QUWLegend = new LegendItem() {
|
|
||||||
Label = "73 °Oe (QUW)",
|
|
||||||
LineWidth = 2,
|
|
||||||
LineColor = Colors.Orange,
|
|
||||||
Marker = MarkerStyle.None
|
|
||||||
};
|
|
||||||
|
|
||||||
KABLegend = new LegendItem() {
|
|
||||||
Label = "84 °Oe (KAB)",
|
|
||||||
LineWidth = 2,
|
|
||||||
LineColor = Colors.Green,
|
|
||||||
Marker = MarkerStyle.None
|
|
||||||
};
|
|
||||||
|
|
||||||
RefreshGradationLines();
|
RefreshGradationLines();
|
||||||
|
|
||||||
if (SelectedGraphEntry?.GebundenGraph != null) {
|
if (SelectedGraphEntry?.GebundenGraph != null) {
|
||||||
@ -230,7 +223,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
//OechslePricePlot.Plot.XAxis.ManualTickSpacing(1);
|
//OechslePricePlot.Plot.XAxis.ManualTickSpacing(1);
|
||||||
//OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1);
|
//OechslePricePlot.Plot.YAxis.ManualTickSpacing(0.1);
|
||||||
OechslePricePlot.Plot.Axes.SetLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 2);
|
OechslePricePlot.Plot.Axes.SetLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 1.5);
|
||||||
|
|
||||||
//OechslePricePlot.Plot.Layout(padding: 0);
|
//OechslePricePlot.Plot.Layout(padding: 0);
|
||||||
//OechslePricePlot.Plot.XAxis2.Layout(padding: 0);
|
//OechslePricePlot.Plot.XAxis2.Layout(padding: 0);
|
||||||
@ -317,7 +310,7 @@ namespace Elwig.Windows {
|
|||||||
OechslePricePlot.Plot.Axes.Rules.Clear();
|
OechslePricePlot.Plot.Axes.Rules.Clear();
|
||||||
OechslePricePlot.Plot.Axes.Rules.Add(BoundaryRule);
|
OechslePricePlot.Plot.Axes.Rules.Add(BoundaryRule);
|
||||||
OechslePricePlot.Plot.Axes.Rules.Add(SpanRule);
|
OechslePricePlot.Plot.Axes.Rules.Add(SpanRule);
|
||||||
OechslePricePlot.Plot.Axes.SetLimits(GraphEntry.MinX - 1, GraphEntry.MaxX + 1, -0.1, 2);
|
OechslePricePlot.Plot.Axes.SetLimits(GraphEntry.MinX - 1, GraphEntry.MaxX + 1, -0.1, 1.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnlockZoom() {
|
private void UnlockZoom() {
|
||||||
@ -372,9 +365,9 @@ namespace Elwig.Windows {
|
|||||||
OechslePricePlot.Plot.Legend.Location = Alignment.UpperLeft;
|
OechslePricePlot.Plot.Legend.Location = Alignment.UpperLeft;
|
||||||
OechslePricePlot.Plot.Legend.IsVisible = true;
|
OechslePricePlot.Plot.Legend.IsVisible = true;
|
||||||
|
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(LDWLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(LdwLegend);
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(QUWLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(QuwLegend);
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(KABLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(KabLegend);
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(UngebundenLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(UngebundenLegend);
|
||||||
if (SelectedGraphEntry?.GebundenGraph != null) OechslePricePlot.Plot.Legend.ManualItems.Add(GebundenLegend);
|
if (SelectedGraphEntry?.GebundenGraph != null) OechslePricePlot.Plot.Legend.ManualItems.Add(GebundenLegend);
|
||||||
}
|
}
|
||||||
@ -481,10 +474,10 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
if (HoverActive) {
|
if (HoverActive) {
|
||||||
if (PaymentVar.TestVariant && Keyboard.IsKeyDown(System.Windows.Input.Key.LeftCtrl)) {
|
if (PaymentVar.TestVariant && Keyboard.IsKeyDown(System.Windows.Input.Key.LeftCtrl)) {
|
||||||
if (PrimaryMarkedPoint == -1 || ActiveGraph == null || ActiveGraph != Highlighted.graph) {
|
if (PrimaryMarkedPoint == -1 || ActiveGraph == null || ActiveGraph != Highlighted.Graph) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SecondaryMarkedPoint = Highlighted.index;
|
SecondaryMarkedPoint = Highlighted.Index;
|
||||||
|
|
||||||
ChangeMarker(SecondaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(SecondaryMarkedPoint), ActiveGraph.GetPriceAt(SecondaryMarkedPoint));
|
ChangeMarker(SecondaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(SecondaryMarkedPoint), ActiveGraph.GetPriceAt(SecondaryMarkedPoint));
|
||||||
|
|
||||||
@ -493,13 +486,13 @@ namespace Elwig.Windows {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimaryMarkedPoint = Highlighted.index;
|
PrimaryMarkedPoint = Highlighted.Index;
|
||||||
if (ActiveGraph != Highlighted.graph) ChangeActiveGraph(Highlighted.graph);
|
if (ActiveGraph != Highlighted.Graph) ChangeActiveGraph(Highlighted.Graph);
|
||||||
|
|
||||||
ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));
|
ChangeMarker(PrimaryMarkedPointPlot, true, ActiveGraph.GetOechsleAt(PrimaryMarkedPoint), ActiveGraph.GetPriceAt(PrimaryMarkedPoint));
|
||||||
|
|
||||||
OechsleInput.Text = Highlighted.graph.GetOechsleAt(Highlighted.index).ToString();
|
OechsleInput.Text = Highlighted.Graph.GetOechsleAt(Highlighted.Index).ToString();
|
||||||
PriceInput.Text = Highlighted.graph.GetPriceAt(Highlighted.index).ToString();
|
PriceInput.Text = Highlighted.Graph.GetPriceAt(Highlighted.Index).ToString();
|
||||||
|
|
||||||
EnableActionButtons();
|
EnableActionButtons();
|
||||||
} else {
|
} else {
|
||||||
@ -622,8 +615,8 @@ namespace Elwig.Windows {
|
|||||||
if (SelectedGraphEntry == null) return;
|
if (SelectedGraphEntry == null) return;
|
||||||
|
|
||||||
var r = MessageBox.Show(
|
var r = MessageBox.Show(
|
||||||
$"Soll der Graph {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.ContractsStringSimple}) wirklich gelöscht werden?",
|
$"Soll die Kurve {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.VaributeStringSimple}) wirklich gelöscht werden?",
|
||||||
"Graph löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
"Kurve löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||||
|
|
||||||
if (r == MessageBoxResult.Yes) {
|
if (r == MessageBoxResult.Yes) {
|
||||||
GraphEntries.Remove(SelectedGraphEntry);
|
GraphEntries.Remove(SelectedGraphEntry);
|
||||||
@ -635,7 +628,8 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private async void SaveButton_Click(object sender, RoutedEventArgs e) {
|
private async void SaveButton_Click(object sender, RoutedEventArgs e) {
|
||||||
var origData = BillingData.FromJson(PaymentVar.Data);
|
var origData = BillingData.FromJson(PaymentVar.Data);
|
||||||
var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetAttributeVarieties(Context, Year, true));
|
var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(Context, Year, withSlash: true),
|
||||||
|
AllVaributesAssigned, AllVaributesAssignedAbgew);
|
||||||
|
|
||||||
EntityEntry<PaymentVar>? tr = null;
|
EntityEntry<PaymentVar>? tr = null;
|
||||||
try {
|
try {
|
||||||
@ -715,32 +709,45 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ContractInput_Changed(object sender, ItemSelectionChangedEventArgs e) {
|
private void VaributeInput_Changed(object sender, ItemSelectionChangedEventArgs e) {
|
||||||
if (FillingInputs) return;
|
if (FillingInputs || e.Item is not Varibute v) return;
|
||||||
if (e.IsSelected == true) {
|
var isOpen = VaributeInput.IsDropDownOpen;
|
||||||
bool success = RemoveContractFromOtherGraphEntries(e.Item.ToString());
|
if (e.IsSelected) {
|
||||||
if (!success) {
|
if (RemoveVaributeFromOthers(e.Item.ToString())) {
|
||||||
ContractInput.SelectedItems.Remove(e.Item);
|
if (AbgewertetInput.IsChecked == true) {
|
||||||
|
v.AssignedAbgewGraphId = SelectedGraphEntry?.Id;
|
||||||
|
} else {
|
||||||
|
v.AssignedGraphId = SelectedGraphEntry?.Id;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
VaributeInput.SelectedItems.Remove(e.Item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (AbgewertetInput.IsChecked == true) {
|
||||||
|
v.AssignedAbgewGraphId = null;
|
||||||
|
} else {
|
||||||
|
v.AssignedGraphId = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var r = ContractInput.SelectedItems.Cast<ContractSelection>();
|
SelectedGraphEntry!.Vaributes = VaributeInput.SelectedItems.Cast<Varibute>().ToList();
|
||||||
SelectedGraphEntry!.Contracts = r.ToList();
|
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
GraphList.Items.Refresh();
|
GraphList.Items.Refresh();
|
||||||
|
VaributeInput.Items.Refresh();
|
||||||
|
VaributeInput.IsDropDownOpen = isOpen;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool RemoveContractFromOtherGraphEntries(string? contract) {
|
private bool RemoveVaributeFromOthers(string? varibute) {
|
||||||
if (contract == null) return true;
|
if (varibute == null) return true;
|
||||||
foreach (var ge in GraphEntries) {
|
foreach (var ge in GraphEntries) {
|
||||||
if (ge != SelectedGraphEntry && ge.Abgewertet == SelectedGraphEntry?.Abgewertet) {
|
if (ge != SelectedGraphEntry && ge.Abgewertet == SelectedGraphEntry?.Abgewertet) {
|
||||||
var toRemove = ge.Contracts.Where(c => c.Listing.Equals(contract)).ToList();
|
var toRemove = ge.Vaributes.Where(c => c.Listing.Equals(varibute)).ToList();
|
||||||
if (toRemove.Count == 0) continue;
|
if (toRemove.Count == 0) continue;
|
||||||
var r = MessageBox.Show($"Achtung: {string.Join(", ", toRemove)} ist bereits in Graph {ge.Id} in Verwendung!\nSoll die Zuweisung dort entfernt werden?", "Entfernen bestätigen",
|
var r = MessageBox.Show($"Achtung: {string.Join(", ", toRemove)} ist bereits in Kurve {ge.Id} in Verwendung!\nSoll die Zuweisung dort entfernt werden?", "Entfernen bestätigen",
|
||||||
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
||||||
if (r != MessageBoxResult.Yes) {
|
if (r != MessageBoxResult.Yes) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ge.Contracts.RemoveAll(c => c.Listing.Equals(contract));
|
ge.Vaributes.RemoveAll(c => c.Listing.Equals(varibute));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -101,12 +101,12 @@
|
|||||||
Filtern nach:<LineBreak/>
|
Filtern nach:<LineBreak/>
|
||||||
<Bold>Sorte</Bold>: z.B. GV, ZW, rr, sa, !gv (ausgenommen GV), ...<LineBreak/>
|
<Bold>Sorte</Bold>: z.B. GV, ZW, rr, sa, !gv (ausgenommen GV), ...<LineBreak/>
|
||||||
<Bold>Rot/Weiß</Bold>: z.B. r, Rot, w, weiß, ...<LineBreak/>
|
<Bold>Rot/Weiß</Bold>: z.B. r, Rot, w, weiß, ...<LineBreak/>
|
||||||
<Bold>Qualitätsstufe</Bold>: z.B. QUW, kab, !ldw (ausgenommen LDW), ...<LineBreak/>
|
<Bold>Qualitätsstufe</Bold>: z.B. QUW, kab, !ldw (ausgenommen LDW), abgew[ertet], ...<LineBreak/>
|
||||||
<Bold>Gradation</Bold>: z.B. >73, <15, 17-18, 15-, >17,5, 62-75, ...<LineBreak/>
|
<Bold>Gradation</Bold>: z.B. >73, <15, 17-18, 15-, >17,5, 62-75, ...<LineBreak/>
|
||||||
<Bold>Mitglied</Bold>: z.B. 1234, 987, ...<LineBreak/>
|
<Bold>Mitglied</Bold>: z.B. 1234, 987, ...<LineBreak/>
|
||||||
<Bold>Saison</Bold>: z.B. 2020, >2015, 2017-2019, <2005, 2019-, ...<LineBreak/>
|
<Bold>Saison</Bold>: z.B. 2020, >2015, 2017-2019, <2005, 2019-, ...<LineBreak/>
|
||||||
<Bold>Zweigstelle</Bold>: z.B. musterort, ...<LineBreak/>
|
<Bold>Zweigstelle</Bold>: z.B. musterort, ...<LineBreak/>
|
||||||
<Bold>Attribute</Bold>: z.B. kabinett, !kabinett (alle außer kabinett), ...<LineBreak/>
|
<Bold>Attribut</Bold>: z.B. kabinett, !kabinett (alle außer kabinett), ...<LineBreak/>
|
||||||
<Bold>Datum</Bold>: z.B. 1.9., 15.9.-10.10., -15.10.2020, ...<LineBreak/>
|
<Bold>Datum</Bold>: z.B. 1.9., 15.9.-10.10., -15.10.2020, ...<LineBreak/>
|
||||||
<Bold>Uhrzeit</Bold>: z.B. 06:00-08:00, 18:00-, ...<LineBreak/>
|
<Bold>Uhrzeit</Bold>: z.B. 06:00-08:00, 18:00-, ...<LineBreak/>
|
||||||
<Bold>Freitext</Bold>: z.B. Lieferscheinnummern, Anmerkung, "quw" (sucht nach dem Text "quw")
|
<Bold>Freitext</Bold>: z.B. Lieferscheinnummern, Anmerkung, "quw" (sucht nach dem Text "quw")
|
||||||
|
@ -365,13 +365,23 @@ namespace Elwig.Windows {
|
|||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("außer " + var[e[1..].ToUpper()].Name);
|
filterNames.Add("außer " + var[e[1..].ToUpper()].Name);
|
||||||
} else if (e.Length == 3 && qual.ContainsKey(e.ToUpper())) {
|
} else if (e.Length == 3 && qual.ContainsKey(e.ToUpper())) {
|
||||||
filterQual.Add(e.ToUpper());
|
var qualId = e.ToUpper();
|
||||||
|
filterQual.Add(qualId);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add(qual[e.ToUpper()].Name);
|
filterNames.Add(qualId == "WEI" ? "abgewertet" : qual[e.ToUpper()].Name);
|
||||||
} else if (e[0] == '!' && qual.ContainsKey(e[1..].ToUpper())) {
|
} else if (e[0] == '!' && qual.ContainsKey(e[1..].ToUpper())) {
|
||||||
filterNotQual.Add(e[1..].ToUpper());
|
var qualId = e[1..].ToUpper();
|
||||||
|
filterNotQual.Add(qualId);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("außer " + qual[e[1..].ToUpper()].Name);
|
filterNames.Add(qualId == "WEI" ? "nicht abgewertet" : "außer " + qual[e[1..].ToUpper()].Name);
|
||||||
|
} else if (e.Length >= 5 && e.Length <= 10 && "abgewertet".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
|
filterQual.Add("WEI");
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("abgewertet");
|
||||||
|
} else if (e.Length >= 6 && e.Length <= 11 && "!abgewertet".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
|
filterNotQual.Add("WEI");
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("nicht abgewertet");
|
||||||
} else if (e.All(char.IsAsciiDigit) && mgnr.TryGetValue(e, out var member)) {
|
} else if (e.All(char.IsAsciiDigit) && mgnr.TryGetValue(e, out var member)) {
|
||||||
filterMgNr.Add(int.Parse(e));
|
filterMgNr.Add(int.Parse(e));
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
|
@ -74,9 +74,9 @@ namespace Elwig.Dialogs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<Member> list = await members.ToListAsync();
|
IEnumerable<Member> list = await members.ToListAsync();
|
||||||
var data = await DeliveryConfirmationData.ForSeason(Context.DeliveryParts, Year);
|
var data = await DeliveryConfirmationDeliveryData.ForSeason(Context.DeliveryParts, Year);
|
||||||
using var doc = Document.Merge(list.Select(m =>
|
using var doc = Document.Merge(list.Select(m =>
|
||||||
new DeliveryConfirmation(Context, Year, m, data.TryGetValue(m.MgNr, out var d) ? d : DeliveryConfirmationData.CreateEmpty(Year, m)) {
|
new DeliveryConfirmation(Context, Year, m, data.TryGetValue(m.MgNr, out var d) ? d : DeliveryConfirmationDeliveryData.CreateEmpty(Year, m)) {
|
||||||
//DoubleSided = true
|
//DoubleSided = true
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
@ -27,11 +27,6 @@ namespace Elwig.Windows {
|
|||||||
w.Show();
|
w.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MemberListButton_Click(object sender, RoutedEventArgs evt) {
|
|
||||||
var w = new MemberListWindow();
|
|
||||||
w.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ReceiptButton_Click(object sender, RoutedEventArgs evt) {
|
private void ReceiptButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
App.FocusReceipt();
|
App.FocusReceipt();
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
x:Class="Elwig.Windows.MemberAdminWindow"
|
x:Class="Elwig.Windows.MemberAdminWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150"
|
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150"
|
||||||
Loaded="Window_Loaded">
|
Loaded="Window_Loaded">
|
||||||
@ -239,14 +237,42 @@
|
|||||||
<ColumnDefinition Width="2*"/>
|
<ColumnDefinition Width="2*"/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Label Content="E-Mail-Adresse (1):" Margin="10,10,0,0" Grid.Column="0"/>
|
<Label x:Name="EmailAddress1Label" Content="E-Mail-Adresse:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||||
<TextBox x:Name="EmailAddress1Input" Margin="0,10,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
<TextBox x:Name="EmailAddress1Input" Margin="0,10,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
<Label Content="E-Mail-Adresse (2):" Margin="10,40,0,0" Grid.Column="0"/>
|
<Label x:Name="EmailAddress2Label" Content="E-Mail-Adresse:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||||
<TextBox x:Name="EmailAddress2Input" Margin="0,40,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
<TextBox x:Name="EmailAddress2Input" Margin="0,40,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress3Label" Content="E-Mail-Adresse:" Margin="10,70,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress3Input" Margin="0,70,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress4Label" Content="E-Mail-Adresse:" Margin="10,100,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress4Input" Margin="0,100,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress5Label" Content="E-Mail-Adresse:" Margin="10,130,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress5Input" Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress6Label" Content="E-Mail-Adresse:" Margin="10,160,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress6Input" Margin="0,160,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress7Label" Content="E-Mail-Adresse:" Margin="10,190,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress7Input" Margin="0,190,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress8Label" Content="E-Mail-Adresse:" Margin="10,210,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress8Input" Margin="0,210,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label x:Name="EmailAddress9Label" Content="E-Mail-Adresse:" Margin="10,250,0,0" Grid.Column="0"/>
|
||||||
|
<TextBox x:Name="EmailAddress9Input" Margin="0,250,10,0" Grid.Column="1" Grid.ColumnSpan="2"
|
||||||
|
TextChanged="EmailAddressInput_TextChanged" LostFocus="EmailAddressInput_LostFocus"/>
|
||||||
|
|
||||||
<ComboBox x:Name="PhoneNr1TypeInput" DisplayMemberPath="Value" Margin="6,70,5,0" FontSize="12" Padding="6,4,4,4"/>
|
<ComboBox x:Name="PhoneNr1TypeInput" DisplayMemberPath="Value" Margin="6,70,5,0" FontSize="12" Padding="6,4,4,4"/>
|
||||||
<TextBox x:Name="PhoneNr1Input" Margin="0,70,5,0" Grid.Column="1"
|
<TextBox x:Name="PhoneNr1Input" Margin="0,70,5,0" Grid.Column="1"
|
||||||
TextChanged="PhoneNrInput_TextChanged" LostFocus="PhoneNrInput_LostFocus"/>
|
TextChanged="PhoneNrInput_TextChanged" LostFocus="PhoneNrInput_LostFocus"/>
|
||||||
|
@ -17,7 +17,8 @@ namespace Elwig.Windows {
|
|||||||
public partial class MemberAdminWindow : AdministrationWindow {
|
public partial class MemberAdminWindow : AdministrationWindow {
|
||||||
|
|
||||||
private List<string> TextFilter = [];
|
private List<string> TextFilter = [];
|
||||||
private readonly (ComboBox, TextBox, TextBox)[] PhoneNrInputs;
|
private readonly (ComboBox Type, TextBox Number, TextBox Comment)[] PhoneNrInputs;
|
||||||
|
private readonly (Label Label, TextBox Address)[] EmailAddressInputs;
|
||||||
|
|
||||||
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(MemberAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(MemberAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
||||||
private readonly RoutedCommand CtrlP = new("CtrlP", typeof(MemberAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control)]);
|
private readonly RoutedCommand CtrlP = new("CtrlP", typeof(MemberAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control)]);
|
||||||
@ -38,6 +39,17 @@ namespace Elwig.Windows {
|
|||||||
AddressInput, PlzInput, OrtInput, BillingOrtInput,
|
AddressInput, PlzInput, OrtInput, BillingOrtInput,
|
||||||
BusinessSharesInput, BranchInput, DefaultKgInput
|
BusinessSharesInput, BranchInput, DefaultKgInput
|
||||||
];
|
];
|
||||||
|
EmailAddressInputs = [
|
||||||
|
(EmailAddress1Label, EmailAddress1Input),
|
||||||
|
(EmailAddress2Label, EmailAddress2Input),
|
||||||
|
(EmailAddress3Label, EmailAddress3Input),
|
||||||
|
(EmailAddress4Label, EmailAddress4Input),
|
||||||
|
(EmailAddress5Label, EmailAddress5Input),
|
||||||
|
(EmailAddress6Label, EmailAddress6Input),
|
||||||
|
(EmailAddress7Label, EmailAddress7Input),
|
||||||
|
(EmailAddress8Label, EmailAddress8Input),
|
||||||
|
(EmailAddress9Label, EmailAddress9Input),
|
||||||
|
];
|
||||||
PhoneNrInputs = [
|
PhoneNrInputs = [
|
||||||
(PhoneNr1TypeInput, PhoneNr1Input, PhoneNr1CommentInput),
|
(PhoneNr1TypeInput, PhoneNr1Input, PhoneNr1CommentInput),
|
||||||
(PhoneNr2TypeInput, PhoneNr2Input, PhoneNr2CommentInput),
|
(PhoneNr2TypeInput, PhoneNr2Input, PhoneNr2CommentInput),
|
||||||
@ -63,7 +75,7 @@ namespace Elwig.Windows {
|
|||||||
Menu_Print_MemberDataSheet.IsEnabled = App.IsPrintingReady;
|
Menu_Print_MemberDataSheet.IsEnabled = App.IsPrintingReady;
|
||||||
|
|
||||||
ActiveMemberInput.IsChecked = true;
|
ActiveMemberInput.IsChecked = true;
|
||||||
UpdatePhoneNrInputVisibility();
|
UpdateContactInfoVisibility();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,27 +248,55 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private void SetPhoneNrInput(int nr, string? type, string? number, string? comment) {
|
private void SetPhoneNrInput(int nr, string? type, string? number, string? comment) {
|
||||||
var inputs = PhoneNrInputs[nr];
|
var inputs = PhoneNrInputs[nr];
|
||||||
inputs.Item1.SelectedItem = (type == null) ? null : inputs.Item1.ItemsSource.Cast<KeyValuePair<string, string>>().FirstOrDefault(p => p.Key == type);
|
inputs.Type.SelectedItem = (type == null) ? null : inputs.Type.ItemsSource.Cast<KeyValuePair<string, string>>().FirstOrDefault(p => p.Key == type);
|
||||||
inputs.Item2.Text = number;
|
inputs.Number.Text = number;
|
||||||
inputs.Item3.Text = comment;
|
inputs.Comment.Text = comment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEmailAddressInput(int nr, string? address) {
|
||||||
|
var inputs = EmailAddressInputs[nr];
|
||||||
|
inputs.Address.Text = address;
|
||||||
}
|
}
|
||||||
|
|
||||||
private (string, string, string?)? GetPhoneNrInput(int nr) {
|
private (string, string, string?)? GetPhoneNrInput(int nr) {
|
||||||
var inputs = PhoneNrInputs[nr];
|
var inputs = PhoneNrInputs[nr];
|
||||||
var number = inputs.Item2.Text;
|
var number = inputs.Number.Text;
|
||||||
if (string.IsNullOrEmpty(number))
|
if (string.IsNullOrEmpty(number))
|
||||||
return null;
|
return null;
|
||||||
var type = (inputs.Item1.SelectedItem as KeyValuePair<string, string>?)?.Key ?? (number.StartsWith("+43 ") && number[4] == '6' ? "mobile" : "landline");
|
var type = (inputs.Type.SelectedItem as KeyValuePair<string, string>?)?.Key ?? (number.StartsWith("+43 ") && number[4] == '6' ? "mobile" : "landline");
|
||||||
var comment = inputs.Item3.Text;
|
var comment = inputs.Comment.Text;
|
||||||
return (type, number, comment == "" ? null : comment);
|
return (type, number, comment == "" ? null : comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetPhoneNrInputVisible(int nr, bool visible) {
|
private string? GetEmailAddressInput(int nr) {
|
||||||
|
var inputs = EmailAddressInputs[nr];
|
||||||
|
return inputs.Address.Text == "" ? null : inputs.Address.Text;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetPhoneNrInputVisible(int nr, bool visible, int? position = null) {
|
||||||
var inputs = PhoneNrInputs[nr];
|
var inputs = PhoneNrInputs[nr];
|
||||||
|
if (position is int p) {
|
||||||
|
var mt = 10 + p * 30;
|
||||||
|
inputs.Type.Margin = new(6, mt, 5, 0);
|
||||||
|
inputs.Number.Margin = new(0, mt, 5, 0);
|
||||||
|
inputs.Comment.Margin = new(0, mt, 10, 0);
|
||||||
|
}
|
||||||
var vis = visible ? Visibility.Visible : Visibility.Hidden;
|
var vis = visible ? Visibility.Visible : Visibility.Hidden;
|
||||||
inputs.Item1.Visibility = vis;
|
inputs.Type.Visibility = vis;
|
||||||
inputs.Item2.Visibility = vis;
|
inputs.Number.Visibility = vis;
|
||||||
inputs.Item3.Visibility = vis;
|
inputs.Comment.Visibility = vis;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetEmailAddressInputVisible(int nr, bool visible, int? position = null) {
|
||||||
|
var inputs = EmailAddressInputs[nr];
|
||||||
|
if (position is int p) {
|
||||||
|
var mt = 10 + p * 30;
|
||||||
|
inputs.Label.Margin = new(10, mt, 0, 0);
|
||||||
|
inputs.Address.Margin = new(0, mt, 10, 0);
|
||||||
|
}
|
||||||
|
var vis = visible ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
inputs.Label.Visibility = vis;
|
||||||
|
inputs.Address.Visibility = vis;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MemberList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
private void MemberList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||||
@ -274,7 +314,7 @@ namespace Elwig.Windows {
|
|||||||
HideNewEditDeleteButtons();
|
HideNewEditDeleteButtons();
|
||||||
ShowSaveResetCancelButtons();
|
ShowSaveResetCancelButtons();
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
UpdatePhoneNrInputVisibility(true);
|
UpdateContactInfoVisibility(true);
|
||||||
InitInputs();
|
InitInputs();
|
||||||
LockSearchInputs();
|
LockSearchInputs();
|
||||||
}
|
}
|
||||||
@ -289,7 +329,7 @@ namespace Elwig.Windows {
|
|||||||
HideNewEditDeleteButtons();
|
HideNewEditDeleteButtons();
|
||||||
ShowSaveResetCancelButtons();
|
ShowSaveResetCancelButtons();
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
UpdatePhoneNrInputVisibility(true);
|
UpdateContactInfoVisibility(true);
|
||||||
LockSearchInputs();
|
LockSearchInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +355,7 @@ namespace Elwig.Windows {
|
|||||||
HideSaveResetCancelButtons();
|
HideSaveResetCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
UpdatePhoneNrInputVisibility();
|
UpdateContactInfoVisibility();
|
||||||
UnlockSearchInputs();
|
UnlockSearchInputs();
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
await RefreshMemberList();
|
await RefreshMemberList();
|
||||||
@ -342,7 +382,7 @@ namespace Elwig.Windows {
|
|||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
UpdatePhoneNrInputVisibility();
|
UpdateContactInfoVisibility();
|
||||||
UnlockSearchInputs();
|
UnlockSearchInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,13 +544,24 @@ namespace Elwig.Windows {
|
|||||||
ActiveMemberInput.IsEnabled = true;
|
ActiveMemberInput.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdatePhoneNrInputVisibility(bool extra = false) {
|
private void UpdateContactInfoVisibility(bool extra = false) {
|
||||||
bool lastVisible = true;
|
var m = MemberList.SelectedItem as Member;
|
||||||
var m = (Member)MemberList.SelectedItem;
|
bool lastVisible;
|
||||||
|
int num = 0;
|
||||||
|
lastVisible = true;
|
||||||
|
for (int i = 0; i < EmailAddressInputs.Length; i++) {
|
||||||
|
var input = EmailAddressInputs[i];
|
||||||
|
var vis = !string.IsNullOrEmpty(input.Address.Text) || (m?.EmailAddresses.Any(a => a.Nr - 1 == i) ?? false);
|
||||||
|
var cVis = vis || (extra && lastVisible);
|
||||||
|
SetEmailAddressInputVisible(i, cVis, cVis ? num++ : null);
|
||||||
|
lastVisible = vis;
|
||||||
|
}
|
||||||
|
lastVisible = true;
|
||||||
for (int i = 0; i < PhoneNrInputs.Length; i++) {
|
for (int i = 0; i < PhoneNrInputs.Length; i++) {
|
||||||
var input = PhoneNrInputs[i];
|
var input = PhoneNrInputs[i];
|
||||||
var vis = !string.IsNullOrEmpty(input.Item2.Text) || (m?.TelephoneNumbers.Any(p => p.Nr - 1 == i) ?? false);
|
var vis = !string.IsNullOrEmpty(input.Number.Text) || (m?.TelephoneNumbers.Any(n => n.Nr - 1 == i) ?? false);
|
||||||
SetPhoneNrInputVisible(i, vis || (extra && lastVisible));
|
var cVis = vis || (extra && lastVisible);
|
||||||
|
SetPhoneNrInputVisible(i, cVis, cVis ? num++ : null);
|
||||||
lastVisible = vis;
|
lastVisible = vis;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -605,17 +656,17 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++) {
|
for (int i = 0; i < EmailAddressInputs.Length; i++) {
|
||||||
var input = i == 0 ? EmailAddress1Input : EmailAddress2Input;
|
var input = GetEmailAddressInput(i);
|
||||||
var emailAddr = m.EmailAddresses.FirstOrDefault(a => a.Nr - 1 == i);
|
var emailAddr = m.EmailAddresses.FirstOrDefault(a => a.Nr - 1 == i);
|
||||||
if (input.Text == "") {
|
if (input == null || input == "") {
|
||||||
if (emailAddr != null) {
|
if (emailAddr != null) {
|
||||||
Context.Remove(emailAddr);
|
Context.Remove(emailAddr);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MemberEmailAddr a = emailAddr ?? Context.CreateProxy<MemberEmailAddr>();
|
MemberEmailAddr a = emailAddr ?? Context.CreateProxy<MemberEmailAddr>();
|
||||||
a.Nr = i + 1;
|
a.Nr = i + 1;
|
||||||
a.Address = input.Text;
|
a.Address = input ?? "";
|
||||||
a.Comment = null;
|
a.Comment = null;
|
||||||
if (emailAddr == null) {
|
if (emailAddr == null) {
|
||||||
a.MgNr = newMgNr;
|
a.MgNr = newMgNr;
|
||||||
@ -678,8 +729,14 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var emailAddrs = m.EmailAddresses.OrderBy(a => a.Nr).ToList();
|
var emailAddrs = m.EmailAddresses.OrderBy(a => a.Nr).ToList();
|
||||||
EmailAddress1Input.Text = emailAddrs.Count > 0 ? emailAddrs[0].Address : "";
|
for (int i = 0; i< EmailAddressInputs.Length; i++) {
|
||||||
EmailAddress2Input.Text = emailAddrs.Count > 1 ? emailAddrs[1].Address : "";
|
if (i < emailAddrs.Count) {
|
||||||
|
var emailAddr = emailAddrs[i];
|
||||||
|
SetEmailAddressInput(i, emailAddr.Address);
|
||||||
|
} else {
|
||||||
|
SetEmailAddressInput(i, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var phoneNrs = m.TelephoneNumbers.OrderBy(p => p.Nr).ToList();
|
var phoneNrs = m.TelephoneNumbers.OrderBy(p => p.Nr).ToList();
|
||||||
for (int i = 0; i < PhoneNrInputs.Length; i++) {
|
for (int i = 0; i < PhoneNrInputs.Length; i++) {
|
||||||
@ -690,7 +747,7 @@ namespace Elwig.Windows {
|
|||||||
SetPhoneNrInput(i, null, null, null);
|
SetPhoneNrInput(i, null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdatePhoneNrInputVisibility(IsEditing || IsCreating);
|
UpdateContactInfoVisibility(IsEditing || IsCreating);
|
||||||
|
|
||||||
IbanInput.Text = m.Iban;
|
IbanInput.Text = m.Iban;
|
||||||
BicInput.Text = m.Bic;
|
BicInput.Text = m.Bic;
|
||||||
@ -786,9 +843,14 @@ namespace Elwig.Windows {
|
|||||||
InputLostFocus((TextBox)sender, Validator.CheckPredecessorMgNr);
|
InputLostFocus((TextBox)sender, Validator.CheckPredecessorMgNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private new void EmailAddressInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
base.EmailAddressInput_TextChanged(sender, evt);
|
||||||
|
UpdateContactInfoVisibility(IsEditing || IsCreating);
|
||||||
|
}
|
||||||
|
|
||||||
private new void PhoneNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private new void PhoneNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
base.PhoneNrInput_TextChanged(sender, evt);
|
base.PhoneNrInput_TextChanged(sender, evt);
|
||||||
UpdatePhoneNrInputVisibility(IsEditing || IsCreating);
|
UpdateContactInfoVisibility(IsEditing || IsCreating);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void KgDetailsButton_Click(object sender, RoutedEventArgs evt) {
|
private void KgDetailsButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
<Window x:Class="Elwig.Windows.MemberListWindow"
|
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
|
||||||
mc:Ignorable="d"
|
|
||||||
Title="Mitgliederliste - Elwig" Height="450" Width="800">
|
|
||||||
<Grid>
|
|
||||||
<DataGrid x:Name="MemberList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single"
|
|
||||||
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" FontSize="14">
|
|
||||||
<DataGrid.Columns>
|
|
||||||
<DataGridTextColumn Header="MgNr." Binding="{Binding MgNr}" Width="70"/>
|
|
||||||
<DataGridTextColumn Header="Präfix" Binding="{Binding Prefix}" Width="100"/>
|
|
||||||
<DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="100"/>
|
|
||||||
<DataGridTextColumn Header="Weitere Namen" Binding="{Binding MiddleName}" Width="100"/>
|
|
||||||
<DataGridTextColumn Header="Nachname" Binding="{Binding FamilyName}" Width="100"/>
|
|
||||||
<DataGridTextColumn Header="Suffix" Binding="{Binding Suffix}" Width="100"/>
|
|
||||||
</DataGrid.Columns>
|
|
||||||
</DataGrid>
|
|
||||||
</Grid>
|
|
||||||
</Window>
|
|
@ -1,27 +0,0 @@
|
|||||||
using Elwig.Helpers;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
|
||||||
using System.Windows.Data;
|
|
||||||
using System.Windows.Documents;
|
|
||||||
using System.Windows.Input;
|
|
||||||
using System.Windows.Media;
|
|
||||||
using System.Windows.Media.Imaging;
|
|
||||||
using System.Windows.Shapes;
|
|
||||||
|
|
||||||
namespace Elwig.Windows {
|
|
||||||
public partial class MemberListWindow : Window {
|
|
||||||
private readonly AppDbContext Context = new();
|
|
||||||
|
|
||||||
public MemberListWindow() {
|
|
||||||
InitializeComponent();
|
|
||||||
MemberList.ItemsSource = Context.Members.ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,7 +6,7 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Auszahlungsvarianten - Elwig" Height="500" Width="820" MinHeight="500" MinWidth="820">
|
Title="Auszahlungsvarianten - Elwig" Height="510" Width="820" MinHeight="500" MinWidth="820">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Label">
|
<Style TargetType="Label">
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
@ -42,7 +42,7 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
<RowDefinition Height="200"/>
|
<RowDefinition Height="220"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2" SelectionChanged="PaymentVariantList_SelectionChanged">
|
<ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2" SelectionChanged="PaymentVariantList_SelectionChanged">
|
||||||
@ -163,6 +163,9 @@
|
|||||||
<Button x:Name="ExportButton" Content="Exportieren" FontSize="14" Width="180" Margin="10,10,10,10" Height="27" IsEnabled="False"
|
<Button x:Name="ExportButton" Content="Exportieren" FontSize="14" Width="180" Margin="10,10,10,10" Height="27" IsEnabled="False"
|
||||||
Click="ExportButton_Click"
|
Click="ExportButton_Click"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
|
<Button x:Name="TransactionButton" Content="Buchungsliste" FontSize="14" Width="180" Margin="10,42,10,10" Height="27" IsEnabled="False"
|
||||||
|
Click="TransactionButton_Click"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Left"/>
|
||||||
|
|
||||||
<ProgressBar x:Name="ProgressBar" Margin="10,10,10,74" Height="27" Width="180"
|
<ProgressBar x:Name="ProgressBar" Margin="10,10,10,74" Height="27" Width="180"
|
||||||
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
|
||||||
|
@ -57,6 +57,7 @@ namespace Elwig.Windows {
|
|||||||
ShowButton.IsEnabled = true;
|
ShowButton.IsEnabled = true;
|
||||||
PrintButton.IsEnabled = true;
|
PrintButton.IsEnabled = true;
|
||||||
ExportButton.IsEnabled = locked;
|
ExportButton.IsEnabled = locked;
|
||||||
|
TransactionButton.IsEnabled = locked;
|
||||||
|
|
||||||
NameInput.Text = v.Name;
|
NameInput.Text = v.Name;
|
||||||
NameInput.IsReadOnly = false;
|
NameInput.IsReadOnly = false;
|
||||||
@ -101,6 +102,7 @@ namespace Elwig.Windows {
|
|||||||
ShowButton.IsEnabled = false;
|
ShowButton.IsEnabled = false;
|
||||||
PrintButton.IsEnabled = false;
|
PrintButton.IsEnabled = false;
|
||||||
ExportButton.IsEnabled = false;
|
ExportButton.IsEnabled = false;
|
||||||
|
TransactionButton.IsEnabled = false;
|
||||||
|
|
||||||
BillingData = null;
|
BillingData = null;
|
||||||
NameInput.Text = "";
|
NameInput.Text = "";
|
||||||
@ -173,7 +175,7 @@ namespace Elwig.Windows {
|
|||||||
v.Name = "Neue Auszahlungsvariante";
|
v.Name = "Neue Auszahlungsvariante";
|
||||||
v.TestVariant = true;
|
v.TestVariant = true;
|
||||||
v.DateString = $"{DateTime.Today:yyyy-MM-dd}";
|
v.DateString = $"{DateTime.Today:yyyy-MM-dd}";
|
||||||
v.Data = "{\"mode\": \"elwig\", \"version\": 1, \"payment\": 1.0, \"quality\": {\"WEI\": 0}, \"curves\": []}";
|
v.Data = "{\"mode\": \"elwig\", \"version\": 1, \"payment\": {}, \"curves\": []}";
|
||||||
|
|
||||||
await Context.AddAsync(v);
|
await Context.AddAsync(v);
|
||||||
await Context.SaveChangesAsync();
|
await Context.SaveChangesAsync();
|
||||||
@ -311,6 +313,31 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void TransactionButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
if (PaymentVariantList.SelectedValue is not PaymentVar v) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var d = new SaveFileDialog() {
|
||||||
|
FileName = $"{App.Client.NameToken}-Buchungsliste-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.ods",
|
||||||
|
DefaultExt = "ods",
|
||||||
|
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
|
||||||
|
Title = $"Buchungsliste speichern unter - Elwig"
|
||||||
|
};
|
||||||
|
if (d.ShowDialog() == true) {
|
||||||
|
TransactionButton.IsEnabled = false;
|
||||||
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
try {
|
||||||
|
var tbl = await CreditNoteData.ForPaymentVariant(Context, v.Year, v.AvNr);
|
||||||
|
using var ods = new OdsFile(d.FileName);
|
||||||
|
await ods.AddTable(tbl);
|
||||||
|
} catch (Exception exc) {
|
||||||
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||||
|
}
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
TransactionButton.IsEnabled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
|
private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (PaymentVariantList.SelectedItem is not PaymentVar v || BillingData == null) return;
|
if (PaymentVariantList.SelectedItem is not PaymentVar v || BillingData == null) return;
|
||||||
try {
|
try {
|
||||||
@ -488,7 +515,7 @@ namespace Elwig.Windows {
|
|||||||
members = members.OrderBy(m => m.MgNr);
|
members = members.OrderBy(m => m.MgNr);
|
||||||
|
|
||||||
IEnumerable<Member> list = await members.ToListAsync();
|
IEnumerable<Member> list = await members.ToListAsync();
|
||||||
var data = await CreditNoteData.ForPaymentVariant(Context.CreditNoteRows, Context.Seasons, v.Year, v.AvNr);
|
var data = await CreditNoteDeliveryData.ForPaymentVariant(Context.CreditNoteDeliveryRows, Context.Seasons, v.Year, v.AvNr);
|
||||||
var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
|
var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
|
||||||
await Context.GetMemberAreaCommitmentBuckets(Year, 0);
|
await Context.GetMemberAreaCommitmentBuckets(Year, 0);
|
||||||
using var doc = Document.Merge(list.Select(m =>
|
using var doc = Document.Merge(list.Select(m =>
|
||||||
|
@ -48,7 +48,7 @@ namespace Elwig.Windows {
|
|||||||
private async void ZipButton_Click(object sender, RoutedEventArgs evt) {
|
private async void ZipButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
using var ods = new OdsFile(@"C:\Users\Lorenz\Desktop\test.ods");
|
using var ods = new OdsFile(@"C:\Users\Lorenz\Desktop\test.ods");
|
||||||
await ods.AddTable(await DeliveryConfirmationData.ForMember(ctx.DeliveryParts, 2023, ctx.Members.Find(2948)));
|
await ods.AddTable(await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, 2023, ctx.Members.Find(2948)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
::mkdir "C:\Program Files\Elwig"
|
::mkdir "C:\Program Files\Elwig"
|
||||||
::curl -s "http://www.columbia.edu/~em36/PDFtoPrinter.exe" -z "C:\Program Files\Elwig\PDFtoPrinter.exe" -o "C:\Program Files\Elwig\PDFtoPrinter.exe"
|
::curl -s -L "http://www.columbia.edu/~em36/PDFtoPrinter.exe" -z "C:\Program Files\Elwig\PDFtoPrinter.exe" -o "C:\Program Files\Elwig\PDFtoPrinter.exe"
|
||||||
mkdir "C:\ProgramData\Elwig\resources"
|
mkdir "C:\ProgramData\Elwig\resources"
|
||||||
copy /b /y Documents\*.css "C:\ProgramData\Elwig\resources"
|
copy /b /y Documents\*.css "C:\ProgramData\Elwig\resources"
|
||||||
copy /b /y Documents\*.cshtml "C:\ProgramData\Elwig\resources"
|
copy /b /y Documents\*.cshtml "C:\ProgramData\Elwig\resources"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
</Task>
|
</Task>
|
||||||
</UsingTask>
|
</UsingTask>
|
||||||
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
||||||
<Exec Command="curl -s "http://www.columbia.edu/~em36/PDFtoPrinter.exe" -z "$(TargetDir)PDFtoPrinter.exe" -o "$(TargetDir)PDFtoPrinter.exe"" />
|
<Exec Command="curl -s -L "http://www.columbia.edu/~em36/PDFtoPrinter.exe" -z "$(TargetDir)PDFtoPrinter.exe" -o "$(TargetDir)PDFtoPrinter.exe"" />
|
||||||
<Exec Command="dotnet publish "$(SolutionDir)Elwig\Elwig.csproj" "/p:PublishProfile=$(SolutionDir)\Elwig\Properties\PublishProfiles\FolderProfile.pubxml"" />
|
<Exec Command="dotnet publish "$(SolutionDir)Elwig\Elwig.csproj" "/p:PublishProfile=$(SolutionDir)\Elwig\Properties\PublishProfiles\FolderProfile.pubxml"" />
|
||||||
<GetFileVersion AssemblyPath="..\Elwig\bin\Publish\Elwig.exe">
|
<GetFileVersion AssemblyPath="..\Elwig\bin\Publish\Elwig.exe">
|
||||||
<Output TaskParameter="Version" PropertyName="ElwigFileVersion" />
|
<Output TaskParameter="Version" PropertyName="ElwigFileVersion" />
|
||||||
|
@ -5,8 +5,8 @@
|
|||||||
<Cultures>de-AT</Cultures>
|
<Cultures>de-AT</Cultures>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
<Target Name="CustomBeforeBuild" BeforeTargets="BeforeBuild">
|
||||||
<Exec Command='curl -L -s "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -z "$(TargetDir)MicrosoftEdgeWebview2Setup.exe" -o "$(TargetDir)MicrosoftEdgeWebview2Setup.exe"' />
|
<Exec Command='curl -s -L "https://go.microsoft.com/fwlink/p/?LinkId=2124703" -z "$(TargetDir)MicrosoftEdgeWebview2Setup.exe" -o "$(TargetDir)MicrosoftEdgeWebview2Setup.exe"' />
|
||||||
<Exec Command='curl -L -s "https://aka.ms/vs/17/release/vc_redist.x86.exe" -z "$(TargetDir)VC_redist.x86.exe" -o "$(TargetDir)VC_redist.x86.exe"' />
|
<Exec Command='curl -s -L "https://aka.ms/vs/17/release/vc_redist.x86.exe" -z "$(TargetDir)VC_redist.x86.exe" -o "$(TargetDir)VC_redist.x86.exe"' />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<DefineConstants>ElwigProjectDir=..\Elwig</DefineConstants>
|
<DefineConstants>ElwigProjectDir=..\Elwig</DefineConstants>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Billing;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -16,6 +17,11 @@ namespace Tests {
|
|||||||
await AppDbContext.ExecuteEmbeddedScript(Connection, Assembly.GetExecutingAssembly(), "Tests.Resources.Insert.sql");
|
await AppDbContext.ExecuteEmbeddedScript(Connection, Assembly.GetExecutingAssembly(), "Tests.Resources.Insert.sql");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[OneTimeSetUp]
|
||||||
|
public async Task SetupBillingData() {
|
||||||
|
await BillingData.Init();
|
||||||
|
}
|
||||||
|
|
||||||
[OneTimeTearDown]
|
[OneTimeTearDown]
|
||||||
public async Task TeardownDatabase() {
|
public async Task TeardownDatabase() {
|
||||||
AppDbContext.ConnectionStringOverride = null;
|
AppDbContext.ConnectionStringOverride = null;
|
||||||
|
@ -8,12 +8,7 @@ namespace Tests.HelperTests {
|
|||||||
public class BillingDataTest {
|
public class BillingDataTest {
|
||||||
|
|
||||||
private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true };
|
private static readonly JsonSerializerOptions JsonOpts = new() { WriteIndented = true };
|
||||||
private static readonly string[] AttributeVariants = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"];
|
private static readonly string[] Vaributes = ["GV", "GVD", "GVK", "GVS", "GVZ", "WR", "WRS", "ZW", "ZWS", "ZWZ"];
|
||||||
|
|
||||||
[OneTimeSetUp]
|
|
||||||
public async Task SetupBilling() {
|
|
||||||
await BillingData.Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static (string, string?) GetSortIdAttrId(string bucket) {
|
private static (string, string?) GetSortIdAttrId(string bucket) {
|
||||||
return (bucket[..2], bucket.Length > 2 ? bucket[2..] : null);
|
return (bucket[..2], bucket.Length > 2 ? bucket[2..] : null);
|
||||||
@ -52,7 +47,7 @@ namespace Tests.HelperTests {
|
|||||||
"payment": 0.5,
|
"payment": 0.5,
|
||||||
"curves": []
|
"curves": []
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcOe(data, "GV", 73, 0.5m);
|
TestCalcOe(data, "GV", 73, 0.5m);
|
||||||
TestCalcOe(data, "WRS", 74, 0.5m);
|
TestCalcOe(data, "WRS", 74, 0.5m);
|
||||||
@ -77,7 +72,7 @@ namespace Tests.HelperTests {
|
|||||||
"geb": 0.10
|
"geb": 0.10
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcOe(data, "GV", 70, 0.25m);
|
TestCalcOe(data, "GV", 70, 0.25m);
|
||||||
TestCalcOe(data, "GV", 72, 0.25m);
|
TestCalcOe(data, "GV", 72, 0.25m);
|
||||||
@ -114,7 +109,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcKmw(data, "GV", 13.00, 0.10m);
|
TestCalcKmw(data, "GV", 13.00, 0.10m);
|
||||||
TestCalcKmw(data, "GV", 13.50, 0.10m);
|
TestCalcKmw(data, "GV", 13.50, 0.10m);
|
||||||
@ -148,7 +143,7 @@ namespace Tests.HelperTests {
|
|||||||
},
|
},
|
||||||
"curves": []
|
"curves": []
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcOe(data, "WR", 73, 0.10m);
|
TestCalcOe(data, "WR", 73, 0.10m);
|
||||||
TestCalcOe(data, "WRS", 73, 0.15m);
|
TestCalcOe(data, "WRS", 73, 0.15m);
|
||||||
@ -179,7 +174,7 @@ namespace Tests.HelperTests {
|
|||||||
},
|
},
|
||||||
"curves": []
|
"curves": []
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcOe(data, "GV", 75, 0.30m, qualid: "WEI");
|
TestCalcOe(data, "GV", 75, 0.30m, qualid: "WEI");
|
||||||
TestCalcOe(data, "ZW", 76, 0.25m, qualid: "WEI");
|
TestCalcOe(data, "ZW", 76, 0.25m, qualid: "WEI");
|
||||||
@ -221,7 +216,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcKmw(data, "GV", 15.0, 2.0m);
|
TestCalcKmw(data, "GV", 15.0, 2.0m);
|
||||||
TestCalcKmw(data, "GV", 15.5, 2.272727m);
|
TestCalcKmw(data, "GV", 15.5, 2.272727m);
|
||||||
@ -281,7 +276,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcKmw(data, "GV", 15.0, 0.75m);
|
TestCalcKmw(data, "GV", 15.0, 0.75m);
|
||||||
TestCalcKmw(data, "GVS", 15.0, 0.50m);
|
TestCalcKmw(data, "GVS", 15.0, 0.50m);
|
||||||
@ -340,7 +335,7 @@ namespace Tests.HelperTests {
|
|||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
""", AttributeVariants);
|
""", Vaributes);
|
||||||
Assert.Multiple(() => {
|
Assert.Multiple(() => {
|
||||||
TestCalcOe(data, "GVK", 73, 0.032m);
|
TestCalcOe(data, "GVK", 73, 0.032m);
|
||||||
TestCalcOe(data, "ZWS", 74, 0.033m);
|
TestCalcOe(data, "ZWS", 74, 0.033m);
|
||||||
@ -349,11 +344,11 @@ namespace Tests.HelperTests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<ContractSelection> GetSelection(IEnumerable<string> attVars) {
|
private static List<Varibute> GetSelection(IEnumerable<string> attVars) {
|
||||||
return attVars.Select(s => {
|
return attVars.Select(s => {
|
||||||
var sortid = s[..2];
|
var sortid = s[..2];
|
||||||
var attrid = s.Length > 2 ? s[2..] : null;
|
var attrid = s.Length > 2 ? s[2..] : null;
|
||||||
return new ContractSelection(
|
return new Varibute(
|
||||||
new WineVar(sortid, sortid),
|
new WineVar(sortid, sortid),
|
||||||
attrid == null ? null : new WineAttr(attrid, attrid)
|
attrid == null ? null : new WineAttr(attrid, attrid)
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Billing;
|
||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@ -6,6 +7,9 @@ namespace Tests.HelperTests {
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class BillingTest {
|
public class BillingTest {
|
||||||
|
|
||||||
|
private const int Year1 = 2020, Year2 = 2020;
|
||||||
|
private const int MgNr1 = 101, MgNr2 = 102, MgNr3 = 103, MgNr4 = 104;
|
||||||
|
|
||||||
private SqliteConnection? Connection;
|
private SqliteConnection? Connection;
|
||||||
|
|
||||||
[OneTimeSetUp]
|
[OneTimeSetUp]
|
||||||
@ -22,9 +26,120 @@ namespace Tests.HelperTests {
|
|||||||
Connection = null;
|
Connection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public async Task CleanupDatabasePayment() {
|
||||||
|
if (Connection == null) return;
|
||||||
|
await AppDbContext.ExecuteBatch(Connection, """
|
||||||
|
DELETE FROM credit;
|
||||||
|
DELETE FROM delivery_part_bucket;
|
||||||
|
DELETE FROM payment_variant;
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<Dictionary<string, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr) {
|
||||||
|
var ctx = new AppDbContext();
|
||||||
|
return ctx.GetMemberAreaCommitmentBuckets(year, mgnr, Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<Dictionary<string, int>> GetMemberDeliveryBuckets(int year, int mgnr) {
|
||||||
|
var ctx = new AppDbContext();
|
||||||
|
return ctx.GetMemberDeliveryBuckets(year, mgnr, Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<Dictionary<string, int>> GetMemberPaymentBuckets(int year, int mgnr) {
|
||||||
|
var ctx = new AppDbContext();
|
||||||
|
return ctx.GetMemberPaymentBuckets(year, mgnr, Connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Dictionary<(string, string), int>> GetMemberDeliveryPrices(int year, int mgnr) {
|
||||||
|
var buckets = new Dictionary<(string, string), int>();
|
||||||
|
using (var cmd = Connection!.CreateCommand()) {
|
||||||
|
cmd.CommandText = $"""
|
||||||
|
SELECT lsnr || '/' || d.dpnr, d.sortid || b.discr, price
|
||||||
|
FROM v_delivery d
|
||||||
|
LEFT JOIN payment_delivery_part_bucket p ON (p.year, p.did, p.dpnr) = (d.year, d.did, d.dpnr)
|
||||||
|
LEFT JOIN delivery_part_bucket b ON (b.year, b.did, b.dpnr, b.bktnr) = (p.year, p.did, p.dpnr, p.bktnr)
|
||||||
|
WHERE d.year = {year} AND mgnr = {mgnr}
|
||||||
|
""";
|
||||||
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
|
while (await reader.ReadAsync()) {
|
||||||
|
var lsnr = reader.GetString(0);
|
||||||
|
var bucket = reader.GetString(1);
|
||||||
|
buckets[(lsnr, bucket)] = reader.GetInt32(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buckets;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task InsertPaymentVariant(int year, int avnr, string data) {
|
||||||
|
return AppDbContext.ExecuteBatch(Connection!, $"""
|
||||||
|
INSERT INTO payment_variant (year, avnr, name, date, transfer_date, test_variant, calc_time, data)
|
||||||
|
VALUES ({year}, {avnr}, 'Test', '2021-01-15', NULL, TRUE, NULL, '{data}');
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void Test() {
|
public async Task Test_01_NoActiveAreaCommitments() {
|
||||||
// TODO
|
int mgnr = MgNr1, year = Year1;
|
||||||
|
await InsertPaymentVariant(year, 1, """
|
||||||
|
{
|
||||||
|
"mode": "elwig",
|
||||||
|
"version": 1,
|
||||||
|
"payment": {
|
||||||
|
"GV/": "curve:0",
|
||||||
|
"GV/B": "curve:1",
|
||||||
|
"GV/K": "curve:2"
|
||||||
|
},
|
||||||
|
"quality": {"WEI": 0.1},
|
||||||
|
"curves": [{
|
||||||
|
"id": 0,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {"15kmw": 0.5},
|
||||||
|
"geb": 0.1
|
||||||
|
}, {
|
||||||
|
"id": 1,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {"15kmw": 0.54},
|
||||||
|
"geb": 0.1
|
||||||
|
}, {
|
||||||
|
"id": 2,
|
||||||
|
"mode": "oe",
|
||||||
|
"data": {"15kmw": 0.61},
|
||||||
|
"geb": 0.1
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
|
||||||
|
Assert.That(areaCom, Is.Empty);
|
||||||
|
var delivery = await GetMemberDeliveryBuckets(year, mgnr);
|
||||||
|
Assert.Multiple(() => {
|
||||||
|
Assert.That(delivery, Has.Count.EqualTo(4));
|
||||||
|
Assert.That(delivery["GV"], Is.EqualTo(16_000));
|
||||||
|
Assert.That(delivery["GV_"], Is.EqualTo( 1_000));
|
||||||
|
Assert.That(delivery["GVB"], Is.EqualTo( 8_000));
|
||||||
|
Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
|
||||||
|
});
|
||||||
|
|
||||||
|
BillingVariant b = new(year, 1);
|
||||||
|
await b.CalculateBuckets(false, false, false);
|
||||||
|
var payment = await GetMemberPaymentBuckets(year, mgnr);
|
||||||
|
Assert.Multiple(() => {
|
||||||
|
Assert.That(payment, Has.Count.EqualTo(1));
|
||||||
|
Assert.That(payment["GV_"], Is.EqualTo(17_000));
|
||||||
|
});
|
||||||
|
|
||||||
|
await b.Calculate();
|
||||||
|
var prices = await GetMemberDeliveryPrices(year, mgnr);
|
||||||
|
Assert.Multiple(() => {
|
||||||
|
Assert.That(prices, Has.Count.EqualTo(6));
|
||||||
|
Assert.That(prices[("20201001X001/1", "GV_")], Is.EqualTo(0_6100));
|
||||||
|
Assert.That(prices[("20201001X001/2", "GV_")], Is.EqualTo(0_5000));
|
||||||
|
Assert.That(prices[("20201001X002/1", "GV_")], Is.EqualTo(0_5400));
|
||||||
|
Assert.That(prices[("20201001X002/2", "GV_")], Is.EqualTo(0_5400));
|
||||||
|
Assert.That(prices[("20201001X003/1", "GV_")], Is.EqualTo(0_1000));
|
||||||
|
Assert.That(prices[("20201001X003/2", "GV_")], Is.EqualTo(0_5000));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +1,11 @@
|
|||||||
-- deletes for HelpersBillingTest
|
-- deletes for HelperTests.BillingTest
|
||||||
|
|
||||||
|
DELETE FROM credit;
|
||||||
|
DELETE FROM payment_variant
|
||||||
|
DELETE FROM delivery;
|
||||||
|
DELETE FROM area_commitment;
|
||||||
|
DELETE FROM area_commitment_type;
|
||||||
|
DELETE FROM season;
|
||||||
|
DELETE FROM member;
|
||||||
|
DELETE FROM wine_attribute;
|
||||||
|
DELETE FROM wine_cultivation;
|
||||||
|
@ -1 +1,59 @@
|
|||||||
-- inserts for HelpersBillingTest
|
-- inserts for HelperTests.BillingTest
|
||||||
|
|
||||||
|
INSERT INTO wine_cultivation (cultid, name, description) VALUES
|
||||||
|
('N', 'Normal', NULL),
|
||||||
|
('K', 'KIP', 'Kontrollierte Integrierte Produktion'),
|
||||||
|
('B', 'Org. Biologisch', 'Organisch Biologisch');
|
||||||
|
|
||||||
|
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
|
||||||
|
('B', 'Bio', TRUE, NULL, FALSE, 0),
|
||||||
|
('K', 'Kabinett', TRUE, NULL, FALSE, 0),
|
||||||
|
('D', 'DAC', TRUE, 7500, FALSE, 0),
|
||||||
|
('S', 'Saft', TRUE, NULL, FALSE, 0),
|
||||||
|
('Z', 'Sekt', TRUE, NULL, FALSE, 0),
|
||||||
|
('P', 'Vertrag P', TRUE, NULL, TRUE, 0),
|
||||||
|
('Q', 'Vertrag Q', TRUE, NULL, TRUE, 1),
|
||||||
|
('R', 'Vertrag R', TRUE, NULL, TRUE, 2);
|
||||||
|
|
||||||
|
INSERT INTO area_commitment_type (vtrgid, sortid, attrid, disc, min_kg_per_ha, penalty_per_kg, penalty_amount, penalty_none) VALUES
|
||||||
|
('ZW', 'ZW', NULL, NULL, 2500, 600, NULL, NULL),
|
||||||
|
('GV', 'GV', NULL, NULL, 5000, 500, NULL, NULL),
|
||||||
|
('GVK', 'GV', 'K', NULL, 5000, 500, NULL, NULL),
|
||||||
|
('GVD', 'GV', 'D', NULL, 5000, 1000, NULL, NULL),
|
||||||
|
('GVP', 'GV', 'P', NULL, 5000, 1000, 1000000, NULL),
|
||||||
|
('GVQ', 'GV', 'Q', NULL, 5000, 1000, 1000000, NULL),
|
||||||
|
('GVR', 'GV', 'R', NULL, 5000, 1000, 1000000, NULL);
|
||||||
|
|
||||||
|
INSERT INTO member (mgnr, given_name, family_name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr) VALUES
|
||||||
|
(101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109),
|
||||||
|
(102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109),
|
||||||
|
(103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224),
|
||||||
|
(104, 'Waltraud', 'Winzer', 'X', FALSE, FALSE, 40, 212005138, 'Wiener Straße 15', 15224);
|
||||||
|
|
||||||
|
INSERT INTO area_commitment (fbnr, mgnr, vtrgid, cultid, area, kgnr, gstnr, rdnr, year_from, year_to) VALUES
|
||||||
|
( 1, 101, 'GV', 'K', 10000, 06109, '123/4', NULL, 2000, 2019),
|
||||||
|
( 2, 101, 'GV', 'B', 10000, 06109, '123/5', NULL, 2025, 2030);
|
||||||
|
|
||||||
|
INSERT INTO season (year, currency, min_kg_per_bs, max_kg_per_bs, penalty_per_kg, penalty_amount, penalty_none, start_date, end_date) VALUES
|
||||||
|
(2020, 'EUR', 1000, 2000, NULL, NULL, NULL, NULL, NULL),
|
||||||
|
(2021, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
INSERT INTO modifier (year, modid, ordering, name, abs, rel, standard, quick_select) VALUES
|
||||||
|
(2020, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, FALSE, FALSE),
|
||||||
|
(2020, 'A', 0, 'Keine Voranmeldung', -1000, NULL, FALSE, FALSE);
|
||||||
|
|
||||||
|
INSERT INTO delivery (mgnr, year, did, date, time, zwstid, lnr) VALUES
|
||||||
|
(101, 2020, 1, '2020-10-01', NULL, 'X', 1),
|
||||||
|
(101, 2020, 2, '2020-10-01', NULL, 'X', 2),
|
||||||
|
(101, 2020, 3, '2020-10-01', NULL, 'X', 3);
|
||||||
|
|
||||||
|
INSERT INTO delivery_part (year, did, dpnr, sortid, attrid, weight, kmw, qualid, hkid, kgnr, gerebelt, manual_weighing, spl_check, scale_id, weighing_id, weighing_reason) VALUES
|
||||||
|
(2020, 1, 1, 'GV', 'K', 4000, 17, 'KAB', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||||
|
(2020, 1, 2, 'GV', NULL, 4000, 16, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||||
|
(2020, 2, 1, 'GV', 'B', 4000, 15, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||||
|
(2020, 2, 2, 'GV', 'B', 4000, 16, 'QUW', 'WLNO', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||||
|
(2020, 3, 1, 'GV', NULL, 500, 15, 'WEI', 'OEST', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL),
|
||||||
|
(2020, 3, 2, 'GV', NULL, 500, 14, 'LDW', 'WLXX', 06109, TRUE, FALSE, FALSE, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
INSERT INTO delivery_part_modifier (year, did, dpnr, modid) VALUES
|
||||||
|
(2020, 1, 2, 'S');
|
||||||
|
@ -1 +1 @@
|
|||||||
curl -s "https://www.necronda.net/elwig/files/create.sql?v=13" -u "elwig:ganzGeheim123!" -o "Resources\Create.sql"
|
curl -s -L "https://www.necronda.net/elwig/files/create.sql?v=13" -u "elwig:ganzGeheim123!" -o "Resources\Create.sql"
|
||||||
|
Reference in New Issue
Block a user