Compare commits

..

6 Commits

Author SHA1 Message Date
lorenz.stechauner 62346a63a8 [#80] Elwig: Add client parameter to switch between simple and red/white business share mode
Test / Run tests (push) Successful in 2m20s
2026-07-01 17:09:55 +02:00
lorenz.stechauner feee6ad1ec [#20][#80] Elwig: Update member_history and add different types of shares
Test / Run tests (push) Successful in 2m0s
2026-07-01 16:22:01 +02:00
lorenz.stechauner 4ebe07f579 AppDbUpdater: Fix handling of foreign key errors
Test / Run tests (push) Successful in 3m4s
2026-07-01 00:36:04 +02:00
lorenz.stechauner beacba6bd9 Services: Add Utils.RunForeground() to factor Task.Run and try-catch-Blocks out
Test / Run tests (push) Successful in 2m2s
2026-06-30 02:32:24 +02:00
lorenz.stechauner 69efca1cc3 Tests: Use Assert.EnterMultipleScope instead of Assert.Multiple
Test / Run tests (push) Successful in 2m6s
2026-06-29 02:33:36 +02:00
lorenz.stechauner fcd0555e4d Elwig: Add InteractionService to centrally manage MessageBox and SaveFileDialogs
Test / Run tests (push) Successful in 2m50s
2026-06-29 02:28:34 +02:00
74 changed files with 1834 additions and 1361 deletions
+18 -21
View File
@@ -5,6 +5,7 @@ using Elwig.Helpers.Export;
using Elwig.Helpers.Printing; using Elwig.Helpers.Printing;
using Elwig.Helpers.Weighing; using Elwig.Helpers.Weighing;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Elwig.Windows; using Elwig.Windows;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
@@ -91,11 +92,11 @@ namespace Elwig {
try { try {
await AppDbUpdater.CheckDb(); await AppDbUpdater.CheckDb();
} catch (Exception e) { } catch (Exception exc) {
if (Config.UpdateUrl != null && Utils.HasInternetConnectivity()) { if (Config.UpdateUrl != null && Utils.HasInternetConnectivity()) {
await CheckForUpdates(); await CheckForUpdates();
} }
MessageBox.Show($"Invalid Database:\n\n{e.Message}", "Invalid Database", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Fehlerhafte Datenbank", "Fehlerhafte Datenbank", exc);
Shutdown(); Shutdown();
return; return;
} }
@@ -110,8 +111,8 @@ namespace Elwig {
.GetAwaiter().GetResult(); .GetAwaiter().GetResult();
try { try {
Client = new(ctx); Client = new(ctx);
} catch (Exception e) { } catch (Exception exc) {
MessageBox.Show($"Fehler beim Laden der Mandantendaten:\n\n{e.Message}", "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Fehler", "Fehler beim Laden der Mandantendaten", exc);
Shutdown(); Shutdown();
return; return;
} }
@@ -145,18 +146,17 @@ namespace Elwig {
foreach (var s in Config.Scales) { foreach (var s in Config.Scales) {
try { try {
list.Add(Scale.FromConfig(s)); list.Add(Scale.FromConfig(s));
} catch (Exception e) { } catch (Exception exc) {
list.Add(new InvalidScale(s.Id)); list.Add(new InvalidScale(s.Id));
if (s.Required) if (s.Required)
MessageBox.Show($"Verbindung zu Waage {s.Id} konnte nicht hergestellt werden:\n\n{e.Message}", "Waagenfehler", InteractionService.ShowException("Waagenfehler", $"Verbindung zu Waage {s.Id} konnte nicht hergestellt werden", exc);
MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
Scales = list; Scales = list;
if (Config.Branch != null) { if (Config.Branch != null) {
if (!branches.ContainsKey(Config.Branch.ToLower())) { if (!branches.ContainsKey(Config.Branch.ToLower())) {
MessageBox.Show("Ungültige Zweigstelle in Konfigurationsdatei!", "Ungültige Zweigstelle", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowError("Ungültige Zweigstelle", "Ungültige Zweigstelle in Konfigurationsdatei!");
Shutdown(); Shutdown();
} else { } else {
SetBranch(branches[Config.Branch.ToLower()]); SetBranch(branches[Config.Branch.ToLower()]);
@@ -164,7 +164,7 @@ namespace Elwig {
} else if (branches.Count == 1) { } else if (branches.Count == 1) {
SetBranch(branches.First().Value); SetBranch(branches.First().Value);
} else { } else {
MessageBox.Show("Erkennen der lokalen Zweigstelle nicht möglich!", "Ungültige Zweigstelle", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowError("Ungültige Zweigstelle", "Erkennen der lokalen Zweigstelle nicht möglich!");
Shutdown(); Shutdown();
} }
@@ -254,14 +254,13 @@ namespace Elwig {
if (Scales[i] is InvalidScale) { if (Scales[i] is InvalidScale) {
try { try {
Scales[i] = Scale.FromConfig(s); Scales[i] = Scale.FromConfig(s);
MessageBox.Show($"Verbindung zu Waage {s.Id} wieder hergestellt!", $"Waage {s.Id}", MessageBoxButton.OK, MessageBoxImage.Information); InteractionService.ShowInformation($"Waage {s.Id}", $"Verbindung zu Waage {s.Id} wieder hergestellt!");
} catch (Exception e) { } catch (Exception exc) {
Scales[i] = new InvalidScale(s.Id); Scales[i] = new InvalidScale(s.Id);
MessageBox.Show($"Verbindung zu Waage {s.Id} konnte nicht hergestellt werden:\n\n{e.Message}", "Waagenfehler", InteractionService.ShowException("Waagenfehler", $"Verbindung zu Waage {s.Id} konnte nicht hergestellt werden", exc);
MessageBoxButton.OK, MessageBoxImage.Error);
} }
} else if (Scales[i] is IEventScale) { } else if (Scales[i] is IEventScale) {
MessageBox.Show($"Verbindung zu Waage {s.Id} wieder hergestellt!", $"Waage {s.Id}", MessageBoxButton.OK, MessageBoxImage.Information); InteractionService.ShowInformation($"Waage {s.Id}", $"Verbindung zu Waage {s.Id} wieder hergestellt!");
} }
} }
} }
@@ -272,7 +271,7 @@ namespace Elwig {
for (var i = 0; i < Config.Scales.Count; i++) { for (var i = 0; i < Config.Scales.Count; i++) {
var s = Config.Scales[i]; var s = Config.Scales[i];
if ((s.Connection?.StartsWith($"serial://{name}:") ?? false) && Scales[i] is not InvalidScale) { if ((s.Connection?.StartsWith($"serial://{name}:") ?? false) && Scales[i] is not InvalidScale) {
MessageBox.Show($"Verbindung zu Waage {s.Id} unterbrochen!", $"Waagen {s.Id}", MessageBoxButton.OK, MessageBoxImage.Warning); InteractionService.ShowWarning($"Waagen {s.Id}", $"Verbindung zu Waage {s.Id} unterbrochen!");
if (Scales[i] is ICommandScale) { if (Scales[i] is ICommandScale) {
try { try {
Scales[i].Dispose(); Scales[i].Dispose();
@@ -307,11 +306,9 @@ namespace Elwig {
}); });
} else if (showAlert) { } else if (showAlert) {
if (latest == null) { if (latest == null) {
MessageBox.Show("Informationen konnten nicht abgerufen werden!", "Nach Updates suchen", InteractionService.ShowError("Nach Updates suchen", "Informationen konnten nicht abgerufen werden!");
MessageBoxButton.OK, MessageBoxImage.Error);
} else { } else {
MessageBox.Show($"Elwig ist auf dem aktuellsten Stand! (Version: {latest.Value.Version})", "Nach Updates suchen", InteractionService.ShowInformation("Nach Updates suchen", $"Elwig ist auf dem aktuellsten Stand! (Version: {latest.Value.Version})");
MessageBoxButton.OK, MessageBoxImage.Information);
} }
} }
} }
@@ -321,11 +318,11 @@ namespace Elwig {
await Task.Run(async () => { await Task.Run(async () => {
await Database.Import(filename); await Database.Import(filename);
}); });
MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information); InteractionService.ShowInformation("Datenbank ersetzen", "Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!");
ForceShutdown = true; ForceShutdown = true;
Current.Shutdown(); Current.Shutdown();
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show("Fehler beim Ersetzen:\n\n" + exc.Message, "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank ersetzen", "Fehler beim Ersetzen", exc);
} }
} }
+2 -1
View File
@@ -1,4 +1,5 @@
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Services;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
@@ -51,7 +52,7 @@ namespace Elwig.Dialogs {
File.Delete(fileName); File.Delete(fileName);
return; return;
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Process.Start(fileName); Process.Start(fileName);
DialogResult = true; DialogResult = true;
+18 -4
View File
@@ -18,6 +18,7 @@ namespace Elwig.Documents {
public class BusinessDocument : Document { public class BusinessDocument : Document {
public Member Member; public Member Member;
public MemberHistoryPoint MemberHistory;
public string? Location; public string? Location;
public bool IncludeSender = false; public bool IncludeSender = false;
public bool UseBillingAddress = false; public bool UseBillingAddress = false;
@@ -51,6 +52,7 @@ namespace Elwig.Documents {
public BusinessDocument(string title, Member m, DateOnly? dateFrom, bool includeSender = false) : public BusinessDocument(string title, Member m, DateOnly? dateFrom, bool includeSender = false) :
base(title) { base(title) {
Member = m; Member = m;
MemberHistory = new(m.Shares, m.SharesRed, m.SharesWhite, m.SharesDormant);
Location = App.BranchLocation; Location = App.BranchLocation;
IncludeSender = includeSender; IncludeSender = includeSender;
DateFrom = dateFrom; DateFrom = dateFrom;
@@ -263,7 +265,7 @@ namespace Elwig.Documents {
} }
protected Table NewBucketTable( protected Table NewBucketTable(
Season season, Dictionary<string, MemberBucket> buckets, int deliveredWeight, Season season, Dictionary<string, MemberBucket> buckets, int deliveredWeightRed, int deliveredWeightWhite,
bool includeDelivery = true, bool includePayment = false, bool includeDelivery = true, bool includePayment = false,
bool isTiny = false, IEnumerable<string>? filter = null bool isTiny = false, IEnumerable<string>? filter = null
) { ) {
@@ -316,9 +318,21 @@ namespace Elwig.Documents {
.Where(b => !fbVars.Contains(b.Key)) .Where(b => !fbVars.Contains(b.Key))
.OrderBy(b => b.Value.Name); .OrderBy(b => b.Value.Name);
tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA", isTiny: isTiny)); if (MemberHistory.Shares != 0 || (MemberHistory.SharesRed == 0 && MemberHistory.SharesWhite == 0)) {
tbl.AddCells(FormatRow(Member.BusinessShares * season.MinKgPerBusinessShare, Member.BusinessShares * season.MaxKgPerBusinessShare, tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA", isTiny: isTiny));
deliveredWeight, isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny)); tbl.AddCells(FormatRow(MemberHistory.Shares * (season.MinKgPerShare ?? 0), MemberHistory.Shares * (season.MaxKgPerShare ?? 0),
deliveredWeightRed + deliveredWeightWhite, isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
}
if (MemberHistory.SharesRed != 0 || MemberHistory.SharesWhite != 0) {
tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA (rot)", isTiny: isTiny));
tbl.AddCells(FormatRow(MemberHistory.SharesRed * (season.MinKgPerShareRed ?? season.MinKgPerShare ?? 0), MemberHistory.SharesRed * (season.MaxKgPerShareRed ?? season.MaxKgPerShare ?? 0),
deliveredWeightRed, isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
tbl.AddCell(NewBucketTh("Gesamtlieferung lt. gez. GA (weiß)", isTiny: isTiny));
tbl.AddCells(FormatRow(MemberHistory.SharesWhite * (season.MinKgPerShareWhite ?? season.MinKgPerShare ?? 0), MemberHistory.SharesWhite * (season.MaxKgPerShareWhite ?? season.MaxKgPerShare ?? 0),
deliveredWeightWhite, isGa: true, showPayment: includePayment, showArea: !includeDelivery, isTiny: isTiny));
}
if (fbs.Any()) { if (fbs.Any()) {
tbl.AddCell(NewBucketSubHdr("Flächenbindungen" + (vtr.Any() ? " (inkl. Verträge)" : "") + ":", includePayment ? 8 : 7, isTiny: isTiny)); tbl.AddCell(NewBucketSubHdr("Flächenbindungen" + (vtr.Any() ? " (inkl. Verträge)" : "") + ":", includePayment ? 8 : 7, isTiny: isTiny));
+14 -6
View File
@@ -86,19 +86,27 @@ namespace Elwig.Documents {
} }
if (ConsiderTotalPenalty) { if (ConsiderTotalPenalty) {
var total = _data.Rows.SelectMany(r => r.Buckets).Sum(b => b.Value); var weights = _data.Rows.Select(r => new {r.Type, Weight = r.Buckets.Sum(b => b.Value)}).GroupBy(r => r.Type).ToDictionary(r => r.Key, g => g.Sum(r => r.Weight));
var totalUnderDelivery = total - Member.BusinessShares * season.MinKgPerBusinessShare; var red = weights.GetValueOrDefault("R", 0);
MemberTotalUnderDelivery = totalUnderDelivery < 0 ? totalUnderDelivery * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerBsAmount * Math.Floor(-(decimal)totalUnderDelivery / season.MinKgPerBusinessShare) ?? 0) : 0; var white = weights.GetValueOrDefault("W", 0);
var total = red + white;
var underDeliveryTotal = total - Member.Shares * (season.MinKgPerShare ?? 0);
var underDeliveryRed = red - Member.SharesRed * (season.MinKgPerShareRed ?? season.MinKgPerShare ?? 0);
var underDeliveryWhite = white - Member.SharesWhite * (season.MinKgPerShareWhite ?? season.MinKgPerShare ?? 0);
MemberTotalUnderDelivery =
(underDeliveryTotal < 0 ? underDeliveryTotal * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerShareAmount * Math.Floor(-(decimal)underDeliveryTotal / (season.MinKgPerShare ?? 0)) ?? 0) : 0) +
(underDeliveryRed < 0 ? underDeliveryRed * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerShareAmount * Math.Floor(-(decimal)underDeliveryRed / (season.MinKgPerShareRed ?? season.MinKgPerShare ?? 0)) ?? 0) : 0) +
(underDeliveryWhite < 0 ? underDeliveryWhite * (season.PenaltyPerKg ?? 0) - (season.PenaltyAmount ?? 0) - (season.PenaltyPerShareAmount * Math.Floor(-(decimal)underDeliveryWhite / (season.MinKgPerShareWhite ?? season.MinKgPerShare ?? 0)) ?? 0) : 0);
if (total == 0) if (total == 0)
MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0) + (season.PenaltyPerBsNone * Member.BusinessShares ?? 0); MemberTotalUnderDelivery -= (season.PenaltyNone ?? 0) + (season.PenaltyPerShareNone * (Member.Shares + Member.SharesRed + Member.SharesWhite) ?? 0);
} }
if (ConsiderAutoBusinessShares) { if (ConsiderAutoBusinessShares) {
var fromDate = $"{season.Year}-01-01"; var fromDate = $"{season.Year}-01-01";
var toDate = $"{season.Year}-12-31"; var toDate = $"{season.Year}-12-31";
MemberAutoBusinessShares = await ctx.MemberHistory MemberAutoBusinessShares = await ctx.MemberHistory
.Where(h => h.MgNr == Member.MgNr && h.Type == "auto") .Where(h => h.ToMgNr == Member.MgNr && h.Reason == "auto")
.Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) <= 0) .Where(h => h.DateString.CompareTo(fromDate) >= 0 && h.DateString.CompareTo(toDate) <= 0)
.SumAsync(h => h.BusinessShares); .SumAsync(h => h.Shares);
MemberAutoBusinessSharesAmount = MemberAutoBusinessShares * (-season.BusinessShareValue ?? 0); MemberAutoBusinessSharesAmount = MemberAutoBusinessShares * (-season.BusinessShareValue ?? 0);
} }
if (ConsiderContractPenalties) { if (ConsiderContractPenalties) {
+9 -4
View File
@@ -18,7 +18,8 @@ namespace Elwig.Documents {
private readonly int _year; private readonly int _year;
public Season? Season; public Season? Season;
public int MemberDeliveredWeight; public int MemberDeliveredWeightRed;
public int MemberDeliveredWeightWhite;
public DeliveryConfirmationDeliveryData? 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 = [];
@@ -36,10 +37,14 @@ namespace Elwig.Documents {
protected override async Task LoadData(AppDbContext ctx) { protected override async Task LoadData(AppDbContext ctx) {
await base.LoadData(ctx); await base.LoadData(ctx);
Season = await ctx.FetchSeasons(_year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season"); Season = await ctx.FetchSeasons(_year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
MemberDeliveredWeight = await ctx.Deliveries var weights = await ctx.Deliveries
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr) .Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
.SelectMany(d => d.Parts) .SelectMany(d => d.Parts)
.SumAsync(p => p.Weight); .GroupBy(p => p.Variety.Type)
.ToDictionaryAsync(g => g.Key, g => g.Sum(p => p.Weight));
MemberDeliveredWeightRed = weights.GetValueOrDefault("R", 0);
MemberDeliveredWeightWhite = weights.GetValueOrDefault("W", 0);
MemberHistory = await ctx.GetMemberHistory(Season.Year, Member.MgNr);
MemberBuckets = await ctx.GetMemberBuckets(Season.Year, Member.MgNr); MemberBuckets = await ctx.GetMemberBuckets(Season.Year, Member.MgNr);
MemberStats = await AppDbContext.GetMemberStats(Season.Year, Member.MgNr); MemberStats = await AppDbContext.GetMemberStats(Season.Year, Member.MgNr);
Data ??= await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, Season.Year, Member); Data ??= await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, Season.Year, Member);
@@ -63,7 +68,7 @@ namespace Elwig.Documents {
doc.Add(NewDeliveryListTable(Data)); doc.Add(NewDeliveryListTable(Data));
doc.Add(NewWeightsTable(MemberStats) doc.Add(NewWeightsTable(MemberStats)
.SetMarginTopMM(10).SetKeepTogether(true)); .SetMarginTopMM(10).SetKeepTogether(true));
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeight, includePayment: true) doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeightRed, MemberDeliveredWeightWhite, includePayment: true)
.SetMarginTopMM(10).SetKeepTogether(true)); .SetMarginTopMM(10).SetKeepTogether(true));
if (Text != null) { if (Text != null) {
+9 -4
View File
@@ -19,7 +19,8 @@ namespace Elwig.Documents {
public Delivery Delivery; public Delivery Delivery;
public string? Text; public string? Text;
public int MemberDeliveredWeight; public int MemberDeliveredWeightRed;
public int MemberDeliveredWeightWhite;
public Dictionary<string, MemberBucket> MemberBuckets = []; public Dictionary<string, MemberBucket> MemberBuckets = [];
// 0 - none // 0 - none
@@ -59,9 +60,13 @@ namespace Elwig.Documents {
protected override async Task LoadData(AppDbContext ctx) { protected override async Task LoadData(AppDbContext ctx) {
await base.LoadData(ctx); await base.LoadData(ctx);
MemberDeliveredWeight = await ctx.DeliveryParts var weights = await ctx.DeliveryParts
.Where(d => d.Year == Delivery.Year && d.Delivery.MgNr == Member.MgNr) .Where(d => d.Year == Delivery.Year && d.Delivery.MgNr == Member.MgNr)
.SumAsync(p => p.Weight); .GroupBy(p => p.Variety.Type)
.ToDictionaryAsync(g => g.Key, g => g.Sum(p => p.Weight));
MemberDeliveredWeightRed = weights.GetValueOrDefault("R", 0);
MemberDeliveredWeightWhite = weights.GetValueOrDefault("W", 0);
MemberHistory = await ctx.GetMemberHistory(Delivery.Year, Member.MgNr);
MemberBuckets = await ctx.GetMemberBuckets(Delivery.Year, Member.MgNr) ?? []; MemberBuckets = await ctx.GetMemberBuckets(Delivery.Year, Member.MgNr) ?? [];
} }
@@ -81,7 +86,7 @@ namespace Elwig.Documents {
doc.Add(new KernedParagraph($"Anmerkung zur Lieferung: {Delivery.Comment}", 10).SetMarginsMM(5, 0, 0, 0)); doc.Add(new KernedParagraph($"Anmerkung zur Lieferung: {Delivery.Comment}", 10).SetMarginsMM(5, 0, 0, 0));
} }
if (DisplayStats > 0) { if (DisplayStats > 0) {
doc.Add(NewBucketTable(Delivery.Season, MemberBuckets, MemberDeliveredWeight, isTiny: true, doc.Add(NewBucketTable(Delivery.Season, MemberBuckets, MemberDeliveredWeightRed, MemberDeliveredWeightWhite, isTiny: true,
filter: DisplayStats > 2 ? null : DisplayStats == 1 ? [] : Delivery.Parts.Select(p => p.SortId).Distinct().ToList()) filter: DisplayStats > 2 ? null : DisplayStats == 1 ? [] : Delivery.Parts.Select(p => p.SortId).Distinct().ToList())
.SetKeepTogether(true) .SetKeepTogether(true)
.SetMarginsMM(5, 0, 0, 0)); .SetMarginsMM(5, 0, 0, 0));
+12 -5
View File
@@ -18,7 +18,8 @@ namespace Elwig.Documents {
public new static string Name => "Stammdatenblatt"; public new static string Name => "Stammdatenblatt";
public Season? Season; public Season? Season;
public int MemberDeliveredWeight; public int MemberDeliveredWeightRed;
public int MemberDeliveredWeightWhite;
public Dictionary<string, MemberBucket> MemberBuckets = []; public Dictionary<string, MemberBucket> MemberBuckets = [];
public List<AreaCom> ActiveAreaCommitments = []; public List<AreaCom> ActiveAreaCommitments = [];
@@ -40,17 +41,20 @@ namespace Elwig.Documents {
ActiveAreaCommitments = await Member.ActiveAreaCommitments(ctx) ActiveAreaCommitments = await Member.ActiveAreaCommitments(ctx)
.Include(c => c.Contract).ThenInclude(c => c.Revisions) .Include(c => c.Contract).ThenInclude(c => c.Revisions)
.ToListAsync(); .ToListAsync();
MemberDeliveredWeight = await ctx.Deliveries var weights = await ctx.Deliveries
.Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr) .Where(d => d.Year == Season.Year && d.MgNr == Member.MgNr)
.SelectMany(d => d.Parts) .SelectMany(d => d.Parts)
.SumAsync(p => p.Weight); .GroupBy(p => p.Variety.Type)
.ToDictionaryAsync(g => g.Key, g => g.Sum(p => p.Weight));
MemberDeliveredWeightRed = weights.GetValueOrDefault("R", 0);
MemberDeliveredWeightWhite = weights.GetValueOrDefault("W", 0);
} }
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) { protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
if (Season == null) throw new Exception("Call LoadData before RenderBody"); if (Season == null) throw new Exception("Call LoadData before RenderBody");
base.RenderBody(doc, pdf); base.RenderBody(doc, pdf);
doc.Add(NewMemberData(Season).SetMarginBottomMM(5)); doc.Add(NewMemberData(Season).SetMarginBottomMM(5));
doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeight, includeDelivery: false)); doc.Add(NewBucketTable(Season, MemberBuckets, MemberDeliveredWeightRed, MemberDeliveredWeightWhite, includeDelivery: false));
if (ActiveAreaCommitments.Count != 0) { if (ActiveAreaCommitments.Count != 0) {
bool firstOnPage = false; bool firstOnPage = false;
if (pdf.GetNumberOfPages() == 1) { if (pdf.GetNumberOfPages() == 1) {
@@ -132,6 +136,9 @@ namespace Elwig.Documents {
.AddCell(NewTd(i < subTbl2.Count ? subTbl2[i][1] : "", colspan: 2)); .AddCell(NewTd(i < subTbl2.Count ? subTbl2[i][1] : "", colspan: 2));
} }
var shares = (Member.Shares != 0 || (Member.SharesRed == 0 && Member.SharesWhite == 0) ? $"{Member.Shares:N0}" : "") +
(Member.SharesRed != 0 || Member.SharesWhite != 0 ? (Member.Shares != 0 ? " / " : "") + $"{Member.SharesRed:N0} (rot) / {Member.SharesWhite:N0} (weiß)" : "") +
(Member.SharesDormant != 0 ? $" / {Member.SharesDormant:N0} (ruhend)" : "");
tbl.AddCell(NewDataHdr("Betrieb", colspan: 6)) tbl.AddCell(NewDataHdr("Betrieb", colspan: 6))
.AddCell(NewDataTh("Betriebs-Nr.:")).AddCell(NewTd(Member.LfbisNr)) .AddCell(NewDataTh("Betriebs-Nr.:")).AddCell(NewTd(Member.LfbisNr))
.AddCell(NewDataTh("UID:", colspan: 2)).AddCell(NewTd(Member.UstIdNr, colspan: 2)) .AddCell(NewDataTh("UID:", colspan: 2)).AddCell(NewTd(Member.UstIdNr, colspan: 2))
@@ -143,7 +150,7 @@ namespace Elwig.Documents {
.AddCell(NewDataHdr("Genossenschaft", colspan: 6)) .AddCell(NewDataHdr("Genossenschaft", colspan: 6))
.AddCell(NewDataTh("Status:")).AddCell(NewTd(new KernedParagraph(Member.IsActive ? "Aktiv " : "Nicht aktiv ", 10) .AddCell(NewDataTh("Status:")).AddCell(NewTd(new KernedParagraph(Member.IsActive ? "Aktiv " : "Nicht aktiv ", 10)
.Add(Normal("(" + (Member.ExitDate != null ? $"{Member.EntryDate:dd.MM.yyyy}\u2013{Member.ExitDate:dd.MM.yyyy}" : $"seit {Member.EntryDate:dd.MM.yyyy}") + ")", 8)))) .Add(Normal("(" + (Member.ExitDate != null ? $"{Member.EntryDate:dd.MM.yyyy}\u2013{Member.ExitDate:dd.MM.yyyy}" : $"seit {Member.EntryDate:dd.MM.yyyy}") + ")", 8))))
.AddCell(NewDataTh("Geschäftsanteile:", colspan: 2)).AddCell(NewTd($"{Member.BusinessShares:N0}", colspan: 2)) .AddCell(NewDataTh("Geschäftsanteile:", colspan: 2)).AddCell(NewTd(shares, colspan: 2))
.AddCell(NewDataTh("Stamm-Zweigstelle:")).AddCell(NewTd(Member.Branch?.Name)) .AddCell(NewDataTh("Stamm-Zweigstelle:")).AddCell(NewTd(Member.Branch?.Name))
.AddCell(NewDataTh("Volllieferant:", colspan: 2)).AddCell(NewTd(Member.IsVollLieferant ? "Ja" : "Nein", colspan: 2)) .AddCell(NewDataTh("Volllieferant:", colspan: 2)).AddCell(NewTd(Member.IsVollLieferant ? "Ja" : "Nein", colspan: 2))
.AddCell(NewDataTh("Zusendungen per\u2026")).AddCell(NewTd(new KernedParagraph(10) .AddCell(NewDataTh("Zusendungen per\u2026")).AddCell(NewTd(new KernedParagraph(10)
+1 -1
View File
@@ -86,7 +86,7 @@ namespace Elwig.Documents {
.AddCell(NewTd($"{m.Plz}", 8)) .AddCell(NewTd($"{m.Plz}", 8))
.AddCell(NewTd(m.Locality, 6)) .AddCell(NewTd(m.Locality, 6))
.AddCell(NewTd(m.LfbisNr ?? "", 8)) .AddCell(NewTd(m.LfbisNr ?? "", 8))
.AddCell(NewTd($"{m.BusinessShares:N0}", 8, right: true).SetPaddingLeft(0).SetPaddingRight(0)) .AddCell(NewTd($"{m.SharesTotal:N0}", 8, right: true).SetPaddingLeft(0).SetPaddingRight(0))
.AddCell(NewTd(m.DefaultKg ?? "", 6)); .AddCell(NewTd(m.DefaultKg ?? "", 6));
if (AreaComFilters.Length > 0) { if (AreaComFilters.Length > 0) {
foreach (var v in AreaComFilters) { foreach (var v in AreaComFilters) {
+30 -6
View File
@@ -1,10 +1,9 @@
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ScottPlot.TickGenerators.Financial;
using ScottPlot.TickGenerators.TimeUnits;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data; using System.Data;
@@ -12,11 +11,10 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Converters;
namespace Elwig.Helpers { namespace Elwig.Helpers {
public record struct MemberHistoryPoint(int Shares, int SharesRed, int SharesWhite, int SharesDormant);
public record struct AreaComBucket(int Area, int Obligation, int Right); public record struct AreaComBucket(int Area, int Obligation, int Right);
public record struct UnderDelivery(int Weight, int Diff); public record struct UnderDelivery(int Weight, int Diff);
public record struct MemberBucket(string Name, int Area, int Obligation, int Right, int Delivery, int DeliveryStrict, int DeliveryTotal, int Payment); public record struct MemberBucket(string Name, int Area, int Obligation, int Right, int Delivery, int DeliveryStrict, int DeliveryTotal, int Payment);
@@ -149,6 +147,7 @@ namespace Elwig.Helpers {
.Include(s => s.Modifiers) .Include(s => s.Modifiers)
.OrderByDescending(s => s.Year)); .OrderByDescending(s => s.Year));
private readonly Dictionary<int, Dictionary<int, MemberHistoryPoint>> _memberHistory = [];
private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = []; private readonly Dictionary<int, Dictionary<int, Dictionary<string, AreaComBucket>>> _memberAreaCommitmentBuckets = [];
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = []; private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = [];
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = []; private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBucketsStrict = [];
@@ -162,8 +161,8 @@ namespace Elwig.Helpers {
LogFile = new(file) { LogFile = new(file) {
AutoFlush = true AutoFlush = true
}; };
} catch (Exception e) { } catch (Exception exc) {
MessageBox.Show($"Unable to open database log file:\n\n{e.Message}", "Database Log", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Database Log", $"Unable to open database log file", exc);
} }
} }
SavedLastWriteTime = LastWriteTime; SavedLastWriteTime = LastWriteTime;
@@ -233,6 +232,9 @@ namespace Elwig.Helpers {
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Schedule).AutoInclude(); modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Schedule).AutoInclude();
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Variety).AutoInclude(); modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Variety).AutoInclude();
modelBuilder.Entity<DeliverySchedule>().Navigation(s => s.Branch).AutoInclude(); modelBuilder.Entity<DeliverySchedule>().Navigation(s => s.Branch).AutoInclude();
modelBuilder.Entity<MemberHistory>().Navigation(s => s.FromMember).AutoInclude();
modelBuilder.Entity<MemberHistory>().Navigation(s => s.ToMember).AutoInclude();
modelBuilder.Entity<MemberHistory>().Navigation(s => s.Currency).AutoInclude();
} }
public override void Dispose() { public override void Dispose() {
@@ -400,6 +402,22 @@ namespace Elwig.Helpers {
} }
} }
private async Task FetchMemberHistory(int year, SqliteConnection? cnx = null) {
var ownCnx = cnx == null;
cnx ??= await ConnectAsync();
var history = new Dictionary<int, MemberHistoryPoint>();
using (var cmd = cnx.CreateCommand()) {
cmd.CommandText = $"SELECT mgnr, shares, shares_red, shares_white, shares_dormant FROM v_member_history WHERE year = {year}";
using var reader = await cmd.ExecuteReaderAsync();
while (await reader.ReadAsync()) {
var mgnr = reader.GetInt32(0);
history[mgnr] = new(reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3), reader.GetInt32(4));
}
}
if (ownCnx) await cnx.DisposeAsync();
_memberHistory[year] = history;
}
private async Task FetchMemberAreaCommitmentBuckets(int year, SqliteConnection? cnx = null) { private async Task FetchMemberAreaCommitmentBuckets(int year, SqliteConnection? cnx = null) {
var ownCnx = cnx == null; var ownCnx = cnx == null;
cnx ??= await ConnectAsync(); cnx ??= await ConnectAsync();
@@ -490,6 +508,12 @@ namespace Elwig.Helpers {
_memberUnderDelivery[year] = buckets; _memberUnderDelivery[year] = buckets;
} }
public async Task<MemberHistoryPoint> GetMemberHistory(int year, int mgnr, SqliteConnection? cnx = null) {
if (!_memberHistory.ContainsKey(year))
await FetchMemberHistory(year, cnx);
return _memberHistory[year].GetValueOrDefault(mgnr, new());
}
public async Task<Dictionary<string, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) { public async Task<Dictionary<string, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
if (!_memberAreaCommitmentBuckets.ContainsKey(year)) if (!_memberAreaCommitmentBuckets.ContainsKey(year))
await FetchMemberAreaCommitmentBuckets(year, cnx); await FetchMemberAreaCommitmentBuckets(year, cnx);
+49 -39
View File
@@ -1,6 +1,6 @@
using Microsoft.Data.Sqlite;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -9,36 +9,41 @@ 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 = 39; public static readonly int RequiredSchemaVersion = 40;
private static int VersionOffset = 0; private static int VersionOffset = 0;
public static async Task<Version> CheckDb() { public static async Task<Version> CheckDb() {
using var cnx = AppDbContext.Connect(); long? applId, schemaVers;
using (var cnx = await AppDbContext.ConnectAsync()) {
applId = (long?)await cnx.ExecuteScalar("PRAGMA application_id") ?? 0;
if (applId != 0x454C5747) throw new Exception($"Invalid application_id in database (0x{applId:X08})");
var applId = (long?)await cnx.ExecuteScalar("PRAGMA application_id") ?? 0; schemaVers = (long?)await cnx.ExecuteScalar("PRAGMA schema_version") ?? 0;
if (applId != 0x454C5747) throw new Exception($"Invalid application_id in database (0x{applId:X08})"); VersionOffset = (int)(schemaVers % 100);
if (VersionOffset != 0) {
var schemaVers = (long?)await cnx.ExecuteScalar("PRAGMA schema_version") ?? 0; // schema was modified manually/externally
VersionOffset = (int)(schemaVers % 100); // TODO issue warning
if (VersionOffset != 0) { }
// schema was modified manually/externally
// TODO issue warning
} }
await UpdateDbSchema(cnx, (int)(schemaVers / 100), RequiredSchemaVersion);
var userVers = (long?)await cnx.ExecuteScalar("PRAGMA user_version") ?? 0; await UpdateDbSchema((int)(schemaVers / 100), RequiredSchemaVersion);
var v = new Version((int)(userVers >> 24), (int)((userVers >> 16) & 0xFF), (int)((userVers >> 8) & 0xFF), (int)(userVers & 0xFF));
if (App.Version > v) { Version v;
long vers = (App.Version.Major << 24) | (App.Version.Minor << 16) | (App.Version.Build << 8) | App.Version.Revision; using (var cnx = await AppDbContext.ConnectAsync()) {
await cnx.ExecuteBatch($"PRAGMA user_version = {vers}"); var userVers = (long?)await cnx.ExecuteScalar("PRAGMA user_version") ?? 0;
v = new Version((int)(userVers >> 24), (int)((userVers >> 16) & 0xFF), (int)((userVers >> 8) & 0xFF), (int)(userVers & 0xFF));
if (App.Version > v) {
long vers = (App.Version.Major << 24) | (App.Version.Minor << 16) | (App.Version.Build << 8) | App.Version.Revision;
await cnx.ExecuteBatch($"PRAGMA user_version = {vers}");
}
} }
return v; return v;
} }
private static async Task UpdateDbSchema(SqliteConnection cnx, int fromVersion, int toVersion) { private static async Task UpdateDbSchema(int fromVersion, int toVersion) {
if (fromVersion == toVersion) { if (fromVersion == toVersion) {
return; return;
} else if (fromVersion > toVersion) { } else if (fromVersion > toVersion) {
@@ -48,43 +53,48 @@ namespace Elwig.Helpers {
} }
var asm = Assembly.GetExecutingAssembly(); var asm = Assembly.GetExecutingAssembly();
(int From, int To, string Name)[] scripts = asm.GetManifestResourceNames() (int From, int To, string Name)[] scripts = [.. asm.GetManifestResourceNames()
.Where(n => n.StartsWith("Elwig.Resources.Sql.")) .Where(n => n.StartsWith("Elwig.Resources.Sql."))
.Select(n => { .Select(n => {
var p = n.Split(".")[^2].Split("-"); var p = n.Split(".")[^2].Split("-");
return (int.Parse(p[0]), int.Parse(p[1]), n); return (int.Parse(p[0]), int.Parse(p[1]), n);
}) })
.OrderBy(s => s.Item1).ThenBy(s => s.Item2) .OrderBy(s => s.Item1).ThenBy(s => s.Item2)];
.ToArray();
List<string> toExecute = []; List<string> toExecute = [];
var vers = fromVersion; var vers = fromVersion;
while (vers < toVersion) { while (vers < toVersion) {
var (_, to, name) = scripts.Where(s => s.From == vers).Last(); var (_, to, name) = scripts.Last(s => s.From == vers);
toExecute.Add(name); toExecute.Add(name);
vers = to; vers = to;
} }
if (toExecute.Count == 0) if (toExecute.Count == 0)
return; return;
await cnx.ExecuteBatch(""" var backup = Path.ChangeExtension(App.Config.DatabaseFile, $".v{fromVersion}.sqlite3");
PRAGMA locking_mode = EXCLUSIVE; File.Copy(App.Config.DatabaseFile, backup, true);
BEGIN EXCLUSIVE; try {
"""); using var cnx = await AppDbContext.ConnectAsync();
foreach (var script in toExecute) { await cnx.ExecuteBatch("PRAGMA locking_mode = EXCLUSIVE");
await cnx.ExecuteEmbeddedScript(asm, script); foreach (var script in toExecute) {
} await cnx.ExecuteEmbeddedScript(asm, script);
var violations = await cnx.ForeignKeyCheck(); }
if (violations.Length > 0) {
throw new Exception($"Foreign key violations ({violations.Length}):\n" + string.Join("\n", violations
.Select(v => $"{v.Table} - {v.RowId} - {v.Parent} - {v.FkId}")));
}
await cnx.ExecuteBatch($""" var violations = await cnx.ForeignKeyCheck();
COMMIT; if (violations.Length > 0) {
VACUUM; throw new Exception($"Foreign key violations ({violations.Length}):\n" + string.Join("\n", violations
PRAGMA schema_version = {toVersion * 100 + VersionOffset}; .Take(50)
"""); .Select(v => $"{v.Table} - {v.RowId} - {v.Parent} - {v.FkId}")));
}
await cnx.ExecuteBatch("VACUUM");
await cnx.ExecuteBatch($"PRAGMA schema_version = {toVersion * 100 + VersionOffset}");
} catch (Exception) {
File.Move(backup, App.Config.DatabaseFile, true);
throw;
} finally {
File.Delete(backup);
}
} }
} }
} }
+12 -28
View File
@@ -50,45 +50,29 @@ namespace Elwig.Helpers.Billing {
"""); """);
} }
public async Task AutoAdjustBusinessShares(DateOnly date, int allowanceKg = 0, double allowanceBs = 0, int allowanceKgPerBs = 0, double allowanceRel = 0, int addMinBs = 1) { public async Task AutoAdjustBusinessShares(DateOnly date, int allowanceKg = 0, double allowanceShares = 0, int allowanceKgPerShare = 0, double allowanceRel = 0, int addMinShares = 1) {
if (addMinBs < 1) addMinBs = 1; if (addMinShares < 1) addMinShares = 1;
using var cnx = await AppDbContext.ConnectAsync(); using var cnx = await AppDbContext.ConnectAsync();
await cnx.ExecuteBatch($""" await cnx.ExecuteBatch($"""
UPDATE member DELETE FROM member_history WHERE source = 'elwig' AND reason = 'auto' AND SUBSTR(date, 1, 4) = '{Year}';
SET business_shares = member.business_shares - h.business_shares INSERT INTO member_history (histnr, from_mgnr, from_type, to_mgnr, to_type, date, reason, source, shares, value_per_share, currency)
FROM member_history h SELECT COALESCE((SELECT MAX(histnr) AS histnr FROM member_history), 0) + ROW_NUMBER() OVER(ORDER BY m.mgnr),
WHERE h.date = '{Year}-11-30' AND h.type = 'auto' AND h.mgnr = member.mgnr AND member.active; NULL, NULL, u.mgnr, 1, '{date:yyyy-MM-dd}', 'auto', 'elwig',
CEIL((u.diff - {allowanceKg}.0 - {allowanceKgPerShare}.0 * u.shares) / s.max_kg_per_share
INSERT INTO member_history (mgnr, date, type, business_shares) - {allowanceShares.ToString(CultureInfo.InvariantCulture)}
SELECT u.mgnr, - {allowanceRel.ToString(CultureInfo.InvariantCulture)} * u.shares) AS adjust_shares,
'{date:yyyy-MM-dd}', s.share_value / POW(10, s.precision - 2), s.currency
'auto',
CEIL((u.diff - {allowanceKg}.0 - {allowanceKgPerBs}.0 * u.business_shares) / s.max_kg_per_bs
- {allowanceBs.ToString(CultureInfo.InvariantCulture)}
- {allowanceRel.ToString(CultureInfo.InvariantCulture)} * u.business_shares) AS bs
FROM v_total_under_delivery u FROM v_total_under_delivery u
JOIN season s ON s.year = u.year JOIN season s ON s.year = u.year
JOIN member m ON m.mgnr = u.mgnr JOIN member m ON m.mgnr = u.mgnr
WHERE s.year = {Year} AND bs >= {addMinBs} AND m.active WHERE s.year = {Year} AND adjust_shares >= {addMinShares} AND m.active
ON CONFLICT DO UPDATE
SET business_shares = excluded.business_shares;
UPDATE member
SET business_shares = member.business_shares + h.business_shares
FROM member_history h
WHERE h.date = '{Year}-11-30' AND h.type = 'auto' AND h.mgnr = member.mgnr;
"""); """);
} }
public async Task UnAdjustBusinessShares() { public async Task UnAdjustBusinessShares() {
using var cnx = await AppDbContext.ConnectAsync(); using var cnx = await AppDbContext.ConnectAsync();
await cnx.ExecuteBatch($""" await cnx.ExecuteBatch($"""
UPDATE member DELETE FROM member_history WHERE source = 'elwig' AND reason = 'auto' AND SUBSTR(date, 1, 4) = '{Year}';
SET business_shares = member.business_shares - h.business_shares
FROM member_history h
WHERE h.date = '{Year}-11-30' AND h.type = 'auto' AND h.mgnr = member.mgnr AND member.active;
DELETE FROM member_history WHERE date = '{Year}-11-30' AND type = 'auto';
"""); """);
} }
+5 -5
View File
@@ -76,7 +76,7 @@ namespace Elwig.Helpers.Billing {
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(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) + ROUND(IIF({Data.ConsiderTotalPenalty}, COALESCE(b.total_penalty, 0), 0) / POW(10, s.precision - 2)) +
ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) + ROUND(IIF({Data.ConsiderContractPenalties}, COALESCE(u.total_penalty, 0), 0) / POW(10, 4 - 2)) +
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0) / POW(10, s.precision - 2)) + ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0)) +
IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0) IIF({Data.ConsiderCustomModifiers}, COALESCE(x.amount, 0), 0)
AS modifiers, AS modifiers,
IIF(lc.amount < 0, 0, lc.modifiers) AS prev_modifiers IIF(lc.amount < 0, 0, lc.modifiers) AS prev_modifiers
@@ -137,11 +137,11 @@ namespace Elwig.Helpers.Billing {
await cnx.ExecuteBatch($""" await cnx.ExecuteBatch($"""
INSERT INTO payment_member (year, avnr, mgnr, net_amount, mod_abs, mod_rel) INSERT INTO payment_member (year, avnr, mgnr, net_amount, mod_abs, mod_rel)
SELECT c.year, {AvNr}, s.mgnr, 0, SELECT c.year, {AvNr}, s.mgnr, 0,
ROUND(s.sum * COALESCE(m.abs, 0)), ROUND(s.weight_total * COALESCE(m.abs, 0)),
COALESCE(m.rel, 0) COALESCE(m.rel, 0)
FROM (SELECT {Year} AS year, m.mgnr, FROM (SELECT {Year} AS year, m.mgnr,
ROUND(AVG(COALESCE(a.sum, b.sum)) * {multiplier}) AS baseline, ROUND(AVG(COALESCE(a.weight_total, b.weight_total)) * {multiplier}) AS baseline,
COUNT(*) = {lastYears} AND MIN(COALESCE(a.sum, b.sum)) > 0 AS allowed COUNT(*) = {lastYears} AND MIN(COALESCE(a.weight_total, b.weight_total)) > 0 AS allowed
FROM member m FROM member m
LEFT JOIN v_stat_member a ON a.mgnr = m.mgnr LEFT JOIN v_stat_member a ON a.mgnr = m.mgnr
FULL OUTER JOIN v_stat_member b ON b.mgnr = m.predecessor_mgnr AND b.year = a.year AND {(includePredecessor ? "TRUE" : "FALSE")} FULL OUTER JOIN v_stat_member b ON b.mgnr = m.predecessor_mgnr AND b.year = a.year AND {(includePredecessor ? "TRUE" : "FALSE")}
@@ -150,7 +150,7 @@ namespace Elwig.Helpers.Billing {
HAVING allowed) c HAVING allowed) c
JOIN v_stat_member s ON (s.year, s.mgnr) = (c.year, c.mgnr) JOIN v_stat_member s ON (s.year, s.mgnr) = (c.year, c.mgnr)
LEFT JOIN modifier m ON m.year = c.year AND m.name LIKE '{modName}' LEFT JOIN modifier m ON m.year = c.year AND m.name LIKE '{modName}'
WHERE sum >= baseline WHERE weight_total >= baseline
ON CONFLICT DO UPDATE ON CONFLICT DO UPDATE
SET mod_abs = mod_abs + excluded.mod_abs, SET mod_abs = mod_abs + excluded.mod_abs,
mod_rel = mod_rel + excluded.mod_rel mod_rel = mod_rel + excluded.mod_rel
+25 -5
View File
@@ -56,6 +56,10 @@ namespace Elwig.Helpers {
public string? EmailAddress; public string? EmailAddress;
public string? Website; public string? Website;
public bool EnableMemberHistory;
public int ModeBusinessShares;
public bool HasRedWhite => ModeBusinessShares == 1;
public int ModeDeliveryNoteStats; public int ModeDeliveryNoteStats;
public int ModeWineQualityStatistics; public int ModeWineQualityStatistics;
public int OrderingMemberList; public int OrderingMemberList;
@@ -75,7 +79,7 @@ namespace Elwig.Helpers {
public int ExportEbicsVersion; public int ExportEbicsVersion;
public int ExportEbicsAddress; public int ExportEbicsAddress;
public (int? AllowanceKg, double? AllowanceBs, int? AllowanceKgPerBs, double? AllowancePercent, int? MinBs) AutoAdjustBs; public (int? AllowanceKg, double? AllowanceShares, int? AllowanceKgPerShare, double? AllowancePercent, int? MinShares) AutoAdjustShares;
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)) { }
@@ -112,6 +116,15 @@ namespace Elwig.Helpers {
Iban = parameters.GetValueOrDefault("CLIENT_IBAN"); Iban = parameters.GetValueOrDefault("CLIENT_IBAN");
OrganicAuthority = parameters.GetValueOrDefault("CLIENT_ORGANIC_AUTHORITY"); OrganicAuthority = parameters.GetValueOrDefault("CLIENT_ORGANIC_AUTHORITY");
EnableMemberHistory = (parameters.GetValueOrDefault("ENABLE_MEMBERHISTORY")?.ToUpper()) switch {
"1" or "TRUE" or "YES" or "JA" => true,
_ => false,
};
switch (parameters.GetValueOrDefault("MODE_BUSINESSSHARES", "SIMPLE")?.ToUpper()) {
case "SIMPLE": ModeBusinessShares = 0; break;
case "RED_WHITE": ModeBusinessShares = 1; break;
}
switch (parameters.GetValueOrDefault("MODE_DELIVERYNOTE_STATS", "SHORT")?.ToUpper()) { switch (parameters.GetValueOrDefault("MODE_DELIVERYNOTE_STATS", "SHORT")?.ToUpper()) {
case "NONE": ModeDeliveryNoteStats = 0; break; case "NONE": ModeDeliveryNoteStats = 0; break;
case "GA_ONLY": ModeDeliveryNoteStats = 1; break; case "GA_ONLY": ModeDeliveryNoteStats = 1; break;
@@ -176,7 +189,7 @@ namespace Elwig.Helpers {
} }
var autoAdjust = (parameters.GetValueOrDefault("AUTOADJUST_BUSINESSSHARES") ?? "").Split(';'); var autoAdjust = (parameters.GetValueOrDefault("AUTOADJUST_BUSINESSSHARES") ?? "").Split(';');
AutoAdjustBs = autoAdjust.Length == 5 ? ( AutoAdjustShares = autoAdjust.Length == 5 ? (
int.TryParse(autoAdjust[0], out var v1) ? v1 : null, int.TryParse(autoAdjust[0], out var v1) ? v1 : null,
double.TryParse(autoAdjust[1], out var v2) ? v2 : null, double.TryParse(autoAdjust[1], out var v2) ? v2 : null,
int.TryParse(autoAdjust[2], out var v3) ? v3 : null, int.TryParse(autoAdjust[2], out var v3) ? v3 : null,
@@ -189,6 +202,11 @@ namespace Elwig.Helpers {
} }
private IEnumerable<(string, string?)> GetParamValues() { private IEnumerable<(string, string?)> GetParamValues() {
string businessShares = "SIMPLE";
switch (ModeBusinessShares) {
case 0: businessShares = "SIMPLE"; break;
case 1: businessShares = "RED_WHITE"; break;
}
string deliveryNoteStats = "SHORT"; string deliveryNoteStats = "SHORT";
switch (ModeDeliveryNoteStats) { switch (ModeDeliveryNoteStats) {
case 0: deliveryNoteStats = "NONE"; break; case 0: deliveryNoteStats = "NONE"; break;
@@ -235,9 +253,9 @@ namespace Elwig.Helpers {
case 1: exportEbicsAddress = "LINES"; break; case 1: exportEbicsAddress = "LINES"; break;
case 2: exportEbicsAddress = "FULL"; break; case 2: exportEbicsAddress = "FULL"; break;
} }
string autoAdjust = $"{AutoAdjustBs.AllowanceKg};{AutoAdjustBs.AllowanceBs?.ToString(CultureInfo.InvariantCulture)};" + string autoAdjust = $"{AutoAdjustShares.AllowanceKg};{AutoAdjustShares.AllowanceShares?.ToString(CultureInfo.InvariantCulture)};" +
$"{AutoAdjustBs.AllowanceKgPerBs};{AutoAdjustBs.AllowancePercent?.ToString(CultureInfo.InvariantCulture)};" + $"{AutoAdjustShares.AllowanceKgPerShare};{AutoAdjustShares.AllowancePercent?.ToString(CultureInfo.InvariantCulture)};" +
$"{AutoAdjustBs.MinBs}"; $"{AutoAdjustShares.MinShares}";
return [ return [
("CLIENT_NAME_TOKEN", NameToken), ("CLIENT_NAME_TOKEN", NameToken),
("CLIENT_NAME_SHORT", NameShort), ("CLIENT_NAME_SHORT", NameShort),
@@ -256,6 +274,8 @@ namespace Elwig.Helpers {
("CLIENT_BIC", Bic), ("CLIENT_BIC", Bic),
("CLIENT_IBAN", Iban), ("CLIENT_IBAN", Iban),
("CLIENT_ORGANIC_AUTHORITY", OrganicAuthority), ("CLIENT_ORGANIC_AUTHORITY", OrganicAuthority),
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
("MODE_BUSINESSSHARES", businessShares),
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats), ("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics), ("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics),
("ORDERING_MEMBERLIST", orderingMemberList), ("ORDERING_MEMBERLIST", orderingMemberList),
+95 -28
View File
@@ -1,4 +1,5 @@
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -8,7 +9,6 @@ using System.IO.Compression;
using System.Linq; using System.Linq;
using System.Text.Json.Nodes; using System.Text.Json.Nodes;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
namespace Elwig.Helpers.Export { namespace Elwig.Helpers.Export {
public static class ElwigData { public static class ElwigData {
@@ -59,6 +59,7 @@ namespace Elwig.Helpers.Export {
List<BillingAddr> BillingAddresses, List<BillingAddr> BillingAddresses,
List<MemberTelNr> TelephoneNumbers, List<MemberTelNr> TelephoneNumbers,
List<MemberEmailAddr> EmailAddresses, List<MemberEmailAddr> EmailAddresses,
List<MemberHistory> MemberHistory,
List<AreaCom> AreaCommitments, List<AreaCom> AreaCommitments,
List<AreaComContract> Contracts, List<AreaComContract> Contracts,
List<WbRd> Riede, List<WbRd> Riede,
@@ -76,7 +77,7 @@ namespace Elwig.Helpers.Export {
foreach (var filename in filenames) { foreach (var filename in filenames) {
try { try {
data.Add(new([], [], [], [], [], [], [], new([], [], [], [], [], new() { data.Add(new([], [], [], [], [], [], [], new([], [], [], [], [], [], new() {
["member"] = [], ["member"] = [],
["area_commitment_contract"] = [], ["area_commitment_contract"] = [],
["area_commitment"] = [], ["area_commitment"] = [],
@@ -142,6 +143,17 @@ namespace Elwig.Helpers.Export {
} }
} }
var historyJson = zip.GetEntry("member_history.json");
if (historyJson != null) {
using var reader = new StreamReader(historyJson.Open(), Utils.UTF8);
string? line;
while ((line = await reader.ReadLineAsync()) != null) {
var obj = JsonNode.Parse(line)!.AsObject();
var h = obj.ToMemberHistory();
r.MemberHistory.Add(h);
}
}
// legacy area commitments // legacy area commitments
var areaComsJson = zip.GetEntry("area_commitments.json"); var areaComsJson = zip.GetEntry("area_commitments.json");
if (areaComsJson != null) { if (areaComsJson != null) {
@@ -208,16 +220,11 @@ namespace Elwig.Helpers.Export {
exc is FileNotFoundException || exc is FileNotFoundException ||
exc is IOException) { exc is IOException) {
data.RemoveAt(data.Count - 1); data.RemoveAt(data.Count - 1);
var str = $"Die Elwig-Export-Datei '{Path.GetFileName(filename)}' konnte nicht verarbeitet werden und wird übersprungen.\n\n" + exc.Message; InteractionService.ShowException("Fehler beim Importieren", $"Die Elwig-Export-Datei '{Path.GetFileName(filename)}' konnte nicht verarbeitet werden und wird übersprungen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Fehler beim Importieren", MessageBoxButton.OK, MessageBoxImage.Error);
await AddImportedFiles(Path.GetFileName(filename)); await AddImportedFiles(Path.GetFileName(filename));
} catch (Exception exc) { } catch (Exception exc) {
data.RemoveAt(data.Count - 1); data.RemoveAt(data.Count - 1);
var str = $"Die Elwig-Export-Datei '{Path.GetFileName(filename)}' konnte nicht verarbeitet werden. Soll sie in Zukunft übersprungen werden?\n\n" + exc.Message; if (InteractionService.AskException("Fehler beim Importieren", $"Die Elwig-Export-Datei '{Path.GetFileName(filename)}' konnte nicht verarbeitet werden. Soll sie in Zukunft übersprungen werden?", exc)) {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
var r = MessageBox.Show(str, "Fehler beim Importieren", MessageBoxButton.YesNo, MessageBoxImage.Error, MessageBoxResult.No);
if (r == MessageBoxResult.Yes) {
await AddImportedFiles(Path.GetFileName(filename)); await AddImportedFiles(Path.GetFileName(filename));
} }
} }
@@ -227,7 +234,7 @@ namespace Elwig.Helpers.Export {
var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>(); var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>(); var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, areaCommitments, contracts, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) { foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, history, areaCommitments, contracts, riede, wbKgs, wbGls, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
var branch = branches[meta.ZwstId]; var branch = branches[meta.ZwstId];
var device = meta.Device; var device = meta.Device;
@@ -239,6 +246,12 @@ namespace Elwig.Helpers.Export {
.Select(k => k.KgNr) .Select(k => k.KgNr)
.ToListAsync(); .ToListAsync();
var histNrs = history.Select(h => h.HistNr).ToList();
var duplicateHistNrs = await ctx.MemberHistory
.Where(h => histNrs.Contains(h.HistNr))
.Select(h => h.HistNr)
.ToListAsync();
var mgnrs = members.Select(m => m.MgNr).ToList(); var mgnrs = members.Select(m => m.MgNr).ToList();
var duplicateMgNrs = await ctx.Members var duplicateMgNrs = await ctx.Members
.Where(m => mgnrs.Contains(m.MgNr)) .Where(m => mgnrs.Contains(m.MgNr))
@@ -328,6 +341,11 @@ namespace Elwig.Helpers.Export {
importedMembers.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, members.Count - n - o, meta.MemberFilters)); importedMembers.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, members.Count - n - o, meta.MemberFilters));
} }
if (importDuplicateMembers || importNewMembers) {
ctx.UpdateRange(history.Where(h => duplicateHistNrs.Contains(h.HistNr)));
ctx.AddRange(history.Where(h => !duplicateHistNrs.Contains(h.HistNr)));
}
if (importDuplicateContracts) { if (importDuplicateContracts) {
ctx.RemoveRange(ctx.AreaCommitments.IgnoreAutoIncludes().Where(c => duplicateFbNrs.Contains(c.FbNr))); ctx.RemoveRange(ctx.AreaCommitments.IgnoreAutoIncludes().Where(c => duplicateFbNrs.Contains(c.FbNr)));
ctx.UpdateRange(contracts.Where(c => duplicateFbNrs.Contains(c.FbNr))); ctx.UpdateRange(contracts.Where(c => duplicateFbNrs.Contains(c.FbNr)));
@@ -384,7 +402,9 @@ namespace Elwig.Helpers.Export {
importedDeliveries.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, deliveries.Count - n - o, meta.DeliveryFilters)); importedDeliveries.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, deliveries.Count - n - o, meta.DeliveryFilters));
} }
await ctx.Database.ExecuteSqlAsync($"UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS'");
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
await ctx.Database.ExecuteSqlAsync($"UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS'");
var primaryKeys = new Dictionary<string, string>() { var primaryKeys = new Dictionary<string, string>() {
["member"] = "mgnr, 0, 0", ["member"] = "mgnr, 0, 0",
@@ -411,7 +431,7 @@ namespace Elwig.Helpers.Export {
} }
App.HintContextChange(); App.HintContextChange();
MessageBox.Show( InteractionService.ShowInformation("Importieren erfolgreich",
$"Das importieren der Daten war erfolgreich!\n" + $"Das importieren der Daten war erfolgreich!\n" +
$"Folgendes wurde importiert:\n" + $"Folgendes wurde importiert:\n" +
string.Join("\n", [ string.Join("\n", [
@@ -433,37 +453,32 @@ namespace Elwig.Helpers.Export {
$" ({d.New} neu, {d.Overwritten} überschr., {d.NotImported} nicht importiert)\n" + $" ({d.New} neu, {d.Overwritten} überschr., {d.NotImported} nicht importiert)\n" +
$" Zwst.: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" + $" Zwst.: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
$" Filter: {d.Filters}") $" Filter: {d.Filters}")
]), ]));
"Importieren erfolgreich",
MessageBoxButton.OK, MessageBoxImage.Information);
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\nEvtl. muss die Datenbank manuell auf dieses Gerät kopieren werden.\n\n" + exc.Message; InteractionService.ShowException("Fehler beim Importieren", "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\nEvtl. muss die Datenbank manuell auf dieses Gerät kopieren werden", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Fehler beim Importieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
GC.Collect(); GC.Collect();
GC.WaitForPendingFinalizers(); GC.WaitForPendingFinalizers();
} }
private static bool ImportQuestion(string branch, string device, string subject, bool duplicate, int number) { private static bool ImportQuestion(string branch, string device, string subject, bool duplicate, int number) {
return MessageBox.Show( return InteractionService.AskQuestion($"{subject} importieren",
$"Sollen {number} {(duplicate ? "" : "neue ")}{subject} durch die Zweigstelle\n" + $"Sollen {number} {(duplicate ? "" : "neue ")}{subject} durch die Zweigstelle\n" +
$"{branch} (Gerät {device}) {(duplicate ? "überschrieben" : "importiert")} werden?", $"{branch} (Gerät {device}) {(duplicate ? "überschrieben" : "importiert")} werden?", true);
$"{subject} importieren",
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes
) == MessageBoxResult.Yes;
} }
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) { public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
return new ElwigExport { return new ElwigExport {
Members = (members, filters), Members = (members, filters),
History = (history, ["von exportierten Mitgliedern"]),
WbKgs = (wbKgs, ["von exportierten Mitgliedern"]), WbKgs = (wbKgs, ["von exportierten Mitgliedern"]),
}.Export(filename); }.Export(filename);
} }
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) { public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
return new ElwigExport { return new ElwigExport {
Members = (members, filters), Members = (members, filters),
History = (history, ["von exportierten Mitgliedern"]),
AreaComs = (areaComs, ["von exportierten Mitgliedern"]), AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
WbKgs = (wbKgs, ["von exportierten Mitgliedern und Flächenbindungen"]), WbKgs = (wbKgs, ["von exportierten Mitgliedern und Flächenbindungen"]),
}.Export(filename); }.Export(filename);
@@ -479,6 +494,7 @@ namespace Elwig.Helpers.Export {
public class ElwigExport { public class ElwigExport {
public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; } public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; }
public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; } public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; }
public (IEnumerable<MemberHistory> History, IEnumerable<string> Filters)? History { get; set; }
public (IEnumerable<AreaComContract> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; } public (IEnumerable<AreaComContract> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; }
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; } public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
@@ -498,17 +514,21 @@ namespace Elwig.Helpers.Export {
["zwstid"] = App.ZwstId, ["zwstid"] = App.ZwstId,
["device"] = Environment.MachineName, ["device"] = Environment.MachineName,
}; };
if (WbKgs != null) { if (WbKgs != null)
obj["wb_kgs"] = new JsonObject { obj["wb_kgs"] = new JsonObject {
["count"] = WbKgs.Value.WbKgs.Count(), ["count"] = WbKgs.Value.WbKgs.Count(),
["filters"] = new JsonArray(WbKgs.Value.Filters.Select(f => (JsonNode)f).ToArray()), ["filters"] = new JsonArray(WbKgs.Value.Filters.Select(f => (JsonNode)f).ToArray()),
}; };
}
if (Members != null) if (Members != null)
obj["members"] = new JsonObject { obj["members"] = new JsonObject {
["count"] = Members.Value.Members.Count(), ["count"] = Members.Value.Members.Count(),
["filters"] = new JsonArray(Members.Value.Filters.Select(f => (JsonNode)f).ToArray()), ["filters"] = new JsonArray(Members.Value.Filters.Select(f => (JsonNode)f).ToArray()),
}; };
if (History != null)
obj["member_history"] = new JsonObject {
["count"] = History.Value.History.Count(),
["filters"] = new JsonArray(History.Value.Filters.Select(f => (JsonNode)f).ToArray()),
};
if (AreaComs != null) if (AreaComs != null)
obj["area_commitment_contracts"] = new JsonObject { obj["area_commitment_contracts"] = new JsonObject {
["count"] = AreaComs.Value.AreaComs.Count(), ["count"] = AreaComs.Value.AreaComs.Count(),
@@ -539,6 +559,13 @@ namespace Elwig.Helpers.Export {
await writer.WriteLineAsync(m.ToJson().ToJsonString(Utils.JsonOpts)); await writer.WriteLineAsync(m.ToJson().ToJsonString(Utils.JsonOpts));
} }
} }
if (History != null) {
var json = zip.CreateEntry("member_history.json", CompressionLevel.SmallestSize);
using var writer = new StreamWriter(json.Open(), Utils.UTF8);
foreach (var h in History.Value.History) {
await writer.WriteLineAsync(h.ToJson().ToJsonString(Utils.JsonOpts));
}
}
if (AreaComs != null) { if (AreaComs != null) {
var json = zip.CreateEntry("area_commitment_contracts.json", CompressionLevel.SmallestSize); var json = zip.CreateEntry("area_commitment_contracts.json", CompressionLevel.SmallestSize);
using var writer = new StreamWriter(json.Open(), Utils.UTF8); using var writer = new StreamWriter(json.Open(), Utils.UTF8);
@@ -597,7 +624,10 @@ namespace Elwig.Helpers.Export {
["birthday"] = m.Birthday, ["birthday"] = m.Birthday,
["entry_date"] = m.EntryDate != null ? $"{m.EntryDate:yyyy-MM-dd}" : null, ["entry_date"] = m.EntryDate != null ? $"{m.EntryDate:yyyy-MM-dd}" : null,
["exit_date"] = m.ExitDate != null ? $"{m.ExitDate:yyyy-MM-dd}" : null, ["exit_date"] = m.ExitDate != null ? $"{m.ExitDate:yyyy-MM-dd}" : null,
["business_shares"] = m.BusinessShares, ["shares"] = m.Shares,
["shares_red"] = m.SharesRed,
["shares_white"] = m.SharesWhite,
["shares_dormant"] = m.SharesDormant,
["accounting_nr"] = m.AccountingNr, ["accounting_nr"] = m.AccountingNr,
["zwstid"] = m.ZwstId, ["zwstid"] = m.ZwstId,
["lfbis_nr"] = m.LfbisNr, ["lfbis_nr"] = m.LfbisNr,
@@ -666,7 +696,10 @@ namespace Elwig.Helpers.Export {
Birthday = json["birthday"]?.AsValue().GetValue<string>(), Birthday = json["birthday"]?.AsValue().GetValue<string>(),
EntryDateString = json["entry_date"]?.AsValue().GetValue<string>(), EntryDateString = json["entry_date"]?.AsValue().GetValue<string>(),
ExitDateString = json["exit_date"]?.AsValue().GetValue<string>(), ExitDateString = json["exit_date"]?.AsValue().GetValue<string>(),
BusinessShares = json["business_shares"]?.AsValue().GetValue<int>() ?? 0, Shares = json["shares"]?.AsValue().GetValue<int>() ?? json["business_shares"]?.AsValue().GetValue<int>() ?? 0,
SharesRed = json["shares_red"]?.AsValue().GetValue<int>() ?? 0,
SharesWhite = json["shares_white"]?.AsValue().GetValue<int>() ?? 0,
SharesDormant = json["shares_dormant"]?.AsValue().GetValue<int>() ?? 0,
AccountingNr = json["accounting_nr"]?.AsValue().GetValue<string>(), AccountingNr = json["accounting_nr"]?.AsValue().GetValue<string>(),
ZwstId = json["zwstid"]?.AsValue().GetValue<string>(), ZwstId = json["zwstid"]?.AsValue().GetValue<string>(),
LfbisNr = json["lfbis_nr"]?.AsValue().GetValue<string>(), LfbisNr = json["lfbis_nr"]?.AsValue().GetValue<string>(),
@@ -711,6 +744,40 @@ namespace Elwig.Helpers.Export {
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None))); DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
} }
public static JsonObject ToJson(this MemberHistory h) {
return new JsonObject {
["histnr"] = h.HistNr,
["from_mgnr"] = h.FromMgNr,
["from_type"] = h.FromType,
["to_mgnr"] = h.ToMgNr,
["to_type"] = h.ToType,
["date"] = h.DateString,
["reason"] = h.Reason,
["source"] = h.Source,
["shares"] = h.Shares,
["value_per_share"] = h.ValuePerShare,
["currency"] = h.CurrencyCode,
["comment"] = h.Comment,
};
}
public static MemberHistory ToMemberHistory(this JsonNode json) {
return new MemberHistory {
HistNr = json["histnr"]!.AsValue().GetValue<int>(),
FromMgNr = json["from_mgnr"]?.AsValue().GetValue<int>(),
FromType = json["from_type"]?.AsValue().GetValue<int>(),
ToMgNr = json["to_mgnr"]?.AsValue().GetValue<int>(),
ToType = json["to_type"]?.AsValue().GetValue<int>(),
DateString = json["date"]!.AsValue().GetValue<string>(),
Reason = json["reason"]!.AsValue().GetValue<string>(),
Source = json["source"]!.AsValue().GetValue<string>(),
Shares = json["shares"]!.AsValue().GetValue<int>(),
ValuePerShare = json["value_per_share"]?.AsValue().GetValue<decimal>(),
CurrencyCode = json["currency"]?.AsValue().GetValue<string>(),
Comment = json["comment"]?.AsValue().GetValue<string>(),
};
}
public static JsonObject ToJson(this AreaComContract c) { public static JsonObject ToJson(this AreaComContract c) {
return new JsonObject { return new JsonObject {
["fbnr"] = c.FbNr, ["fbnr"] = c.FbNr,
+3 -3
View File
@@ -1,8 +1,8 @@
using Elwig.Services;
using Elwig.Windows; using Elwig.Windows;
using System; using System;
using System.Drawing.Printing; using System.Drawing.Printing;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
namespace Elwig.Helpers.Printing { namespace Elwig.Helpers.Printing {
public static class Pdf { public static class Pdf {
@@ -46,8 +46,8 @@ namespace Elwig.Helpers.Printing {
PrinterSettings = settings, PrinterSettings = settings,
}; };
printDoc.Print(); printDoc.Print();
} catch (Exception e) { } catch (Exception exc) {
MessageBox.Show("Beim Drucken ist ein Fehler aufgetreten:\n\n" + e.Message, "Fehler beim Drucken", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Fehler beim Drucken", "Beim Drucken ist ein Fehler aufgetreten", exc);
} }
return Task.CompletedTask; return Task.CompletedTask;
} }
+29 -24
View File
@@ -3,12 +3,12 @@ using Elwig.Documents;
using Elwig.Helpers.Billing; using Elwig.Helpers.Billing;
using Elwig.Models; using Elwig.Models;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using iText.Layout.Element; using iText.Layout.Element;
using LinqKit; using LinqKit;
using MailKit.Net.Smtp; using MailKit.Net.Smtp;
using MailKit.Security; using MailKit.Security;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using MimeKit; using MimeKit;
using System; using System;
using System.Collections; using System.Collections;
@@ -31,6 +31,7 @@ using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input;
using System.Windows.Markup; using System.Windows.Markup;
namespace Elwig.Helpers { namespace Elwig.Helpers {
@@ -209,16 +210,29 @@ namespace Elwig.Helpers {
return Regex.Replace(iban.Trim(), ".{4}", "$0 ").Trim(); 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> function) {
Task.Run(async () => { Task.Run(async () => {
try { try {
await a(); await function();
} catch (Exception e) { } catch (Exception exc) {
MessageBox.Show(e.ToString(), title, MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(title, exc);
} }
}); });
} }
public static async Task RunForeground(Func<Task> function) {
var isSTA = Thread.CurrentThread.GetApartmentState() == ApartmentState.STA;
if (isSTA) Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
await function();
} catch (Exception exc) {
InteractionService.ShowException(exc);
}
});
if (isSTA) Mouse.OverrideCursor = null;
}
public static void MailTo(string emailAddress) { public static void MailTo(string emailAddress) {
MailTo([emailAddress]); MailTo([emailAddress]);
} }
@@ -443,7 +457,7 @@ namespace Elwig.Helpers {
Timeout = TimeSpan.FromSeconds(5), Timeout = TimeSpan.FromSeconds(5),
}; };
client.DefaultRequestHeaders.UserAgent.Clear(); client.DefaultRequestHeaders.UserAgent.Clear();
client.DefaultRequestHeaders.UserAgent.ParseAdd($"Elwig/{App.Version} ({App.Client.NameToken}, {App.BranchName}, {Environment.MachineName}, {Environment.OSVersion})"); client.DefaultRequestHeaders.UserAgent.ParseAdd($"Elwig/{App.Version} ({App.Client?.NameToken}, {App.BranchName}, {Environment.MachineName}, {Environment.OSVersion})");
client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Clear();
if (accept != null) if (accept != null)
client.DefaultRequestHeaders.Accept.Add(new(accept)); client.DefaultRequestHeaders.Accept.Add(new(accept));
@@ -537,7 +551,7 @@ namespace Elwig.Helpers {
subject, docs.Select(d => d.Title).ToArray() subject, docs.Select(d => d.Title).ToArray()
)]); )]);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
return false; return false;
} finally { } finally {
if (client != null) if (client != null)
@@ -551,8 +565,7 @@ namespace Elwig.Helpers {
public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member Member, string Subject, string Text)? emailData = null) { public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member Member, string Subject, string Text)? emailData = null) {
if (mode == ExportMode.Print && !App.Config.Debug) { if (mode == ExportMode.Print && !App.Config.Debug) {
if (doc.IsPreview) { if (doc.IsPreview) {
MessageBox.Show("Dieses Dokument ist als vorläufig markiert und kann daher nicht ausgedruckt werden!", InteractionService.ShowError("Vorläufiges Dokument", "Dieses Dokument ist als vorläufig markiert und kann daher nicht ausgedruckt werden!");
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
} }
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
@@ -561,8 +574,7 @@ namespace Elwig.Helpers {
await doc.Print(); await doc.Print();
} else if (mode == ExportMode.Email && emailData is (Member, string, string) e) { } else if (mode == ExportMode.Email && emailData is (Member, string, string) e) {
if (doc.IsPreview) { if (doc.IsPreview) {
MessageBox.Show("Dieses Dokument ist als vorläufig markiert und kann daher nicht verschickt werden!", InteractionService.ShowError("Vorläufiges Dokument", "Dieses Dokument ist als vorläufig markiert und kann daher nicht verschickt werden!");
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
} }
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
@@ -570,25 +582,18 @@ namespace Elwig.Helpers {
} }
var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]); var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]);
if (success) if (success)
MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mail im Posteingang des Empfängers aufscheint.", "E-Mail verschickt", InteractionService.ShowInformation("E-Mail verschickt", "Die E-Mail wurde erfolgreich verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mail im Posteingang des Empfängers aufscheint.");
MessageBoxButton.OK, MessageBoxImage.Information);
} else if (mode == ExportMode.SavePdf) { } else if (mode == ExportMode.SavePdf) {
if (doc.IsPreview) { if (doc.IsPreview) {
MessageBox.Show("Dieses Dokument ist als vorläufig markiert und sollte daher nicht langfristig gespeichert werden!", InteractionService.ShowWarning("Vorläufiges Dokument", "Dieses Dokument ist als vorläufig markiert und sollte daher nicht langfristig gespeichert werden!");
"Vorläufiges Dokument", MessageBoxButton.OK, MessageBoxImage.Warning);
} }
var d = new SaveFileDialog() { filename = InteractionService.SaveFile(doc.Title, NormalizeFileName(filename ?? doc.Title), "pdf");
FileName = $"{NormalizeFileName(filename ?? doc.Title)}.pdf", if (filename != null) {
DefaultExt = "pdf",
Filter = "PDF-Datei (*.pdf)|*.pdf",
Title = $"{doc.Title} speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
await doc.Generate(ctx); await doc.Generate(ctx);
} }
doc.SaveTo(d.FileName); doc.SaveTo(filename);
Process.Start("explorer.exe", d.FileName); if (!App.Config.Debug) Process.Start("explorer.exe", filename);
} }
} else { } else {
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
+3 -4
View File
@@ -1,9 +1,9 @@
using Elwig.Services;
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
namespace Elwig.Helpers.Weighing { namespace Elwig.Helpers.Weighing {
public class AveryEventScale : Scale, IEventScale, IDisposable { public class AveryEventScale : Scale, IEventScale, IDisposable {
@@ -60,9 +60,8 @@ namespace Elwig.Helpers.Weighing {
} catch (TimeoutException) { } catch (TimeoutException) {
await Task.Delay(500); await Task.Delay(500);
await Reconnect(); await Reconnect();
} catch (Exception ex) { } catch (Exception exc) {
MessageBox.Show($"Beim Wiegen ist ein Fehler Aufgetreten:\n\n{ex.Message} ({ex.GetType().Name})", "Waagenfehler", InteractionService.ShowException("Waagenfehler", "Beim Wiegen ist ein Fehler Aufgetreten", exc, showExcType: true);
MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
} }
+3 -4
View File
@@ -1,9 +1,9 @@
using Elwig.Services;
using System; using System;
using System.IO; using System.IO;
using System.IO.Ports; using System.IO.Ports;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text; using System.Text;
using System.Windows;
namespace Elwig.Helpers.Weighing { namespace Elwig.Helpers.Weighing {
public abstract class Scale : IDisposable { public abstract class Scale : IDisposable {
@@ -42,11 +42,10 @@ namespace Elwig.Helpers.Weighing {
if (cnx.StartsWith("serial:")) { if (cnx.StartsWith("serial:")) {
try { try {
Serial = Utils.OpenSerialConnection(cnx); Serial = Utils.OpenSerialConnection(cnx);
} catch (Exception e) { } catch (Exception exc) {
if (!softFail) throw; if (!softFail) throw;
if (!failSilent) if (!failSilent)
MessageBox.Show($"Verbindung zu Waage konnte nicht hergestellt werden:\n\n{e.Message}", "Waagenfehler", InteractionService.ShowException("Waagenfehler", "Verbindung zu Waage konnte nicht hergestellt werden", exc, isError: false);
MessageBoxButton.OK, MessageBoxImage.Warning);
} }
Stream = Serial?.BaseStream ?? Stream.Null; Stream = Serial?.BaseStream ?? Stream.Null;
} else if (cnx.StartsWith("tcp:")) { } else if (cnx.StartsWith("tcp:")) {
+15 -15
View File
@@ -29,7 +29,7 @@ namespace Elwig.Models.Dtos {
("Gross", "Brutto", "€", 20), ("Gross", "Brutto", "€", 20),
("Penalties", "Pönalen FB", "€", 20), ("Penalties", "Pönalen FB", "€", 20),
("Penalty", "Unterl. GA", "€", 20), ("Penalty", "Unterl. GA", "€", 20),
("AutoBs", "GA Nachz.", "€", 20), ("AutoShares", "GA Nachz.", "€", 20),
("Custom", "Weitere", "€", 20), ("Custom", "Weitere", "€", 20),
("Others", "Sonstige", "€", 20), ("Others", "Sonstige", "€", 20),
("Considered", "Berückstgt.", "€", 20), ("Considered", "Berückstgt.", "€", 20),
@@ -56,9 +56,9 @@ namespace Elwig.Models.Dtos {
p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision, p.plz, o.name AS ort, m.address, m.iban, c.tgnr, s.year, s.precision,
p.amount - p.net_amount AS surcharge, p.amount - p.net_amount AS surcharge,
c.net_amount, c.prev_net_amount, c.vat, c.vat_amount, c.gross_amount, c.modifiers, c.prev_modifiers, c.amount, c.net_amount, c.prev_net_amount, c.vat, c.vat_amount, c.gross_amount, c.modifiers, c.prev_modifiers, c.amount,
ROUND(b.total_penalty / POW(10, s.precision - 2)) AS bs_penalty, ROUND(b.total_penalty / POW(10, s.precision - 2)) AS shares_penalty,
ROUND(u.total_penalty / POW(10, 4 - 2)) AS fb_penalty, ROUND(u.total_penalty / POW(10, 4 - 2)) AS ac_penalty,
ROUND(-a.total_amount / POW(10, s.precision - 2)) AS auto_bs, -a.total_amount AS auto_shares,
x.amount AS custom_mod x.amount AS custom_mod
FROM credit c FROM credit c
LEFT JOIN member m ON m.mgnr = c.mgnr LEFT JOIN member m ON m.mgnr = c.mgnr
@@ -94,7 +94,7 @@ namespace Elwig.Models.Dtos {
public decimal Gross; public decimal Gross;
public decimal? Penalties; public decimal? Penalties;
public decimal? Penalty; public decimal? Penalty;
public decimal? AutoBs; public decimal? AutoShares;
public decimal? Custom; public decimal? Custom;
public decimal? Others; public decimal? Others;
public decimal? Considered; public decimal? Considered;
@@ -122,14 +122,14 @@ namespace Elwig.Models.Dtos {
} }
decimal mod = (row.Modifiers == null) ? 0 : Utils.DecFromDb((long)row.Modifiers, prec1); decimal mod = (row.Modifiers == null) ? 0 : Utils.DecFromDb((long)row.Modifiers, prec1);
if (data.ConsiderContractPenalties) if (data.ConsiderContractPenalties)
Penalties = (row.FbPenalty == null) ? null : Utils.DecFromDb((long)row.FbPenalty, prec1); Penalties = (row.AcPenalty == null) ? null : Utils.DecFromDb((long)row.AcPenalty, prec1);
if (data.ConsiderTotalPenalty) if (data.ConsiderTotalPenalty)
Penalty = (row.BsPenalty == null) ? null : Utils.DecFromDb((long)row.BsPenalty, prec1); Penalty = (row.SharesPenalty == null) ? null : Utils.DecFromDb((long)row.SharesPenalty, prec1);
if (data.ConsiderAutoBusinessShares) if (data.ConsiderAutoBusinessShares)
AutoBs = (row.AutoBs == null) ? null : Utils.DecFromDb((long)row.AutoBs, prec1); AutoShares = (row.AutoShares == null) ? null : Utils.DecFromDb((long)row.AutoShares, prec1);
if (data.ConsiderCustomModifiers) if (data.ConsiderCustomModifiers)
Custom = (row.CustomMod == null) ? null : Utils.DecFromDb((long)row.CustomMod, prec1); Custom = (row.CustomMod == null) ? null : Utils.DecFromDb((long)row.CustomMod, prec1);
mod -= (Penalties ?? 0) + (Penalty ?? 0) + (AutoBs ?? 0) + (Custom ?? 0); mod -= (Penalties ?? 0) + (Penalty ?? 0) + (AutoShares ?? 0) + (Custom ?? 0);
Others = (mod == 0) ? null : mod; Others = (mod == 0) ? null : mod;
Gross = Utils.DecFromDb(row.GrossAmount, prec1); Gross = Utils.DecFromDb(row.GrossAmount, prec1);
Considered = (row.PrevModifiers == null || row.PrevModifiers == 0) ? null : -Utils.DecFromDb((long)row.PrevModifiers, prec1); Considered = (row.PrevModifiers == null || row.PrevModifiers == 0) ? null : -Utils.DecFromDb((long)row.PrevModifiers, prec1);
@@ -179,12 +179,12 @@ namespace Elwig.Models.Dtos {
public long? PrevModifiers { get; set; } public long? PrevModifiers { get; set; }
[Column("amount")] [Column("amount")]
public long Amount { get; set; } public long Amount { get; set; }
[Column("bs_penalty")] [Column("shares_penalty")]
public long? BsPenalty { get; set; } public long? SharesPenalty { get; set; }
[Column("fb_penalty")] [Column("ac_penalty")]
public long? FbPenalty { get; set; } public long? AcPenalty { get; set; }
[Column("auto_bs")] [Column("auto_shares")]
public long? AutoBs { get; set; } public long? AutoShares { get; set; }
[Column("custom_mod")] [Column("custom_mod")]
public long? CustomMod { get; set; } public long? CustomMod { get; set; }
} }
+11 -11
View File
@@ -42,13 +42,10 @@ namespace Elwig.Models.Dtos {
} }
private static async Task<IEnumerable<CreditNoteDeliveryRowSingle>> FromDbSet(DbSet<CreditNoteDeliveryRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) { private static async Task<IEnumerable<CreditNoteDeliveryRowSingle>> FromDbSet(DbSet<CreditNoteDeliveryRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
var y = year?.ToString() ?? "NULL"; return await table.FromSql($"""
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, 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, 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, c.name AS cultivation, q.qualid AS qualid, q.name AS quality_level, d.oe, d.kmw, d.net_weight s.name AS variety, s.type AS type, a.name AS attribute, c.name AS cultivation, q.qualid AS qualid, q.name AS quality_level, d.oe, d.kmw, d.net_weight
FROM v_delivery d FROM v_delivery d
JOIN wine_variety s ON s.sortid = d.sortid JOIN wine_variety s ON s.sortid = d.sortid
LEFT JOIN wine_attribute a ON a.attrid = d.attrid LEFT JOIN wine_attribute a ON a.attrid = d.attrid
@@ -59,7 +56,7 @@ namespace Elwig.Models.Dtos {
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 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 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) 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) WHERE b.value > 0 AND (d.year = {year} OR {year} IS NULL) AND (v.avnr = {avnr} OR {avnr} IS NULL) AND (d.mgnr = {mgnr} OR {mgnr} IS NULL)
ORDER BY d.year, v.avnr, d.mgnr, d.lsnr, d.dpnr ORDER BY d.year, v.avnr, d.mgnr, d.lsnr, d.dpnr
""").ToListAsync(); """).ToListAsync();
} }
@@ -75,6 +72,7 @@ namespace Elwig.Models.Dtos {
public string LsNr; public string LsNr;
public int DPNr; public int DPNr;
public string Variety; public string Variety;
public string Type;
public string? Attribute; public string? Attribute;
public string? Cultivation; public string? Cultivation;
public string[] Modifiers; public string[] Modifiers;
@@ -97,24 +95,24 @@ namespace Elwig.Models.Dtos {
LsNr = f.LsNr; LsNr = f.LsNr;
DPNr = f.DPNr; DPNr = f.DPNr;
Variety = f.Variety; Variety = f.Variety;
Type = f.Type;
Attribute = f.Attribute; Attribute = f.Attribute;
Cultivation = f.Cultivation; Cultivation = f.Cultivation;
var modifiers = (IEnumerable<Modifier>)(f.Modifiers ?? "").Split(',') var modifiers = (IEnumerable<Modifier>)(f.Modifiers ?? "").Split(',')
.Select(m => season?.Modifiers.FirstOrDefault(s => s.ModId == m)) .Select(m => season?.Modifiers.FirstOrDefault(s => s.ModId == m))
.Where(m => m != null) .Where(m => m != null)
.OrderBy(m => m.Ordering) .OrderBy(m => m!.Ordering)
.ToList(); .ToList();
Modifiers = modifiers.Select(m => m.Name).ToArray(); Modifiers = [.. modifiers.Select(m => m.Name)];
QualId = f.QualId; QualId = f.QualId;
QualityLevel = f.QualityLevel; QualityLevel = f.QualityLevel;
Gradation = (f.Oe, f.Kmw); Gradation = (f.Oe, f.Kmw);
Buckets = rows Buckets = [.. rows
.Where(b => b.Value > 0) .Where(b => b.Value > 0)
.OrderByDescending(b => b.BktNr) .OrderByDescending(b => b.BktNr)
.Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {f.SortId}{b.Discr}", b.Value, .Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {f.SortId}{b.Discr}", b.Value,
b.Price != null ? season?.DecFromDb((long)b.Price) : null, b.Price != null ? season?.DecFromDb((long)b.Price) : null,
b.Amount != null ? season?.DecFromDb((long)b.Amount) : null)) b.Amount != null ? season?.DecFromDb((long)b.Amount) : null))];
.ToArray();
WeighingModifier = (varData == null || !varData.ConsiderDelieryModifiers) ? 0 : f.NetWeight ? varData.NetWeightModifier : varData.GrossWeightModifier; WeighingModifier = (varData == null || !varData.ConsiderDelieryModifiers) ? 0 : f.NetWeight ? varData.NetWeightModifier : varData.GrossWeightModifier;
Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null; Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null;
var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null; var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null;
@@ -161,6 +159,8 @@ namespace Elwig.Models.Dtos {
public long? TotalAmount { get; set; } public long? TotalAmount { get; set; }
[Column("variety")] [Column("variety")]
public required string Variety { get; set; } public required string Variety { get; set; }
[Column("type")]
public required string Type { get; set; }
[Column("attribute")] [Column("attribute")]
public string? Attribute { get; set; } public string? Attribute { get; set; }
[Column("cultivation")] [Column("cultivation")]
+1 -1
View File
@@ -8,7 +8,7 @@ namespace Elwig.Models.Dtos {
public class MemberDeliveryData : DataTable<MemberDeliveryRow> { public class MemberDeliveryData : DataTable<MemberDeliveryRow> {
private static readonly (string, string, string?, int?)[] FieldNames = [ private static readonly (string, string, string?, int?)[] FieldNames = [
("MgNr", "MgNr.", null, 12), ("MgNr", "MgNr.", null, 12),
("Name1", "Name", null, 40), ("Name1", "Name", null, 40),
("Name2", "Vorname", null, 40), ("Name2", "Vorname", null, 40),
("Address", "Adresse", null, 60), ("Address", "Adresse", null, 60),
+11 -3
View File
@@ -19,7 +19,7 @@ namespace Elwig.Models.Dtos {
("Locality", "Ort", null, 60), ("Locality", "Ort", null, 60),
("DefaultKg", "Stammgemeinde", null, 60), ("DefaultKg", "Stammgemeinde", null, 60),
("Branch", "Zweigstelle", null, 40), ("Branch", "Zweigstelle", null, 40),
("BusinessShares", "GA", null, 10), ("SharesTotal", "GA", null, 10),
("BillingName", "Rechnungsname", null, 60), ("BillingName", "Rechnungsname", null, 60),
("BillingAddress", "Rechnungsadresse", null, 60), ("BillingAddress", "Rechnungsadresse", null, 60),
("BillingPlz", "PLZ", null, 10), ("BillingPlz", "PLZ", null, 10),
@@ -66,7 +66,11 @@ namespace Elwig.Models.Dtos {
public string? Name2; public string? Name2;
public string? DefaultKg; public string? DefaultKg;
public string? Branch; public string? Branch;
public int BusinessShares; public int Shares;
public int SharesRed;
public int SharesWhite;
public int SharesDormant;
public int SharesTotal;
public string Address; public string Address;
public int Plz; public int Plz;
public string Locality; public string Locality;
@@ -98,7 +102,11 @@ namespace Elwig.Models.Dtos {
Name2 = m.AdministrativeName2; Name2 = m.AdministrativeName2;
DefaultKg = m.DefaultKg?.Name; DefaultKg = m.DefaultKg?.Name;
Branch = m.Branch?.Name; Branch = m.Branch?.Name;
BusinessShares = m.BusinessShares; Shares = m.Shares;
SharesRed = m.SharesRed;
SharesWhite = m.SharesWhite;
SharesDormant = m.SharesDormant;
SharesTotal = Shares + SharesRed + SharesWhite + SharesDormant;
Address = m.Address; Address = m.Address;
Plz = m.PostalDest.AtPlz!.Plz; Plz = m.PostalDest.AtPlz!.Plz;
Locality = m.PostalDest.AtPlz!.Ort.Name; Locality = m.PostalDest.AtPlz!.Ort.Name;
+81 -18
View File
@@ -13,35 +13,74 @@ namespace Elwig.Models.Dtos {
("Address", "Adresse", null, 60), ("Address", "Adresse", null, 60),
("Plz", "PLZ", null, 10), ("Plz", "PLZ", null, 10),
("Locality", "Ort", null, 60), ("Locality", "Ort", null, 60),
("BusinessShares", "GA", null, 10), ("Shares", "GA", null, 10),
("DeliveryObligation", "Lieferpflicht", "kg", 22), ("DeliveryObligation", "Lieferpflicht", "kg", 22),
("DeliveryRight", "Lieferrecht", "kg", 22), ("DeliveryRight", "Lieferrecht", "kg", 22),
("Weight", "Geliefert", "kg", 22), ("WeightTotal", "Geliefert", "kg", 22),
("OverUnderDelivery", "Über-/Unterliefert", "kg|%", 34), ("OverUnderDelivery", "Über-/Unterliefert", "kg|%", 34),
]; ];
private static readonly (string, string, string?, int)[] FieldNamesRed = [
("MgNr", "MgNr.", null, 12),
("Name1", "Name", null, 40),
("Name2", "Vorname", null, 40),
("Address", "Adresse", null, 60),
("Plz", "PLZ", null, 10),
("Locality", "Ort", null, 60),
("SharesRed", "GA", null, 10),
("DeliveryObligationRed", "Lieferpflicht", "kg", 22),
("DeliveryRightRed", "Lieferrecht", "kg", 22),
("WeightRed", "Geliefert", "kg", 22),
("OverUnderDeliveryRed", "Über-/Unterliefert", "kg|%", 34),
];
private static readonly (string, string, string?, int)[] FieldNamesWhite = [
("MgNr", "MgNr.", null, 12),
("Name1", "Name", null, 40),
("Name2", "Vorname", null, 40),
("Address", "Adresse", null, 60),
("Plz", "PLZ", null, 10),
("Locality", "Ort", null, 60),
("SharesWhite", "GA", null, 10),
("DeliveryObligationWhite", "Lieferpflicht", "kg", 22),
("DeliveryRightWhite", "Lieferrecht", "kg", 22),
("WeightWhite", "Geliefert", "kg", 22),
("OverUnderDeliveryWhite", "Ü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) {
} }
public static async Task<OverUnderDeliveryData> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) { public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year, string mode) :
base($"Über-Unterlieferungen-{(mode == "R" ? "rot" : "weiß")}", $"Über- und Unterlieferungen laut gezeichneten Geschäftsanteilen {(mode == "R" ? "rot" : "weiß")} {year}", rows,
mode == "R" ? FieldNamesRed : FieldNamesWhite) {
}
public static async Task<(OverUnderDeliveryData Total, OverUnderDeliveryData Red, OverUnderDeliveryData White)> ForSeason(DbSet<OverUnderDeliveryRow> table, int year) {
var rows = await table.FromSql($""" var rows = await table.FromSql($"""
SELECT m.mgnr, m.name AS name_1, SELECT m.mgnr, m.name AS name_1,
COALESCE(m.prefix || ' ', '') || m.given_name || COALESCE(m.prefix || ' ', '') || m.given_name ||
COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2,
p.plz, o.name AS ort, m.address, m.business_shares, p.plz, o.name AS ort, m.address, h.shares, h.shares_red, h.shares_white,
m.business_shares * s.min_kg_per_bs AS min_kg, h.shares * COALESCE(s.min_kg_per_share, 0) AS min_kg,
m.business_shares * s.max_kg_per_bs AS max_kg, h.shares * COALESCE(s.max_kg_per_share, 0) AS max_kg,
COALESCE(SUM(d.weight), 0) AS sum h.shares_red * COALESCE(s.min_kg_per_share_red, s.min_kg_per_share, 0) AS min_kg_red,
h.shares_red * COALESCE(s.max_kg_per_share_red, s.max_kg_per_share, 0) AS max_kg_red,
h.shares_white * COALESCE(s.min_kg_per_share_white, s.min_kg_per_share, 0) AS min_kg_white,
h.shares_white * COALESCE(s.max_kg_per_share_white, s.max_kg_per_share, 0) AS max_kg_white,
COALESCE(d.weight_total, 0) AS weight_total,
COALESCE(d.weight_red, 0) AS weight_red,
COALESCE(d.weight_white, 0) AS weight_white
FROM season s, member m FROM season s, member m
LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest
LEFT JOIN AT_ort o ON o.okz = p.okz LEFT JOIN AT_ort o ON o.okz = p.okz
LEFT JOIN v_delivery d ON (d.year, d.mgnr) = (s.year, m.mgnr) LEFT JOIN v_member_history h ON (h.year, h.mgnr) = (s.year, m.mgnr)
WHERE s.year = {year} AND (m.active = TRUE OR d.weight > 0) LEFT JOIN v_stat_member d ON (d.year, d.mgnr) = (s.year, m.mgnr)
GROUP BY s.year, m.mgnr WHERE s.year = {year} AND (m.active = TRUE OR d.weight_total > 0)
ORDER BY 100.0 * sum / max_kg, m.mgnr ORDER BY 100.0 * weight_total / (max_kg + max_kg_red + max_kg_white), m.mgnr
""").ToListAsync(); """).ToListAsync();
return new OverUnderDeliveryData(rows, year); return (new OverUnderDeliveryData(rows, year), new OverUnderDeliveryData(rows, year, "R"), new OverUnderDeliveryData(rows, year, "W"));
} }
} }
@@ -61,17 +100,41 @@ namespace Elwig.Models.Dtos {
public required string LocalityFull { get; set; } public required string LocalityFull { get; set; }
[NotMapped] [NotMapped]
public string Locality => LocalityFull.Split(",")[0]; public string Locality => LocalityFull.Split(",")[0];
[Column("business_shares")] [Column("shares")]
public int BusinessShares { get; set; } public int Shares { get; set; }
[Column("shares_red")]
public int SharesRed { get; set; }
[Column("shares_white")]
public int SharesWhite { get; set; }
[Column("min_kg")] [Column("min_kg")]
public int DeliveryObligation { get; set; } public int DeliveryObligation { get; set; }
[Column("max_kg")] [Column("max_kg")]
public int DeliveryRight { get; set; } public int DeliveryRight { get; set; }
[Column("sum")]
public int Weight { get; set; }
[NotMapped] [NotMapped]
public (int? Kg, double? Percent) OverUnderDelivery => public (int? Kg, double? Percent) OverUnderDelivery =>
Weight < DeliveryObligation ? (Weight - DeliveryObligation, Weight * 100.0 / DeliveryObligation - 100.0) : WeightTotal < DeliveryObligation ? (WeightTotal - DeliveryObligation, WeightTotal * 100.0 / DeliveryObligation - 100.0) :
Weight > DeliveryRight ? (Weight - DeliveryRight, Weight * 100.0 / DeliveryRight - 100.0) : (null, null); WeightTotal > DeliveryRight ? (WeightTotal - DeliveryRight, WeightTotal * 100.0 / DeliveryRight - 100.0) : (null, null);
[Column("min_kg_red")]
public int DeliveryObligationRed { get; set; }
[Column("max_kg_red")]
public int DeliveryRightRed { get; set; }
[NotMapped]
public (int? Kg, double? Percent) OverUnderDeliveryRed =>
WeightRed < DeliveryObligationRed ? (WeightRed - DeliveryObligationRed, WeightRed * 100.0 / DeliveryObligationRed - 100.0) :
WeightRed > DeliveryRightRed ? (WeightRed - DeliveryRightRed, WeightRed * 100.0 / DeliveryRightRed - 100.0) : (null, null);
[Column("min_kg_white")]
public int DeliveryObligationWhite { get; set; }
[Column("max_kg_white")]
public int DeliveryRightWhite { get; set; }
[NotMapped]
public (int? Kg, double? Percent) OverUnderDeliveryWhite =>
WeightWhite < DeliveryObligationWhite ? (WeightWhite - DeliveryObligationWhite, WeightWhite * 100.0 / DeliveryObligationWhite - 100.0) :
WeightWhite > DeliveryRightWhite ? (WeightWhite - DeliveryRightWhite, WeightWhite * 100.0 / DeliveryRightWhite - 100.0) : (null, null);
[Column("weight_total")]
public int WeightTotal { get; set; }
[Column("weight_red")]
public int WeightRed { get; set; }
[Column("weight_white")]
public int WeightWhite { get; set; }
} }
} }
+22 -3
View File
@@ -67,8 +67,22 @@ namespace Elwig.Models.Entities {
set => ExitDateString = value?.ToString("yyyy-MM-dd"); set => ExitDateString = value?.ToString("yyyy-MM-dd");
} }
[Column("business_shares")] [Column("shares")]
public int BusinessShares { get; set; } public int Shares { get; set; }
[Column("shares_red")]
public int SharesRed { get; set; }
[Column("shares_white")]
public int SharesWhite { get; set; }
[Column("shares_dormant")]
public int SharesDormant { get; set; }
[NotMapped]
public int SharesTotal => Shares + SharesRed + SharesWhite + SharesDormant;
[NotMapped]
public int SharesActive => Shares + SharesRed + SharesWhite;
[Column("accounting_nr")] [Column("accounting_nr")]
public string? AccountingNr { get; set; } public string? AccountingNr { get; set; }
@@ -189,9 +203,14 @@ namespace Elwig.Models.Entities {
[InverseProperty(nameof(BillingAddr.Member))] [InverseProperty(nameof(BillingAddr.Member))]
public virtual BillingAddr? BillingAddress { get; private set; } public virtual BillingAddr? BillingAddress { get; private set; }
[InverseProperty(nameof(Delivery.Member))] [InverseProperty(nameof(DeliveryAncmt.Member))]
public virtual ICollection<DeliveryAncmt> Announcements { get; private set; } = null!; public virtual ICollection<DeliveryAncmt> Announcements { get; private set; } = null!;
[InverseProperty(nameof(MemberHistory.FromMember))]
public virtual ICollection<MemberHistory> HistoryFrom { get; private set; } = null!;
[InverseProperty(nameof(MemberHistory.ToMember))]
public virtual ICollection<MemberHistory> HistoryTo { get; private set; } = null!;
[InverseProperty(nameof(Delivery.Member))] [InverseProperty(nameof(Delivery.Member))]
public virtual ICollection<Delivery> Deliveries { get; private set; } = null!; public virtual ICollection<Delivery> Deliveries { get; private set; } = null!;
+43 -9
View File
@@ -1,12 +1,23 @@
using Elwig.Helpers;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
namespace Elwig.Models.Entities { namespace Elwig.Models.Entities {
[Table("member_history"), PrimaryKey("MgNr", "DateString", "Type")] [Table("member_history"), PrimaryKey("HistNr")]
public class MemberHistory { public class MemberHistory {
[Column("mgnr")] [Column("histnr")]
public int MgNr { get; set; } public int HistNr { get; set; }
[Column("from_mgnr")]
public int? FromMgNr { get; set; }
[Column("from_type")]
public int? FromType { get; set; }
[Column("to_mgnr")]
public int? ToMgNr { get; set; }
[Column("to_type")]
public int? ToType { get; set; }
[Column("date")] [Column("date")]
public required string DateString { get; set; } public required string DateString { get; set; }
@@ -16,16 +27,39 @@ namespace Elwig.Models.Entities {
set => value.ToString("yyyy-MM-dd"); set => value.ToString("yyyy-MM-dd");
} }
[Column("type")] [Column("reason")]
public required string Type { get; set; } public required string Reason { get; set; }
[Column("business_shares")] [Column("source")]
public int BusinessShares { get; set; } public required string Source { get; set; }
[Column("shares")]
public int Shares { get; set; }
[Column("value_per_share")]
public long? ValuePerShareValue { get; set; }
[NotMapped]
public decimal? ValuePerShare {
get => ValuePerShareValue != null ? Utils.DecFromDb(ValuePerShareValue.Value, 2) : null;
set => ValuePerShareValue = value != null ? Utils.DecToDb(value.Value, 2) : null;
}
[NotMapped]
public decimal? TotalValue => Shares * ValuePerShare;
[Column("currency")]
public string? CurrencyCode { get; set; }
[Column("comment")] [Column("comment")]
public string? Comment { get; set; } public string? Comment { get; set; }
[ForeignKey("MgNr")] [ForeignKey("FromMgNr")]
public virtual Member Member { get; private set; } = null!; public virtual Member FromMember { get; private set; } = null!;
[ForeignKey("ToMgNr")]
public virtual Member ToMember { get; private set; } = null!;
[ForeignKey("CurrencyCode")]
public virtual Currency Currency { get; private set; } = null!;
} }
} }
+24 -15
View File
@@ -25,11 +25,20 @@ namespace Elwig.Models.Entities {
[Column("vat_flatrate")] [Column("vat_flatrate")]
public double VatFlatrate { get; set; } public double VatFlatrate { get; set; }
[Column("min_kg_per_bs")] [Column("min_kg_per_share")]
public int MinKgPerBusinessShare { get; set; } public int? MinKgPerShare { get; set; }
[Column("max_kg_per_share")]
public int? MaxKgPerShare { get; set; }
[Column("max_kg_per_bs")] [Column("min_kg_per_share_red")]
public int MaxKgPerBusinessShare { get; set; } public int? MinKgPerShareRed { get; set; }
[Column("max_kg_per_share_red")]
public int? MaxKgPerShareRed { get; set; }
[Column("min_kg_per_share_white")]
public int? MinKgPerShareWhite { get; set; }
[Column("max_kg_per_share_white")]
public int? MaxKgPerShareWhite { get; set; }
[Column("penalty_per_kg")] [Column("penalty_per_kg")]
public long? PenaltyPerKgValue { get; set; } public long? PenaltyPerKgValue { get; set; }
@@ -55,23 +64,23 @@ namespace Elwig.Models.Entities {
set => PenaltyNoneValue = value != null ? DecToDb(value.Value) : null; set => PenaltyNoneValue = value != null ? DecToDb(value.Value) : null;
} }
[Column("penalty_per_bs_amount")] [Column("penalty_per_share_amount")]
public long? PenaltyPerBsAmountValue { get; set; } public long? PenaltyPerShareAmountValue { get; set; }
[NotMapped] [NotMapped]
public decimal? PenaltyPerBsAmount { public decimal? PenaltyPerShareAmount {
get => PenaltyPerBsAmountValue != null ? DecFromDb(PenaltyPerBsAmountValue.Value) : null; get => PenaltyPerShareAmountValue != null ? DecFromDb(PenaltyPerShareAmountValue.Value) : null;
set => PenaltyPerBsAmountValue = value != null ? DecToDb(value.Value) : null; set => PenaltyPerShareAmountValue = value != null ? DecToDb(value.Value) : null;
} }
[Column("penalty_per_bs_none")] [Column("penalty_per_share_none")]
public long? PenaltyPerBsNoneValue { get; set; } public long? PenaltyPerShareNoneValue { get; set; }
[NotMapped] [NotMapped]
public decimal? PenaltyPerBsNone { public decimal? PenaltyPerShareNone {
get => PenaltyPerBsNoneValue != null ? DecFromDb(PenaltyPerBsNoneValue.Value) : null; get => PenaltyPerShareNoneValue != null ? DecFromDb(PenaltyPerShareNoneValue.Value) : null;
set => PenaltyPerBsNoneValue = value != null ? DecToDb(value.Value) : null; set => PenaltyPerShareNoneValue = value != null ? DecToDb(value.Value) : null;
} }
[Column("bs_value")] [Column("share_value")]
public long? BusinessShareValueValue { get; set; } public long? BusinessShareValueValue { get; set; }
[NotMapped] [NotMapped]
public decimal? BusinessShareValue { public decimal? BusinessShareValue {
+318
View File
@@ -0,0 +1,318 @@
-- schema version 39 to 40
PRAGMA writable_schema = ON;
ALTER TABLE member RENAME COLUMN business_shares TO shares;
ALTER TABLE member ADD COLUMN shares_red INTEGER NOT NULL DEFAULT 0;
ALTER TABLE member ADD COLUMN shares_white INTEGER NOT NULL DEFAULT 0;
ALTER TABLE member ADD COLUMN shares_dormant INTEGER NOT NULL DEFAULT 0;
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
UPDATE member
SET shares_dormant = shares + shares_red + shares_white,
shares = 0, shares_red = 0, shares_white = 0
WHERE NOT active;
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
CREATE TABLE member_history_new (
histnr INTEGER NOT NULL,
from_mgnr INTEGER,
from_type INTEGER,
to_mgnr INTEGER,
to_type INTEGER,
date TEXT NOT NULL CHECK (date REGEXP '^[1-9][0-9]{3}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$') DEFAULT CURRENT_DATE,
reason TEXT NOT NULL CHECK (reason REGEXP '^[a-z_]+$'),
source TEXT NOT NULL CHECK (source REGEXP '^[a-z_]+$'),
shares INTEGER NOT NULL,
value_per_share INTEGER DEFAULT NULL,
currency TEXT DEFAULT NULL,
comment TEXT DEFAULT NULL,
CONSTRAINT pk_member_history PRIMARY KEY (histnr),
CONSTRAINT fk_member_history_member_from FOREIGN KEY (from_mgnr) REFERENCES member (mgnr)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT fk_member_history_member_to FOREIGN KEY (to_mgnr) REFERENCES member (mgnr)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT fk_member_history_currency FOREIGN KEY (currency) REFERENCES currency (code)
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT c_member_history CHECK ((from_mgnr IS NOT NULL OR to_mgnr IS NOT NULL) AND
((from_mgnr IS NULL AND from_type IS NULL) OR (from_mgnr IS NOT NULL AND from_type IS NOT NULL)) AND
((to_mgnr IS NULL AND to_type IS NULL) OR (to_mgnr IS NOT NULL AND to_type IS NOT NULL)))
) STRICT;
INSERT INTO member_history_new (histnr, from_mgnr, from_type, to_mgnr, to_type, date, reason, source, shares, value_per_share, currency, comment)
SELECT ROW_NUMBER() OVER(ORDER BY h.date, h.mgnr), NULL, NULL, h.mgnr, 1, h.date, h.type, 'elwig', h.business_shares, s.bs_value / POW(10, s.precision - 2), s.currency, comment
FROM member_history h
JOIN season s ON s.year = SUBSTR(h.date, 1, 4);
PRAGMA foreign_keys = OFF;
DROP TABLE member_history;
ALTER TABLE member_history_new RENAME TO member_history;
PRAGMA foreign_keys = ON;
CREATE TRIGGER t_member_history_i_member
AFTER INSERT ON member_history FOR EACH ROW
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS') = 1
BEGIN
UPDATE member SET shares = shares - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 1;
UPDATE member SET shares_red = shares_red - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 2;
UPDATE member SET shares_white = shares_white - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 3;
UPDATE member SET shares_dormant = shares_dormant - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 9;
UPDATE member SET shares = shares + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 1;
UPDATE member SET shares_red = shares_red + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 2;
UPDATE member SET shares_white = shares_white + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 3;
UPDATE member SET shares_dormant = shares_dormant + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 9;
END;
CREATE TRIGGER t_member_history_u_member
AFTER UPDATE ON member_history FOR EACH ROW
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS') = 1
BEGIN
UPDATE member SET shares = shares + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 1;
UPDATE member SET shares_red = shares_red + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 2;
UPDATE member SET shares_white = shares_white + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 3;
UPDATE member SET shares_dormant = shares_dormant + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 9;
UPDATE member SET shares = shares - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 1;
UPDATE member SET shares_red = shares_red - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 2;
UPDATE member SET shares_white = shares_white - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 3;
UPDATE member SET shares_dormant = shares_dormant - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 9;
UPDATE member SET shares = shares - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 1;
UPDATE member SET shares_red = shares_red - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 2;
UPDATE member SET shares_white = shares_white - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 3;
UPDATE member SET shares_dormant = shares_dormant - NEW.shares WHERE mgnr = NEW.from_mgnr AND NEW.from_type = 9;
UPDATE member SET shares = shares + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 1;
UPDATE member SET shares_red = shares_red + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 2;
UPDATE member SET shares_white = shares_white + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 3;
UPDATE member SET shares_dormant = shares_dormant + NEW.shares WHERE mgnr = NEW.to_mgnr AND NEW.to_type = 9;
END;
CREATE TRIGGER t_member_history_d_member
AFTER DELETE ON member_history FOR EACH ROW
WHEN (SELECT value FROM client_parameter WHERE param = 'ENABLE_MEMBER_HISTORY_TRIGGERS') = 1
BEGIN
UPDATE member SET shares = shares + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 1;
UPDATE member SET shares_red = shares_red + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 2;
UPDATE member SET shares_white = shares_white + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 3;
UPDATE member SET shares_dormant = shares_dormant + OLD.shares WHERE mgnr = OLD.from_mgnr AND OLD.from_type = 9;
UPDATE member SET shares = shares - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 1;
UPDATE member SET shares_red = shares_red - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 2;
UPDATE member SET shares_white = shares_white - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 3;
UPDATE member SET shares_dormant = shares_dormant - OLD.shares WHERE mgnr = OLD.to_mgnr AND OLD.to_type = 9;
END;
INSERT INTO client_parameter (param, value) VALUES ('ENABLE_MEMBER_HISTORY_TRIGGERS', '1');
CREATE TABLE season_new (
year INTEGER NOT NULL CHECK (year >= 1000 AND year <= 9999),
currency TEXT NOT NULL,
precision INTEGER NOT NULL DEFAULT 4,
max_kg_per_ha INTEGER NOT NULL DEFAULT 10000,
vat_normal REAL NOT NULL DEFAULT 0.10,
vat_flatrate REAL NOT NULL DEFAULT 0.13,
min_kg_per_share INTEGER DEFAULT NULL,
max_kg_per_share INTEGER DEFAULT NULL,
min_kg_per_share_red INTEGER DEFAULT NULL,
max_kg_per_share_red INTEGER DEFAULT NULL,
min_kg_per_share_white INTEGER DEFAULT NULL,
max_kg_per_share_white INTEGER DEFAULT NULL,
penalty_per_kg INTEGER DEFAULT NULL,
penalty_amount INTEGER DEFAULT NULL,
penalty_none INTEGER DEFAULT NULL,
penalty_per_share_amount INTEGER DEFAULT NULL,
penalty_per_share_none INTEGER DEFAULT NULL,
share_value INTEGER,
start_date TEXT CHECK (start_date REGEXP '^[1-9][0-9]{3}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$'),
end_date TEXT CHECK (end_date REGEXP '^[1-9][0-9]{3}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])$'),
calc_mode INTEGER NOT NULL DEFAULT 0,
CONSTRAINT pk_season PRIMARY KEY (year),
CONSTRAINT fk_season_currency FOREIGN KEY (currency) REFERENCES currency (code)
ON UPDATE CASCADE
ON DELETE RESTRICT
) STRICT;
INSERT INTO season_new (year, currency, precision, max_kg_per_ha, vat_normal, vat_flatrate, min_kg_per_share, max_kg_per_share, penalty_per_kg, penalty_amount, penalty_none, penalty_per_share_amount, penalty_per_share_none, share_value, start_date, end_date, calc_mode)
SELECT year, currency, precision, max_kg_per_ha, vat_normal, vat_flatrate, min_kg_per_bs, max_kg_per_bs, penalty_per_kg, penalty_amount, penalty_none, penalty_per_bs_amount, penalty_per_bs_none, bs_value, start_date, end_date, calc_mode
FROM season;
PRAGMA foreign_keys = OFF;
DROP TABLE season;
ALTER TABLE season_new RENAME TO season;
PRAGMA foreign_keys = ON;
DROP VIEW v_delivery;
CREATE VIEW v_delivery AS
SELECT p.year, p.did, p.dpnr,
d.date, d.time, d.zwstid, d.lnr, d.lsnr,
m.mgnr, m.name, m.given_name,
v.sortid, v.type, a.attrid, p.cultid,
p.weight, p.kmw, ROUND(p.kmw * (4.54 + 0.022 * p.kmw), 0) AS oe, p.qualid,
p.hkid, p.kgnr, p.rdnr,
p.net_weight, p.gebunden,
p.qualid IN (SELECT l.qualid FROM wine_quality_level l WHERE NOT l.predicate AND (p.kmw >= l.min_kmw OR l.min_kmw IS NULL) ORDER BY l.min_kmw DESC LIMIT 1,100) AS abgewertet,
p.qualid NOT IN ('WEI', 'RSW', 'LDW') AS min_quw,
IIF(a.strict, COALESCE(a.fill_lower, 0), 0) AS attribute_prio,
GROUP_CONCAT(o.modid) AS modifiers,
d.comment, p.comment AS part_comment
FROM delivery_part p
JOIN delivery d ON (d.year, d.did) = (p.year, p.did)
JOIN member m ON m.mgnr = d.mgnr
LEFT JOIN wine_variety v ON v.sortid = p.sortid
LEFT JOIN wine_attribute a ON a.attrid = p.attrid
LEFT JOIN delivery_part_modifier o ON (o.year, o.did, o.dpnr) = (p.year, p.did, p.dpnr)
GROUP BY p.year, p.did, p.dpnr
ORDER BY p.year, p.did, p.dpnr, o.modid;
DROP VIEW v_stat_season;
CREATE VIEW v_stat_season AS
SELECT year,
SUM(weight) AS weight_total,
SUM(IIF(type = 'R', weight, 0)) AS weight_red,
SUM(IIF(type = 'W', weight, 0)) AS weight_white,
ROUND(SUM(kmw * weight) / SUM(weight), 2) AS kmw,
ROUND(SUM(oe * weight) / SUM(weight), 1) AS oe,
COUNT(DISTINCT did) AS lieferungen,
COUNT(DISTINCT mgnr) AS mitglieder
FROM v_delivery
GROUP BY year
ORDER BY year;
DROP VIEW v_stat_sort;
CREATE VIEW v_stat_variety AS
SELECT year, sortid,
SUM(weight) AS weight_total,
SUM(IIF(type = 'R', weight, 0)) AS weight_red,
SUM(IIF(type = 'W', weight, 0)) AS weight_white,
ROUND(SUM(kmw * weight) / SUM(weight), 2) AS kmw,
ROUND(SUM(oe * weight) / SUM(weight), 1) AS oe,
COUNT(DISTINCT did) AS lieferungen,
COUNT(DISTINCT mgnr) AS mitglieder
FROM v_delivery
GROUP BY year, sortid
ORDER BY year, sortid;
DROP VIEW v_stat_attr;
CREATE VIEW v_stat_attr AS
SELECT year, attrid,
SUM(weight) AS weight_total,
SUM(IIF(type = 'R', weight, 0)) AS weight_red,
SUM(IIF(type = 'W', weight, 0)) AS weight_white,
ROUND(SUM(kmw * weight) / SUM(weight), 2) AS kmw,
ROUND(SUM(oe * weight) / SUM(weight), 1) AS oe,
COUNT(DISTINCT did) AS lieferungen,
COUNT(DISTINCT mgnr) AS mitglieder
FROM v_delivery
GROUP BY year, attrid
ORDER BY year, attrid;
DROP VIEW v_stat_sort_attr;
CREATE VIEW v_stat_variety_attr AS
SELECT year, sortid, attrid,
SUM(weight) AS weight_total,
SUM(IIF(type = 'R', weight, 0)) AS weight_red,
SUM(IIF(type = 'W', weight, 0)) AS weight_white,
ROUND(SUM(kmw * weight) / SUM(weight), 2) AS kmw,
ROUND(SUM(oe * weight) / SUM(weight), 1) AS oe,
COUNT(DISTINCT did) AS lieferungen,
COUNT(DISTINCT mgnr) AS mitglieder
FROM v_delivery
GROUP BY year, sortid, attrid
ORDER BY year, sortid, attrid;
DROP VIEW v_stat_member;
CREATE VIEW v_stat_member AS
SELECT year, mgnr,
SUM(weight) AS weight_total,
SUM(IIF(type = 'R', weight, 0)) AS weight_red,
SUM(IIF(type = 'W', weight, 0)) AS weight_white,
ROUND(SUM(kmw * weight) / SUM(weight), 2) AS kmw,
ROUND(SUM(oe * weight) / SUM(weight), 1) AS oe,
COUNT(DISTINCT did) AS lieferungen
FROM v_delivery
GROUP BY year, mgnr
ORDER BY year, mgnr;
CREATE VIEW v_member_history AS
SELECT m.mgnr, s.year,
m.shares + SUM(IIF(h1.from_type = 1, h1.shares, 0)) - SUM(IIF(h2.to_type = 1, h2.shares, 0)) AS shares,
m.shares_red + SUM(IIF(h1.from_type = 2, h1.shares, 0)) - SUM(IIF(h2.to_type = 2, h2.shares, 0)) AS shares_red,
m.shares_white + SUM(IIF(h1.from_type = 3, h1.shares, 0)) - SUM(IIF(h2.to_type = 3, h2.shares, 0)) AS shares_white,
m.shares_dormant + SUM(IIF(h1.from_type = 9, h1.shares, 0)) - SUM(IIF(h2.to_type = 9, h2.shares, 0)) AS shares_dormant
FROM member m, v_virtual_season s
LEFT JOIN member_history h1 ON (SUBSTR(h1.date, 1, 4) + 0) > s.year AND h1.from_mgnr = m.mgnr
LEFT JOIN member_history h2 ON (SUBSTR(h2.date, 1, 4) + 0) > s.year AND h2.to_mgnr = m.mgnr
GROUP BY m.mgnr, s.year
ORDER BY m.mgnr, s.year;
DROP VIEW v_total_under_delivery;
CREATE VIEW v_total_under_delivery AS
SELECT s.year, m.mgnr,
h.shares,
h.shares * COALESCE(s.min_kg_per_share, 0) AS min_kg,
h.shares * COALESCE(s.max_kg_per_share, 0) AS max_kg,
COALESCE(d.weight_total, 0) AS weight_total,
IIF(COALESCE(d.weight_total, 0) < h.shares * COALESCE(s.min_kg_per_share, 0),
COALESCE(d.weight_total, 0) - h.shares * COALESCE(s.min_kg_per_share, 0),
IIF(COALESCE(d.weight_total, 0) > h.shares * COALESCE(s.max_kg_per_share, 0),
COALESCE(d.weight_total, 0) - h.shares * COALESCE(s.max_kg_per_share, 0),
0)) AS diff,
h.shares_red,
h.shares_red * COALESCE(s.min_kg_per_share_red, s.min_kg_per_share, 0) AS min_kg_red,
h.shares_red * COALESCE(s.max_kg_per_share_red, s.max_kg_per_share, 0) AS max_kg_red,
COALESCE(d.weight_red, 0) AS weight_red,
IIF(COALESCE(d.weight_red, 0) < h.shares_red * COALESCE(s.min_kg_per_share_red, s.min_kg_per_share, 0),
COALESCE(d.weight_red, 0) - h.shares_red * COALESCE(s.min_kg_per_share_red, s.min_kg_per_share, 0),
IIF(COALESCE(d.weight_red, 0) > h.shares_red * COALESCE(s.max_kg_per_share_red, s.max_kg_per_share, 0),
COALESCE(d.weight_red, 0) - h.shares_red * COALESCE(s.max_kg_per_share_red, s.max_kg_per_share, 0),
0)) AS diff_red,
h.shares_white,
h.shares_white * COALESCE(s.min_kg_per_share_white, s.min_kg_per_share, 0) AS min_kg_white,
h.shares_white * COALESCE(s.max_kg_per_share_white, s.max_kg_per_share, 0) AS max_kg_white,
COALESCE(d.weight_white, 0) AS weight_white,
IIF(COALESCE(d.weight_white, 0) < h.shares_white * COALESCE(s.min_kg_per_share_white, s.min_kg_per_share, 0),
COALESCE(d.weight_white, 0) - h.shares_white * COALESCE(s.min_kg_per_share_white, s.min_kg_per_share, 0),
IIF(COALESCE(d.weight_white, 0) > h.shares_white * COALESCE(s.max_kg_per_share_white, s.max_kg_per_share, 0),
COALESCE(d.weight_white, 0) - h.shares_white * COALESCE(s.max_kg_per_share_white, s.max_kg_per_share, 0),
0)) AS diff_white
FROM member m, season s
LEFT JOIN v_member_history h ON (h.year, h.mgnr) = (s.year, m.mgnr)
LEFT JOIN v_stat_member d ON (d.year, d.mgnr) = (s.year, m.mgnr)
ORDER BY s.year, m.mgnr;
DROP VIEW v_penalty_business_shares;
CREATE VIEW v_penalty_business_shares AS
SELECT u.year, u.mgnr,
SUM(IIF(u.weight_total = 0, COALESCE(-s.penalty_none, 0) + COALESCE(-(u.shares + u.shares_red + u.shares_white) * s.penalty_per_share_none, 0), 0) +
IIF(u.diff < 0 OR u.diff_red < 0 OR u.diff_white < 0, COALESCE(-s.penalty_amount, 0), 0) +
COALESCE((u.diff + u.diff_red + u.diff_white) * s.penalty_per_kg, 0) +
COALESCE(CEIL(CAST(u.diff AS REAL) / s.min_kg_per_share) * s.penalty_per_share_amount, 0) +
COALESCE(CEIL(CAST(u.diff_red AS REAL) / s.min_kg_per_share_red) * s.penalty_per_share_amount, 0) +
COALESCE(CEIL(CAST(u.diff_white AS REAL) / s.min_kg_per_share_white) * s.penalty_per_share_amount, 0)
) AS total_penalty
FROM v_total_under_delivery u
JOIN season s ON u.year = s.year
JOIN member m ON m.mgnr = u.mgnr
WHERE m.active
GROUP BY u.year, u.mgnr
HAVING total_penalty < 0
ORDER BY u.year, u.mgnr;
DROP VIEW v_auto_business_shares;
CREATE VIEW v_auto_business_shares AS
SELECT (SUBSTR(h.date, 1, 4) + 0) AS year,
h.to_mgnr AS mgnr,
SUM(h.shares) AS shares,
SUM(h.shares * COALESCE(h.value_per_share, 0)) AS total_amount
FROM member_history h
WHERE h.reason = 'auto' AND h.source = 'elwig'
GROUP BY year, h.to_mgnr
ORDER BY year, h.to_mgnr;
PRAGMA writable_schema = OFF;
+10 -29
View File
@@ -8,8 +8,6 @@ using Microsoft.EntityFrameworkCore;
using Elwig.Documents; using Elwig.Documents;
using Elwig.Helpers.Export; using Elwig.Helpers.Export;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Microsoft.Win32;
using System.Windows.Input;
using System.Windows; using System.Windows;
using System; using System;
using LinqKit; using LinqKit;
@@ -261,37 +259,20 @@ namespace Elwig.Services {
.ThenBy(a => a.Member.MgNr); .ThenBy(a => a.Member.MgNr);
if (mode == ExportMode.SaveList) { if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile(DeliveryAncmtList.Name, DeliveryAncmtList.Name, "ods");
FileName = $"{DeliveryAncmtList.Name}.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", var data = await DeliveryAncmtListData.FromQuery(query, filterNames);
Title = $"{DeliveryAncmtList.Name} speichern unter - Elwig" using var ods = new OdsFile(filename);
}; await ods.AddTable(data);
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await DeliveryAncmtListData.FromQuery(query, filterNames);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} else { } else {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { var data = await DeliveryAncmtListData.FromQuery(query, filterNames);
try { using var doc = new DeliveryAncmtList(string.Join(" / ", filterNames), data);
var data = await DeliveryAncmtListData.FromQuery(query, filterNames); await Utils.ExportDocument(doc, mode);
using var doc = new DeliveryAncmtList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
+81 -174
View File
@@ -3,11 +3,9 @@ using Elwig.Helpers.Export;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Microsoft.Win32;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows; using System.Windows;
using System; using System;
using Elwig.ViewModels; using Elwig.ViewModels;
@@ -727,16 +725,10 @@ namespace Elwig.Services {
} }
public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) { public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { using var doc = await DeliveryNote.Initialize(year, did);
try { await Utils.ExportDocument(doc, mode, doc.Delivery.LsNr, (doc.Member, $"{DeliveryNote.Name} Nr. {doc.Delivery.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {doc.Delivery.LsNr}"));
using var doc = await DeliveryNote.Initialize(year, did);
await Utils.ExportDocument(doc, mode, doc.Delivery.LsNr, (doc.Member, $"{DeliveryNote.Name} Nr. {doc.Delivery.LsNr}", $"Im Anhang finden Sie den {DeliveryNote.Name} Nr. {doc.Delivery.LsNr}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
public static async Task GenerateDeliveryJournal(this DeliveryAdminViewModel vm, ExportSubject subject, ExportMode mode) { public static async Task GenerateDeliveryJournal(this DeliveryAdminViewModel vm, ExportSubject subject, ExportMode mode) {
@@ -773,75 +765,44 @@ namespace Elwig.Services {
.ThenBy(p => p.DPNr); .ThenBy(p => p.DPNr);
if (mode == ExportMode.SaveList) { if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile(DeliveryJournal.Name, DeliveryJournal.Name, "ods");
FileName = $"{DeliveryJournal.Name}.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", var data = await DeliveryJournalData.FromQuery(query, filterNames);
Title = $"{DeliveryJournal.Name} speichern unter - Elwig" using var ods = new OdsFile(filename);
}; await ods.AddTable(data);
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile(DeliveryJournal.Name, subject == ExportSubject.Selected ? $"Lieferung_{vm.SelectedDelivery?.LsNr}" : $"Lieferungen_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}", "elwig.zip");
FileName = subject == ExportSubject.Selected ? $"Lieferung_{vm.SelectedDelivery?.LsNr}.elwig.zip" : $"Lieferungen_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip", if (filename != null) {
DefaultExt = "elwig.zip", if (!filename.EndsWith(".elwig.zip")) filename += ".elwig.zip";
Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip", await Utils.RunForeground(async () => {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig", var list = await query
AddExtension = false, .Select(p => p.Delivery)
}; .Distinct()
if (d.ShowDialog() == true) { .Include(d => d.Parts).ThenInclude(p => p.PartModifiers)
if (!d.FileName.EndsWith(".elwig.zip")) d.FileName += ".elwig.zip"; .ToListAsync();
Mouse.OverrideCursor = Cursors.Wait; var wbKgs = list
await Task.Run(async () => { .SelectMany(d => d.Parts)
try { .Where(p => p.Kg != null)
var list = await query .Select(p => p.Kg!)
.Select(p => p.Delivery) .DistinctBy(k => k.KgNr)
.Distinct() .OrderBy(k => k.KgNr)
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers) .ToList();
.ToListAsync(); await ElwigData.Export(filename, list, wbKgs, filterNames);
var wbKgs = list
.SelectMany(d => d.Parts)
.Where(p => p.Kg != null)
.Select(p => p.Kg!)
.DistinctBy(k => k.KgNr)
.OrderBy(k => k.KgNr)
.ToList();
await ElwigData.Export(d.FileName, list, wbKgs, filterNames);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) { } else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => {
await SyncService.Upload(App.Config.SyncUrl, App.Config.SyncUrl, App.Config.SyncPassword, query, filterNames); await SyncService.Upload(App.Config.SyncUrl, App.Config.SyncUrl, App.Config.SyncPassword, query, filterNames);
}); });
Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { var data = await DeliveryJournalData.FromQuery(query, filterNames);
try { using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data);
var data = await DeliveryJournalData.FromQuery(query, filterNames); await Utils.ExportDocument(doc, mode);
using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
@@ -862,17 +823,11 @@ namespace Elwig.Services {
throw new ArgumentException("Invalid value for ExportSubject"); throw new ArgumentException("Invalid value for ExportSubject");
} }
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList);
try { using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data);
var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList); await Utils.ExportDocument(doc, mode);
using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
public static async Task GenerateLocalityStatistics(this DeliveryAdminViewModel vm, ExportSubject subject) { public static async Task GenerateLocalityStatistics(this DeliveryAdminViewModel vm, ExportSubject subject) {
@@ -888,24 +843,13 @@ namespace Elwig.Services {
throw new ArgumentException("Invalid value for ExportSubject"); throw new ArgumentException("Invalid value for ExportSubject");
} }
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Lieferstatistik pro Ort", $"Lieferstatistik-{vm.FilterSeason ?? Utils.CurrentLastSeason}", "ods");
FileName = $"Lieferstatistik-{vm.FilterSeason ?? Utils.CurrentLastSeason}.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", using var ods = new OdsFile(filename);
Title = $"Lieferstatistik pro Ort speichern unter - Elwig" var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames);
}; await ods.AddTable(tbl);
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ods = new OdsFile(d.FileName);
var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames);
await ods.AddTable(tbl);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
@@ -936,45 +880,28 @@ namespace Elwig.Services {
filterNames.Remove("abgewertet"); filterNames.Remove("abgewertet");
if (mode == ExportMode.SaveList) { if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile(DeliveryDepreciationList.Name, $"{DeliveryDepreciationList.Name}-{vm.FilterSeason ?? Utils.CurrentLastSeason}", "ods");
FileName = $"{DeliveryDepreciationList.Name}-{vm.FilterSeason ?? Utils.CurrentLastSeason}.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", using var ods = new OdsFile(filename);
Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig" var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames);
}; tblTotal.FullName = DeliveryDepreciationList.Name;
if (d.ShowDialog() == true) { tblTotal.Name = "Gesamt";
Mouse.OverrideCursor = Cursors.Wait; await ods.AddTable(tblTotal);
await Task.Run(async () => { foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
try { var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
using var ods = new OdsFile(d.FileName); tbl.FullName = DeliveryDepreciationList.Name;
var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames); tbl.Name = branch.Name;
tblTotal.FullName = DeliveryDepreciationList.Name; await ods.AddTable(tbl);
tblTotal.Name = "Gesamt";
await ods.AddTable(tblTotal);
foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
var tbl = await DeliveryJournalData.FromQuery(query.Where(p => p.Delivery.ZwstId == branch.ZwstId), filterNames);
tbl.FullName = DeliveryDepreciationList.Name;
tbl.Name = branch.Name;
await ods.AddTable(tbl);
}
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
}); });
Mouse.OverrideCursor = null;
} }
} else { } else {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { var data = await DeliveryJournalData.FromQuery(query, filterNames);
try { using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
var data = await DeliveryJournalData.FromQuery(query, filterNames); await Utils.ExportDocument(doc, mode);
using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
@@ -1001,26 +928,15 @@ namespace Elwig.Services {
.ThenBy(p => p.AttrId) .ThenBy(p => p.AttrId)
.ThenBy(p => p.CultId); .ThenBy(p => p.CultId);
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Liefermengen", "Liefermengen", "ods");
FileName = $"Liefermengen.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", using var ods = new OdsFile(filename);
Title = $"Liefermengen speichern unter - Elwig" var tblTotal = await MemberDeliveryData.FromQuery(query, filterNames);
}; var tbl = await MemberDeliveryPerVarietyData.FromQuery(query, filterNames);
if (d.ShowDialog() == true) { await ods.AddTable(tblTotal);
Mouse.OverrideCursor = Cursors.Wait; await ods.AddTable(tbl);
await Task.Run(async () => {
try {
using var ods = new OdsFile(d.FileName);
var tblTotal = await MemberDeliveryData.FromQuery(query, filterNames);
var tbl = await MemberDeliveryPerVarietyData.FromQuery(query, filterNames);
await ods.AddTable(tblTotal);
await ods.AddTable(tbl);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
@@ -1219,12 +1135,11 @@ namespace Elwig.Services {
attrid = $"'{attr.AttrId}'"; attrid = $"'{attr.AttrId}'";
} }
var dids = await vm.GetDidsFromFilters(); var dids = await vm.GetDidsFromFilters();
var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) das Attribut\n'{attributeName}' gesetz werden?", if (!InteractionService.AskContinue("Massenaktion: Attribut setzen",
"Massenaktion: Attribut setzen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); $"Soll wirklich für {dids.Length:N0} Teillieferung(en) das Attribut\n'{attributeName}' gesetz werden?"))
if (res != MessageBoxResult.OK) return; return;
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => {
using (var cnx = await AppDbContext.ConnectAsync()) { using (var cnx = await AppDbContext.ConnectAsync()) {
await cnx.ExecuteBatch($""" await cnx.ExecuteBatch($"""
UPDATE delivery_part SET attrid = {attrid} UPDATE delivery_part SET attrid = {attrid}
@@ -1234,9 +1149,7 @@ namespace Elwig.Services {
App.HintContextChange(); App.HintContextChange();
}); });
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} finally {
Mouse.OverrideCursor = null;
} }
} }
@@ -1249,12 +1162,11 @@ namespace Elwig.Services {
} }
var dids = await vm.GetDidsFromFilters(); var dids = await vm.GetDidsFromFilters();
var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' hinzugefügt werden?", if (!InteractionService.AskContinue("Massenaktion: Zu-/Abschlag hinzufügen",
"Massenaktion: Zu-/Abschlag hinzufügen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); $"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' hinzugefügt werden?"))
if (res != MessageBoxResult.OK) return; return;
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => {
using (var cnx = await AppDbContext.ConnectAsync()) { using (var cnx = await AppDbContext.ConnectAsync()) {
await cnx.ExecuteBatch($""" await cnx.ExecuteBatch($"""
INSERT INTO delivery_part_modifier (year, did, dpnr, modid) INSERT INTO delivery_part_modifier (year, did, dpnr, modid)
@@ -1265,9 +1177,7 @@ namespace Elwig.Services {
App.HintContextChange(); App.HintContextChange();
}); });
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} finally {
Mouse.OverrideCursor = null;
} }
} }
@@ -1280,12 +1190,11 @@ namespace Elwig.Services {
} }
var dids = await vm.GetDidsFromFilters(); var dids = await vm.GetDidsFromFilters();
var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' entfernt werden?", if (!InteractionService.AskContinue("Massenaktion: Zu-/Abschlag entfernen",
"Massenaktion: Zu-/Abschlag entfernen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); $"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' entfernt werden?"))
if (res != MessageBoxResult.OK) return; return;
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => {
using (var cnx = await AppDbContext.ConnectAsync()) { using (var cnx = await AppDbContext.ConnectAsync()) {
await cnx.ExecuteBatch($""" await cnx.ExecuteBatch($"""
DELETE FROM delivery_part_modifier DELETE FROM delivery_part_modifier
@@ -1295,9 +1204,7 @@ namespace Elwig.Services {
App.HintContextChange(); App.HintContextChange();
}); });
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} finally {
Mouse.OverrideCursor = null;
} }
} }
} }
+150
View File
@@ -0,0 +1,150 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Windows;
namespace Elwig.Services {
public static class InteractionService {
public static Func<string, string, string, string?>? Override;
public static Action<string, string>? NextInformation;
public static Action<string, string>? NextWarning;
public static Action<string, string>? NextError;
public static Func<string, string, bool>? NextContinue;
public static Func<string, string, bool>? NextConfirmation;
public static Func<string, string, bool>? NextQuestion;
public static Func<string, string, string?>? NextSave;
public static readonly Dictionary<string, string> ExtensionFilters = new() {
["pdf"] = "PDF-Datei (*.pdf)|*.pdf",
["ods"] = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
["vcf"] = "vCard-Datei (*.vcf)|*.vcf",
["xml"] = "EBICS-Datei (*.xml)|*.xml",
["csv"] = "CSV-Datei (*.csv)|*.csv",
["sql.zip"] = "Komprimierte SQL-Datei (*.sql.zip)|*.sql.zip",
["elwig.zip"] = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip",
};
public static void ShowInformation(string title, string text) {
if (NextInformation != null) {
NextInformation(title, text);
NextInformation = null;
} else if (Override != null) {
Override("information", title, text);
} else {
MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Information);
}
}
public static bool AskContinue(string title, string text) {
if (NextContinue != null) {
var r = NextContinue(title, text);
NextContinue = null;
return r;
} else if (Override != null) {
return Override("continue", title, text) != null;
} else {
return MessageBox.Show(text, title, MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel) == MessageBoxResult.OK;
}
}
public static bool AskConfirmation(string title, string text) {
if (NextConfirmation != null) {
var r = NextConfirmation(title, text);
NextConfirmation = null;
return r;
} else if (Override != null) {
return Override("confirm", title, text) != null;
} else {
return MessageBox.Show(text, title, MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No) == MessageBoxResult.Yes;
}
}
public static bool AskQuestion(string title, string text, bool defaultResult) {
if (NextQuestion != null) {
var r = NextQuestion(title, text);
NextQuestion = null;
return r;
} else if (Override != null) {
return Override("question", title, text) != null;
} else {
return MessageBox.Show(text, title, MessageBoxButton.YesNo, MessageBoxImage.Question, defaultResult ? MessageBoxResult.Yes : MessageBoxResult.No) == MessageBoxResult.Yes;
}
}
public static void ShowWarning(string title, string text) {
if (NextWarning != null) {
NextWarning(title, text);
NextWarning = null;
} else if (Override != null) {
Override("warning", title, text);
} else {
MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Warning);
}
}
public static void ShowError(string title, string text) {
if (NextError != null) {
NextError(title, text);
NextError = null;
} else if (Override != null) {
Override("error", title, text);
} else {
MessageBox.Show(text, title, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public static void ShowException(Exception exc, bool showExcType = false, bool isError = true) {
ShowException("Fehler", exc, showExcType, isError);
}
public static void ShowException(string title, Exception exc, bool showExcType = false, bool isError = true) {
ShowException(title, null, exc, showExcType, isError);
}
public static void ShowException(string title, string? text, Exception exc, bool showExcType = false, bool isError = true) {
text = text == null ? "" : text + (text.EndsWith('.') || text.EndsWith('!') || text.EndsWith('?') ? "" : ":") + "\n\n";
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
if (isError) {
ShowError(title, text);
} else {
ShowWarning(title, text);
}
}
public static void ShowDbException(string title, Exception exc) {
ShowException(title, "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!", exc);
}
public static bool AskException(string title, string? text, Exception exc) {
text = text == null ? "" : text + (text.EndsWith('.') || text.EndsWith('!') || text.EndsWith('?') ? "" : ":") + "\n\n";
text += exc.Message;
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
if (Override != null) {
return Override("error", title, text) != null;
} else {
return MessageBox.Show(text, title, MessageBoxButton.YesNo, MessageBoxImage.Error, MessageBoxResult.No) == MessageBoxResult.Yes;
}
}
public static string? SaveFile(string title, string defaultFileName, string extension) {
if (NextSave != null) {
var r = NextSave(title, $"{defaultFileName}.{extension}");
NextSave = null;
return r;
} else if (Override != null) {
return Override("save", title, $"{defaultFileName}.{extension}");
} else {
var d = new SaveFileDialog() {
FileName = $"{defaultFileName}.{extension}",
DefaultExt = extension,
Filter = ExtensionFilters.GetValueOrDefault(extension, ""),
Title = $"{title} speichern unter - Elwig",
AddExtension = !extension.Contains('.'),
};
return d.ShowDialog() == true ? d.FileName : null;
}
}
}
}
+76 -121
View File
@@ -6,13 +6,10 @@ using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.ViewModels; using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Elwig.Services { namespace Elwig.Services {
public static class MemberService { public static class MemberService {
@@ -129,7 +126,15 @@ namespace Elwig.Services {
vm.EntryDate = (m.EntryDateString != null) ? string.Join(".", m.EntryDateString.Split("-").Reverse()) : null; vm.EntryDate = (m.EntryDateString != null) ? string.Join(".", m.EntryDateString.Split("-").Reverse()) : null;
vm.ExitDate = (m.ExitDateString != null) ? string.Join(".", m.ExitDateString.Split("-").Reverse()) : null; vm.ExitDate = (m.ExitDateString != null) ? string.Join(".", m.ExitDateString.Split("-").Reverse()) : null;
vm.BusinessShares = m.BusinessShares; if (App.Client.HasRedWhite) {
vm.BusinessShares1 = m.SharesRed;
vm.BusinessShares2 = m.SharesWhite;
vm.BusinessShares3 = m.SharesDormant + m.Shares;
} else {
vm.BusinessShares1 = m.Shares;
vm.BusinessShares2 = m.SharesDormant + m.SharesRed + m.SharesWhite;
vm.BusinessShares3 = 0;
}
vm.AccountingNr = m.AccountingNr; vm.AccountingNr = m.AccountingNr;
vm.Branch = (Branch?)ControlUtils.GetItemFromSourceWithPk(vm.BranchSource, m.ZwstId); vm.Branch = (Branch?)ControlUtils.GetItemFromSourceWithPk(vm.BranchSource, m.ZwstId);
vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr); vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr);
@@ -392,47 +397,29 @@ namespace Elwig.Services {
} }
public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) { public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { using var doc = new MemberDataSheet(m);
try { await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
using var doc = new MemberDataSheet(m);
await Utils.ExportDocument(doc, mode, emailData: (m, MemberDataSheet.Name, "Im Anhang finden Sie das aktuelle Stammdatenblatt"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) { public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { var b = await Billing.Create(year);
try { await b.FinishSeason();
var b = await Billing.Create(year); await b.CalculateBuckets();
await b.FinishSeason(); App.HintContextChange();
await b.CalculateBuckets();
App.HintContextChange();
using var doc = new DeliveryConfirmation(year, m, null); using var doc = new DeliveryConfirmation(year, m, null);
await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}")); await Utils.ExportDocument(doc, mode, emailData: (m, $"{DeliveryConfirmation.Name} {year}", $"Im Anhang finden Sie die Anlieferungsbestätigung {year}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) { public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { using var doc = await CreditNote.Initialize(year, avnr, m.MgNr, null);
try { await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {doc.Payment.Variant.Name}", $"Im Anhang finden Sie die Traubengutschrift {doc.Payment.Variant.Name}"));
using var doc = await CreditNote.Initialize(year, avnr, m.MgNr, null);
await Utils.ExportDocument(doc, mode, emailData: (m, $"{CreditNote.Name} {doc.Payment.Variant.Name}", $"Im Anhang finden Sie die Traubengutschrift {doc.Payment.Variant.Name}"));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
public static async Task GenerateMemberList(this MemberAdminViewModel vm, ExportSubject subject, ExportMode mode) { public static async Task GenerateMemberList(this MemberAdminViewModel vm, ExportSubject subject, ExportMode mode) {
@@ -477,104 +464,69 @@ namespace Elwig.Services {
} }
if (mode == ExportMode.SaveList) { if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile(MemberList.Name, MemberList.Name, "ods");
FileName = $"{MemberList.Name}.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
Title = $"{MemberList.Name} speichern unter - Elwig" using var ods = new OdsFile(filename);
}; await ods.AddTable(data);
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Vcf) { } else if (mode == ExportMode.Vcf) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Kontakte", "Mitglieder", "vcf");
FileName = "Mitglieder.vcf", if (filename != null) {
DefaultExt = "vcf", await Utils.RunForeground(async () => {
Filter = "vCard-Datei (*.vcf)|*.vcf", var members = await query
Title = "Kontakte speichern unter - Elwig" .OrderBy(m => m.MgNr)
}; .Include(m => m.TelephoneNumbers)
if (d.ShowDialog() == true) { .Include(m => m.EmailAddresses)
Mouse.OverrideCursor = Cursors.Wait; .ToListAsync();
await Task.Run(async () => { using var exporter = new VCard(filename);
try { await exporter.ExportAsync(members);
var members = await query
.OrderBy(m => m.MgNr)
.Include(m => m.TelephoneNumbers)
.Include(m => m.EmailAddresses)
.ToListAsync();
using var exporter = new VCard(d.FileName);
await exporter.ExportAsync(members);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile(MemberList.Name, subject == ExportSubject.Selected ? $"Mitglied_{vm.SelectedMember?.MgNr}" : $"Mitglieder_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}", "elwig.zip");
FileName = subject == ExportSubject.Selected ? $"Mitglied_{vm.SelectedMember?.MgNr}.elwig.zip" : $"Mitglieder_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip", if (filename != null) {
DefaultExt = "elwig.zip", if (!filename.EndsWith(".elwig.zip")) filename += ".elwig.zip";
Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip", await Utils.RunForeground(async () => {
Title = $"{MemberList.Name} speichern unter - Elwig", var members = await query
AddExtension = false, .OrderBy(m => m.MgNr)
}; .Include(m => m.TelephoneNumbers)
if (d.ShowDialog() == true) { .Include(m => m.EmailAddresses)
if (!d.FileName.EndsWith(".elwig.zip")) d.FileName += ".elwig.zip"; .ToListAsync();
Mouse.OverrideCursor = Cursors.Wait; var history1 = await query.IgnoreAutoIncludes()
await Task.Run(async () => { .SelectMany(m => m.HistoryFrom)
try { .ToListAsync();
var members = await query var history2 = await query.IgnoreAutoIncludes()
.OrderBy(m => m.MgNr) .SelectMany(m => m.HistoryTo)
.Include(m => m.TelephoneNumbers) .ToListAsync();
.Include(m => m.EmailAddresses) var history = history1.Union(history2).DistinctBy(h => h.HistNr).OrderBy(h => h.HistNr).ToList();
.ToListAsync(); var areaComs = await query
var areaComs = await query .SelectMany(m => m.AreaCommitments)
.SelectMany(m => m.AreaCommitments) .Select(c => c.Contract).Distinct()
.Select(c => c.Contract).Distinct() .Include(c => c.Revisions)
.Include(c => c.Revisions) .ToListAsync();
.ToListAsync(); var wbKgs = members
var wbKgs = members .Where(m => m.DefaultWbKg != null)
.Where(m => m.DefaultWbKg != null) .Select(m => m.DefaultWbKg!)
.Select(m => m.DefaultWbKg!) .Union(areaComs.Select(c => c.Kg))
.Union(areaComs.Select(c => c.Kg)) .Distinct()
.Distinct() .OrderBy(k => k.KgNr)
.OrderBy(k => k.KgNr) .ToList();
.ToList(); await ElwigData.Export(filename, members, history, areaComs, wbKgs, filterNames);
await ElwigData.Export(d.FileName, members, areaComs, wbKgs, filterNames);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) { } else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => {
await SyncService.Upload(App.Config.SyncUrl, App.Config.SyncUrl, App.Config.SyncPassword, query, filterNames); await SyncService.Upload(App.Config.SyncUrl, App.Config.SyncUrl, App.Config.SyncPassword, query, filterNames);
}); });
Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
try { using var doc = new MemberList(string.Join(" / ", filterNames), data);
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); await Utils.ExportDocument(doc, mode);
using var doc = new MemberList(string.Join(" / ", filterNames), data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
@@ -605,7 +557,10 @@ namespace Elwig.Services {
EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()), EntryDateString = string.IsNullOrEmpty(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()),
ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()), ExitDateString = string.IsNullOrEmpty(vm.ExitDate) ? null : string.Join("-", vm.ExitDate.Split(".").Reverse()),
BusinessShares = (int)vm.BusinessShares!, Shares = App.Client.HasRedWhite ? 0 : vm.BusinessShares1 ?? 0,
SharesRed = App.Client.HasRedWhite ? vm.BusinessShares1 ?? 0 : 0,
SharesWhite = App.Client.HasRedWhite ? vm.BusinessShares2 ?? 0 : 0,
SharesDormant = App.Client.HasRedWhite ? vm.BusinessShares3 ?? 0 : vm.BusinessShares2 ?? 0,
AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr, AccountingNr = string.IsNullOrEmpty(vm.AccountingNr) ? null : vm.AccountingNr,
IsActive = vm.IsActive, IsActive = vm.IsActive,
IsVollLieferant = vm.IsVollLieferant, IsVollLieferant = vm.IsVollLieferant,
+33 -76
View File
@@ -6,14 +6,12 @@ using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.ViewModels; using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Input;
namespace Elwig.Services { namespace Elwig.Services {
public static class PaymentVariantService { public static class PaymentVariantService {
@@ -190,37 +188,20 @@ namespace Elwig.Services {
public static async Task GenerateSummary(PaymentVar v, ExportMode mode) { public static async Task GenerateSummary(PaymentVar v, ExportMode mode) {
if (mode == ExportMode.SaveList) { if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile($"Variantendaten {v.Name}", $"Variantendaten-{v.Name.Trim().Replace(' ', '-')}", "ods");
FileName = $"Variantendaten-{v.Name.Trim().Replace(' ', '-')}.ods", if (filename == null)
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Variantendaten {v.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { using var ctx = new AppDbContext();
try { var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var ctx = new AppDbContext(); using var ods = new OdsFile(filename);
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows); await ods.AddTable(data);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.Wait; await Utils.RunForeground(async () => {
await Task.Run(async () => { using var doc = await PaymentVariantSummary.Initialize(v.Year, v.AvNr);
try { await Utils.ExportDocument(doc, mode);
using var doc = await PaymentVariantSummary.Initialize(v.Year, v.AvNr);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
@@ -230,57 +211,35 @@ namespace Elwig.Services {
var withoutIban = v.Credits.Count(c => c.Member.Iban == null); var withoutIban = v.Credits.Count(c => c.Member.Iban == null);
if (withoutIban > 0) { if (withoutIban > 0) {
var r = MessageBox.Show($"Achtung: Für {withoutIban:N0} Mitglieder ist kein IBAN hinterlegt.\n\nDiese werden NICHT exportiert.", if (!InteractionService.AskContinue("Mitglieder ohne IBAN",
"Mitglieder ohne IBAN", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); $"Achtung: Für {withoutIban:N0} Mitglieder ist kein IBAN hinterlegt.\n\nDiese werden NICHT exportiert."))
if (r != MessageBoxResult.OK) return; return;
} }
var withNegAmount = v.Credits.Count(c => c.Amount <= 0); var withNegAmount = v.Credits.Count(c => c.Amount <= 0);
if (withNegAmount > 0) { if (withNegAmount > 0) {
var r = MessageBox.Show($"Achtung: Es gibt {withNegAmount:N0} Traubengutschriften mit negativem Betrag.\n\nDiese werden NICHT exportiert.", if (!InteractionService.AskContinue("Traubengutschriften mit negativem Betrag",
"Traubengutschriften mit negativem Betrag", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.OK); $"Achtung: Es gibt {withNegAmount:N0} Traubengutschriften mit negativem Betrag.\n\nDiese werden NICHT exportiert."))
if (r != MessageBoxResult.OK) return; return;
} }
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Überweisungsdaten", $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}", Ebics.FileExtension);
FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}", if (filename != null) {
DefaultExt = Ebics.FileExtension, await Utils.RunForeground(async () => {
Filter = "EBICS-Datei (*.xml)|*.xml", using var e = new Ebics(v, filename, App.Client.ExportEbicsVersion, (Ebics.AddressMode)App.Client.ExportEbicsAddress);
Title = $"Überweisungsdaten speichern unter - Elwig", await e.ExportAsync(Transaction.FromPaymentVariant(v));
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var e = new Ebics(v, d.FileName, App.Client.ExportEbicsVersion, (Ebics.AddressMode)App.Client.ExportEbicsAddress);
await e.ExportAsync(Transaction.FromPaymentVariant(v));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
}); });
Mouse.OverrideCursor = null;
} }
} }
public static async Task GenerateAccountingList(int year, int avnr, string name) { public static async Task GenerateAccountingList(int year, int avnr, string name) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Buchungsliste", $"{App.Client.NameToken}-Buchungsliste-{year}-{name.Trim().Replace(' ', '-')}", "ods");
FileName = $"{App.Client.NameToken}-Buchungsliste-{year}-{name.Trim().Replace(' ', '-')}.ods", if (filename != null) {
DefaultExt = "ods", await Utils.RunForeground(async () => {
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", using var ctx = new AppDbContext();
Title = $"Buchungsliste speichern unter - Elwig" var tbl = await CreditNoteData.ForPaymentVariant(ctx, year, avnr);
}; using var ods = new OdsFile(filename);
if (d.ShowDialog() == true) { await ods.AddTable(tbl);
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
var tbl = await CreditNoteData.ForPaymentVariant(ctx, year, 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;
} }
} }
@@ -383,11 +342,10 @@ namespace Elwig.Services {
} }
} }
if (membersLess.Count > 0) { if (membersLess.Count > 0) {
var res = MessageBox.Show($"Achtung: Bei {membersLess.Count:N0} Mitglied(ern) ist der Soll-Betrag der Auszahlung (\"Gesamtbetrag\") kleiner als bei der letzten Auszahlung. Das sollte nicht vorkommen!\n\n" + if (!InteractionService.AskContinue("Kleinerer Gesamtbetrag",
$"Achtung: Bei {membersLess.Count:N0} Mitglied(ern) ist der Soll-Betrag der Auszahlung (\"Gesamtbetrag\") kleiner als bei der letzten Auszahlung. Das sollte nicht vorkommen!\n\n" +
$"{string.Join(", ", membersLess.Select(m => $"{m.AdministrativeName} ({m.MgNr})"))}\n\n" + $"{string.Join(", ", membersLess.Select(m => $"{m.AdministrativeName} ({m.MgNr})"))}\n\n" +
"Soll trotzdem forgefahren werden?", "Soll trotzdem forgefahren werden?"))
"Kleinerer Gesamtbetrag", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (res != MessageBoxResult.OK)
return; return;
} }
@@ -401,9 +359,8 @@ namespace Elwig.Services {
membersNeg = await ctx.Credits.Where(c => c.Year == year && c.AvNr == avnr && c.AmountValue < 0).Select(c => c.Member).ToListAsync(); membersNeg = await ctx.Credits.Where(c => c.Year == year && c.AvNr == avnr && c.AmountValue < 0).Select(c => c.Member).ToListAsync();
} }
if (membersNeg.Count > 0) { if (membersNeg.Count > 0) {
var res = MessageBox.Show($"Achtung: Bei {membersNeg.Count:N0} Mitglied(ern) ist der Auszahlungsbetrag negativ!\n\n" + InteractionService.ShowWarning("Negativer Auszahlungsbetrag", $"Achtung: Bei {membersNeg.Count:N0} Mitglied(ern) ist der Auszahlungsbetrag negativ!\n\n" +
$"{string.Join(", ", membersNeg.Select(m => $"{m.AdministrativeName} ({m.MgNr})"))}", $"{string.Join(", ", membersNeg.Select(m => $"{m.AdministrativeName} ({m.MgNr})"))}");
"Negativer Auszahlungsbetrag", MessageBoxButton.OK, MessageBoxImage.Warning);
} }
} }
+31 -33
View File
@@ -10,7 +10,6 @@ using System.Linq;
using System.Linq.Expressions; using System.Linq.Expressions;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows;
namespace Elwig.Services { namespace Elwig.Services {
public static class SyncService { public static class SyncService {
@@ -28,6 +27,13 @@ namespace Elwig.Services {
.Include(m => m.TelephoneNumbers) .Include(m => m.TelephoneNumbers)
.Include(m => m.EmailAddresses) .Include(m => m.EmailAddresses)
.ToListAsync(); .ToListAsync();
var history1 = await query.IgnoreAutoIncludes()
.SelectMany(m => m.HistoryFrom)
.ToListAsync();
var history2 = await query.IgnoreAutoIncludes()
.SelectMany(m => m.HistoryTo)
.ToListAsync();
var history = history1.Union(history2).DistinctBy(h => h.HistNr).OrderBy(h => h.HistNr).ToList();
var areaComs = await query var areaComs = await query
.SelectMany(m => m.AreaCommitments) .SelectMany(m => m.AreaCommitments)
.Select(c => c.Contract).Distinct() .Select(c => c.Contract).Distinct()
@@ -42,22 +48,20 @@ namespace Elwig.Services {
.OrderBy(k => k.KgNr) .OrderBy(k => k.KgNr)
.ToList(); .ToList();
if (members.Count == 0) { if (members.Count == 0) {
MessageBox.Show("Es wurden keine Mitglieder zum Hochladen ausgewählt!", "Mitglieder hochladen", InteractionService.ShowError("Mitglieder hochladen", "Es wurden keine Mitglieder zum Hochladen ausgewählt!");
MessageBoxButton.OK, MessageBoxImage.Error);
} else { } else {
var exportedAt = DateTime.Now; var exportedAt = DateTime.Now;
await ElwigData.Export(path, members, areaComs, wbKgs, filterNames); await ElwigData.Export(path, members, history, areaComs, wbKgs, filterNames);
await Utils.UploadExportData(path, url, username, password); await Utils.UploadExportData(path, url, username, password);
await UpdateExportedAt(members, areaComs, [], exportedAt); await UpdateExportedAt(members, areaComs, [], exportedAt);
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!", "Mitglieder hochgeladen", InteractionService.ShowInformation("Mitglieder hochgeladen", $"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!");
MessageBoxButton.OK, MessageBoxImage.Information);
} }
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Mitglieder hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Mitglieder hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Mitglieder hochladen", exc);
} }
} }
@@ -78,22 +82,20 @@ namespace Elwig.Services {
.OrderBy(k => k.KgNr) .OrderBy(k => k.KgNr)
.ToList(); .ToList();
if (list.Count == 0) { if (list.Count == 0) {
MessageBox.Show("Es wurden keine Lieferungen zum Hochladen ausgewählt!", "Lieferungen hochladen", InteractionService.ShowError("Lieferungen hochladen", "Es wurden keine Lieferungen zum Hochladen ausgewählt!");
MessageBoxButton.OK, MessageBoxImage.Error);
} else { } else {
var exportedAt = DateTime.Now; var exportedAt = DateTime.Now;
await ElwigData.Export(path, list, wbKgs, filterNames); await ElwigData.Export(path, list, wbKgs, filterNames);
await Utils.UploadExportData(path, url, username, password); await Utils.UploadExportData(path, url, username, password);
await UpdateExportedAt([], [], list, exportedAt); await UpdateExportedAt([], [], list, exportedAt);
MessageBox.Show($"Hochladen von {list.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochgeladen", InteractionService.ShowInformation("Lieferungen hochgeladen", $"Hochladen von {list.Count:N0} Lieferungen erfolgreich!");
MessageBoxButton.OK, MessageBoxImage.Information);
} }
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Lieferungen hochladen", exc);
} }
} }
@@ -132,8 +134,7 @@ namespace Elwig.Services {
.OrderBy(k => k.KgNr) .OrderBy(k => k.KgNr)
.ToList(); .ToList();
if (members.Count == 0 && deliveries.Count == 0) { if (members.Count == 0 && deliveries.Count == 0) {
MessageBox.Show("Es gibt keine geänderten Mitglieder oder Lieferungen, die hochgeladen werden könnten!", "Mitglieder und Lieferungen hochladen", InteractionService.ShowInformation("Mitglieder und Lieferungen hochladen", "Es gibt keine geänderten Mitglieder oder Lieferungen, die hochgeladen werden könnten!");
MessageBoxButton.OK, MessageBoxImage.Information);
} else { } else {
var exportedAt = DateTime.Now; var exportedAt = DateTime.Now;
await (new ElwigData.ElwigExport { await (new ElwigData.ElwigExport {
@@ -144,15 +145,14 @@ namespace Elwig.Services {
}).Export(path); }).Export(path);
await Utils.UploadExportData(path, url, username, password); await Utils.UploadExportData(path, url, username, password);
await UpdateExportedAt(members, areaComs, deliveries, exportedAt); await UpdateExportedAt(members, areaComs, deliveries, exportedAt);
MessageBox.Show($"Hochladen von {members.Count:N0} Mitgliedern, {areaComs.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!", "Mitglieder und Lieferungen hochladen", InteractionService.ShowInformation("Mitglieder und Lieferungen hochladen", $"Hochladen von {members.Count:N0} Mitgliedern, {areaComs.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!");
MessageBoxButton.OK, MessageBoxImage.Information);
} }
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder und Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Mitglieder und Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Mitglieder und Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Mitglieder und Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Mitglieder und Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Mitglieder und Lieferungen hochladen", exc);
} }
} }
@@ -173,22 +173,20 @@ namespace Elwig.Services {
.DistinctBy(k => k.KgNr) .DistinctBy(k => k.KgNr)
.ToList(); .ToList();
if (deliveries.Count == 0) { if (deliveries.Count == 0) {
MessageBox.Show("Es gibt keine Lieferungen, die hochgeladen werden können!", "Lieferungen hochladen", InteractionService.ShowError("Lieferungen hochladen", "Es gibt keine Lieferungen, die hochgeladen werden können!");
MessageBoxButton.OK, MessageBoxImage.Error);
} else { } else {
var exportedAt = DateTime.Now; var exportedAt = DateTime.Now;
await ElwigData.Export(path, deliveries, wbKgs, [$"{year}", $"Zweigstelle {App.BranchName}"]); await ElwigData.Export(path, deliveries, wbKgs, [$"{year}", $"Zweigstelle {App.BranchName}"]);
await Utils.UploadExportData(path, url, username, password); await Utils.UploadExportData(path, url, username, password);
await UpdateExportedAt([], [], deliveries, exportedAt); await UpdateExportedAt([], [], deliveries, exportedAt);
MessageBox.Show($"Hochladen von {deliveries.Count:N0} Lieferungen erfolgreich!", "Lieferungen hochladen", InteractionService.ShowInformation("Lieferungen hochladen", $"Hochladen von {deliveries.Count:N0} Lieferungen erfolgreich!");
MessageBoxButton.OK, MessageBoxImage.Information);
} }
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Lieferungen hochladen", exc);
} }
} }
@@ -227,11 +225,11 @@ namespace Elwig.Services {
} }
await ElwigData.Import(paths, ElwigData.ImportMode.FromBranches); await ElwigData.Import(paths, ElwigData.ImportMode.FromBranches);
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Daten herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Daten herunterladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Daten herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Daten herunterladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Daten herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Daten herunterladen", exc);
} }
} }
+16 -4
View File
@@ -124,10 +124,22 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private string? _exitDate; private string? _exitDate;
[ObservableProperty] [ObservableProperty]
private string? _businessSharesString; private string? _businessShares1String;
public int? BusinessShares { public int? BusinessShares1 {
get => int.TryParse(BusinessSharesString, out var bs) ? bs : null; get => int.TryParse(BusinessShares1String, out var shares) ? shares : null;
set => BusinessSharesString = $"{value}"; set => BusinessShares1String = $"{value}";
}
[ObservableProperty]
private string? _businessShares2String;
public int? BusinessShares2 {
get => int.TryParse(BusinessShares2String, out var shares) ? shares : null;
set => BusinessShares2String = $"{value}";
}
[ObservableProperty]
private string? _businessShares3String;
public int? BusinessShares3 {
get => int.TryParse(BusinessShares3String, out var shares) ? shares : null;
set => BusinessShares3String = $"{value}";
} }
[ObservableProperty] [ObservableProperty]
private string? _accountingNr; private string? _accountingNr;
+3 -4
View File
@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Elwig.Services;
namespace Elwig.Windows { namespace Elwig.Windows {
public abstract class AdministrationWindow : ContextWindow { public abstract class AdministrationWindow : ContextWindow {
@@ -109,9 +110,7 @@ namespace Elwig.Windows {
private void OnClosing(object? sender, CancelEventArgs evt) { private void OnClosing(object? sender, CancelEventArgs evt) {
if ((IsCreating || IsEditing) && HasChanged) { if ((IsCreating || IsEditing) && HasChanged) {
var r = MessageBox.Show("Soll das Fenster wirklich geschlossen werden?", "Schließen bestätigen", if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) {
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (r != MessageBoxResult.Yes) {
evt.Cancel = true; evt.Cancel = true;
return; return;
} }
@@ -390,7 +389,7 @@ namespace Elwig.Windows {
protected bool InputLostFocus(TextBox input, ValidationResult res, string? msg = null) { protected bool InputLostFocus(TextBox input, ValidationResult res, string? msg = null) {
if (DoShowWarningWindows && !res.IsValid && !IsClosing && (IsEditing || IsCreating)) if (DoShowWarningWindows && !res.IsValid && !IsClosing && (IsEditing || IsCreating))
MessageBox.Show(res.ErrorContent?.ToString(), msg ?? res.ErrorContent?.ToString(), MessageBoxButton.OK, MessageBoxImage.Warning); InteractionService.ShowWarning(msg ?? res.ErrorContent?.ToString() ?? "", res.ErrorContent?.ToString() ?? "");
return res.IsValid; return res.IsValid;
} }
+2 -6
View File
@@ -246,9 +246,7 @@ namespace Elwig.Windows {
} }
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Flächenbindung löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Flächenbindung löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -298,9 +296,7 @@ namespace Elwig.Windows {
} }
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Flächenbindung aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return; return;
+19 -5
View File
@@ -453,13 +453,13 @@
HorizontalAlignment="Left"/> HorizontalAlignment="Left"/>
<Label Content="Lieferpflicht/-recht:" Margin="10,10,0,10" Grid.Column="2"/> <Label Content="Lieferpflicht/-recht:" Margin="10,10,0,10" Grid.Column="2"/>
<ctrl:UnitTextBox x:Name="SeasonMinKgPerBsInput" Unit="kg/GA" TextChanged="SeasonMinMaxKgInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonMinKgPerShareInput" Unit="kg/GA" TextChanged="SeasonMinMaxKgInput_TextChanged"
Grid.Column="3" Width="80" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Grid.Column="3" Width="80" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ctrl:UnitTextBox x:Name="SeasonMaxKgPerBsInput" Unit="kg/GA" TextChanged="SeasonMinMaxKgInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonMaxKgPerShareInput" Unit="kg/GA" TextChanged="SeasonMinMaxKgInput_TextChanged"
Grid.Column="3" Width="80" Margin="85,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Grid.Column="3" Width="80" Margin="85,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Label Content="GA-Wert (Nachz.):" Margin="10,40,0,10" Grid.Column="2"/> <Label Content="GA-Wert (Nachz.):" Margin="10,40,0,10" Grid.Column="2"/>
<ctrl:UnitTextBox x:Name="SeasonBsValueInput" Unit="€/GA" TextChanged="SeasonPenaltyInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonShareValueInput" Unit="€/GA" TextChanged="SeasonPenaltyInput_TextChanged"
Grid.Column="3" Width="85" Margin="0,40,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Grid.Column="3" Width="85" Margin="0,40,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<GroupBox Header="Strafen bei Unterlieferung lt. GA" Grid.Column="2" Grid.ColumnSpan="2" Margin="0,70,10,0"> <GroupBox Header="Strafen bei Unterlieferung lt. GA" Grid.Column="2" Grid.ColumnSpan="2" Margin="0,70,10,0">
@@ -468,13 +468,13 @@
Width="80" Margin="65,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Width="80" Margin="65,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ctrl:UnitTextBox x:Name="SeasonPenaltyInput" Unit="€" TextChanged="SeasonPenaltyInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonPenaltyInput" Unit="€" TextChanged="SeasonPenaltyInput_TextChanged"
Width="68" Margin="150,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Width="68" Margin="150,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ctrl:UnitTextBox x:Name="SeasonPenaltyPerBsInput" Unit="€/GA" TextChanged="SeasonPenaltyPerBsInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonPenaltyPerShareInput" Unit="€/GA" TextChanged="SeasonPenaltyPerShareInput_TextChanged"
Width="100" Margin="222,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Width="100" Margin="222,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Label Content="Zzgl. bei Nicht-Lieferung:" Margin="10,40,0,10"/> <Label Content="Zzgl. bei Nicht-Lieferung:" Margin="10,40,0,10"/>
<ctrl:UnitTextBox x:Name="SeasonPenaltyNoneInput" Unit="€" TextChanged="SeasonPenaltyInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonPenaltyNoneInput" Unit="€" TextChanged="SeasonPenaltyInput_TextChanged"
Width="68" Margin="150,40,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Width="68" Margin="150,40,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<ctrl:UnitTextBox x:Name="SeasonPenaltyPerBsNoneInput" Unit="€/GA" TextChanged="SeasonPenaltyPerBsInput_TextChanged" <ctrl:UnitTextBox x:Name="SeasonPenaltyPerShareNoneInput" Unit="€/GA" TextChanged="SeasonPenaltyPerShareInput_TextChanged"
Width="100" Margin="222,40,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/> Width="100" Margin="222,40,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
@@ -541,6 +541,20 @@
</TabItem> </TabItem>
<TabItem Header="Parameter"> <TabItem Header="Parameter">
<StackPanel> <StackPanel>
<GroupBox x:Name="ParameterBusinessShare" Header="Geschäftsanteile" Margin="10,10,10,0" VerticalAlignment="Top">
<Grid>
<Label Content="Modus:" Margin="10,10,10,10"/>
<ComboBox x:Name="ParameterBusinessShareModeInput" Margin="160,10,10,10" Width="100"
HorizontalAlignment="Left">
<ComboBoxItem IsSelected="True">Normal</ComboBoxItem>
<ComboBoxItem>Rot/weiß</ComboBoxItem>
</ComboBox>
<Label Content="Mitgliederbewegungen:" Margin="10,40,10,10"/>
<CheckBox x:Name="ParameterBusinessShareHistoryInput" Content="Mit Elwig erfassen" Margin="160,45,10,15"
HorizontalAlignment="Left"/>
</Grid>
</GroupBox>
<GroupBox x:Name="ParameterAreaComGroup" Header="Berechnung Flächenbindungen (aktuelle Saison)" Margin="10,10,10,0" VerticalAlignment="Top"> <GroupBox x:Name="ParameterAreaComGroup" Header="Berechnung Flächenbindungen (aktuelle Saison)" Margin="10,10,10,0" VerticalAlignment="Top">
<Grid> <Grid>
<CheckBox x:Name="ParameterAllowAttrIntoLowerInput" Content="Erlauben Lieferungen auch auf (konfigurierte) &quot;schlechtere&quot; Flächenbindungen aufzuteilen" <CheckBox x:Name="ParameterAllowAttrIntoLowerInput" Content="Erlauben Lieferungen auch auf (konfigurierte) &quot;schlechtere&quot; Flächenbindungen aufzuteilen"
+42 -35
View File
@@ -1,6 +1,7 @@
using Elwig.Dialogs; using Elwig.Dialogs;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -46,23 +47,23 @@ namespace Elwig.Windows {
SeasonVatFlatrateInput.Text = (s.VatFlatrate * 100).ToString(); SeasonVatFlatrateInput.Text = (s.VatFlatrate * 100).ToString();
SeasonStartInput.Text = $"{s.StartDate:dd.MM.yyyy}"; SeasonStartInput.Text = $"{s.StartDate:dd.MM.yyyy}";
SeasonEndInput.Text = $"{s.EndDate:dd.MM.yyyy}"; SeasonEndInput.Text = $"{s.EndDate:dd.MM.yyyy}";
SeasonMinKgPerBsInput.Text = s.MinKgPerBusinessShare.ToString(); SeasonMinKgPerShareInput.Text = s.MinKgPerShare?.ToString() ?? s.MinKgPerShareRed?.ToString() ?? s.MinKgPerShareWhite?.ToString() ?? "0";
SeasonMaxKgPerBsInput.Text = s.MaxKgPerBusinessShare.ToString(); SeasonMaxKgPerShareInput.Text = s.MaxKgPerShare?.ToString() ?? s.MaxKgPerShareRed?.ToString() ?? s.MaxKgPerShareWhite?.ToString() ?? "0";
SeasonPenaltyPerKgInput.Text = s.PenaltyPerKg?.ToString() ?? ""; SeasonPenaltyPerKgInput.Text = s.PenaltyPerKg?.ToString() ?? "";
SeasonPenaltyInput.Text = s.PenaltyAmount?.ToString() ?? ""; SeasonPenaltyInput.Text = s.PenaltyAmount?.ToString() ?? "";
SeasonPenaltyNoneInput.Text = s.PenaltyNone?.ToString() ?? ""; SeasonPenaltyNoneInput.Text = s.PenaltyNone?.ToString() ?? "";
SeasonPenaltyPerBsInput.Text = s.PenaltyPerBsAmount?.ToString() ?? ""; SeasonPenaltyPerShareInput.Text = s.PenaltyPerShareAmount?.ToString() ?? "";
SeasonPenaltyPerBsNoneInput.Text = s.PenaltyPerBsNone?.ToString() ?? ""; SeasonPenaltyPerShareNoneInput.Text = s.PenaltyPerShareNone?.ToString() ?? "";
SeasonBsValueInput.Text = s.BusinessShareValue?.ToString() ?? ""; SeasonShareValueInput.Text = s.BusinessShareValue?.ToString() ?? "";
var sym = s.Currency.Symbol ?? s.Currency.Code; var sym = s.Currency.Symbol ?? s.Currency.Code;
SeasonModifierAbsInput.Unit = $"{sym}/kg"; SeasonModifierAbsInput.Unit = $"{sym}/kg";
SeasonPenaltyPerKgInput.Unit = $"{sym}/kg"; SeasonPenaltyPerKgInput.Unit = $"{sym}/kg";
SeasonPenaltyInput.Unit = sym; SeasonPenaltyInput.Unit = sym;
SeasonPenaltyNoneInput.Unit = sym; SeasonPenaltyNoneInput.Unit = sym;
SeasonPenaltyPerBsInput.Unit = $"{sym}/GA"; SeasonPenaltyPerShareInput.Unit = $"{sym}/GA";
SeasonPenaltyPerBsNoneInput.Unit = $"{sym}/GA"; SeasonPenaltyPerShareNoneInput.Unit = $"{sym}/GA";
SeasonBsValueInput.Unit = $"{sym}/GA"; SeasonShareValueInput.Unit = $"{sym}/GA";
AreaCommitmentTypePenaltyPerKgInput.Unit = $"{sym}/kg"; AreaCommitmentTypePenaltyPerKgInput.Unit = $"{sym}/kg";
AreaCommitmentTypePenaltyInput.Unit = sym; AreaCommitmentTypePenaltyInput.Unit = sym;
AreaCommitmentTypePenaltyNoneInput.Unit = sym; AreaCommitmentTypePenaltyNoneInput.Unit = sym;
@@ -73,14 +74,14 @@ namespace Elwig.Windows {
SeasonVatFlatrateInput.Text = ""; SeasonVatFlatrateInput.Text = "";
SeasonStartInput.Text = ""; SeasonStartInput.Text = "";
SeasonEndInput.Text = ""; SeasonEndInput.Text = "";
SeasonMinKgPerBsInput.Text = ""; SeasonMinKgPerShareInput.Text = "";
SeasonMaxKgPerBsInput.Text = ""; SeasonMaxKgPerShareInput.Text = "";
SeasonPenaltyPerKgInput.Text = ""; SeasonPenaltyPerKgInput.Text = "";
SeasonPenaltyInput.Text = ""; SeasonPenaltyInput.Text = "";
SeasonPenaltyNoneInput.Text = ""; SeasonPenaltyNoneInput.Text = "";
SeasonPenaltyPerBsInput.Text = ""; SeasonPenaltyPerShareInput.Text = "";
SeasonPenaltyPerBsNoneInput.Text = ""; SeasonPenaltyPerShareNoneInput.Text = "";
SeasonBsValueInput.Text = ""; SeasonShareValueInput.Text = "";
} }
_seasonUpdate = false; _seasonUpdate = false;
} }
@@ -95,16 +96,28 @@ namespace Elwig.Windows {
s.VatNormal = double.Parse(SeasonVatNormalInput.Text) / 100; s.VatNormal = double.Parse(SeasonVatNormalInput.Text) / 100;
if (SeasonVatFlatrateInput.Text.Length > 0) if (SeasonVatFlatrateInput.Text.Length > 0)
s.VatFlatrate = double.Parse(SeasonVatFlatrateInput.Text) / 100; s.VatFlatrate = double.Parse(SeasonVatFlatrateInput.Text) / 100;
if (SeasonMinKgPerBsInput.Text.Length > 0) if (ParameterBusinessShareModeInput.SelectedIndex == 0) {
s.MinKgPerBusinessShare = int.Parse(SeasonMinKgPerBsInput.Text); s.MinKgPerShare = (SeasonMinKgPerShareInput.Text.Length > 0) ? int.Parse(SeasonMinKgPerShareInput.Text) : null;
if (SeasonMaxKgPerBsInput.Text.Length > 0) s.MaxKgPerShare = (SeasonMaxKgPerShareInput.Text.Length > 0) ? int.Parse(SeasonMaxKgPerShareInput.Text) : null;
s.MaxKgPerBusinessShare = int.Parse(SeasonMaxKgPerBsInput.Text); s.MinKgPerShareRed = null;
s.MaxKgPerShareRed = null;
s.MinKgPerShareWhite = null;
s.MaxKgPerShareWhite = null;
} else {
s.MinKgPerShare = null;
s.MaxKgPerShare = null;
s.MinKgPerShareRed = (SeasonMinKgPerShareInput.Text.Length > 0) ? int.Parse(SeasonMinKgPerShareInput.Text) : null;
s.MaxKgPerShareRed = (SeasonMaxKgPerShareInput.Text.Length > 0) ? int.Parse(SeasonMaxKgPerShareInput.Text) : null;
s.MinKgPerShareWhite = s.MinKgPerShareRed;
s.MaxKgPerShareWhite = s.MaxKgPerShareRed;
}
s.PenaltyPerKg = (SeasonPenaltyPerKgInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyPerKgInput.Text) : null; s.PenaltyPerKg = (SeasonPenaltyPerKgInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyPerKgInput.Text) : null;
s.PenaltyAmount = (SeasonPenaltyInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyInput.Text) : null; s.PenaltyAmount = (SeasonPenaltyInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyInput.Text) : null;
s.PenaltyNone = (SeasonPenaltyNoneInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyNoneInput.Text) : null; s.PenaltyNone = (SeasonPenaltyNoneInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyNoneInput.Text) : null;
s.PenaltyPerBsAmount = (SeasonPenaltyPerBsInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyPerBsInput.Text) : null; s.PenaltyPerShareAmount = (SeasonPenaltyPerShareInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyPerShareInput.Text) : null;
s.PenaltyPerBsNone = (SeasonPenaltyPerBsNoneInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyPerBsNoneInput.Text) : null; s.PenaltyPerShareNone = (SeasonPenaltyPerShareNoneInput.Text.Length > 0) ? decimal.Parse(SeasonPenaltyPerShareNoneInput.Text) : null;
s.BusinessShareValue = (SeasonBsValueInput.Text.Length > 0) ? decimal.Parse(SeasonBsValueInput.Text) : null; s.BusinessShareValue = (SeasonShareValueInput.Text.Length > 0) ? decimal.Parse(SeasonShareValueInput.Text) : null;
UpdateButtons(); UpdateButtons();
} }
@@ -130,7 +143,7 @@ namespace Elwig.Windows {
Season_Changed(sender, evt); Season_Changed(sender, evt);
} }
private void SeasonPenaltyPerBsInput_TextChanged(object sender, TextChangedEventArgs evt) { private void SeasonPenaltyPerShareInput_TextChanged(object sender, TextChangedEventArgs evt) {
if (SeasonList.SelectedItem is not Season s) return; if (SeasonList.SelectedItem is not Season s) return;
InputTextChanged((TextBox)sender, Validator.CheckDecimal((TextBox)sender, false, 4, s.Precision)); InputTextChanged((TextBox)sender, Validator.CheckDecimal((TextBox)sender, false, 4, s.Precision));
Season_Changed(sender, evt); Season_Changed(sender, evt);
@@ -159,13 +172,13 @@ namespace Elwig.Windows {
MaxKgPerHa = s?.MaxKgPerHa ?? 10000, MaxKgPerHa = s?.MaxKgPerHa ?? 10000,
VatNormal = s?.VatNormal ?? 0.10, VatNormal = s?.VatNormal ?? 0.10,
VatFlatrate = s?.VatFlatrate ?? 0.13, VatFlatrate = s?.VatFlatrate ?? 0.13,
MinKgPerBusinessShare = s?.MinKgPerBusinessShare ?? 500, MinKgPerShare = s?.MinKgPerShare,
MaxKgPerBusinessShare = s?.MaxKgPerBusinessShare ?? 1000, MaxKgPerShare = s?.MaxKgPerShare,
PenaltyPerKgValue = s?.PenaltyPerKgValue, PenaltyPerKgValue = s?.PenaltyPerKgValue,
PenaltyAmoutValue = s?.PenaltyAmoutValue, PenaltyAmoutValue = s?.PenaltyAmoutValue,
PenaltyNoneValue = s?.PenaltyNoneValue, PenaltyNoneValue = s?.PenaltyNoneValue,
PenaltyPerBsAmountValue = s?.PenaltyPerBsAmountValue, PenaltyPerShareAmountValue = s?.PenaltyPerShareAmountValue,
PenaltyPerBsNoneValue = s?.PenaltyPerBsNoneValue, PenaltyPerShareNoneValue = s?.PenaltyPerShareNoneValue,
BusinessShareValueValue = s?.BusinessShareValueValue, BusinessShareValueValue = s?.BusinessShareValueValue,
CalcMode = s?.CalcMode ?? 0, CalcMode = s?.CalcMode ?? 0,
}); });
@@ -180,13 +193,12 @@ namespace Elwig.Windows {
AbsValue = m.AbsValue * mult / div, AbsValue = m.AbsValue * mult / div,
RelValue = m.RelValue, RelValue = m.RelValue,
IsActive = m.IsActive, IsActive = m.IsActive,
IsRedacted = m.IsRedacted,
})); }));
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Saison anlegen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Saison anlegen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
App.HintContextChange(); App.HintContextChange();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -197,19 +209,14 @@ namespace Elwig.Windows {
private async void SeasonRemoveButton_Click(object sender, RoutedEventArgs evt) { private async void SeasonRemoveButton_Click(object sender, RoutedEventArgs evt) {
if (SeasonList.SelectedItem is not Season s) if (SeasonList.SelectedItem is not Season s)
return; return;
var r = MessageBox.Show( if (InteractionService.AskContinue("Saison löschen", $"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?")) {
$"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?",
"Saison löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
ctx.Remove(s); ctx.Remove(s);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Saison löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Saison löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
App.HintContextChange(); App.HintContextChange();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
+19 -27
View File
@@ -1,5 +1,6 @@
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Linq; using System.Linq;
@@ -31,14 +32,15 @@ namespace Elwig.Windows {
AreaCommitmentTypeMinKgPerHaInput, AreaCommitmentTypePenaltyPerKgInput, AreaCommitmentTypeMinKgPerHaInput, AreaCommitmentTypePenaltyPerKgInput,
AreaCommitmentTypePenaltyInput, AreaCommitmentTypePenaltyNoneInput, AreaCommitmentTypePenaltyInput, AreaCommitmentTypePenaltyNoneInput,
SeasonMaxKgPerHaInput, SeasonVatNormalInput, SeasonVatFlatrateInput, SeasonStartInput, SeasonEndInput, SeasonMaxKgPerHaInput, SeasonVatNormalInput, SeasonVatFlatrateInput, SeasonStartInput, SeasonEndInput,
SeasonMinKgPerBsInput, SeasonMaxKgPerBsInput, SeasonBsValueInput, SeasonMinKgPerShareInput, SeasonMaxKgPerShareInput, SeasonShareValueInput,
SeasonPenaltyPerKgInput, SeasonPenaltyInput, SeasonPenaltyNoneInput, SeasonPenaltyPerKgInput, SeasonPenaltyInput, SeasonPenaltyNoneInput,
SeasonPenaltyPerBsInput, SeasonPenaltyPerBsNoneInput, SeasonPenaltyPerShareInput, SeasonPenaltyPerShareNoneInput,
SeasonModifierIdInput, SeasonModifierNameInput, SeasonModifierRelInput, SeasonModifierAbsInput, SeasonModifierIdInput, SeasonModifierNameInput, SeasonModifierRelInput, SeasonModifierAbsInput,
]; ];
WineAttributeFillLowerInput.Visibility = Visibility.Hidden; WineAttributeFillLowerInput.Visibility = Visibility.Hidden;
WineAttributeFillLowerLabel.Visibility = Visibility.Hidden; WineAttributeFillLowerLabel.Visibility = Visibility.Hidden;
ParameterAreaComGroup.Header = ParameterAreaComGroup.Header.ToString()!.Split('(')[0] + $"({Utils.CurrentLastSeason})"; ParameterAreaComGroup.Header = ParameterAreaComGroup.Header.ToString()!.Split('(')[0] + $"({Utils.CurrentLastSeason})";
LockInputs();
} }
protected override void ShortcutNew() { } protected override void ShortcutNew() { }
@@ -78,25 +80,19 @@ namespace Elwig.Windows {
SeasonMaxKgPerHaInput.IsReadOnly = true; SeasonMaxKgPerHaInput.IsReadOnly = true;
SeasonVatNormalInput.IsReadOnly = true; SeasonVatNormalInput.IsReadOnly = true;
SeasonVatFlatrateInput.IsReadOnly = true; SeasonVatFlatrateInput.IsReadOnly = true;
SeasonMinKgPerBsInput.IsReadOnly = true; SeasonMinKgPerShareInput.IsReadOnly = true;
SeasonMaxKgPerBsInput.IsReadOnly = true; SeasonMaxKgPerShareInput.IsReadOnly = true;
SeasonPenaltyPerKgInput.IsReadOnly = true; SeasonPenaltyPerKgInput.IsReadOnly = true;
SeasonPenaltyInput.IsReadOnly = true; SeasonPenaltyInput.IsReadOnly = true;
SeasonPenaltyNoneInput.IsReadOnly = true; SeasonPenaltyNoneInput.IsReadOnly = true;
SeasonPenaltyPerBsInput.IsReadOnly = true; SeasonPenaltyPerShareInput.IsReadOnly = true;
SeasonPenaltyPerBsNoneInput.IsReadOnly = true; SeasonPenaltyPerShareNoneInput.IsReadOnly = true;
SeasonBsValueInput.IsReadOnly = true; SeasonShareValueInput.IsReadOnly = true;
SeasonModifierIdInput.IsReadOnly = true; SeasonModifierIdInput.IsReadOnly = true;
SeasonModifierNameInput.IsReadOnly = true; SeasonModifierNameInput.IsReadOnly = true;
SeasonModifierRelInput.IsReadOnly = true; SeasonModifierRelInput.IsReadOnly = true;
SeasonModifierAbsInput.IsReadOnly = true; SeasonModifierAbsInput.IsReadOnly = true;
ParameterAllowAttrIntoLowerInput.IsEnabled = false;
ParameterAvoidUnderDeliveriesInput.IsEnabled = false;
ParameterHonorGebundenInput.IsEnabled = false;
ParameterExportEbicsVersion.IsEnabled = false;
ParameterExportEbicsAddress.IsEnabled = false;
} }
new protected void UnlockInputs() { new protected void UnlockInputs() {
@@ -132,25 +128,19 @@ namespace Elwig.Windows {
SeasonMaxKgPerHaInput.IsReadOnly = false; SeasonMaxKgPerHaInput.IsReadOnly = false;
SeasonVatNormalInput.IsReadOnly = false; SeasonVatNormalInput.IsReadOnly = false;
SeasonVatFlatrateInput.IsReadOnly = false; SeasonVatFlatrateInput.IsReadOnly = false;
SeasonMinKgPerBsInput.IsReadOnly = false; SeasonMinKgPerShareInput.IsReadOnly = false;
SeasonMaxKgPerBsInput.IsReadOnly = false; SeasonMaxKgPerShareInput.IsReadOnly = false;
SeasonPenaltyPerKgInput.IsReadOnly = false; SeasonPenaltyPerKgInput.IsReadOnly = false;
SeasonPenaltyInput.IsReadOnly = false; SeasonPenaltyInput.IsReadOnly = false;
SeasonPenaltyNoneInput.IsReadOnly = false; SeasonPenaltyNoneInput.IsReadOnly = false;
SeasonPenaltyPerBsInput.IsReadOnly = false; SeasonPenaltyPerShareInput.IsReadOnly = false;
SeasonPenaltyPerBsNoneInput.IsReadOnly = false; SeasonPenaltyPerShareNoneInput.IsReadOnly = false;
SeasonBsValueInput.IsReadOnly = false; SeasonShareValueInput.IsReadOnly = false;
SeasonModifierIdInput.IsReadOnly = false; SeasonModifierIdInput.IsReadOnly = false;
SeasonModifierNameInput.IsReadOnly = false; SeasonModifierNameInput.IsReadOnly = false;
SeasonModifierRelInput.IsReadOnly = false; SeasonModifierRelInput.IsReadOnly = false;
SeasonModifierAbsInput.IsReadOnly = false; SeasonModifierAbsInput.IsReadOnly = false;
ParameterAllowAttrIntoLowerInput.IsEnabled = true;
ParameterAvoidUnderDeliveriesInput.IsEnabled = true;
ParameterHonorGebundenInput.IsEnabled = true;
ParameterExportEbicsVersion.IsEnabled = true;
ParameterExportEbicsAddress.IsEnabled = true;
} }
protected override async Task OnRenewContext(AppDbContext ctx) { protected override async Task OnRenewContext(AppDbContext ctx) {
@@ -300,9 +290,7 @@ namespace Elwig.Windows {
try { try {
await Save(); await Save();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Stammdaten aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Stammdaten aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return; return;
@@ -360,6 +348,8 @@ namespace Elwig.Windows {
TextElementDeliveryConfirmation.Text = p.TextDeliveryConfirmation; TextElementDeliveryConfirmation.Text = p.TextDeliveryConfirmation;
TextElementCreditNote.Text = p.TextCreditNote; TextElementCreditNote.Text = p.TextCreditNote;
ParameterBusinessShareModeInput.SelectedIndex = p.ModeBusinessShares;
ParameterBusinessShareHistoryInput.IsChecked = p.EnableMemberHistory;
ParameterAllowAttrIntoLowerInput.IsChecked = s?.Billing_AllowAttrsIntoLower ?? false; ParameterAllowAttrIntoLowerInput.IsChecked = s?.Billing_AllowAttrsIntoLower ?? false;
ParameterAvoidUnderDeliveriesInput.IsChecked = s?.Billing_AvoidUnderDeliveries ?? false; ParameterAvoidUnderDeliveriesInput.IsChecked = s?.Billing_AvoidUnderDeliveries ?? false;
ParameterHonorGebundenInput.IsChecked = s?.Billing_HonorGebunden ?? false; ParameterHonorGebundenInput.IsChecked = s?.Billing_HonorGebunden ?? false;
@@ -388,6 +378,8 @@ namespace Elwig.Windows {
p.EmailAddress = string.IsNullOrEmpty(ClientEmailAddressInput.Text) ? null : ClientEmailAddressInput.Text; p.EmailAddress = string.IsNullOrEmpty(ClientEmailAddressInput.Text) ? null : ClientEmailAddressInput.Text;
p.Website = string.IsNullOrEmpty(ClientWebsiteInput.Text) ? null : ClientWebsiteInput.Text; p.Website = string.IsNullOrEmpty(ClientWebsiteInput.Text) ? null : ClientWebsiteInput.Text;
p.ModeBusinessShares = ParameterBusinessShareModeInput.SelectedIndex;
p.EnableMemberHistory = ParameterBusinessShareHistoryInput.IsChecked ?? false;
p.TextDeliveryNote = string.IsNullOrEmpty(TextElementDeliveryNote.Text) ? null : TextElementDeliveryNote.Text; p.TextDeliveryNote = string.IsNullOrEmpty(TextElementDeliveryNote.Text) ? null : TextElementDeliveryNote.Text;
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 = string.IsNullOrEmpty(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text; p.TextDeliveryConfirmation = string.IsNullOrEmpty(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text;
+19 -29
View File
@@ -10,6 +10,7 @@ using Elwig.Helpers.Billing;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using ScottPlot.Plottables; using ScottPlot.Plottables;
using ScottPlot; using ScottPlot;
using Elwig.Services;
namespace Elwig.Windows { namespace Elwig.Windows {
public partial class ChartWindow : ContextWindow { public partial class ChartWindow : ContextWindow {
@@ -82,9 +83,7 @@ namespace Elwig.Windows {
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
if (HasChanged) { if (HasChanged) {
var r = MessageBox.Show("Soll das Fenster wirklich geschlossen werden? Nicht gespeicherte Änderungen werden NICHT übernommen!", "Schließen bestätigen", if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden? Nicht gespeicherte Änderungen werden NICHT übernommen!")) {
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (r != MessageBoxResult.Yes) {
e.Cancel = true; e.Cancel = true;
return; return;
} }
@@ -105,23 +104,22 @@ namespace Elwig.Windows {
try { try {
var data = EditBillingData.FromJson(PaymentVar.Data, await Utils.GetVaributes(ctx, Year)); var data = EditBillingData.FromJson(PaymentVar.Data, await Utils.GetVaributes(ctx, Year));
var paymentEntries = await data.GetPaymentGraphEntries(ctx, Season); var paymentEntries = (await data.GetPaymentGraphEntries(ctx, Season)).ToList();
GraphEntries = [ GraphEntries = [
..paymentEntries, ..paymentEntries,
..await data.GetQualityGraphEntries(ctx, Season, paymentEntries.Any() ? paymentEntries.Max(e => e.Id) : 0) ..await data.GetQualityGraphEntries(ctx, Season, paymentEntries.Count != 0 ? paymentEntries.Max(e => e.Id) : 0)
]; ];
} catch (KeyNotFoundException ex) { } catch (KeyNotFoundException exc) {
var key = ex.Message.Split('\'')[1].Split('\'')[0]; var key = exc.Message.Split('\'')[1].Split('\'')[0];
MessageBox.Show($"Fehler beim Laden der Auszahlungsvariante:\n\n" + InteractionService.ShowError("Fehler",
$"Mit unbekanntem Attribut '{key}' kann nicht umgegangen werden.", "Fehler", $"Fehler beim Laden der Auszahlungsvariante:\n\n" +
MessageBoxButton.OK, MessageBoxImage.Error); $"Mit unbekanntem Attribut '{key}' kann nicht umgegangen werden.");
} catch (ArgumentException) { } catch (ArgumentException) {
MessageBox.Show($"Fehler beim Laden der Auszahlungsvariante:\n\n" + InteractionService.ShowError("Fehler",
$"Die Daten der Auszahlungsvariante entsprechen nicht dem benötigtem Format.", "Fehler", $"Fehler beim Laden der Auszahlungsvariante:\n\n" +
MessageBoxButton.OK, MessageBoxImage.Error); $"Die Daten der Auszahlungsvariante entsprechen nicht dem benötigtem Format.");
} catch (Exception ex) { } catch (Exception exc) {
MessageBox.Show("Fehler beim Laden der Auszahlungsvariante:\n\n" + ex.Message, "Fehler", InteractionService.ShowException("Fehler", "Fehler beim Laden der Auszahlungsvariante", exc);
MessageBoxButton.OK, MessageBoxImage.Error);
} }
Vaributes = await Utils.GetVaributeList(ctx, Year); Vaributes = await Utils.GetVaributeList(ctx, Year);
GraphEntries.ForEach(e => { GraphEntries.ForEach(e => {
@@ -622,11 +620,7 @@ namespace Elwig.Windows {
private void DeleteButton_Click(object sender, RoutedEventArgs e) { private void DeleteButton_Click(object sender, RoutedEventArgs e) {
if (SelectedGraphEntry == null) return; if (SelectedGraphEntry == null) return;
var r = MessageBox.Show( if (InteractionService.AskConfirmation("Kurve löschen", $"Soll die Kurve {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.VaributeStringSimple}) wirklich gelöscht werden?")) {
$"Soll die Kurve {SelectedGraphEntry.Id} (verwendet in folgenden Verträgen: {SelectedGraphEntry.VaributeStringSimple}) wirklich gelöscht werden?",
"Kurve löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (r == MessageBoxResult.Yes) {
GraphEntries.Remove(SelectedGraphEntry); GraphEntries.Remove(SelectedGraphEntry);
SetHasChanged(); SetHasChanged();
GraphList.Items.Refresh(); GraphList.Items.Refresh();
@@ -651,9 +645,7 @@ namespace Elwig.Windows {
}); });
} catch (Exception exc) { } catch (Exception exc) {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
var str = "Der Eintrag konnte nicht in der Datenbank gespeichert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Auszahlungsvariante speichern", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante speichern", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return; return;
} }
@@ -664,9 +656,9 @@ namespace Elwig.Windows {
await b.Calculate(false); await b.Calculate(false);
}); });
} catch (KeyNotFoundException exc) { } catch (KeyNotFoundException exc) {
MessageBox.Show(exc.Message, "Noch nicht alle Preise festgelegt", MessageBoxButton.OK, MessageBoxImage.Information); InteractionService.ShowInformation("Noch nicht alle Preise festgelegt", exc.Message);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Berechnungsfehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Berechnungsfehler", exc);
} }
LockContext = false; LockContext = false;
@@ -773,9 +765,7 @@ namespace Elwig.Windows {
if (ge != SelectedGraphEntry && ge.Abgewertet == SelectedGraphEntry?.Abgewertet) { if (ge != SelectedGraphEntry && ge.Abgewertet == SelectedGraphEntry?.Abgewertet) {
var toRemove = ge.Vaributes.Where(c => c.Listing.Equals(varibute)).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 Kurve {ge.Id} in Verwendung!\nSoll die Zuweisung dort entfernt werden?", "Entfernen bestätigen", if (!InteractionService.AskConfirmation("Entfernen bestätigen", $"Achtung: {string.Join(", ", toRemove)} ist bereits in Kurve {ge.Id} in Verwendung!\nSoll die Zuweisung dort entfernt werden?")) {
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (r != MessageBoxResult.Yes) {
return false; return false;
} }
ge.Vaributes.RemoveAll(c => c.Listing.Equals(varibute)); ge.Vaributes.RemoveAll(c => c.Listing.Equals(varibute));
+19 -42
View File
@@ -6,7 +6,6 @@ using Elwig.Models.Entities;
using Elwig.Services; using Elwig.Services;
using Elwig.ViewModels; using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -137,8 +136,9 @@ namespace Elwig.Windows {
if (ViewModel.IsReceipt) { if (ViewModel.IsReceipt) {
NewDeliveryButton_Click(null, null); NewDeliveryButton_Click(null, null);
if (await ctx.FetchSeasons(Utils.CurrentYear).SingleOrDefaultAsync() == null) { if (await ctx.FetchSeasons(Utils.CurrentYear).SingleOrDefaultAsync() == null) {
MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n(Stammdaten -> Saisons -> Neu anlegen...)", InteractionService.ShowWarning("Saison noch nicht erstellt",
"Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Warning); "Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n" +
"(Stammdaten -> Saisons -> Neu anlegen...)");
} }
} }
} }
@@ -164,9 +164,7 @@ namespace Elwig.Windows {
private async void Menu_DeliveryNote_Email_Click(object sender, RoutedEventArgs evt) { private async void Menu_DeliveryNote_Email_Click(object sender, RoutedEventArgs evt) {
if (DeliveryList.SelectedItem is not Delivery d) if (DeliveryList.SelectedItem is not Delivery d)
return; return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Lieferschein verschicken", if (!InteractionService.AskQuestion("Lieferschein verschicken", "Soll eine E-Mail verschickt werden?", true))
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return; return;
await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.Email); await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.Email);
} }
@@ -174,16 +172,11 @@ namespace Elwig.Windows {
private async void Menu_Bki_SaveList_Click(object sender, RoutedEventArgs evt) { private async void Menu_Bki_SaveList_Click(object sender, RoutedEventArgs evt) {
if (sender is not MenuItem m) return; if (sender is not MenuItem m) return;
var year = int.Parse(m.Header.ToString()?.Split(" ")[^1] ?? Utils.CurrentLastSeason.ToString()); var year = int.Parse(m.Header.ToString()?.Split(" ")[^1] ?? Utils.CurrentLastSeason.ToString());
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Traubentransportscheinliste (BKI)", $"{App.Client.NameToken}-Traubentransportscheinliste-{year}", Bki.FileExtension);
FileName = $"{App.Client.NameToken}-Traubentransportscheinliste-{year}.{Bki.FileExtension}", if (filename != null) {
DefaultExt = Bki.FileExtension,
Filter = "CSV-Datei (*.csv)|*.csv",
Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
using var file = new Bki(d.FileName); using var file = new Bki(filename);
await file.ExportAsync(year); await file.ExportAsync(year);
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -641,11 +634,10 @@ namespace Elwig.Windows {
try { try {
var res = await s.Weigh(); var res = await s.Weigh();
OnWeighingResult(s, res); OnWeighingResult(s, res);
} catch (Exception ex) { } catch (Exception exc) {
ViewModel.LastScaleError = ex.Message.Split(": ")[^1]; ViewModel.LastScaleError = exc.Message.Split(": ")[^1];
OnWeighingResult(s, new()); OnWeighingResult(s, new());
MessageBox.Show($"Beim Wiegen ist ein Fehler aufgetreten:\n\n{ex.Message}", "Waagenfehler", InteractionService.ShowException("Waagenfehler", "Beim Wiegen ist ein Fehler aufgetreten", exc);
MessageBoxButton.OK, MessageBoxImage.Error);
} }
ViewModel.ManualWeighingReason = null; ViewModel.ManualWeighingReason = null;
ManualWeighingInput.IsChecked = false; ManualWeighingInput.IsChecked = false;
@@ -801,9 +793,7 @@ namespace Elwig.Windows {
); );
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Lieferung aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
FinishButton.IsEnabled = true; FinishButton.IsEnabled = true;
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -839,9 +829,7 @@ namespace Elwig.Windows {
); );
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Lieferung aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
FinishButton.IsEnabled = true; FinishButton.IsEnabled = true;
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -871,9 +859,8 @@ namespace Elwig.Windows {
private async void CancelCreatingButton_Click(object sender, RoutedEventArgs evt) { private async void CancelCreatingButton_Click(object sender, RoutedEventArgs evt) {
if (IsCreating && HasChanged) { if (IsCreating && HasChanged) {
var r = MessageBox.Show("Soll der Vorgang wirklich abgebrochen werden?", "Abbrechen bestätigen", if (!InteractionService.AskConfirmation("Abbrechen bestätigen", "Soll der Vorgang wirklich abgebrochen werden?"))
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); return;
if (r != MessageBoxResult.Yes) return;
} }
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
@@ -954,9 +941,7 @@ namespace Elwig.Windows {
} }
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Lieferung aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -1003,18 +988,13 @@ namespace Elwig.Windows {
if (DeliveryList.SelectedItem is not Delivery d) if (DeliveryList.SelectedItem is not Delivery d)
return; return;
var r = MessageBox.Show( if (InteractionService.AskContinue("Lieferung löschen", $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?")) {
$"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?",
"Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await DeliveryService.DeleteDelivery(d.LsNr); await DeliveryService.DeleteDelivery(d.LsNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Lieferung löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -1042,9 +1022,7 @@ namespace Elwig.Windows {
); );
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Lieferung aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return; return;
@@ -1281,8 +1259,7 @@ namespace Elwig.Windows {
UpdateWineQualityLevels(); UpdateWineQualityLevels();
if (!ViewModel.WineVar?.IsQuw ?? false) { if (!ViewModel.WineVar?.IsQuw ?? false) {
App.MainDispatcher.BeginInvoke(() => { App.MainDispatcher.BeginInvoke(() => {
MessageBox.Show("Die eingegebene Sorte darf nicht als Qualitätswein\nübernommen werden!", "Kein Qualitätswein", InteractionService.ShowWarning("Kein Qualitätswein", "Die eingegebene Sorte darf nicht als Qualitätswein\nübernommen werden!");
MessageBoxButton.OK, MessageBoxImage.Warning);
}); });
} }
} }
+3 -10
View File
@@ -309,10 +309,7 @@ namespace Elwig.Windows {
private async void DeleteDeliveryAncmtButton_Click(object? sender, RoutedEventArgs? evt) { private async void DeleteDeliveryAncmtButton_Click(object? sender, RoutedEventArgs? evt) {
if (ViewModel.SelectedDeliveryAncmt is not DeliveryAncmt a) if (ViewModel.SelectedDeliveryAncmt is not DeliveryAncmt a)
return; return;
var r = MessageBox.Show( if (InteractionService.AskContinue("Anmeldung löschen", "Soll die Anmeldung wirklich unwiderruflich gelöscht werden?")) {
$"Soll die Anmeldung wirklich unwiderruflich gelöscht werden?",
"Anmeldung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Task.Run(async () => { await Task.Run(async () => {
@@ -322,9 +319,7 @@ namespace Elwig.Windows {
}); });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Anmeldung löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Anmeldung löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -347,9 +342,7 @@ namespace Elwig.Windows {
(year, dsnr, mgnr, sortid) = await ViewModel.UpdateDeliveryAncmt(s?.Year, s?.DsNr, s?.MgNr, s?.SortId, s?.Type); (year, dsnr, mgnr, sortid) = await ViewModel.UpdateDeliveryAncmt(s?.Year, s?.DsNr, s?.MgNr, s?.SortId, s?.Type);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Anmeldung aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Anmeldung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return; return;
} finally { } finally {
@@ -177,10 +177,7 @@ namespace Elwig.Windows {
private async void DeleteDeliveryScheduleButton_Click(object? sender, RoutedEventArgs? evt) { private async void DeleteDeliveryScheduleButton_Click(object? sender, RoutedEventArgs? evt) {
if (ViewModel.SelectedDeliverySchedule is not DeliverySchedule s) if (ViewModel.SelectedDeliverySchedule is not DeliverySchedule s)
return; return;
var r = MessageBox.Show( if (InteractionService.AskContinue("Leseplan löschen", $"Soll der Leseplan \"{s.Description}\" vom {s.Date:dd.MM.yyyy} wirklich unwiderruflich gelöscht werden?")) {
$"Soll der Leseplan \"{s.Description}\" vom {s.Date:dd.MM.yyyy} wirklich unwiderruflich gelöscht werden?",
"Leseplan löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Task.Run(async () => { await Task.Run(async () => {
@@ -190,9 +187,7 @@ namespace Elwig.Windows {
}); });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Leseplan löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Leseplan löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -212,9 +207,7 @@ namespace Elwig.Windows {
await ViewModel.UpdateDeliverySchedule(ViewModel.SelectedDeliverySchedule?.Year, ViewModel.SelectedDeliverySchedule?.DsNr); await ViewModel.UpdateDeliverySchedule(ViewModel.SelectedDeliverySchedule?.Year, ViewModel.SelectedDeliverySchedule?.DsNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Leseplan aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Leseplan aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return; return;
} finally { } finally {
+10 -15
View File
@@ -3,6 +3,7 @@ using Elwig.Helpers;
using Elwig.Helpers.Billing; using Elwig.Helpers.Billing;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using MailKit.Net.Smtp; using MailKit.Net.Smtp;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Win32; using Microsoft.Win32;
@@ -690,7 +691,7 @@ namespace Elwig.Windows {
PrintButton.IsEnabled = PrintDocument != null && !hasPreviewDocs; PrintButton.IsEnabled = PrintDocument != null && !hasPreviewDocs;
EmailButton.IsEnabled = EmailDocuments != null && !hasPreviewDocs && App.Config.Smtp != null; EmailButton.IsEnabled = EmailDocuments != null && !hasPreviewDocs && App.Config.Smtp != null;
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} finally { } finally {
UnlockInputs(); UnlockInputs();
GenerateButton.IsEnabled = true; GenerateButton.IsEnabled = true;
@@ -774,7 +775,7 @@ namespace Elwig.Windows {
throw new NotImplementedException("Invalid DocType"); throw new NotImplementedException("Invalid DocType");
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
return []; return [];
} finally { } finally {
App.MainDispatcher.Invoke(() => { App.MainDispatcher.Invoke(() => {
@@ -787,9 +788,9 @@ namespace Elwig.Windows {
var hasPreviewDocs = memberDocs.Any(m => m.Docs.Any(d => d.Doc.IsPreview)); var hasPreviewDocs = memberDocs.Any(m => m.Docs.Any(d => d.Doc.IsPreview));
if (hasPreviewDocs) { if (hasPreviewDocs) {
var res = MessageBox.Show("Einige der ausgewählten Dokumente sind nur als vorläufig zu betrachten und können daher nicht verschickt/ausgedruckt werden!\n\nDies könnte an einer noch nicht festgesetzen Auszahlungsvariante liegen oder daran, dass nicht alle Adressaten/Empfänger eine Traubengutschrift erhalten\n(\"Empfänger von Gutschriften\").\n\nSoll mit dem Generieren fortgefahren werden?", if (!InteractionService.AskContinue("Vorläufige Dokumente",
"Vorläufige Dokumente", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Einige der ausgewählten Dokumente sind nur als vorläufig zu betrachten und können daher nicht verschickt/ausgedruckt werden!\n\n" +
if (res != MessageBoxResult.OK) { "Dies könnte an einer noch nicht festgesetzen Auszahlungsvariante liegen oder daran, dass nicht alle Adressaten/Empfänger eine Traubengutschrift erhalten\n(\"Empfänger von Gutschriften\").\n\nSoll mit dem Generieren fortgefahren werden?")) {
throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!"); throw new OperationCanceledException("Dokumentenerzeugung abgebrochen!");
} }
} }
@@ -892,9 +893,7 @@ namespace Elwig.Windows {
GenerateButton.IsEnabled = false; GenerateButton.IsEnabled = false;
LockInputs(); LockInputs();
var res = MessageBox.Show($"Sollen {PrintDocument.Pages} Blätter ({PrintDocument.TotalPages} Seiten) gedruckt werden?", if (InteractionService.AskQuestion("Rundschreiben drucken", $"Sollen {PrintDocument.Pages} Blätter ({PrintDocument.TotalPages} Seiten) gedruckt werden?", false)) {
"Rundschreiben drucken", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
if (res == MessageBoxResult.Yes) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
if (App.Config.Debug) { if (App.Config.Debug) {
@@ -932,11 +931,8 @@ namespace Elwig.Windows {
client = await Task.Run(Utils.GetSmtpClient); client = await Task.Run(Utils.GetSmtpClient);
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
var res = MessageBox.Show($"Sollen {EmailDocuments.Count:N0} E-Mails verschickt werden?", if (!InteractionService.AskQuestion("Rundschreiben verschicken", $"Sollen {EmailDocuments.Count:N0} E-Mails verschickt werden?", false))
"Rundschreiben verschicken", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
if (res != MessageBoxResult.Yes) {
return; return;
}
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
var subject = EmailSubjectInput.Text; var subject = EmailSubjectInput.Text;
@@ -965,10 +961,9 @@ namespace Elwig.Windows {
} }
}); });
MessageBox.Show("Erfolgreich alle E-Mails verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mails in den Posteingängen der Empfänger aufscheinen.", "Rundschreiben verschicken", InteractionService.ShowInformation("Rundschreiben verschicken", "Erfolgreich alle E-Mails verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mails in den Posteingängen der Empfänger aufscheinen.");
MessageBoxButton.OK, MessageBoxImage.Information);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} finally { } finally {
if (client != null) if (client != null)
await client.DisconnectAsync(true); await client.DisconnectAsync(true);
+53 -81
View File
@@ -59,9 +59,7 @@ namespace Elwig.Windows {
} }
Thread.Sleep(100); Thread.Sleep(100);
if (App.NumWindows > 1 && !App.Current.Windows.Cast<Window>().Any(w => ((w as AdministrationWindow)?.IsEditing ?? false) || ((w as AdministrationWindow)?.IsCreating ?? false))) { if (App.NumWindows > 1 && !App.Current.Windows.Cast<Window>().Any(w => ((w as AdministrationWindow)?.IsEditing ?? false) || ((w as AdministrationWindow)?.IsCreating ?? false))) {
var res = MessageBox.Show("Es sind noch weitere Fenster geöffnet.\nSollen alle Fenster geschlossen werden?", if (!InteractionService.AskConfirmation("Elwig beenden", "Es sind noch weitere Fenster geöffnet.\nSollen alle Fenster geschlossen werden?")) {
"Elwig beenden", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (res != MessageBoxResult.Yes) {
evt.Cancel = true; evt.Cancel = true;
} else { } else {
Application.Current.Shutdown(); Application.Current.Shutdown();
@@ -84,9 +82,9 @@ namespace Elwig.Windows {
try { try {
using var client = await Utils.GetSmtpClient(); using var client = await Utils.GetSmtpClient();
await client!.DisconnectAsync(true); await client!.DisconnectAsync(true);
MessageBox.Show("E-Mail-Einstellungen erfolgreich überprüft!", "Erfolg", MessageBoxButton.OK, MessageBoxImage.Information); InteractionService.ShowInformation("Erfolg", "E -Mail-Einstellungen erfolgreich überprüft!");
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -115,17 +113,17 @@ namespace Elwig.Windows {
private async void Menu_Scale_SetDateTime_Click(object sender, RoutedEventArgs evt) { private async void Menu_Scale_SetDateTime_Click(object sender, RoutedEventArgs evt) {
if (App.CommandScales.Count == 0) { if (App.CommandScales.Count == 0) {
MessageBox.Show("Es sind keine geeigneten Waagen verfügbar!", "Datum und Uhrzeit setzen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowError("Datum und Uhrzeit setzen", "Es sind keine geeigneten Waagen verfügbar!");
return; return;
} }
foreach (var s in App.CommandScales) { foreach (var s in App.CommandScales) {
try { try {
await s.SetDateAndTime(DateTime.Now); await s.SetDateAndTime(DateTime.Now);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
} }
MessageBox.Show("Datum und Uhrzeit auf entsprechenden Waagen gesetzt!", "Datum und Uhrzeit setzen", MessageBoxButton.OK, MessageBoxImage.Information); InteractionService.ShowInformation("Datum und Uhrzeit setzen", "Datum und Uhrzeit auf entsprechenden Waagen gesetzt!");
} }
private void Menu_Database_Query_Click(object sender, RoutedEventArgs evt) { private void Menu_Database_Query_Click(object sender, RoutedEventArgs evt) {
@@ -157,29 +155,23 @@ namespace Elwig.Windows {
}); });
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
private async void Menu_Database_Backup_Click(object sender, RoutedEventArgs evt) { private async void Menu_Database_Backup_Click(object sender, RoutedEventArgs evt) {
try { try {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Datenbank-Sicherung", $"database_{Utils.Today:yyyy-MM-dd}", "sql.zip");
Title = "Datenbank sichern - Elwig", if (filename != null) {
FileName = $"database_{Utils.Today:yyyy-MM-dd}.sql.zip", if (!filename.EndsWith(".sql.zip")) filename += ".sql.zip";
DefaultExt = "sql.zip",
Filter = "Komprimierte SQL-Datei (*.sql.zip)|*.sql.zip",
AddExtension = false,
};
if (d.ShowDialog() == true) {
if (!d.FileName.EndsWith(".sql.zip")) d.FileName += ".sql.zip";
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
await Database.ExportSql(d.FileName, true); await Database.ExportSql(filename, true);
}); });
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -192,16 +184,13 @@ namespace Elwig.Windows {
Filter = "SQLite-Datenbank (*.sqlite3, *.sqlite3.zip, *.sql, *.sql.zip)|*.sqlite3;*.sqlite3.zip;*.sql;*.sql.zip", Filter = "SQLite-Datenbank (*.sqlite3, *.sqlite3.zip, *.sql, *.sql.zip)|*.sqlite3;*.sqlite3.zip;*.sql;*.sql.zip",
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
var res = MessageBox.Show("Soll die Datenbank wirklich unwiederruflich durch die wiederhergestellte Version ersetzt werden?", "Datenbank wiederherstellen", if (!InteractionService.AskContinue("Datenbank wiederherstellen", "Soll die Datenbank wirklich unwiederruflich durch die wiederhergestellte Version ersetzt werden?"))
MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (res != MessageBoxResult.OK)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await App.ReplaceDatabase(d.FileName); await App.ReplaceDatabase(d.FileName);
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -266,15 +255,15 @@ namespace Elwig.Windows {
.ToList(); .ToList();
if (files.Count == 0) { if (files.Count == 0) {
MessageBox.Show("Die Datenbank wurde noch nicht vom Hauptgerät hochgeladen!", "Datenbank herunterladen", InteractionService.ShowError("Datenbank herunterladen", "Die Datenbank wurde noch nicht vom Hauptgerät hochgeladen!");
MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
} }
var file = files[0]; var file = files[0];
var res = MessageBox.Show($"Es wurde eine komprimierte Datenbank (ca. {file.Size / 1024 / 1024} MB) vom {file.Timestamp:dd.MM.yyyy, HH:mm} gefunden.\n\nWollen Sie wirklich die aktuelle Datenbank unwiederruflich\nlöschen und durch die gefundene ersetzen?\n\nDas kann zu Datenverlust führen!", "Datenbank herunterladen", if (!InteractionService.AskContinue("Datenbank herunterladen",
MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); $"Es wurde eine komprimierte Datenbank (ca. {file.Size / 1024 / 1024} MB) vom {file.Timestamp:dd.MM.yyyy, HH:mm} gefunden.\n\n" +
if (res != MessageBoxResult.OK) $"Wollen Sie wirklich die aktuelle Datenbank unwiederruflich\nlöschen und durch die gefundene ersetzen?\n\n" +
$"Das kann zu Datenverlust führen!"))
return; return;
var filename = Path.Combine(App.TempPath, file.Name); var filename = Path.Combine(App.TempPath, file.Name);
@@ -283,20 +272,21 @@ namespace Elwig.Windows {
await client.DownloadAsync(file.Url, stream); await client.DownloadAsync(file.Url, stream);
} }
res = MessageBox.Show("Die Datenbank wurde erfolgreich heruntergeladen!\n\nSoll die Datenbank wirklich unwiederruflich ersetzt werden?\n\nWenn Sie unsicher sind sprechen Sie sich mit dem Benutzer des Hauptgerätes ab!", "Datenbank herunterladen", if (!InteractionService.AskContinue("Datenbank herunterladen",
MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Die Datenbank wurde erfolgreich heruntergeladen!\n\n" +
if (res != MessageBoxResult.OK) "Soll die Datenbank wirklich unwiederruflich ersetzt werden?\n\n" +
"Wenn Sie unsicher sind sprechen Sie sich mit dem Benutzer des Hauptgerätes ab!"))
return; return;
await App.MainDispatcher.BeginInvoke(async () => { await App.MainDispatcher.BeginInvoke(async () => {
await App.ReplaceDatabase(filename); await App.ReplaceDatabase(filename);
}); });
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank herunterladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank herunterladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Datenbank herunterladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank herunterladen", exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -306,9 +296,7 @@ namespace Elwig.Windows {
if (App.Config.SyncUrl == null) if (App.Config.SyncUrl == null)
return; return;
var res = MessageBox.Show("Sind Sie wirklich sicher, dass Sie die Datenbank dieses\nGerätes hochladen möchten? Das sollte nur vom Hauptgerät aus passieren!", "Datenbank hochladen", if (!InteractionService.AskContinue("Datenbank hochladen", "Sind Sie wirklich sicher, dass Sie die Datenbank dieses\nGerätes hochladen möchten? Das sollte nur vom Hauptgerät aus passieren!"))
MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (res != MessageBoxResult.OK)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
@@ -317,14 +305,13 @@ namespace Elwig.Windows {
var path = Path.Combine(App.TempPath, "database.sql.zip"); var path = Path.Combine(App.TempPath, "database.sql.zip");
await Database.ExportSql(path, true); await Database.ExportSql(path, true);
await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
MessageBox.Show($"Hochladen der gesamten Datenbank erfolgreich!", "Datenbank hochladen", InteractionService.ShowInformation("Datenbank hochladen", $"Hochladen der gesamten Datenbank erfolgreich!");
MessageBoxButton.OK, MessageBoxImage.Information);
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Datenbank hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank hochladen", "Eventuell Internetverbindung prüfen!", exc);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Datenbank hochladen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Datenbank hochladen", exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -457,13 +444,8 @@ namespace Elwig.Windows {
private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) { private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) {
if (SeasonInput.Value is not int year) if (SeasonInput.Value is not int year)
return; return;
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile($"Über-/Unterlieferungen {year}", $"Über-Unterlieferungen-{year}", "ods");
FileName = $"Über-Unterlieferungen-{year}.ods", if (filename == null)
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Über-/Unterlieferungen {year} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
@@ -477,11 +459,16 @@ namespace Elwig.Windows {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year); var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year);
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year); var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(filename);
await ods.AddTable(tbl1); if (App.Client.HasRedWhite) {
await ods.AddTable(tbl1.Red);
await ods.AddTable(tbl1.White);
} else {
await ods.AddTable(tbl1.Total);
}
await ods.AddTable(tbl2); await ods.AddTable(tbl2);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -490,13 +477,8 @@ namespace Elwig.Windows {
private async void BreakdownButton_Click(object sender, RoutedEventArgs evt) { private async void BreakdownButton_Click(object sender, RoutedEventArgs evt) {
if (SeasonInput.Value is not int year) if (SeasonInput.Value is not int year)
return; return;
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile($"Sorten-/Qualitätsaufschlüsselung {year}", $"Aufschlüsselung-{year}", "ods");
FileName = $"Aufschlüsselung-{year}.ods", if (filename == null)
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Sorten-/Qualitätsaufschlüsselung {year} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
@@ -508,7 +490,7 @@ namespace Elwig.Windows {
App.HintContextChange(); App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(filename);
var tblTotal = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year); var tblTotal = await WeightBreakdownData.ForSeason(ctx.WeightBreakDownRows, year);
await ods.AddTable(tblTotal); await ods.AddTable(tblTotal);
foreach (var branch in await ctx.FetchBranches().ToListAsync()) { foreach (var branch in await ctx.FetchBranches().ToListAsync()) {
@@ -516,7 +498,7 @@ namespace Elwig.Windows {
await ods.AddTable(tbl); await ods.AddTable(tbl);
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -525,13 +507,8 @@ namespace Elwig.Windows {
private async void AreaCommitmentsButton_Click(object sender, RoutedEventArgs evt) { private async void AreaCommitmentsButton_Click(object sender, RoutedEventArgs evt) {
if (SeasonInput.Value is not int year) if (SeasonInput.Value is not int year)
return; return;
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile($"Flächenbindungen {year}", $"Flächenbindungen-{year}", "ods");
FileName = $"Flächenbindungen-{year}.ods", if (filename == null)
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Flächenbindungen {year} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
@@ -544,10 +521,10 @@ namespace Elwig.Windows {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year); var tbl = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(filename);
await ods.AddTable(tbl); await ods.AddTable(tbl);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
@@ -556,13 +533,8 @@ namespace Elwig.Windows {
private async void BreakdownMemberVarietyButton_Click(object sender, RoutedEventArgs evt) { private async void BreakdownMemberVarietyButton_Click(object sender, RoutedEventArgs evt) {
if (SeasonInput.Value is not int year) if (SeasonInput.Value is not int year)
return; return;
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile($"Liefermengen/Ertrag {year}", $"Liefermengen-Ertrag-{year}", "ods");
FileName = $"Liefermengen-Ertrag-{year}.ods", if (filename == null)
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Liefermengen/Ertrag {year} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
@@ -575,10 +547,10 @@ namespace Elwig.Windows {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl = await MemberDeliveryYieldsPerVarietyData.ForSeason(ctx.MemberDeliveryPerVariantRows, year); var tbl = await MemberDeliveryYieldsPerVarietyData.ForSeason(ctx.MemberDeliveryPerVariantRows, year);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(filename);
await ods.AddTable(tbl); await ods.AddTable(tbl);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
+11 -4
View File
@@ -233,7 +233,7 @@
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Nachname" Binding="{Binding Name}" Width="140"/> <DataGridTextColumn Header="Nachname" Binding="{Binding Name}" Width="140"/>
<DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="140"/> <DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="140"/>
<DataGridTextColumn Header="GA" Binding="{Binding BusinessShares, StringFormat='{}{0} '}" Width="40"> <DataGridTextColumn Header="GA" Binding="{Binding SharesTotal, StringFormat='{}{0} '}" Width="40">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
@@ -619,9 +619,16 @@
Margin="0,40,10,0" Width="78" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right" Margin="0,40,10,0" Width="78" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="DateInput_TextChanged" LostFocus="DateInput_LostFocus"/> TextChanged="DateInput_TextChanged" LostFocus="DateInput_LostFocus"/>
<Label Content="Geschäftsanteile:" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="Geschäftsanteile:" Margin="10,65,0,0" Grid.Column="0"/>
<TextBox x:Name="BusinessSharesInput" Text="{Binding BusinessSharesString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <Label x:Name="BusinessSharesLabel" Content="(rot/weiß/ruhend)" Margin="10,78,0,0" Grid.Column="0" FontSize="10"/>
Margin="0,70,10,0" Width="48" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right" <TextBox x:Name="BusinessShares1Input" Text="{Binding BusinessShares1String, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,70,10,0" Width="32" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="IntegerInput_TextChanged"/>
<TextBox x:Name="BusinessShares2Input" Text="{Binding BusinessShares2String, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="37,70,10,0" Width="32" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="IntegerInput_TextChanged"/>
<TextBox x:Name="BusinessShares3Input" Text="{Binding BusinessShares3String, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="74,70,10,0" Width="32" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="IntegerInput_TextChanged"/> TextChanged="IntegerInput_TextChanged"/>
<Label Content="BH-Konto:" Margin="10,100,0,0" Grid.Column="0"/> <Label Content="BH-Konto:" Margin="10,100,0,0" Grid.Column="0"/>
+31 -22
View File
@@ -13,6 +13,7 @@ using Elwig.Dialogs;
using Elwig.Services; using Elwig.Services;
using Elwig.ViewModels; using Elwig.ViewModels;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Media;
namespace Elwig.Windows { namespace Elwig.Windows {
public partial class MemberAdminWindow : AdministrationWindow { public partial class MemberAdminWindow : AdministrationWindow {
@@ -43,7 +44,7 @@ namespace Elwig.Windows {
RequiredInputs = [ RequiredInputs = [
MgNrInput, GivenNameInput, NameInput, MgNrInput, GivenNameInput, NameInput,
AddressInput, PlzInput, OrtInput, BillingOrtInput, AddressInput, PlzInput, OrtInput, BillingOrtInput,
BusinessSharesInput, BranchInput, DefaultKgInput BusinessShares1Input, BusinessShares2Input, BusinessShares3Input, BranchInput, DefaultKgInput
]; ];
EmailAddressInputs = [ EmailAddressInputs = [
(EmailAddress1Label, EmailAddress1Input), (EmailAddress1Label, EmailAddress1Input),
@@ -84,6 +85,24 @@ namespace Elwig.Windows {
Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null; Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null;
ViewModel.ShowOnlyActiveMembers = true; ViewModel.ShowOnlyActiveMembers = true;
if (App.Client.HasRedWhite) {
BusinessSharesLabel.Content = "(rot/weiß/ruhend)";
//BusinessShares1Input.Background = Brushes.MistyRose;
BusinessShares1Input.Foreground = Brushes.DarkRed;
BusinessShares1Input.ToolTip = "Geschäftsanteile (rot)";
//BusinessShares2Input.Background = Brushes.MintCream;
BusinessShares2Input.Foreground = Brushes.DarkGreen;
BusinessShares2Input.ToolTip = "Geschäftsanteile (weiß)";
BusinessShares3Input.Background = Brushes.WhiteSmoke;
BusinessShares3Input.ToolTip = "Geschäftsanteile (ruhend)";
} else {
BusinessSharesLabel.Content = "(normal/ruhend)";
BusinessShares1Input.ToolTip = "Geschäftsanteile (normal)";
BusinessShares2Input.Background = Brushes.WhiteSmoke;
BusinessShares2Input.ToolTip = "Geschäftsanteile (ruhend)";
BusinessShares3Input.Visibility = Visibility.Hidden;
}
UpdateContactInfoVisibility(); UpdateContactInfoVisibility();
} }
@@ -142,7 +161,7 @@ namespace Elwig.Windows {
} }
var totalMemberCount = await ctx.Members.CountAsync(); var totalMemberCount = await ctx.Members.CountAsync();
var totalBusinessShares = await ctx.Members.SumAsync(m => m.BusinessShares); var totalBusinessShares = await ctx.Members.SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant);
return (members, totalMemberCount, totalBusinessShares); return (members, totalMemberCount, totalBusinessShares);
}); });
@@ -155,7 +174,7 @@ namespace Elwig.Windows {
MemberList.ScrollIntoView(MemberList.SelectedItem); MemberList.ScrollIntoView(MemberList.SelectedItem);
ViewModel.StatusMembers = $"{members.Count:N0} ({totalMemberCount:N0})"; ViewModel.StatusMembers = $"{members.Count:N0} ({totalMemberCount:N0})";
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.BusinessShares):N0} ({totalBusinessShares:N0})"; ViewModel.StatusBusinessShares = $"{members.Sum(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0} ({totalBusinessShares:N0})";
} }
private void RefreshInputs(bool validate = false) { private void RefreshInputs(bool validate = false) {
@@ -279,9 +298,9 @@ namespace Elwig.Windows {
$"{new string(s1, Math.Max(0, mM - mI.Length))}{(mS && mI.Length < 4 ? s2 : "")}{mI} nicht aktive Mitglieder\n" + $"{new string(s1, Math.Max(0, mM - mI.Length))}{(mS && mI.Length < 4 ? s2 : "")}{mI} nicht aktive Mitglieder\n" +
$"{new string(s1, Math.Max(0, mM - mT.Length))}{(mS && mT.Length < 4 ? s2 : "")}{mT} Mitglieder gesamt"; $"{new string(s1, Math.Max(0, mM - mT.Length))}{(mS && mT.Length < 4 ? s2 : "")}{mT} Mitglieder gesamt";
var bA = $"{await ctx.Members.Where(m => m.IsActive).SumAsync(m => m.BusinessShares):N0}"; var bA = $"{await ctx.Members.Where(m => m.IsActive).SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0}";
var bI = $"{await ctx.Members.Where(m => !m.IsActive).SumAsync(m => m.BusinessShares):N0}"; var bI = $"{await ctx.Members.Where(m => !m.IsActive).SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0}";
var bT = $"{await ctx.Members.SumAsync(m => m.BusinessShares):N0}"; var bT = $"{await ctx.Members.SumAsync(m => m.Shares + m.SharesRed + m.SharesWhite + m.SharesDormant):N0}";
var bM = Math.Max(bA.Length, Math.Max(bI.Length, bT.Length)); var bM = Math.Max(bA.Length, Math.Max(bI.Length, bT.Length));
var bS = bM > 3; var bS = bM > 3;
if (bS) bM--; if (bS) bM--;
@@ -399,9 +418,7 @@ namespace Elwig.Windows {
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs); await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Mitglied löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Mitglied löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -422,9 +439,7 @@ namespace Elwig.Windows {
mgnr = await ViewModel.UpdateMember(ViewModel.SelectedMember?.MgNr); mgnr = await ViewModel.UpdateMember(ViewModel.SelectedMember?.MgNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Mitglied aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Mitglied aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return; return;
@@ -512,7 +527,7 @@ namespace Elwig.Windows {
} }
}); });
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -534,9 +549,7 @@ namespace Elwig.Windows {
private async void Menu_MemberDataSheet_Email_Click(object sender, RoutedEventArgs evt) { private async void Menu_MemberDataSheet_Email_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return; if (ViewModel.SelectedMember is not Member m) return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Stammdatenblatt verschicken", if (!InteractionService.AskQuestion("Stammdatenblatt verschicken", "Soll eine E-Mail verschickt werden?", true))
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return; return;
await MemberService.GenerateMemberDataSheet(m, ExportMode.Email); await MemberService.GenerateMemberDataSheet(m, ExportMode.Email);
} }
@@ -566,9 +579,7 @@ namespace Elwig.Windows {
var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
if (ViewModel.SelectedMember is not Member m || year == null) if (ViewModel.SelectedMember is not Member m || year == null)
return; return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Anlieferungsbestätigung verschicken", if (!InteractionService.AskQuestion("Anlieferungsbestätigung verschicken", "Soll eine E-Mail verschickt werden?", true))
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return; return;
await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.Email); await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.Email);
} }
@@ -602,9 +613,7 @@ namespace Elwig.Windows {
var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag; var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
if (ViewModel.SelectedMember is not Member m || year == null || avnr == null) if (ViewModel.SelectedMember is not Member m || year == null || avnr == null)
return; return;
var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Traubengutschrift verschicken", if (!InteractionService.AskQuestion("Traubengutschrift verschicken", "Soll eine E-Mail verschickt werden?", true))
MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
if (res != MessageBoxResult.Yes)
return; return;
await MemberService.GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Email); await MemberService.GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Email);
} }
+5 -10
View File
@@ -1,5 +1,6 @@
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -192,18 +193,14 @@ namespace Elwig.Windows {
App.HintContextChange(); App.HintContextChange();
ControlUtils.SelectItemWithPk(WbGlKgs, k.KgNr); ControlUtils.SelectItemWithPk(WbGlKgs, k.KgNr);
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Katastralgemeinde aktivieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Katastralgemeinde aktivieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
private async void DeactivateKgButton_Click(object sender, RoutedEventArgs e) { private async void DeactivateKgButton_Click(object sender, RoutedEventArgs e) {
if (WbGlKgs.SelectedItem is not AT_Kg k || k.WbKg == null) return; if (WbGlKgs.SelectedItem is not AT_Kg k || k.WbKg == null) return;
var r = MessageBox.Show( if (!InteractionService.AskConfirmation("Katastralgemeinde deaktivieren", $"Sollen alle Riede und Stammgemeinden-Einträge von der KG {k.Name} wirklich unwiderruflich gelöscht werden?"))
$"Sollen alle Riede und Stammgemeinden-Einträge von der KG {k.Name} wirklich unwiderruflich gelöscht werden?", return;
"Katastralgemeinde deaktivieren", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (r != MessageBoxResult.Yes) return;
try { try {
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
ctx.Remove(k.WbKg); ctx.Remove(k.WbKg);
@@ -213,9 +210,7 @@ namespace Elwig.Windows {
ControlUtils.SelectItemWithPk(WbKgs, k.KgNr); ControlUtils.SelectItemWithPk(WbKgs, k.KgNr);
} catch (Exception exc) { } catch (Exception exc) {
await ForceContextReload(); await ForceContextReload();
var str = "Der Eintrag konnte nicht aus der Datenbank gelöscht werden!\n\n" + exc.Message; InteractionService.ShowDbException("Katastralgemeinde deaktivieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Katastralgemeinde deaktivieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
+10 -10
View File
@@ -76,7 +76,7 @@
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Nachname" Binding="{Binding Name}" Width="100"/> <DataGridTextColumn Header="Nachname" Binding="{Binding Name}" Width="100"/>
<DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="90"/> <DataGridTextColumn Header="Vorname" Binding="{Binding GivenName}" Width="90"/>
<DataGridTextColumn Header="GA" Binding="{Binding BusinessShares, StringFormat='{}{0:N0} '}" Width="35"> <DataGridTextColumn Header="GA" Binding="{Binding SharesActive, StringFormat='{}{0:N0} '}" Width="35">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
@@ -104,7 +104,7 @@
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Strafe GA" Binding="{Binding PenaltyBs, Converter={StaticResource CurrencyConverter}, StringFormat='{}{0} '}" Width="65"> <DataGridTextColumn Header="Strafe GA" Binding="{Binding PenaltyShares, Converter={StaticResource CurrencyConverter}, StringFormat='{}{0} '}" Width="65">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
@@ -204,28 +204,28 @@
<Label Content="Absoluter Freibetrag:" Margin="10,10,0,0" Grid.ColumnSpan="2"/> <Label Content="Absoluter Freibetrag:" Margin="10,10,0,0" Grid.ColumnSpan="2"/>
<ctrl:UnitTextBox x:Name="AllowanceKgInput" Unit="kg" Margin="128,10,0,0" Width="70" <ctrl:UnitTextBox x:Name="AllowanceKgInput" Unit="kg" Margin="128,10,0,0" Width="70"
TextChanged="KgInput_TextChanged" Grid.Column="1"/> TextChanged="KgInput_TextChanged" Grid.Column="1"/>
<ctrl:UnitTextBox x:Name="AllowanceBsInput" Unit="GA" Margin="203,10,0,0" Width="60" <ctrl:UnitTextBox x:Name="AllowanceShareInput" Unit="GA" Margin="203,10,0,0" Width="60"
TextChanged="PercentInput_TextChanged" Grid.Column="1"/> TextChanged="PercentInput_TextChanged" Grid.Column="1"/>
<Label Content="Relativer Freibetrag:" Margin="10,40,0,0" Grid.ColumnSpan="2"/> <Label Content="Relativer Freibetrag:" Margin="10,40,0,0" Grid.ColumnSpan="2"/>
<ctrl:UnitTextBox x:Name="AllowanceKgPerBsInput" Unit="kg/GA" Margin="128,40,0,0" Width="87" <ctrl:UnitTextBox x:Name="AllowanceKgPerShareInput" Unit="kg/GA" Margin="128,40,0,0" Width="87"
TextChanged="KgInput_TextChanged" Grid.Column="1"/> TextChanged="KgInput_TextChanged" Grid.Column="1"/>
<ctrl:UnitTextBox x:Name="AllowancePercentInput" Unit="%" Margin="220,40,0,0" Width="60" <ctrl:UnitTextBox x:Name="AllowancePercentInput" Unit="%" Margin="220,40,0,0" Width="60"
TextChanged="PercentInput_TextChanged" Grid.Column="1"/> TextChanged="PercentInput_TextChanged" Grid.Column="1"/>
<Label Content="Nur mind. nachz.:" Margin="10,70,0,0" Grid.ColumnSpan="2"/> <Label Content="Nur mind. nachz.:" Margin="10,70,0,0" Grid.ColumnSpan="2"/>
<ctrl:UnitTextBox x:Name="MinBsInput" Unit="GA" Margin="128,70,0,0" Width="50" <ctrl:UnitTextBox x:Name="MinSharesInput" Unit="GA" Margin="128,70,0,0" Width="50"
TextChanged="BsInput_TextChanged" Grid.Column="1"/> TextChanged="SharesInput_TextChanged" Grid.Column="1"/>
<Button x:Name="SeasonButton" Content="GA-Wert" Margin="0,0,10,42" Width="120" <Button x:Name="SeasonButton" Content="GA-Wert" Margin="0,0,10,42" Width="120"
HorizontalAlignment="Right" VerticalAlignment="Bottom" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Click="SeasonButton_Click" Grid.Column="1"/> Click="SeasonButton_Click" Grid.Column="1"/>
<Button x:Name="AutoAdjustBsButton" Content="Nachzeichnen" Margin="0,0,135,10" Width="120" <Button x:Name="AutoAdjustSharesButton" Content="Nachzeichnen" Margin="0,0,135,10" Width="120"
HorizontalAlignment="Right" VerticalAlignment="Bottom" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Click="AutoAdjustBsButton_Click" Grid.Column="1"/> Click="AutoAdjustSharesButton_Click" Grid.Column="1"/>
<Button x:Name="UnAdjustBsButton" Content="Rückgängig" Margin="0,0,10,10" Width="120" <Button x:Name="UnAdjustSharesButton" Content="Rückgängig" Margin="0,0,10,10" Width="120"
HorizontalAlignment="Right" VerticalAlignment="Bottom" HorizontalAlignment="Right" VerticalAlignment="Bottom"
Click="UnAdjustBsButton_Click" Grid.Column="1"/> Click="UnAdjustSharesButton_Click" Grid.Column="1"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
</Grid> </Grid>
+48 -53
View File
@@ -2,6 +2,7 @@ using Elwig.Helpers;
using Elwig.Helpers.Billing; using Elwig.Helpers.Billing;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -25,18 +26,18 @@ namespace Elwig.Windows {
Year = year; Year = year;
// using (var ctx = new AppDbContext()) { SeasonLocked = ctx.Seasons.Find(Year + 1) != null; } // using (var ctx = new AppDbContext()) { SeasonLocked = ctx.Seasons.Find(Year + 1) != null; }
Title = $"Auszahlung anpassen - Lese {Year} - Elwig"; Title = $"Auszahlung anpassen - Lese {Year} - Elwig";
AutoAdjustBsButton.IsEnabled = !SeasonLocked; AutoAdjustSharesButton.IsEnabled = !SeasonLocked;
UnAdjustBsButton.IsEnabled = !SeasonLocked; UnAdjustSharesButton.IsEnabled = !SeasonLocked;
SaveCustomButton.IsEnabled = !SeasonLocked; SaveCustomButton.IsEnabled = !SeasonLocked;
RemoveCustomButton.IsEnabled = !SeasonLocked; RemoveCustomButton.IsEnabled = !SeasonLocked;
CustomAmountInput.IsEnabled = !SeasonLocked; CustomAmountInput.IsEnabled = !SeasonLocked;
CustomCommentInput.IsEnabled = !SeasonLocked; CustomCommentInput.IsEnabled = !SeasonLocked;
AllowanceKgInput.Text = $"{App.Client.AutoAdjustBs.AllowanceKg}"; AllowanceKgInput.Text = $"{App.Client.AutoAdjustShares.AllowanceKg}";
AllowanceBsInput.Text = $"{App.Client.AutoAdjustBs.AllowanceBs}"; AllowanceShareInput.Text = $"{App.Client.AutoAdjustShares.AllowanceShares}";
AllowanceKgPerBsInput.Text = $"{App.Client.AutoAdjustBs.AllowanceKgPerBs}"; AllowanceKgPerShareInput.Text = $"{App.Client.AutoAdjustShares.AllowanceKgPerShare}";
AllowancePercentInput.Text = $"{App.Client.AutoAdjustBs.AllowancePercent}"; AllowancePercentInput.Text = $"{App.Client.AutoAdjustShares.AllowancePercent}";
MinBsInput.Text = $"{App.Client.AutoAdjustBs.MinBs}"; MinSharesInput.Text = $"{App.Client.AutoAdjustShares.MinShares}";
} }
protected override async Task OnRenewContext(AppDbContext ctx) { protected override async Task OnRenewContext(AppDbContext ctx) {
@@ -45,36 +46,36 @@ namespace Elwig.Windows {
m.MgNr, m.MgNr,
m.Name, m.Name,
m.GivenName, m.GivenName,
m.BusinessShares, m.SharesActive,
m.IsActive, m.IsActive,
}) })
.ToListAsync(); .ToListAsync();
var season = await ctx.FetchSeasons(Year).SingleAsync(); var season = await ctx.FetchSeasons(Year).SingleAsync();
var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t); var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year); var (tbl1, _, _) = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year);
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, Year); var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, Year);
var weight = tbl1.Rows.ToDictionary(r => r.MgNr, r => r.Weight); var weight = tbl1.Rows.ToDictionary(r => r.MgNr, r => r.WeightTotal);
var areaComs = tbl2.Rows.ToDictionary(r => r.MgNr, r => r.VtrgIds.Zip(r.UnderDeliveries).ToDictionary(r => r.First, r => r.Second)); var areaComs = tbl2.Rows.ToDictionary(r => r.MgNr, r => r.VtrgIds.Zip(r.UnderDeliveries).ToDictionary(r => r.First, r => r.Second));
CustomPayments = await ctx.CustomPayments.Where(p => p.Year == Year).ToDictionaryAsync(p => p.MgNr, p => p); CustomPayments = await ctx.CustomPayments.Where(p => p.Year == Year).ToDictionaryAsync(p => p.MgNr, p => p);
var history = await ctx.MemberHistory var history = await ctx.MemberHistory
.Where(h => h.DateString.CompareTo($"{Year}-01-01") >= 0 && h.DateString.CompareTo($"{Year}-12-31") <= 0 && h.Type == "auto" && h.BusinessShares > 0) .Where(h => h.DateString.CompareTo($"{Year}-01-01") >= 0 && h.DateString.CompareTo($"{Year}-12-31") <= 0 && h.Reason == "auto" && h.Shares > 0)
.GroupBy(h => h.Member) .GroupBy(h => h.ToMember)
.ToDictionaryAsync(h => h.Key.MgNr, h => h.Sum(g => g.BusinessShares)); .ToDictionaryAsync(h => h.Key.MgNr, h => h.Sum(g => g.Shares));
var list = members var list = members
.Select(m => new { .Select(m => new {
m.MgNr, m.Name, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.IsActive, m.IsActive,
BusinessShares = m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0), SharesActive = m.SharesActive - history.GetValueOrDefault(m.MgNr, 0),
DeliveryObligation = (m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0)) * season.MinKgPerBusinessShare, DeliveryObligation = (m.SharesActive - history.GetValueOrDefault(m.MgNr, 0)) * season.MinKgPerShare,
DeliveryRight = (m.BusinessShares - history.GetValueOrDefault(m.MgNr, 0)) * season.MaxKgPerBusinessShare, DeliveryRight = (m.SharesActive - history.GetValueOrDefault(m.MgNr, 0)) * season.MaxKgPerShare,
Adjust = history.TryGetValue(m.MgNr, out int v2) ? (int?)v2 : null, Adjust = history.TryGetValue(m.MgNr, out int v2) ? (int?)v2 : null,
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.Name, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.SharesActive,
Weight = weight.GetValueOrDefault(m.MgNr, 0), Weight = weight.GetValueOrDefault(m.MgNr, 0),
OverUnder = weight.TryGetValue(m.MgNr, out int v1) ? OverUnder = weight.TryGetValue(m.MgNr, out int v1) ?
(v1 < m.DeliveryObligation ? (int?)v1 - m.DeliveryObligation : (v1 < m.DeliveryObligation ? (int?)v1 - m.DeliveryObligation :
@@ -85,12 +86,12 @@ namespace Elwig.Windows {
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.Name, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.SharesActive, m.Weight, m.OverUnder,
PenaltyBs = m.OverUnder != null && m.OverUnder < 0 ? PenaltyShares = m.OverUnder != null && m.OverUnder < 0 ?
(season.PenaltyPerKg * m.OverUnder ?? 0) + (season.PenaltyPerKg * m.OverUnder ?? 0) +
(-season.PenaltyAmount ?? 0) + (-season.PenaltyAmount ?? 0) +
(season.PenaltyPerBsAmount * Math.Floor(m.OverUnder / season.MinKgPerBusinessShare ?? 0m) ?? 0) + (season.PenaltyPerShareAmount * Math.Floor(m.OverUnder / season.MinKgPerShare ?? 0m) ?? 0) +
(m.Weight == 0 ? (-season.PenaltyNone ?? 0) + (-season.PenaltyPerBsNone * m.BusinessShares ?? 0) : 0) (m.Weight == 0 ? (-season.PenaltyNone ?? 0) + (-season.PenaltyPerShareNone * m.SharesActive ?? 0) : 0)
: (decimal?)null, : (decimal?)null,
PenaltyAc = areaComs.TryGetValue(m.MgNr, out var c) ? c.Select(r => { PenaltyAc = areaComs.TryGetValue(m.MgNr, out var c) ? c.Select(r => {
var con = contracts[r.Key]; var con = contracts[r.Key];
@@ -102,30 +103,30 @@ namespace Elwig.Windows {
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.Name, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.SharesActive, m.Weight, m.OverUnder,
PenaltyBs = m.PenaltyBs == null || m.PenaltyBs == 0 ? (decimal?)null : Math.Round((decimal)m.PenaltyBs, 2), PenaltyShares = m.PenaltyShares == null || m.PenaltyShares == 0 ? (decimal?)null : Math.Round((decimal)m.PenaltyShares, 2),
PenaltyAc = m.PenaltyAc == null ? (decimal?)null : Math.Round((decimal)m.PenaltyAc, 2), PenaltyAc = m.PenaltyAc == null ? (decimal?)null : Math.Round((decimal)m.PenaltyAc, 2),
m.Adjust, m.Adjust,
AdjustAmount = m.AdjustAmount == null ? (decimal?)null : Math.Round((decimal)m.AdjustAmount, 2), AdjustAmount = m.AdjustAmount == null ? (decimal?)null : Math.Round((decimal)m.AdjustAmount, 2),
CustomAmount = m.Custom?.Amount, CustomAmount = m.Custom?.Amount,
ModAbs = m.Custom?.ModAbs, m.Custom?.ModAbs,
ModRel = m.Custom?.ModRel, m.Custom?.ModRel,
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.Name, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.SharesActive, m.Weight, m.OverUnder,
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.CustomAmount, m.ModAbs, m.ModRel, m.PenaltyShares, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.CustomAmount, m.ModAbs, m.ModRel,
Total = (m.PenaltyBs ?? 0) + (m.PenaltyAc ?? 0) + (m.AdjustAmount ?? 0) + (m.CustomAmount ?? 0), Total = (m.PenaltyShares ?? 0) + (m.PenaltyAc ?? 0) + (m.AdjustAmount ?? 0) + (m.CustomAmount ?? 0),
}) })
.Select(m => new { .Select(m => new {
m.MgNr, m.Name, m.GivenName, m.MgNr, m.Name, m.GivenName,
m.BusinessShares, m.Weight, m.OverUnder, m.SharesActive, m.Weight, m.OverUnder,
m.PenaltyBs, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.CustomAmount, m.ModAbs, m.ModRel, m.PenaltyShares, m.PenaltyAc, m.Adjust, m.AdjustAmount, m.CustomAmount, m.ModAbs, m.ModRel,
m.Total, m.Total,
Background = m.Weight == 0 ? Brushes.Orange : m.Weight / 2 < -m.Total ? Brushes.Red : Brushes.White, Background = m.Weight == 0 ? Brushes.Orange : m.Weight / 2 < -m.Total ? Brushes.Red : Brushes.White,
Foreground = m.Total == 0 ? Brushes.Gray : Brushes.Black, Foreground = m.Total == 0 ? Brushes.Gray : Brushes.Black,
}) })
.Where(m => m.OverUnder != null || m.Adjust != null || m.PenaltyBs != null || m.PenaltyAc != null || m.CustomAmount != null || m.ModAbs != null || m.ModRel != null) .Where(m => m.OverUnder != null || m.Adjust != null || m.PenaltyShares != null || m.PenaltyAc != null || m.CustomAmount != null || m.ModAbs != null || m.ModRel != null)
.OrderByDescending(m => m.OverUnder ?? 0) .OrderByDescending(m => m.OverUnder ?? 0)
.ThenBy(m => m.Name) .ThenBy(m => m.Name)
.ThenBy(m => m.GivenName) .ThenBy(m => m.GivenName)
@@ -135,7 +136,7 @@ namespace Elwig.Windows {
MemberList.ItemsSource = list; MemberList.ItemsSource = list;
var sym = season.Currency.Symbol ?? season.Currency.Code; var sym = season.Currency.Symbol ?? season.Currency.Code;
PenaltyBusinessShares.Text = $"{list.Count(r => r.PenaltyBs != null && r.PenaltyBs != 0)} Mg. / {list.Sum(r => r.PenaltyBs):N2} {sym}"; PenaltyBusinessShares.Text = $"{list.Count(r => r.PenaltyShares != null && r.PenaltyShares != 0)} Mg. / {list.Sum(r => r.PenaltyShares):N2} {sym}";
PenaltyAreaCommitments.Text = $"{list.Count(r => r.PenaltyAc != null && r.PenaltyAc != 0)} Mg. / {list.Sum(r => r.PenaltyAc):N2} {sym}"; PenaltyAreaCommitments.Text = $"{list.Count(r => r.PenaltyAc != null && r.PenaltyAc != 0)} Mg. / {list.Sum(r => r.PenaltyAc):N2} {sym}";
AutoBusinessShareAdjustment.Text = $"{list.Count(r => r.Adjust > 0)} Mg. / {list.Sum(r => r.Adjust)} GA / {list.Sum(r => r.AdjustAmount):N2} {sym}"; AutoBusinessShareAdjustment.Text = $"{list.Count(r => r.Adjust > 0)} Mg. / {list.Sum(r => r.Adjust)} GA / {list.Sum(r => r.AdjustAmount):N2} {sym}";
CustomModifiers.Text = $"{list.Count(r => r.CustomAmount != null)} Mg. / {list.Sum(r => r.CustomAmount):N2} {sym}"; CustomModifiers.Text = $"{list.Count(r => r.CustomAmount != null)} Mg. / {list.Sum(r => r.CustomAmount):N2} {sym}";
@@ -146,36 +147,34 @@ namespace Elwig.Windows {
CustomAmountInput.Unit = sym; CustomAmountInput.Unit = sym;
} }
private async void AutoAdjustBsButton_Click(object sender, RoutedEventArgs evt) { private async void AutoAdjustSharesButton_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
int? kg = AllowanceKgInput.Text == "" ? null : int.Parse(AllowanceKgInput.Text); int? kg = AllowanceKgInput.Text == "" ? null : int.Parse(AllowanceKgInput.Text);
double? bs = AllowanceBsInput.Text == "" ? null : double.Parse(AllowanceBsInput.Text); double? shares = AllowanceShareInput.Text == "" ? null : double.Parse(AllowanceShareInput.Text);
int? kgPerBs = AllowanceKgPerBsInput.Text == "" ? null : int.Parse(AllowanceKgPerBsInput.Text); int? kgPerShare = AllowanceKgPerShareInput.Text == "" ? null : int.Parse(AllowanceKgPerShareInput.Text);
double? percent = AllowancePercentInput.Text == "" ? null : double.Parse(AllowancePercentInput.Text); double? percent = AllowancePercentInput.Text == "" ? null : double.Parse(AllowancePercentInput.Text);
int? minBs = MinBsInput.Text == "" ? null : int.Parse(MinBsInput.Text); int? minShares = MinSharesInput.Text == "" ? null : int.Parse(MinSharesInput.Text);
App.Client.AutoAdjustBs.AllowanceKg = kg; App.Client.AutoAdjustShares.AllowanceKg = kg;
App.Client.AutoAdjustBs.AllowanceBs = bs; App.Client.AutoAdjustShares.AllowanceShares = shares;
App.Client.AutoAdjustBs.AllowanceKgPerBs = kgPerBs; App.Client.AutoAdjustShares.AllowanceKgPerShare = kgPerShare;
App.Client.AutoAdjustBs.AllowancePercent = percent; App.Client.AutoAdjustShares.AllowancePercent = percent;
App.Client.AutoAdjustBs.MinBs = minBs; App.Client.AutoAdjustShares.MinShares = minShares;
await Task.Run(async () => { await Task.Run(async () => {
await App.Client.UpdateValues(); await App.Client.UpdateValues();
var b = await Billing.Create(Year); var b = await Billing.Create(Year);
await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, bs ?? default, kgPerBs ?? default, percent / 100.0 ?? default, minBs ?? default); await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, shares ?? default, kgPerShare ?? default, percent / 100.0 ?? default, minShares ?? default);
}); });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("GA Nachzeichnen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "GA Nachzeichnen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
private async void UnAdjustBsButton_Click(object sender, RoutedEventArgs evt) { private async void UnAdjustSharesButton_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Task.Run(async () => { await Task.Run(async () => {
@@ -184,9 +183,7 @@ namespace Elwig.Windows {
}); });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("GA Nachzeichnen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "GA Nachzeichnen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -199,7 +196,7 @@ namespace Elwig.Windows {
Validator.CheckInteger((TextBox)sender, false, 6); Validator.CheckInteger((TextBox)sender, false, 6);
} }
private void BsInput_TextChanged(object sender, TextChangedEventArgs evt) { private void SharesInput_TextChanged(object sender, TextChangedEventArgs evt) {
Validator.CheckInteger((TextBox)sender, false, 3); Validator.CheckInteger((TextBox)sender, false, 3);
} }
@@ -303,9 +300,7 @@ namespace Elwig.Windows {
}); });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Benutzerdefinierten Zu-/Abschlag speichern", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Benutzerdefinierten Zu-/Abschlag speichern", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
+11 -24
View File
@@ -90,9 +90,7 @@ namespace Elwig.Windows {
App.HintContextChange(); App.HintContextChange();
ControlUtils.SelectItem(PaymentVariantList, v); ControlUtils.SelectItem(PaymentVariantList, v);
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Auszahlungsvariante erstellen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante erstellen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -106,9 +104,7 @@ namespace Elwig.Windows {
App.HintContextChange(); App.HintContextChange();
ControlUtils.SelectItem(PaymentVariantList, n); ControlUtils.SelectItem(PaymentVariantList, n);
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Auszahlungsvariante kopieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante kopieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -116,19 +112,14 @@ namespace Elwig.Windows {
private async void DeleteButton_Click(object sender, RoutedEventArgs evt) { private async void DeleteButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v || !v.TestVariant) if (PaymentVariantList.SelectedItem is not PaymentVar v || !v.TestVariant)
return; return;
var res = MessageBox.Show( if (!InteractionService.AskContinue("Auszahlungsvariante löschen", $"Soll die Auszahlungsvariante \"{v.Name}\" wirklich unwiderruflich gelöscht werden?"))
$"Soll die Auszahlungsvariante \"{v.Name}\" wirklich unwiderruflich gelöscht werden?",
"Auszahlungsvariante löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (res != MessageBoxResult.OK)
return; return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await PaymentVariantService.DeletePaymentVariant(v.Year, v.AvNr); await PaymentVariantService.DeletePaymentVariant(v.Year, v.AvNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Auszahlungsvariante löschen", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -142,7 +133,7 @@ namespace Elwig.Windows {
await PaymentVariantService.Calculate(v.Year, v.AvNr); await PaymentVariantService.Calculate(v.Year, v.AvNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Berechnungsfehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Berechnungsfehler", exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
ViewModel.CalculateIsEnabled = true; ViewModel.CalculateIsEnabled = true;
@@ -204,7 +195,7 @@ namespace Elwig.Windows {
await PaymentVariantService.Commit(v.Year, v.AvNr); await PaymentVariantService.Commit(v.Year, v.AvNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
ViewModel.RevertIsEnabled = true; ViewModel.RevertIsEnabled = true;
@@ -213,11 +204,9 @@ namespace Elwig.Windows {
private async void RevertButton_Click(object sender, RoutedEventArgs evt) { private async void RevertButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
var res = MessageBox.Show( if (!InteractionService.AskConfirmation("Traubengutschriften löschen",
"Sollen wirklich alle festgesetzten Traubengutschriften der ausgewählten Auszahlungsvariante unwiderruflich gelöscht werden?\n\n" + "Sollen wirklich alle festgesetzten Traubengutschriften der ausgewählten Auszahlungsvariante unwiderruflich gelöscht werden?\n\n" +
"Dies ist im Allgemeinen nie empfohlen. Handelt es sich um die aktuellste Auszahlungsvariante könnte das eine Ausnahme sein.", "Dies ist im Allgemeinen nie empfohlen. Handelt es sich um die aktuellste Auszahlungsvariante könnte das eine Ausnahme sein."))
"Traubengutschriften löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (res != MessageBoxResult.Yes)
return; return;
ViewModel.RevertIsEnabled = false; ViewModel.RevertIsEnabled = false;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
@@ -225,7 +214,7 @@ namespace Elwig.Windows {
await PaymentVariantService.Revert(v.Year, v.AvNr); await PaymentVariantService.Revert(v.Year, v.AvNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException(exc);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
ViewModel.CommitIsEnabled = true; ViewModel.CommitIsEnabled = true;
@@ -235,7 +224,7 @@ namespace Elwig.Windows {
if (PaymentVariantList.SelectedItem is not PaymentVar v) { if (PaymentVariantList.SelectedItem is not PaymentVar v) {
return; return;
} else if (v.TransferDate == null) { } else if (v.TransferDate == null) {
MessageBox.Show("Überweisungsdatum muss gesetzt sein!", "Exportieren nicht möglich", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowError("Exportieren nicht möglich", "Überweisungsdatum muss gesetzt sein!");
return; return;
} }
await PaymentVariantService.GenerateEbics(v.Year, v.AvNr); await PaymentVariantService.GenerateEbics(v.Year, v.AvNr);
@@ -256,9 +245,7 @@ namespace Elwig.Windows {
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
await ForceContextReload(); await ForceContextReload();
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; InteractionService.ShowDbException("Auszahlungsvariante aktualisieren", exc);
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
await EnsureContextRenewed(); await EnsureContextRenewed();
+7 -12
View File
@@ -1,6 +1,6 @@
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Helpers.Export; using Elwig.Helpers.Export;
using Microsoft.Win32; using Elwig.Services;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
@@ -42,9 +42,9 @@ namespace Elwig.Windows {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await DisplayQuery(QueryInput.Text); await DisplayQuery(QueryInput.Text);
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} catch (Exception e) { } catch (Exception exc) {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
MessageBox.Show(e.Message, "Fehler beim Ausführen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Fehler beim Ausführen", exc);
} }
} }
@@ -85,21 +85,16 @@ namespace Elwig.Windows {
} }
private static async Task SaveQuery(string sqlQuery) { private static async Task SaveQuery(string sqlQuery) {
var d = new SaveFileDialog() { var filename = InteractionService.SaveFile("Datenbank Abfrage", "Abfrage", "csv");
FileName = $"Abfrage.csv", if (filename != null) {
DefaultExt = "csv",
Filter = "CSV-Datei (*.csv)|*.csv",
Title = $"Datenbank Abfrage speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
try { try {
var (header, rows) = await ExecuteQuery(sqlQuery); var (header, rows) = await ExecuteQuery(sqlQuery);
using var csv = new CsvSimple(d.FileName, ';', Utils.UTF8BOM); using var csv = new CsvSimple(filename, ';', Utils.UTF8BOM);
await csv.ExportAsync(rows.Prepend([.. header.Select(h => h.ColumnName)])); await csv.ExportAsync(rows.Prepend([.. header.Select(h => h.ColumnName)]));
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler beim Ausführen", MessageBoxButton.OK, MessageBoxImage.Error); InteractionService.ShowException("Fehler beim Ausführen", exc);
} }
}); });
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
+3 -3
View File
@@ -32,9 +32,9 @@ INSERT INTO area_commitment (fbnr, revnr, mgnr, vtrgid, cultid, area, gstnr, yea
( 2, 1, 101, 'GV', 'KIP', 10000, '123/5', 2025, 2030), ( 2, 1, 101, 'GV', 'KIP', 10000, '123/5', 2025, 2030),
( 3, 1, 101, 'GV', 'KIP', 10000, '123/6', 2021, 2031); ( 3, 1, 101, 'GV', 'KIP', 10000, '123/6', 2021, 2031);
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 INSERT INTO season (year, currency, min_kg_per_share, max_kg_per_share, start_date, end_date) VALUES
(2020, 'EUR', 1000, 2000, NULL, NULL, NULL, NULL, NULL), (2020, 'EUR', 1000, 2000, NULL, NULL),
(2021, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL); (2021, 'EUR', 2000, 4000, NULL, NULL);
INSERT INTO modifier (year, modid, ordering, name, abs, rel, active) VALUES INSERT INTO modifier (year, modid, ordering, name, abs, rel, active) VALUES
(2020, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, TRUE), (2020, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, TRUE),
+2 -2
View File
@@ -6,8 +6,8 @@ INSERT INTO wine_cultivation (cultid, name, description) VALUES
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
('K', 'Kabinett', TRUE, NULL, FALSE, 0); ('K', 'Kabinett', TRUE, NULL, FALSE, 0);
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 INSERT INTO season (year, currency, min_kg_per_share, max_kg_per_share, start_date, end_date) VALUES
(2020, 'EUR', 1000, 2000, NULL, NULL, NULL, NULL, NULL); (2020, 'EUR', 1000, 2000, NULL, NULL);
INSERT INTO delivery_schedule (year, dsnr, date, zwstid, description, max_weight, ancmt_from, ancmt_to) VALUES INSERT INTO delivery_schedule (year, dsnr, date, zwstid, description, max_weight, ancmt_from, ancmt_to) VALUES
(2020, 1, '2020-10-01', 'X', 'GV Kabinettaktion', 100000, NULL, NULL); (2020, 1, '2020-10-01', 'X', 'GV Kabinettaktion', 100000, NULL, NULL);
+4 -4
View File
@@ -42,10 +42,10 @@ INSERT INTO area_commitment (fbnr, revnr, mgnr, vtrgid, cultid, area, gstnr, yea
( 4, 1, 204, 'GV', NULL, 10000, '123/3', 2021, 2031); ( 4, 1, 204, 'GV', NULL, 10000, '123/3', 2021, 2031);
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 INSERT INTO season (year, currency, min_kg_per_share, max_kg_per_share, start_date, end_date) VALUES
(2021, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL), (2021, 'EUR', 2000, 4000, NULL, NULL),
(2022, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL), (2022, 'EUR', 2000, 4000, NULL, NULL),
(2023, 'EUR', 2000, 4000, NULL, NULL, NULL, NULL, NULL); (2023, 'EUR', 2000, 4000, NULL, NULL);
INSERT INTO modifier (year, modid, ordering, name, abs, rel, active) VALUES INSERT INTO modifier (year, modid, ordering, name, abs, rel, active) VALUES
(2021, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, TRUE), (2021, 'S', 0, 'Geschädigte Trauben', NULL, -0.1, TRUE),
@@ -8,7 +8,7 @@ namespace Tests.UnitTests.DocumentTests {
public async Task Test_01_VirtualCreditNote() { public async Task Test_01_VirtualCreditNote() {
using var doc = await CreditNote.Initialize(2020, 1, 101, null); using var doc = await CreditNote.Initialize(2020, 1, 101, null);
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
MUSTERMANN Max MUSTERMANN Max
Winzerstraße 1 Winzerstraße 1
@@ -32,7 +32,7 @@ namespace Tests.UnitTests.DocumentTests {
""")); """));
Assert.That(text, Contains.Substring("Gesamtbetrag: € 1 000,00")); Assert.That(text, Contains.Substring("Gesamtbetrag: € 1 000,00"));
Assert.That(text, Contains.Substring("Auszahlungsbetrag: € 1 000,00")); Assert.That(text, Contains.Substring("Auszahlungsbetrag: € 1 000,00"));
}); }
} }
} }
} }
@@ -14,7 +14,7 @@ namespace Tests.UnitTests.DocumentTests {
using var doc = new DeliveryAncmtList(filter, data); using var doc = new DeliveryAncmtList(filter, data);
var text = await Utils.GeneratePdfText(doc, true); var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text); var table = Utils.ExtractTable(text);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("Anmeldeliste")); Assert.That(text, Contains.Substring("Anmeldeliste"));
Assert.That(text, Contains.Substring("01.10.2020 Matzen GV Kabinettaktion")); Assert.That(text, Contains.Substring("01.10.2020 Matzen GV Kabinettaktion"));
Assert.That(table, Is.EqualTo(new string[][] { Assert.That(table, Is.EqualTo(new string[][] {
@@ -24,7 +24,7 @@ namespace Tests.UnitTests.DocumentTests {
["01.10.2020", "104 WINZER Waltraud", "Wolkersdorf", "Grüner Veltliner", "-", "2 000"], ["01.10.2020", "104 WINZER Waltraud", "Wolkersdorf", "Grüner Veltliner", "-", "2 000"],
["Gesamt:", "Anmeldungen: 4", "25 000"], ["Gesamt:", "Anmeldungen: 4", "25 000"],
})); }));
}); }
} }
} }
} }
@@ -13,7 +13,7 @@ namespace Tests.UnitTests.DocumentTests {
var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, 2020, m!); var data = await DeliveryConfirmationDeliveryData.ForMember(ctx.DeliveryParts, 2020, m!);
using var doc = new DeliveryConfirmation(2020, m!, null, data); using var doc = new DeliveryConfirmation(2020, m!, null, data);
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
MUSTERMANN Max MUSTERMANN Max
Winzerstraße 1 Winzerstraße 1
@@ -39,7 +39,7 @@ namespace Tests.UnitTests.DocumentTests {
Welschriesling 5 382 - 5 382 Welschriesling 5 382 - 5 382
12 442 3 129 15 571 12 442 3 129 15 571
""")); """));
}); }
} }
} }
} }
@@ -13,7 +13,7 @@ namespace Tests.UnitTests.DocumentTests {
using var doc = new DeliveryDepreciationList("Saison 2020", data); using var doc = new DeliveryDepreciationList("Saison 2020", data);
var text = await Utils.GeneratePdfText(doc, true); var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text); var table = Utils.ExtractTable(text);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("Abwertungsliste")); Assert.That(text, Contains.Substring("Abwertungsliste"));
Assert.That(text, Contains.Substring("Saison 2020")); Assert.That(text, Contains.Substring("Saison 2020"));
Assert.That(table, Is.EqualTo(new string[][] { Assert.That(table, Is.EqualTo(new string[][] {
@@ -26,7 +26,7 @@ namespace Tests.UnitTests.DocumentTests {
["20201002X002 1 02.10.2020 09:28 Grüner Veltliner", "Bio", "78", "16,0", "2 901"], ["20201002X002 1 02.10.2020 09:28 Grüner Veltliner", "Bio", "78", "16,0", "2 901"],
["Gesamt:", "(Teil-)Lieferungen: 3 (5)", "80", "16,3", "13 069"], ["Gesamt:", "(Teil-)Lieferungen: 3 (5)", "80", "16,3", "13 069"],
})); }));
}); }
} }
} }
} }
@@ -13,7 +13,7 @@ namespace Tests.UnitTests.DocumentTests {
using var doc = new DeliveryJournal("Saison 2020", data); using var doc = new DeliveryJournal("Saison 2020", data);
var text = await Utils.GeneratePdfText(doc, true); var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text); var table = Utils.ExtractTable(text);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("Lieferjournal")); Assert.That(text, Contains.Substring("Lieferjournal"));
Assert.That(text, Contains.Substring("Saison 2020")); Assert.That(text, Contains.Substring("Saison 2020"));
Assert.That(table, Is.EqualTo(new string[][] { Assert.That(table, Is.EqualTo(new string[][] {
@@ -42,7 +42,7 @@ namespace Tests.UnitTests.DocumentTests {
["20201003X003", "2", "03.10.2020 15:15", "104 WINZER Waltraud", "Blauer Portugieser", "89", "18,1", "2 313"], ["20201003X003", "2", "03.10.2020 15:15", "104 WINZER Waltraud", "Blauer Portugieser", "89", "18,1", "2 313"],
["Gesamt:", "(Teil-)Lieferungen: 12 (23)", "82", "16,6", "58 886"], ["Gesamt:", "(Teil-)Lieferungen: 12 (23)", "82", "16,6", "58 886"],
})); }));
}); }
} }
} }
} }
@@ -135,7 +135,7 @@ namespace Tests.UnitTests.DocumentTests {
public async Task Test_05_DeliveryPartsWithModifier() { public async Task Test_05_DeliveryPartsWithModifier() {
using var doc = await DeliveryNote.Initialize(2020, 2); using var doc = await DeliveryNote.Initialize(2020, 2);
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
W&B Weinbauer GesbR W&B Weinbauer GesbR
WEINBAUER Wernhardt WEINBAUER Wernhardt
@@ -160,7 +160,7 @@ namespace Tests.UnitTests.DocumentTests {
Waage: ?, ID: ? (gerebelt gewogen) Waage: ?, ID: ? (gerebelt gewogen)
Gesamt: 87 17,6 4 860 Gesamt: 87 17,6 4 860
""")); """));
}); }
} }
} }
} }
@@ -11,14 +11,14 @@ namespace Tests.UnitTests.DocumentTests {
var m = await ctx.FetchMembers(104).SingleAsync(); var m = await ctx.FetchMembers(104).SingleAsync();
using var doc = new Letterhead(m!); using var doc = new Letterhead(m!);
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("WG Test | Genossenschaftsstraße 1 | 2120 Wolkersdorf")); Assert.That(text, Contains.Substring("WG Test | Genossenschaftsstraße 1 | 2120 Wolkersdorf"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
WINZER Waltraud WINZER Waltraud
Wiener Straße 15 Wiener Straße 15
2120 Wolkersdorf im Weinviertel 2120 Wolkersdorf im Weinviertel
""")); """));
}); }
} }
} }
} }
@@ -8,7 +8,7 @@ namespace Tests.UnitTests.DocumentTests {
public async Task Test_01_SimpleMember() { public async Task Test_01_SimpleMember() {
using var doc = await MemberDataSheet.Initialize(104); using var doc = await MemberDataSheet.Initialize(104);
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
WINZER Waltraud WINZER Waltraud
Wiener Straße 15 Wiener Straße 15
@@ -32,7 +32,7 @@ namespace Tests.UnitTests.DocumentTests {
Assert.That(text, Contains.Substring("IBAN: AT97 1234 5678 9012 3460")); Assert.That(text, Contains.Substring("IBAN: AT97 1234 5678 9012 3460"));
Assert.That(text, Contains.Substring("Betriebs-Nr.: 0123498")); Assert.That(text, Contains.Substring("Betriebs-Nr.: 0123498"));
Assert.That(text, Contains.Substring("Stammgemeinde: Wolkersdorf")); Assert.That(text, Contains.Substring("Stammgemeinde: Wolkersdorf"));
}); }
} }
} }
} }
@@ -13,7 +13,7 @@ namespace Tests.UnitTests.DocumentTests {
using var doc = new MemberList("Alle Mitglieder", data); using var doc = new MemberList("Alle Mitglieder", data);
var text = await Utils.GeneratePdfText(doc, true); var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text); var table = Utils.ExtractTable(text);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("Mitgliederliste")); Assert.That(text, Contains.Substring("Mitgliederliste"));
Assert.That(text, Contains.Substring("Alle Mitglieder")); Assert.That(text, Contains.Substring("Alle Mitglieder"));
Assert.That(table.Take(3), Is.EqualTo(new string[][] { Assert.That(table.Take(3), Is.EqualTo(new string[][] {
@@ -21,7 +21,7 @@ namespace Tests.UnitTests.DocumentTests {
["102 WEINBAUER Wernhardt", "Winzerstraße 2", "2223", "Hohenruppersdorf", "0123471", "0 Hohenruppersdorf"], ["102 WEINBAUER Wernhardt", "Winzerstraße 2", "2223", "Hohenruppersdorf", "0123471", "0 Hohenruppersdorf"],
[ "W&B Weinbauer GesbR", "Winzerstraße 2", "2223", "Hohenruppersdorf"], [ "W&B Weinbauer GesbR", "Winzerstraße 2", "2223", "Hohenruppersdorf"],
})); }));
}); }
} }
} }
} }
@@ -9,7 +9,7 @@ namespace Tests.UnitTests.DocumentTests {
using var doc = await PaymentVariantSummary.Initialize(2020, 1); using var doc = await PaymentVariantSummary.Initialize(2020, 1);
var text = await Utils.GeneratePdfText(doc, true); var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text); var table = Utils.ExtractTable(text);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("Auszahlungsvariante")); Assert.That(text, Contains.Substring("Auszahlungsvariante"));
Assert.That(text, Contains.Substring(doc.Variant.Name)); Assert.That(text, Contains.Substring(doc.Variant.Name));
Assert.That(table.Skip(19).ToArray(), Is.EqualTo(new string[][] { Assert.That(table.Skip(19).ToArray(), Is.EqualTo(new string[][] {
@@ -18,7 +18,7 @@ namespace Tests.UnitTests.DocumentTests {
["Grüner Veltliner", "3 219", "0", "0", "1 609,50"], ["Grüner Veltliner", "3 219", "0", "0", "1 609,50"],
["Qualitätswein", "73", "3 219", "0,5000", "-", "-", "-", "-", "1 609,50"] ["Qualitätswein", "73", "3 219", "0,5000", "-", "-", "-", "-", "1 609,50"]
})); }));
}); }
} }
} }
} }
+7 -5
View File
@@ -4,10 +4,13 @@ using NReco.PdfRenderer;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace Tests.UnitTests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
public static class Utils { public static partial class Utils {
private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf"); private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf");
[GeneratedRegex(@"\s{2,}")]
private static partial Regex WideSpaces();
public static async Task<string> GeneratePdfText(Document doc, bool preserveLayout = false) { public static async Task<string> GeneratePdfText(Document doc, bool preserveLayout = false) {
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
await doc.Generate(ctx); await doc.Generate(ctx);
@@ -22,11 +25,10 @@ namespace Tests.UnitTests.DocumentTests {
} }
public static string[][] ExtractTable(string text) { public static string[][] ExtractTable(string text) {
return text.Split('\n') return [.. text.Split('\n')
.Select(row => Regex.Split(row, @"\s{2,}").Select(c => c.Trim()).Where(c => c.Length > 0).ToArray()) .Select(row => WideSpaces().Split(row).Select(c => c.Trim()).Where(c => c.Length > 0).ToArray())
.Where(row => row.Length >= 3) .Where(row => row.Length >= 3)
.Skip(1) .Skip(1)];
.ToArray();
} }
} }
} }
@@ -12,7 +12,7 @@ namespace Tests.UnitTests.DocumentTests {
var data = await WineQualityStatisticsData.FromQuery(ctx.Deliveries.Where(d => d.Year == 2020).SelectMany(d => d.Parts)); var data = await WineQualityStatisticsData.FromQuery(ctx.Deliveries.Where(d => d.Year == 2020).SelectMany(d => d.Parts));
using var doc = new WineQualityStatistics("Saison 2020", data); using var doc = new WineQualityStatistics("Saison 2020", data);
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(text, Contains.Substring("Qualitätsstatistik")); Assert.That(text, Contains.Substring("Qualitätsstatistik"));
Assert.That(text, Contains.Substring("Saison 2020")); Assert.That(text, Contains.Substring("Saison 2020"));
Assert.That(text, Contains.Substring(""" Assert.That(text, Contains.Substring("""
@@ -44,7 +44,7 @@ namespace Tests.UnitTests.DocumentTests {
"- 0 0 " + "- 0 0 " +
"77 5 " + "11 568 " + "77 5 " + "11 568 " +
"85 6 " + "17 561")); "85 6 " + "17 561"));
}); }
} }
} }
} }
+25 -26
View File
@@ -51,10 +51,10 @@ namespace Tests.UnitTests.HelperTests {
"curves": [] "curves": []
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
TestCalcOe(data, "GV", 73, 0.5m); TestCalcOe(data, "GV", 73, 0.5m);
TestCalcOe(data, "WRS", 74, 0.5m); TestCalcOe(data, "WRS", 74, 0.5m);
}); }
} }
[Test] [Test]
@@ -76,7 +76,7 @@ namespace Tests.UnitTests.HelperTests {
}] }]
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
TestCalcOe(data, "GV", 70, 0.25m); TestCalcOe(data, "GV", 70, 0.25m);
TestCalcOe(data, "GV", 72, 0.25m); TestCalcOe(data, "GV", 72, 0.25m);
TestCalcOe(data, "GV", 73, 0.50m); TestCalcOe(data, "GV", 73, 0.50m);
@@ -89,7 +89,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcOe(data, "GV", 80, 0.95m, geb: true); TestCalcOe(data, "GV", 80, 0.95m, geb: true);
TestCalcOe(data, "GV", 83, 1.10m, geb: true); TestCalcOe(data, "GV", 83, 1.10m, geb: true);
TestCalcOe(data, "GV", 90, 1.10m, geb: true); TestCalcOe(data, "GV", 90, 1.10m, geb: true);
}); }
} }
[Test] [Test]
@@ -113,7 +113,7 @@ namespace Tests.UnitTests.HelperTests {
}] }]
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
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);
TestCalcKmw(data, "GV", 13.99, 0.10m); TestCalcKmw(data, "GV", 13.99, 0.10m);
@@ -128,7 +128,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcKmw(data, "GV", 17.50, 1.25m); TestCalcKmw(data, "GV", 17.50, 1.25m);
TestCalcKmw(data, "GV", 18.00, 1.25m); TestCalcKmw(data, "GV", 18.00, 1.25m);
TestCalcKmw(data, "GV", 18.50, 1.25m); TestCalcKmw(data, "GV", 18.50, 1.25m);
}); }
} }
[Test] [Test]
@@ -147,7 +147,7 @@ namespace Tests.UnitTests.HelperTests {
"curves": [] "curves": []
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
TestCalcOe(data, "WR", 73, 0.10m); TestCalcOe(data, "WR", 73, 0.10m);
TestCalcOe(data, "WRS", 73, 0.15m); TestCalcOe(data, "WRS", 73, 0.15m);
TestCalcOe(data, "GV", 73, 0.20m); TestCalcOe(data, "GV", 73, 0.20m);
@@ -158,7 +158,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcOe(data, "ZW", 73, 0.25m); TestCalcOe(data, "ZW", 73, 0.25m);
TestCalcOe(data, "ZWS", 73, 0.15m); TestCalcOe(data, "ZWS", 73, 0.15m);
TestCalcOe(data, "ZWZ", 73, 0.25m); TestCalcOe(data, "ZWZ", 73, 0.25m);
}); }
} }
[Test] [Test]
@@ -175,7 +175,7 @@ namespace Tests.UnitTests.HelperTests {
"curves": [] "curves": []
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
TestCalcOe(data, "WR", 73, 0.10m); TestCalcOe(data, "WR", 73, 0.10m);
TestCalcOe(data, "WR-B", 73, 0.20m); TestCalcOe(data, "WR-B", 73, 0.20m);
TestCalcOe(data, "WRS", 73, 0.30m); TestCalcOe(data, "WRS", 73, 0.30m);
@@ -191,7 +191,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcOe(data, "ZW-B", 73, 0.20m); TestCalcOe(data, "ZW-B", 73, 0.20m);
TestCalcOe(data, "ZWS", 73, 0.30m); TestCalcOe(data, "ZWS", 73, 0.30m);
TestCalcOe(data, "ZWZ", 73, 0.10m); TestCalcOe(data, "ZWZ", 73, 0.10m);
}); }
} }
[Test] [Test]
@@ -211,7 +211,7 @@ namespace Tests.UnitTests.HelperTests {
"curves": [] "curves": []
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
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");
TestCalcOe(data, "GVS", 75, 0.20m, qualid: "WEI"); TestCalcOe(data, "GVS", 75, 0.20m, qualid: "WEI");
@@ -222,7 +222,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcOe(data, "GV", 73, 0.5m); TestCalcOe(data, "GV", 73, 0.5m);
TestCalcOe(data, "ZWS", 74, 0.5m); TestCalcOe(data, "ZWS", 74, 0.5m);
TestCalcOe(data, "GVK", 80, 0.5m); TestCalcOe(data, "GVK", 80, 0.5m);
}); }
} }
[Test] [Test]
@@ -253,7 +253,7 @@ namespace Tests.UnitTests.HelperTests {
}] }]
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
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);
TestCalcKmw(data, "GV", 16.0, 2.454545m); TestCalcKmw(data, "GV", 16.0, 2.454545m);
@@ -264,7 +264,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcKmw(data, "ZW", 16.0, 2.50m); TestCalcKmw(data, "ZW", 16.0, 2.50m);
TestCalcKmw(data, "ZW", 16.5, 2.75m); TestCalcKmw(data, "ZW", 16.5, 2.75m);
TestCalcKmw(data, "ZW", 17.0, 3.0m); TestCalcKmw(data, "ZW", 17.0, 3.0m);
}); }
} }
[Test] [Test]
@@ -313,7 +313,7 @@ namespace Tests.UnitTests.HelperTests {
}] }]
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
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);
TestCalcKmw(data, "GVS", 16.0, 0.55m); TestCalcKmw(data, "GVS", 16.0, 0.55m);
@@ -333,7 +333,7 @@ namespace Tests.UnitTests.HelperTests {
TestCalcKmw(data, "WRS", 15.0, 0.80m, geb: true); TestCalcKmw(data, "WRS", 15.0, 0.80m, geb: true);
TestCalcKmw(data, "WRS", 16.0, 0.875m, geb: true); TestCalcKmw(data, "WRS", 16.0, 0.875m, geb: true);
TestCalcKmw(data, "WRS", 17.0, 0.95m, geb: true); TestCalcKmw(data, "WRS", 17.0, 0.95m, geb: true);
}); }
} }
[Test] [Test]
@@ -372,12 +372,12 @@ namespace Tests.UnitTests.HelperTests {
}] }]
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
TestCalcOe(data, "GVK", 73, 0.032m); TestCalcOe(data, "GVK", 73, 0.032m);
TestCalcOe(data, "ZWS", 74, 0.033m); TestCalcOe(data, "ZWS", 74, 0.033m);
TestCalcOe(data, "GV", 75, 0.005m, qualid: "WEI"); TestCalcOe(data, "GV", 75, 0.005m, qualid: "WEI");
TestCalcOe(data, "GVK", 115, 0.065m); TestCalcOe(data, "GVK", 115, 0.065m);
}); }
} }
[Test] [Test]
@@ -395,17 +395,17 @@ namespace Tests.UnitTests.HelperTests {
"curves": [] "curves": []
} }
""", Vaributes); """, Vaributes);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
TestCalcOe(data, "GV", 73, 0.10m); TestCalcOe(data, "GV", 73, 0.10m);
TestCalcOe(data, "GVS", 73, 0.20m); TestCalcOe(data, "GVS", 73, 0.20m);
TestCalcOe(data, "GV-B", 73, 0.30m); TestCalcOe(data, "GV-B", 73, 0.30m);
TestCalcOe(data, "GVS-B", 73, 0.40m); TestCalcOe(data, "GVS-B", 73, 0.40m);
TestCalcOe(data, "ZWS-B", 73, 0.20m); TestCalcOe(data, "ZWS-B", 73, 0.20m);
}); }
} }
private static List<Varibute> GetSelection(IEnumerable<string> attVars) { private static List<Varibute> GetSelection(IEnumerable<string> attVars) {
return attVars.Select(s => new Varibute(new RawVaribute(s))).ToList(); return [.. attVars.Select(s => new Varibute(new RawVaribute(s)))];
} }
[Test] [Test]
@@ -1002,11 +1002,10 @@ namespace Tests.UnitTests.HelperTests {
if (!TestedCurves.Add(str)) if (!TestedCurves.Add(str))
return; return;
var vaributes = curves.SelectMany(v => v).ToList(); var vaributes = curves.SelectMany(v => v).ToList();
List<GraphEntry> entries = curves List<GraphEntry> entries = [.. curves
.Select((l, n) => new GraphEntry(n, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() { .Select((l, n) => new GraphEntry(n, 4, new BillingData.Curve(BillingData.CurveMode.Oe, new() {
[73] = n + 1, [73] = n + 1,
}, null), GetSelection(l.Select(v => v.ToString())))) }, null), GetSelection(l.Select(v => v.ToString()))))];
.ToList();
var data = BillingData.FromGraphEntries(entries); var data = BillingData.FromGraphEntries(entries);
var test = PaymentBillingData.FromJson(data.ToJsonString(), vaributes); var test = PaymentBillingData.FromJson(data.ToJsonString(), vaributes);
for (int i = 0; i < curves.Count; i++) { for (int i = 0; i < curves.Count; i++) {
@@ -1027,12 +1026,12 @@ namespace Tests.UnitTests.HelperTests {
[new("GV/-"), new("WR/-"), new("GV/-B"), new("WR/-B"), new("GV/-KIP"), new("WR/-KIP")], [new("GV/-"), new("WR/-"), new("GV/-B"), new("WR/-B"), new("GV/-KIP"), new("WR/-KIP")],
[new("GV/-"), new("GV/K-"), new("ZW/-"), new("ZW/K-"), new("GV/-B"), new("GV/K-B"), new("ZW/-B"), new("ZW/K-B")], [new("GV/-"), new("GV/K-"), new("ZW/-"), new("ZW/K-"), new("GV/-B"), new("GV/K-B"), new("ZW/-B"), new("ZW/K-B")],
]; ];
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
foreach (var config in configurations) { foreach (var config in configurations) {
foreach (var c in GetCurves(config)) foreach (var c in GetCurves(config))
TestCollapse(c); TestCollapse(c);
} }
}); }
} }
} }
} }
+22 -22
View File
@@ -128,24 +128,24 @@ namespace Tests.UnitTests.HelperTests {
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr); var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
Assert.That(areaCom, Is.Empty); Assert.That(areaCom, Is.Empty);
var delivery = await GetMemberDeliveryBuckets(year, mgnr); var delivery = await GetMemberDeliveryBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(delivery, Has.Count.EqualTo(3)); Assert.That(delivery, Has.Count.EqualTo(3));
Assert.That(delivery["GV"], Is.EqualTo(16_000)); Assert.That(delivery["GV"], Is.EqualTo(16_000));
Assert.That(delivery["GV_"], Is.EqualTo( 1_000)); Assert.That(delivery["GV_"], Is.EqualTo( 1_000));
Assert.That(delivery["GVK"], Is.EqualTo( 4_000)); Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
}); }
var b = await BillingVariant.Create(year, 1); var b = await BillingVariant.Create(year, 1);
await b.CalculateBuckets(false, false, false); await b.CalculateBuckets(false, false, false);
var payment = await GetMemberPaymentBuckets(year, mgnr); var payment = await GetMemberPaymentBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(payment, Has.Count.EqualTo(1)); Assert.That(payment, Has.Count.EqualTo(1));
Assert.That(payment["GV_"], Is.EqualTo(17_000)); Assert.That(payment["GV_"], Is.EqualTo(17_000));
}); }
await b.Calculate(); await b.Calculate();
var prices = await GetMemberDeliveryPrices(year, mgnr); var prices = await GetMemberDeliveryPrices(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(prices, Has.Count.EqualTo(6)); Assert.That(prices, Has.Count.EqualTo(6));
// Kabinett // Kabinett
Assert.That(prices[("20201001X001/1", "GV_")], Is.EqualTo((4_000, GV_ungeb))); Assert.That(prices[("20201001X001/1", "GV_")], Is.EqualTo((4_000, GV_ungeb)));
@@ -159,7 +159,7 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(prices[("20201001X003/1", "GV_")], Is.EqualTo(( 500, WEI))); Assert.That(prices[("20201001X003/1", "GV_")], Is.EqualTo(( 500, WEI)));
// ohne Attribut // ohne Attribut
Assert.That(prices[("20201001X003/2", "GV_")], Is.EqualTo(( 500, GV_ungeb))); Assert.That(prices[("20201001X003/2", "GV_")], Is.EqualTo(( 500, GV_ungeb)));
}); }
} }
[Test] [Test]
@@ -167,30 +167,30 @@ namespace Tests.UnitTests.HelperTests {
int mgnr = MgNr1, year = Year2; int mgnr = MgNr1, year = Year2;
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr); var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(areaCom, Has.Count.EqualTo(1)); Assert.That(areaCom, Has.Count.EqualTo(1));
Assert.That(areaCom["GV"], Is.EqualTo(new AreaComBucket(10_000, 5_000, 10_000))); Assert.That(areaCom["GV"], Is.EqualTo(new AreaComBucket(10_000, 5_000, 10_000)));
}); }
var delivery = await GetMemberDeliveryBuckets(year, mgnr); var delivery = await GetMemberDeliveryBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(delivery, Has.Count.EqualTo(3)); Assert.That(delivery, Has.Count.EqualTo(3));
Assert.That(delivery["GV"], Is.EqualTo(16_000)); Assert.That(delivery["GV"], Is.EqualTo(16_000));
Assert.That(delivery["GV_"], Is.EqualTo( 1_000)); Assert.That(delivery["GV_"], Is.EqualTo( 1_000));
Assert.That(delivery["GVK"], Is.EqualTo( 4_000)); Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
}); }
var b = await BillingVariant.Create(year, 1); var b = await BillingVariant.Create(year, 1);
await b.CalculateBuckets(false, false, false, Connection); await b.CalculateBuckets(false, false, false, Connection);
var payment = await GetMemberPaymentBuckets(year, mgnr); var payment = await GetMemberPaymentBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(payment, Has.Count.EqualTo(2)); Assert.That(payment, Has.Count.EqualTo(2));
Assert.That(payment["GV_"], Is.EqualTo( 7_000)); Assert.That(payment["GV_"], Is.EqualTo( 7_000));
Assert.That(payment["GV"], Is.EqualTo(10_000)); Assert.That(payment["GV"], Is.EqualTo(10_000));
}); }
await b.Calculate(true, false, false, false); await b.Calculate(true, false, false, false);
var prices = await GetMemberDeliveryPrices(year, mgnr); var prices = await GetMemberDeliveryPrices(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(prices, Has.Count.EqualTo(7)); Assert.That(prices, Has.Count.EqualTo(7));
// Kabinett // Kabinett
Assert.That(prices[("20211001X001/1", "GV")] , Is.EqualTo((4_000, GV_geb))); Assert.That(prices[("20211001X001/1", "GV")] , Is.EqualTo((4_000, GV_geb)));
@@ -205,7 +205,7 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(prices[("20211001X003/1", "GV_")], Is.EqualTo(( 500, WEI))); Assert.That(prices[("20211001X003/1", "GV_")], Is.EqualTo(( 500, WEI)));
// ohne Attribut // ohne Attribut
Assert.That(prices[("20211001X003/2", "GV_")], Is.EqualTo(( 500, GV_ungeb))); Assert.That(prices[("20211001X003/2", "GV_")], Is.EqualTo(( 500, GV_ungeb)));
}); }
} }
[Test] [Test]
@@ -213,30 +213,30 @@ namespace Tests.UnitTests.HelperTests {
int mgnr = MgNr1, year = Year2; int mgnr = MgNr1, year = Year2;
var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr); var areaCom = await GetMemberAreaCommitmentBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(areaCom, Has.Count.EqualTo(1)); Assert.That(areaCom, Has.Count.EqualTo(1));
Assert.That(areaCom["GV"], Is.EqualTo(new AreaComBucket(10_000, 5_000, 10_000))); Assert.That(areaCom["GV"], Is.EqualTo(new AreaComBucket(10_000, 5_000, 10_000)));
}); }
var delivery = await GetMemberDeliveryBuckets(year, mgnr); var delivery = await GetMemberDeliveryBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(delivery, Has.Count.EqualTo(3)); Assert.That(delivery, Has.Count.EqualTo(3));
Assert.That(delivery["GV"], Is.EqualTo(16_000)); Assert.That(delivery["GV"], Is.EqualTo(16_000));
Assert.That(delivery["GV_"], Is.EqualTo( 1_000)); Assert.That(delivery["GV_"], Is.EqualTo( 1_000));
Assert.That(delivery["GVK"], Is.EqualTo( 4_000)); Assert.That(delivery["GVK"], Is.EqualTo( 4_000));
}); }
var b = await BillingVariant.Create(year, 1); var b = await BillingVariant.Create(year, 1);
await b.CalculateBuckets(true, false, false, Connection); await b.CalculateBuckets(true, false, false, Connection);
var payment = await GetMemberPaymentBuckets(year, mgnr); var payment = await GetMemberPaymentBuckets(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(payment, Has.Count.EqualTo(2)); Assert.That(payment, Has.Count.EqualTo(2));
Assert.That(payment["GV_"], Is.EqualTo(9_000)); Assert.That(payment["GV_"], Is.EqualTo(9_000));
Assert.That(payment["GV"], Is.EqualTo(8_000)); Assert.That(payment["GV"], Is.EqualTo(8_000));
}); }
await b.Calculate(true, true, false, false); await b.Calculate(true, true, false, false);
var prices = await GetMemberDeliveryPrices(year, mgnr); var prices = await GetMemberDeliveryPrices(year, mgnr);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(prices, Has.Count.EqualTo(6)); Assert.That(prices, Has.Count.EqualTo(6));
// Kabinett // Kabinett
Assert.That(prices[("20211001X001/1", "GV")], Is.EqualTo((4_000, GV_geb))); Assert.That(prices[("20211001X001/1", "GV")], Is.EqualTo((4_000, GV_geb)));
@@ -250,7 +250,7 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(prices[("20211001X003/1", "GV_")], Is.EqualTo(( 500, WEI))); Assert.That(prices[("20211001X003/1", "GV_")], Is.EqualTo(( 500, WEI)));
// ohne Attribut // ohne Attribut
Assert.That(prices[("20211001X003/2", "GV_")], Is.EqualTo(( 500, GV_ungeb))); Assert.That(prices[("20211001X003/2", "GV_")], Is.EqualTo(( 500, GV_ungeb)));
}); }
} }
[Test] [Test]
+16 -16
View File
@@ -17,45 +17,45 @@ namespace Tests.UnitTests.HelperTests {
[Test] [Test]
public void Test_KmwToOe() { public void Test_KmwToOe() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
for (int i = 0; i < Gradation.GetLength(0); i++) { for (int i = 0; i < Gradation.GetLength(0); i++) {
Assert.That(Utils.KmwToOe(Gradation[i, 0]), Is.EqualTo(Gradation[i, 1])); Assert.That(Utils.KmwToOe(Gradation[i, 0]), Is.EqualTo(Gradation[i, 1]));
} }
}); }
} }
[Test] [Test]
public void Test_OeToKmw() { public void Test_OeToKmw() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
for (int i = 0; i < Gradation.GetLength(0); i++) { for (int i = 0; i < Gradation.GetLength(0); i++) {
Assert.That(Utils.OeToKmw(Gradation[i, 1]), Is.EqualTo(Gradation[i, 0])); Assert.That(Utils.OeToKmw(Gradation[i, 1]), Is.EqualTo(Gradation[i, 0]));
} }
}); }
} }
[Test] [Test]
public void Test_DecFromDb() { public void Test_DecFromDb() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Utils.DecFromDb(10670, 3), Is.EqualTo(10.67M)); Assert.That(Utils.DecFromDb(10670, 3), Is.EqualTo(10.67M));
Assert.That(Utils.DecFromDb(-1009999, 4), Is.EqualTo(-100.9999M)); Assert.That(Utils.DecFromDb(-1009999, 4), Is.EqualTo(-100.9999M));
Assert.That(Utils.DecFromDb(1, 2), Is.EqualTo(0.01M)); Assert.That(Utils.DecFromDb(1, 2), Is.EqualTo(0.01M));
}); }
} }
[Test] [Test]
public void Test_DecToDb() { public void Test_DecToDb() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Utils.DecToDb(219.48M, 2), Is.EqualTo(21948)); Assert.That(Utils.DecToDb(219.48M, 2), Is.EqualTo(21948));
Assert.That(Utils.DecToDb(-1.2345M, 4), Is.EqualTo(-12345)); Assert.That(Utils.DecToDb(-1.2345M, 4), Is.EqualTo(-12345));
Assert.That(Utils.DecToDb(99190, 0), Is.EqualTo(99190)); Assert.That(Utils.DecToDb(99190, 0), Is.EqualTo(99190));
Assert.That(Utils.DecToDb(817.9099M, 3), Is.EqualTo(817910)); Assert.That(Utils.DecToDb(817.9099M, 3), Is.EqualTo(817910));
Assert.That(Utils.DecToDb(-5618.944M, 2), Is.EqualTo(-561894)); Assert.That(Utils.DecToDb(-5618.944M, 2), Is.EqualTo(-561894));
}); }
} }
[Test] [Test]
public void Test_Modulo() { public void Test_Modulo() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Utils.Modulo("1", 2), Is.EqualTo(1)); Assert.That(Utils.Modulo("1", 2), Is.EqualTo(1));
Assert.That(Utils.Modulo("12", 11), Is.EqualTo(1)); Assert.That(Utils.Modulo("12", 11), Is.EqualTo(1));
Assert.That(Utils.Modulo("65", 16), Is.EqualTo(1)); Assert.That(Utils.Modulo("65", 16), Is.EqualTo(1));
@@ -66,12 +66,12 @@ namespace Tests.UnitTests.HelperTests {
Assert.Throws<ArgumentException>(() => Utils.Modulo("123", 1)); Assert.Throws<ArgumentException>(() => Utils.Modulo("123", 1));
Assert.Throws<ArgumentException>(() => Utils.Modulo("456", 0)); Assert.Throws<ArgumentException>(() => Utils.Modulo("456", 0));
Assert.Throws<ArgumentException>(() => Utils.Modulo("789", -1)); Assert.Throws<ArgumentException>(() => Utils.Modulo("789", -1));
}); }
} }
[Test] [Test]
public void Test_SplitAddress() { public void Test_SplitAddress() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Utils.SplitAddress("Winzerstraße 1"), Is.EqualTo(("Winzerstraße", "1"))); Assert.That(Utils.SplitAddress("Winzerstraße 1"), Is.EqualTo(("Winzerstraße", "1")));
Assert.That(Utils.SplitAddress("Auf dem Feld 12"), Is.EqualTo(("Auf dem Feld", "12"))); Assert.That(Utils.SplitAddress("Auf dem Feld 12"), Is.EqualTo(("Auf dem Feld", "12")));
Assert.That(Utils.SplitAddress("Winzerstraße 5a"), Is.EqualTo(("Winzerstraße", "5a"))); Assert.That(Utils.SplitAddress("Winzerstraße 5a"), Is.EqualTo(("Winzerstraße", "5a")));
@@ -80,12 +80,12 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(Utils.SplitAddress("Winzerstraße 7/2/4/77"), Is.EqualTo(("Winzerstraße", "7/2/4/77"))); Assert.That(Utils.SplitAddress("Winzerstraße 7/2/4/77"), Is.EqualTo(("Winzerstraße", "7/2/4/77")));
Assert.That(Utils.SplitAddress("Winzerstraße 95b"), Is.EqualTo(("Winzerstraße", "95b"))); Assert.That(Utils.SplitAddress("Winzerstraße 95b"), Is.EqualTo(("Winzerstraße", "95b")));
Assert.That(Utils.SplitAddress("Winzerstraße 1, TOP 3"), Is.EqualTo(("Winzerstraße", "1, TOP 3"))); Assert.That(Utils.SplitAddress("Winzerstraße 1, TOP 3"), Is.EqualTo(("Winzerstraße", "1, TOP 3")));
}); }
} }
[Test] [Test]
public void Test_SplitName() { public void Test_SplitName() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Utils.SplitName("Max Bauer", "Bauer"), Is.EqualTo(("Bauer", "Max"))); Assert.That(Utils.SplitName("Max Bauer", "Bauer"), Is.EqualTo(("Bauer", "Max")));
Assert.That(Utils.SplitName("Bauer Max", "Bauer"), Is.EqualTo(("Bauer", "Max"))); Assert.That(Utils.SplitName("Bauer Max", "Bauer"), Is.EqualTo(("Bauer", "Max")));
Assert.That(Utils.SplitName("Max und Moritz Bauer", "Bauer"), Is.EqualTo(("Bauer", "Max und Moritz"))); Assert.That(Utils.SplitName("Max und Moritz Bauer", "Bauer"), Is.EqualTo(("Bauer", "Max und Moritz")));
@@ -98,12 +98,12 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(Utils.SplitName("Max und Moritz Bauer und Mustermann", "Bauer"), Is.EqualTo(("Bauer und Mustermann", "Max und Moritz"))); Assert.That(Utils.SplitName("Max und Moritz Bauer und Mustermann", "Bauer"), Is.EqualTo(("Bauer und Mustermann", "Max und Moritz")));
Assert.That(Utils.SplitName("Bauer und Mustermann Max und Moritz", "Bauer"), Is.EqualTo(("Bauer und Mustermann", "Max und Moritz"))); Assert.That(Utils.SplitName("Bauer und Mustermann Max und Moritz", "Bauer"), Is.EqualTo(("Bauer und Mustermann", "Max und Moritz")));
Assert.That(Utils.SplitName("ABC GesbR", "Bauer"), Is.EqualTo(((string, string?))("ABC GesbR", null))); Assert.That(Utils.SplitName("ABC GesbR", "Bauer"), Is.EqualTo(((string, string?))("ABC GesbR", null)));
}); }
} }
[Test] [Test]
public void Test_CalcCrc16Modbus() { public void Test_CalcCrc16Modbus() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Utils.CalcCrc16Modbus(""), Is.EqualTo(0xFFFF)); Assert.That(Utils.CalcCrc16Modbus(""), Is.EqualTo(0xFFFF));
Assert.That(Utils.CalcCrc16Modbus("abcd"), Is.EqualTo(0x1D97)); Assert.That(Utils.CalcCrc16Modbus("abcd"), Is.EqualTo(0x1D97));
Assert.That(Utils.CalcCrc16Modbus("ABCD"), Is.EqualTo(0x0F85)); Assert.That(Utils.CalcCrc16Modbus("ABCD"), Is.EqualTo(0x0F85));
@@ -145,7 +145,7 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(Utils.CalcCrc16Modbus("000019.02.2410:50 91 40 0 40kg 001"), Is.EqualTo(60047)); Assert.That(Utils.CalcCrc16Modbus("000019.02.2410:50 91 40 0 40kg 001"), Is.EqualTo(60047));
Assert.That(Utils.CalcCrc16Modbus("000019.02.2410:50 101 40 0 40kg 001"), Is.EqualTo(60785)); Assert.That(Utils.CalcCrc16Modbus("000019.02.2410:50 101 40 0 40kg 001"), Is.EqualTo(60785));
Assert.That(Utils.CalcCrc16Modbus("000019.02.2410:50 111 45 0 45kg 001"), Is.EqualTo(35918)); Assert.That(Utils.CalcCrc16Modbus("000019.02.2410:50 111 45 0 45kg 001"), Is.EqualTo(35918));
}); }
} }
} }
} }
+18 -18
View File
@@ -15,69 +15,69 @@ namespace Tests.UnitTests.HelperTests {
[Test] [Test]
public void Test_CheckInteger_Simple() { public void Test_CheckInteger_Simple() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckInteger(TB(""), true).IsValid, Is.False); Assert.That(Validator.CheckInteger(TB(""), true).IsValid, Is.False);
Assert.That(Validator.CheckInteger(TB(""), false).IsValid, Is.True); Assert.That(Validator.CheckInteger(TB(""), false).IsValid, Is.True);
Assert.That(Validator.CheckInteger(TB("123"), true).IsValid, Is.True); Assert.That(Validator.CheckInteger(TB("123"), true).IsValid, Is.True);
Assert.That(Validator.CheckInteger(TB("456"), false).IsValid, Is.True); Assert.That(Validator.CheckInteger(TB("456"), false).IsValid, Is.True);
Assert.That(Validator.CheckInteger(TB("1234"), false, 4).IsValid, Is.True); Assert.That(Validator.CheckInteger(TB("1234"), false, 4).IsValid, Is.True);
Assert.That(Validator.CheckInteger(TB("4567"), false, 3).IsValid, Is.True); Assert.That(Validator.CheckInteger(TB("4567"), false, 3).IsValid, Is.True);
}); }
} }
[Test] [Test]
public void Test_CheckInteger_Caret() { public void Test_CheckInteger_Caret() {
var tb = TB("1a2b3c", 2); var tb = TB("1a2b3c", 2);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckInteger(tb, true).IsValid, Is.True); Assert.That(Validator.CheckInteger(tb, true).IsValid, Is.True);
Assert.That(tb.Text, Is.EqualTo("123")); Assert.That(tb.Text, Is.EqualTo("123"));
Assert.That(tb.CaretIndex, Is.EqualTo(1)); Assert.That(tb.CaretIndex, Is.EqualTo(1));
}); }
} }
[Test] [Test]
public void Test_CheckInteger_MaxLen() { public void Test_CheckInteger_MaxLen() {
var tb = TB("1a2b3c4d5e", 4); var tb = TB("1a2b3c4d5e", 4);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckInteger(tb, true, 3).IsValid, Is.True); Assert.That(Validator.CheckInteger(tb, true, 3).IsValid, Is.True);
Assert.That(tb.Text, Is.EqualTo("123")); Assert.That(tb.Text, Is.EqualTo("123"));
Assert.That(tb.CaretIndex, Is.EqualTo(2)); Assert.That(tb.CaretIndex, Is.EqualTo(2));
}); }
} }
[Test] [Test]
public void Test_CheckPhoneNumber_Simple() { public void Test_CheckPhoneNumber_Simple() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckPhoneNumber(TB(""), true).IsValid, Is.False); Assert.That(Validator.CheckPhoneNumber(TB(""), true).IsValid, Is.False);
Assert.That(Validator.CheckPhoneNumber(TB("+43"), false).IsValid, Is.False); Assert.That(Validator.CheckPhoneNumber(TB("+43"), false).IsValid, Is.False);
Assert.That(Validator.CheckPhoneNumber(TB("066412345678"), true).IsValid, Is.True); Assert.That(Validator.CheckPhoneNumber(TB("066412345678"), true).IsValid, Is.True);
Assert.That(Validator.CheckPhoneNumber(TB("0ab66412cd345678"), true).IsValid, Is.True); Assert.That(Validator.CheckPhoneNumber(TB("0ab66412cd345678"), true).IsValid, Is.True);
}); }
} }
[Test] [Test]
public void Test_CheckPhoneNumber_Format_1() { public void Test_CheckPhoneNumber_Format_1() {
var tb = TB("066412345678", 5); var tb = TB("066412345678", 5);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckPhoneNumber(tb, true).IsValid, Is.True); Assert.That(Validator.CheckPhoneNumber(tb, true).IsValid, Is.True);
Assert.That(tb.Text, Is.EqualTo("+43 664 12345678")); Assert.That(tb.Text, Is.EqualTo("+43 664 12345678"));
Assert.That(tb.CaretIndex, Is.EqualTo(9)); Assert.That(tb.CaretIndex, Is.EqualTo(9));
}); }
} }
[Test] [Test]
public void Test_CheckPhoneNumber_Format_2() { public void Test_CheckPhoneNumber_Format_2() {
var tb = TB("0a2574b1c2d34..", 7); var tb = TB("0a2574b1c2d34..", 7);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckPhoneNumber(tb, true).IsValid, Is.True); Assert.That(Validator.CheckPhoneNumber(tb, true).IsValid, Is.True);
Assert.That(tb.Text, Is.EqualTo("+43 2574 1234")); Assert.That(tb.Text, Is.EqualTo("+43 2574 1234"));
Assert.That(tb.CaretIndex, Is.EqualTo(8)); Assert.That(tb.CaretIndex, Is.EqualTo(8));
}); }
} }
[Test] [Test]
public void Test_CheckEmailAddress_Simple() { public void Test_CheckEmailAddress_Simple() {
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckEmailAddress(TB(""), true).IsValid, Is.False); Assert.That(Validator.CheckEmailAddress(TB(""), true).IsValid, Is.False);
Assert.That(Validator.CheckEmailAddress(TB("name"), false).IsValid, Is.False); Assert.That(Validator.CheckEmailAddress(TB("name"), false).IsValid, Is.False);
Assert.That(Validator.CheckEmailAddress(TB("@"), false).IsValid, Is.False); Assert.That(Validator.CheckEmailAddress(TB("@"), false).IsValid, Is.False);
@@ -87,27 +87,27 @@ namespace Tests.UnitTests.HelperTests {
Assert.That(Validator.CheckEmailAddress(TB("name@a.com.a"), true).IsValid, Is.False); Assert.That(Validator.CheckEmailAddress(TB("name@a.com.a"), true).IsValid, Is.False);
Assert.That(Validator.CheckEmailAddress(TB("name@a.com"), true).IsValid, Is.True); Assert.That(Validator.CheckEmailAddress(TB("name@a.com"), true).IsValid, Is.True);
Assert.That(Validator.CheckEmailAddress(TB("my.name@hello#.com"), true).IsValid, Is.True); Assert.That(Validator.CheckEmailAddress(TB("my.name@hello#.com"), true).IsValid, Is.True);
}); }
} }
[Test] [Test]
public void Test_CheckEmailAddress_Format_1() { public void Test_CheckEmailAddress_Format_1() {
var tb = TB("my . name . is @heinz#.com", 17); var tb = TB("my . name . is @heinz#.com", 17);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckEmailAddress(tb, true).IsValid, Is.True); Assert.That(Validator.CheckEmailAddress(tb, true).IsValid, Is.True);
Assert.That(tb.Text, Is.EqualTo("my.name.is@heinz.com")); Assert.That(tb.Text, Is.EqualTo("my.name.is@heinz.com"));
Assert.That(tb.CaretIndex, Is.EqualTo(12)); Assert.That(tb.CaretIndex, Is.EqualTo(12));
}); }
} }
[Test] [Test]
public void Test_CheckEmailAddress_Format_2() { public void Test_CheckEmailAddress_Format_2() {
var tb = TB("sabine.müsterfrau@heinz#.com.b", 30); var tb = TB("sabine.müsterfrau@heinz#.com.b", 30);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(Validator.CheckEmailAddress(tb, true).IsValid, Is.False); Assert.That(Validator.CheckEmailAddress(tb, true).IsValid, Is.False);
Assert.That(tb.Text, Is.EqualTo("sabine.müsterfrau@heinz.com.b")); Assert.That(tb.Text, Is.EqualTo("sabine.müsterfrau@heinz.com.b"));
Assert.That(tb.CaretIndex, Is.EqualTo(29)); Assert.That(tb.CaretIndex, Is.EqualTo(29));
}); }
} }
} }
} }
@@ -67,7 +67,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(d.Parts, Has.Count.EqualTo(1)); Assert.That(d.Parts, Has.Count.EqualTo(1));
var p = d.Parts.First(); var p = d.Parts.First();
Assert.That(p, Is.Not.Null); Assert.That(p, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d.LsNr, Is.EqualTo("20221001X001")); Assert.That(d.LsNr, Is.EqualTo("20221001X001"));
Assert.That(d.Date, Is.EqualTo(new DateOnly(2022, 10, 1))); Assert.That(d.Date, Is.EqualTo(new DateOnly(2022, 10, 1)));
Assert.That(d.ZwstId, Is.EqualTo("X")); Assert.That(d.ZwstId, Is.EqualTo("X"));
@@ -82,7 +82,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(p.IsNetWeight, Is.False); Assert.That(p.IsNetWeight, Is.False);
Assert.That(p.IsManualWeighing, Is.True); Assert.That(p.IsManualWeighing, Is.True);
Assert.That(p.HkId, Is.EqualTo("WLNO")); Assert.That(p.HkId, Is.EqualTo("WLNO"));
}); }
vm = new DeliveryAdminViewModel(); vm = new DeliveryAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
@@ -90,7 +90,7 @@ namespace Tests.UnitTests.ServiceTests {
vm.FillInputs(d); vm.FillInputs(d);
vm.FillInputs(p); vm.FillInputs(p);
}); });
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.LsNr, Is.EqualTo("20221001X001")); Assert.That(vm.LsNr, Is.EqualTo("20221001X001"));
Assert.That(vm.Date, Is.EqualTo("01.10.2022")); Assert.That(vm.Date, Is.EqualTo("01.10.2022"));
Assert.That(vm.Branch?.ZwstId, Is.EqualTo("X")); Assert.That(vm.Branch?.ZwstId, Is.EqualTo("X"));
@@ -104,7 +104,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(vm.IsNetWeight, Is.False); Assert.That(vm.IsNetWeight, Is.False);
Assert.That(vm.IsManualWeighing, Is.True); Assert.That(vm.IsManualWeighing, Is.True);
Assert.That(vm.WineOrigin?.HkId, Is.EqualTo("WLNO")); Assert.That(vm.WineOrigin?.HkId, Is.EqualTo("WLNO"));
}); }
} }
[Test] [Test]
@@ -139,7 +139,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(d.Parts, Has.Count.EqualTo(1)); Assert.That(d.Parts, Has.Count.EqualTo(1));
var p = d.Parts.First(); var p = d.Parts.First();
Assert.That(p, Is.Not.Null); Assert.That(p, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d.LsNr, Is.EqualTo("20221002X001")); Assert.That(d.LsNr, Is.EqualTo("20221002X001"));
Assert.That(d.Date, Is.EqualTo(new DateOnly(2022, 10, 2))); Assert.That(d.Date, Is.EqualTo(new DateOnly(2022, 10, 2)));
Assert.That(d.ZwstId, Is.EqualTo("X")); Assert.That(d.ZwstId, Is.EqualTo("X"));
@@ -156,7 +156,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(p.WeighingData, Is.EqualTo("{}")); Assert.That(p.WeighingData, Is.EqualTo("{}"));
Assert.That(p.HkId, Is.EqualTo("WLNO")); Assert.That(p.HkId, Is.EqualTo("WLNO"));
Assert.That(p.Modifiers.Count(), Is.EqualTo(1)); Assert.That(p.Modifiers.Count(), Is.EqualTo(1));
}); }
vm = new DeliveryAdminViewModel(); vm = new DeliveryAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
@@ -164,7 +164,7 @@ namespace Tests.UnitTests.ServiceTests {
vm.FillInputs(d); vm.FillInputs(d);
vm.FillInputs(p); vm.FillInputs(p);
}); });
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.LsNr, Is.EqualTo("20221002X001")); Assert.That(vm.LsNr, Is.EqualTo("20221002X001"));
Assert.That(vm.Date, Is.EqualTo("02.10.2022")); Assert.That(vm.Date, Is.EqualTo("02.10.2022"));
Assert.That(vm.Branch?.ZwstId, Is.EqualTo("X")); Assert.That(vm.Branch?.ZwstId, Is.EqualTo("X"));
@@ -180,7 +180,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(vm.WeighingData, Is.EqualTo("{}")); Assert.That(vm.WeighingData, Is.EqualTo("{}"));
Assert.That(vm.WineOrigin?.HkId, Is.EqualTo("WLNO")); Assert.That(vm.WineOrigin?.HkId, Is.EqualTo("WLNO"));
Assert.That(vm.Modifiers, Has.Count.EqualTo(1)); Assert.That(vm.Modifiers, Has.Count.EqualTo(1));
}); }
} }
[Test] [Test]
@@ -219,22 +219,22 @@ namespace Tests.UnitTests.ServiceTests {
var d = await GetDelivery("20221003X001"); var d = await GetDelivery("20221003X001");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d.Parts, Has.Count.EqualTo(2)); Assert.That(d.Parts, Has.Count.EqualTo(2));
Assert.That(d.MgNr, Is.EqualTo(101)); Assert.That(d.MgNr, Is.EqualTo(101));
}); }
var p = d.Parts.First(); var p = d.Parts.First();
Assert.That(p, Is.Not.Null); Assert.That(p, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(p.DPNr, Is.EqualTo(1)); Assert.That(p.DPNr, Is.EqualTo(1));
Assert.That(p.SortId, Is.EqualTo("GV")); Assert.That(p.SortId, Is.EqualTo("GV"));
}); }
p = d.Parts.Skip(1).First(); p = d.Parts.Skip(1).First();
Assert.That(p, Is.Not.Null); Assert.That(p, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(p.DPNr, Is.EqualTo(2)); Assert.That(p.DPNr, Is.EqualTo(2));
Assert.That(p.SortId, Is.EqualTo("WR")); Assert.That(p.SortId, Is.EqualTo("WR"));
}); }
} }
[Test] [Test]
@@ -279,10 +279,10 @@ namespace Tests.UnitTests.ServiceTests {
var d = await GetDelivery("20221004X001"); var d = await GetDelivery("20221004X001");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d.Parts, Has.Count.EqualTo(2)); Assert.That(d.Parts, Has.Count.EqualTo(2));
Assert.That(d.MgNr, Is.EqualTo(102)); Assert.That(d.MgNr, Is.EqualTo(102));
}); }
} }
[Test] [Test]
@@ -344,10 +344,10 @@ namespace Tests.UnitTests.ServiceTests {
vm.FillInputs(d); vm.FillInputs(d);
vm.FillInputs(p); vm.FillInputs(p);
}); });
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.SortId, Is.EqualTo("WR")); Assert.That(vm.SortId, Is.EqualTo("WR"));
Assert.That(vm.GradationKmw, Is.EqualTo(15.9)); Assert.That(vm.GradationKmw, Is.EqualTo(15.9));
}); }
} }
[Test] [Test]
@@ -411,45 +411,45 @@ namespace Tests.UnitTests.ServiceTests {
public async Task TestSplit_01_Depreciate_One() { public async Task TestSplit_01_Depreciate_One() {
var d = await GetDelivery("20231001X001"); var d = await GetDelivery("20231001X001");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3)); Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 0, 0])); Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 0, 0]));
d = await GetDelivery("20231001X001"); d = await GetDelivery("20231001X001");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3)); Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.EqualTo("WEI")); Assert.That(ps[0].QualId, Is.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
}); }
} }
[Test] [Test]
public async Task TestSplit_02_Depreciate_Partial() { public async Task TestSplit_02_Depreciate_Partial() {
var d = await GetDelivery("20231001X002"); var d = await GetDelivery("20231001X002");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3)); Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[0].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [600, 0, 0])); Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [600, 0, 0]));
d = await GetDelivery("20231001X002"); d = await GetDelivery("20231001X002");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(4)); Assert.That(ps, Has.Length.EqualTo(4));
Assert.That(ps[0].Weight, Is.EqualTo(400)); Assert.That(ps[0].Weight, Is.EqualTo(400));
@@ -458,14 +458,14 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[3].Weight, Is.EqualTo(600)); Assert.That(ps[3].Weight, Is.EqualTo(600));
Assert.That(ps[3].QualId, Is.EqualTo("WEI")); Assert.That(ps[3].QualId, Is.EqualTo("WEI"));
}); }
} }
[Test] [Test]
public async Task TestSplit_03_Depreciate_Mixed() { public async Task TestSplit_03_Depreciate_Mixed() {
var d = await GetDelivery("20231001X003"); var d = await GetDelivery("20231001X003");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3)); Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
@@ -473,12 +473,12 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps[1].Weight, Is.EqualTo(1000)); Assert.That(ps[1].Weight, Is.EqualTo(1000));
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 700, -5])); Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 700, -5]));
d = await GetDelivery("20231001X003"); d = await GetDelivery("20231001X003");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(4)); Assert.That(ps, Has.Length.EqualTo(4));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
@@ -489,14 +489,14 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[3].Weight, Is.EqualTo(700)); Assert.That(ps[3].Weight, Is.EqualTo(700));
Assert.That(ps[3].QualId, Is.EqualTo("WEI")); Assert.That(ps[3].QualId, Is.EqualTo("WEI"));
}); }
} }
[Test] [Test]
public async Task TestSplit_04_Depreciate_Complete() { public async Task TestSplit_04_Depreciate_Complete() {
var d = await GetDelivery("20231001X004"); var d = await GetDelivery("20231001X004");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3)); Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
@@ -505,12 +505,12 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[1].QualId, Is.Not.EqualTo("WEI"));
Assert.That(ps[2].Weight, Is.EqualTo(1000)); Assert.That(ps[2].Weight, Is.EqualTo(1000));
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 1100, int.MaxValue])); Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 1100, int.MaxValue]));
d = await GetDelivery("20231001X004"); d = await GetDelivery("20231001X004");
Assert.That(d, Is.Not.Null); Assert.That(d, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps = GetParts(d); var ps = GetParts(d);
Assert.That(ps, Has.Length.EqualTo(3)); Assert.That(ps, Has.Length.EqualTo(3));
Assert.That(ps[0].Weight, Is.EqualTo(1000)); Assert.That(ps[0].Weight, Is.EqualTo(1000));
@@ -519,34 +519,34 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps[1].QualId, Is.EqualTo("WEI")); Assert.That(ps[1].QualId, Is.EqualTo("WEI"));
Assert.That(ps[2].Weight, Is.EqualTo(1000)); Assert.That(ps[2].Weight, Is.EqualTo(1000));
Assert.That(ps[2].QualId, Is.EqualTo("WEI")); Assert.That(ps[2].QualId, Is.EqualTo("WEI"));
}); }
} }
[Test] [Test]
public async Task TestSplit_05_OtherMember_One() { public async Task TestSplit_05_OtherMember_One() {
var d1 = await GetDelivery("20231002X001"); var d1 = await GetDelivery("20231002X001");
var d2 = await GetDelivery("20231002X002"); var d2 = await GetDelivery("20231002X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null); Assert.That(d2, Is.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000)); Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000)); Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, 0, 0], 102)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, 0, 0], 102));
d1 = await GetDelivery("20231002X001"); d1 = await GetDelivery("20231002X001");
d2 = await GetDelivery("20231002X002"); d2 = await GetDelivery("20231002X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
@@ -559,34 +559,34 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps2, Has.Length.EqualTo(1)); Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].DPNr, Is.EqualTo(1)); Assert.That(ps2[0].DPNr, Is.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
}); }
} }
[Test] [Test]
public async Task TestSplit_06_OtherMember_Partial() { public async Task TestSplit_06_OtherMember_Partial() {
var d1 = await GetDelivery("20231003X001"); var d1 = await GetDelivery("20231003X001");
var d2 = await GetDelivery("20231003X002"); var d2 = await GetDelivery("20231003X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null); Assert.That(d2, Is.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000)); Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000)); Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [400, -1, -2], 102)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [400, -1, -2], 102));
d1 = await GetDelivery("20231003X001"); d1 = await GetDelivery("20231003X001");
d2 = await GetDelivery("20231003X002"); d2 = await GetDelivery("20231003X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
@@ -597,34 +597,34 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1)); Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(400)); Assert.That(ps2[0].Weight, Is.EqualTo(400));
}); }
} }
[Test] [Test]
public async Task TestSplit_07_OtherMember_Mixed() { public async Task TestSplit_07_OtherMember_Mixed() {
var d1 = await GetDelivery("20231004X001"); var d1 = await GetDelivery("20231004X001");
var d2 = await GetDelivery("20231004X002"); var d2 = await GetDelivery("20231004X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null); Assert.That(d2, Is.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000)); Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000)); Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [200, 1000, int.MinValue], 102)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [200, 1000, int.MinValue], 102));
d1 = await GetDelivery("20231004X001"); d1 = await GetDelivery("20231004X001");
d2 = await GetDelivery("20231004X002"); d2 = await GetDelivery("20231004X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
@@ -639,52 +639,52 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps2[0].Weight, Is.EqualTo(200)); Assert.That(ps2[0].Weight, Is.EqualTo(200));
Assert.That(ps2[1].DPNr, Is.EqualTo(2)); Assert.That(ps2[1].DPNr, Is.EqualTo(2));
Assert.That(ps2[1].Weight, Is.EqualTo(1000)); Assert.That(ps2[1].Weight, Is.EqualTo(1000));
}); }
} }
[Test] [Test]
public async Task TestSplit_08_OtherMember_Complete() { public async Task TestSplit_08_OtherMember_Complete() {
var d1 = await GetDelivery("20231005X001"); var d1 = await GetDelivery("20231005X001");
var d2 = await GetDelivery("20231005X002"); var d2 = await GetDelivery("20231005X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Null); Assert.That(d2, Is.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
Assert.That(d1.MgNr, Is.EqualTo(101)); Assert.That(d1.MgNr, Is.EqualTo(101));
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
Assert.That(ps1[0].Weight, Is.EqualTo(1000)); Assert.That(ps1[0].Weight, Is.EqualTo(1000));
Assert.That(ps1[1].Weight, Is.EqualTo(1000)); Assert.That(ps1[1].Weight, Is.EqualTo(1000));
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, int.MaxValue, 1100], 102)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, int.MaxValue, 1100], 102));
d1 = await GetDelivery("20231005X001"); d1 = await GetDelivery("20231005X001");
d2 = await GetDelivery("20231005X002"); d2 = await GetDelivery("20231005X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Null); Assert.That(d1, Is.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(d2.MgNr, Is.EqualTo(102)); Assert.That(d2.MgNr, Is.EqualTo(102));
Assert.That(ps2, Has.Length.EqualTo(3)); Assert.That(ps2, Has.Length.EqualTo(3));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(1000)); Assert.That(ps2[1].Weight, Is.EqualTo(1000));
Assert.That(ps2[2].Weight, Is.EqualTo(1000)); Assert.That(ps2[2].Weight, Is.EqualTo(1000));
}); }
} }
[Test] [Test]
public async Task TestSplit_09_OtherDelivery_One() { public async Task TestSplit_09_OtherDelivery_One() {
var d1 = await GetDelivery("20231006X001"); var d1 = await GetDelivery("20231006X001");
var d2 = await GetDelivery("20231006X002"); var d2 = await GetDelivery("20231006X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
@@ -693,16 +693,16 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1)); Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 1000, -4], d2.LsNr)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 1000, -4], d2.LsNr));
d1 = await GetDelivery("20231006X001"); d1 = await GetDelivery("20231006X001");
d2 = await GetDelivery("20231006X002"); d2 = await GetDelivery("20231006X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(2)); Assert.That(ps1, Has.Length.EqualTo(2));
@@ -713,18 +713,18 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps2, Has.Length.EqualTo(2)); Assert.That(ps2, Has.Length.EqualTo(2));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(1000)); Assert.That(ps2[1].Weight, Is.EqualTo(1000));
}); }
} }
[Test] [Test]
public async Task TestSplit_10_OtherDelivery_Partial() { public async Task TestSplit_10_OtherDelivery_Partial() {
var d1 = await GetDelivery("20231007X001"); var d1 = await GetDelivery("20231007X001");
var d2 = await GetDelivery("20231007X002"); var d2 = await GetDelivery("20231007X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
@@ -733,16 +733,16 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1)); Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 300, int.MinValue], d2.LsNr)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 300, int.MinValue], d2.LsNr));
d1 = await GetDelivery("20231007X001"); d1 = await GetDelivery("20231007X001");
d2 = await GetDelivery("20231007X002"); d2 = await GetDelivery("20231007X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
@@ -752,18 +752,18 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps2, Has.Length.EqualTo(2)); Assert.That(ps2, Has.Length.EqualTo(2));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(300)); Assert.That(ps2[1].Weight, Is.EqualTo(300));
}); }
} }
[Test] [Test]
public async Task TestSplit_11_OtherDelivery_Mixed() { public async Task TestSplit_11_OtherDelivery_Mixed() {
var d1 = await GetDelivery("20231008X001"); var d1 = await GetDelivery("20231008X001");
var d2 = await GetDelivery("20231008X002"); var d2 = await GetDelivery("20231008X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
@@ -772,16 +772,16 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1)); Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [850, 1000, -4], d2.LsNr)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [850, 1000, -4], d2.LsNr));
d1 = await GetDelivery("20231008X001"); d1 = await GetDelivery("20231008X001");
d2 = await GetDelivery("20231008X002"); d2 = await GetDelivery("20231008X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(2)); Assert.That(ps1, Has.Length.EqualTo(2));
@@ -793,18 +793,18 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(850)); Assert.That(ps2[1].Weight, Is.EqualTo(850));
Assert.That(ps2[2].Weight, Is.EqualTo(1000)); Assert.That(ps2[2].Weight, Is.EqualTo(1000));
}); }
} }
[Test] [Test]
public async Task TestSplit_12_OtherDelivery_Complete() { public async Task TestSplit_12_OtherDelivery_Complete() {
var d1 = await GetDelivery("20231009X001"); var d1 = await GetDelivery("20231009X001");
var d2 = await GetDelivery("20231009X002"); var d2 = await GetDelivery("20231009X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Not.Null); Assert.That(d1, Is.Not.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps1 = GetParts(d1); var ps1 = GetParts(d1);
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps1, Has.Length.EqualTo(3)); Assert.That(ps1, Has.Length.EqualTo(3));
@@ -813,23 +813,23 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(ps1[2].Weight, Is.EqualTo(1000)); Assert.That(ps1[2].Weight, Is.EqualTo(1000));
Assert.That(ps2, Has.Length.EqualTo(1)); Assert.That(ps2, Has.Length.EqualTo(1));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
}); }
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [1200, int.MaxValue, 1000], d2.LsNr)); Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [1200, int.MaxValue, 1000], d2.LsNr));
d1 = await GetDelivery("20231009X001"); d1 = await GetDelivery("20231009X001");
d2 = await GetDelivery("20231009X002"); d2 = await GetDelivery("20231009X002");
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(d1, Is.Null); Assert.That(d1, Is.Null);
Assert.That(d2, Is.Not.Null); Assert.That(d2, Is.Not.Null);
}); }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
var ps2 = GetParts(d2); var ps2 = GetParts(d2);
Assert.That(ps2, Has.Length.EqualTo(4)); Assert.That(ps2, Has.Length.EqualTo(4));
Assert.That(ps2[0].Weight, Is.EqualTo(1000)); Assert.That(ps2[0].Weight, Is.EqualTo(1000));
Assert.That(ps2[1].Weight, Is.EqualTo(1000)); Assert.That(ps2[1].Weight, Is.EqualTo(1000));
Assert.That(ps2[2].Weight, Is.EqualTo(1000)); Assert.That(ps2[2].Weight, Is.EqualTo(1000));
Assert.That(ps2[3].Weight, Is.EqualTo(1000)); Assert.That(ps2[3].Weight, Is.EqualTo(1000));
}); }
} }
[Test] [Test]
@@ -26,46 +26,46 @@ namespace Tests.UnitTests.ServiceTests {
vm.Address = "Neubaugasse 1"; vm.Address = "Neubaugasse 1";
vm.Plz = 2120; vm.Plz = 2120;
vm.Ort = vm.OrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel"); vm.Ort = vm.OrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel");
vm.BusinessShares = 1; vm.BusinessShares1 = 1;
vm.DefaultKg = vm.DefaultKgSource.First(k => k.Name == "Wolkersdorf"); vm.DefaultKg = vm.DefaultKgSource.First(k => k.Name == "Wolkersdorf");
Assert.That(vm.MgNr, Is.EqualTo(205)); Assert.That(vm.MgNr, Is.EqualTo(205));
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
Assert.That(await ctx.FetchMembers(205, includeNotActive: true).SingleOrDefaultAsync(), Is.Null); Assert.That(await ctx.FetchMembers(205).SingleOrDefaultAsync(), Is.Null);
} }
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null)); Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
Member m; Member m;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
m = await ctx.FetchMembers(vm.MgNr, includeNotActive: true, includeContactInfo: true).SingleAsync(); m = await ctx.FetchMembers(vm.MgNr, includeContactInfo: true).SingleAsync();
} }
Assert.That(m, Is.Not.Null); Assert.That(m, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(m.MgNr, Is.EqualTo(205)); Assert.That(m.MgNr, Is.EqualTo(205));
Assert.That(m.Name, Is.EqualTo("Neuling")); Assert.That(m.Name, Is.EqualTo("Neuling"));
Assert.That(m.GivenName, Is.EqualTo("Nadine")); Assert.That(m.GivenName, Is.EqualTo("Nadine"));
Assert.That(m.Address, Is.EqualTo("Neubaugasse 1")); Assert.That(m.Address, Is.EqualTo("Neubaugasse 1"));
Assert.That(m.PostalDest.AtPlz?.Plz, Is.EqualTo(2120)); Assert.That(m.PostalDest.AtPlz?.Plz, Is.EqualTo(2120));
Assert.That(m.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel")); Assert.That(m.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(m.BusinessShares, Is.EqualTo(1)); Assert.That(m.Shares, Is.EqualTo(1));
Assert.That(m.DefaultKg?.Name, Is.EqualTo("Wolkersdorf")); Assert.That(m.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
}); }
vm = new MemberAdminViewModel(); vm = new MemberAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m)); Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.MgNr, Is.EqualTo(205)); Assert.That(vm.MgNr, Is.EqualTo(205));
Assert.That(vm.Name, Is.EqualTo("Neuling")); Assert.That(vm.Name, Is.EqualTo("Neuling"));
Assert.That(vm.GivenName, Is.EqualTo("Nadine")); Assert.That(vm.GivenName, Is.EqualTo("Nadine"));
Assert.That(vm.Address, Is.EqualTo("Neubaugasse 1")); Assert.That(vm.Address, Is.EqualTo("Neubaugasse 1"));
Assert.That(vm.Plz, Is.EqualTo(2120)); Assert.That(vm.Plz, Is.EqualTo(2120));
Assert.That(vm.Ort?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel")); Assert.That(vm.Ort?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(vm.BusinessShares, Is.EqualTo(1)); Assert.That(vm.BusinessShares1, Is.EqualTo(1));
Assert.That(vm.DefaultKg?.Name, Is.EqualTo("Wolkersdorf")); Assert.That(vm.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
}); }
} }
[Test] [Test]
@@ -101,7 +101,7 @@ namespace Tests.UnitTests.ServiceTests {
vm.BillingPlz = 2120; vm.BillingPlz = 2120;
vm.BillingOrt = vm.BillingOrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel"); vm.BillingOrt = vm.BillingOrtSource.First(d => d.Ort.Name == "Wolkersdorf im Weinviertel");
vm.BusinessShares = 10; vm.BusinessShares1 = 10;
vm.AccountingNr = "330999"; vm.AccountingNr = "330999";
vm.DefaultKg = vm.DefaultKgSource.First(k => k.Name == "Wolkersdorf"); vm.DefaultKg = vm.DefaultKgSource.First(k => k.Name == "Wolkersdorf");
vm.Comment = "Ich bin eine Anmerkung"; vm.Comment = "Ich bin eine Anmerkung";
@@ -111,18 +111,18 @@ namespace Tests.UnitTests.ServiceTests {
vm.IsFunktionär = true; vm.IsFunktionär = true;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
Assert.That(await ctx.FetchMembers(999, includeNotActive: true).SingleOrDefaultAsync(), Is.Null); Assert.That(await ctx.FetchMembers(999).SingleOrDefaultAsync(), Is.Null);
} }
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null)); Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
Member m; Member m;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
m = await ctx.FetchMembers(vm.MgNr, includeNotActive: true, includeContactInfo: true).SingleAsync(); m = await ctx.FetchMembers(vm.MgNr, includeContactInfo: true).SingleAsync();
} }
Assert.That(m, Is.Not.Null); Assert.That(m, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(m.MgNr, Is.EqualTo(999)); Assert.That(m.MgNr, Is.EqualTo(999));
Assert.That(m.IsJuridicalPerson, Is.True); Assert.That(m.IsJuridicalPerson, Is.True);
Assert.That(m.Name, Is.EqualTo("Neue GmbH")); Assert.That(m.Name, Is.EqualTo("Neue GmbH"));
@@ -131,15 +131,15 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(m.PostalDest.AtPlz?.Plz, Is.EqualTo(2120)); Assert.That(m.PostalDest.AtPlz?.Plz, Is.EqualTo(2120));
Assert.That(m.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel")); Assert.That(m.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(m.EmailAddresses.Select(a => (a.Nr, a.Address)), Is.EquivalentTo(new (int, string)[] { Assert.That(m.EmailAddresses.Select(a => (a.Nr, a.Address)), Is.EquivalentTo([
(1, "neue.gmbh@mail.com"), (1, "neue.gmbh@mail.com"),
(2, "norbert.neuling@mail.com"), (2, "norbert.neuling@mail.com"),
})); ]));
Assert.That(m.TelephoneNumbers.Select(n => (n.Nr, n.Type, n.Number, n.Comment)), Is.EquivalentTo(new (int, string, string, string?)[] { Assert.That(m.TelephoneNumbers.Select(n => (n.Nr, n.Type, n.Number, n.Comment)), Is.EquivalentTo([
(1, "landline", "+43 2245 9876", "Büro"), (1, "landline", "+43 2245 9876", "Büro"),
(2, "mobile", "+43 664 123456789", "Hr. Neuling"), (2, "mobile", "+43 664 123456789", "Hr. Neuling"),
(3, "fax", "+43 2245 9876-2", null), (3, "fax", "+43 2245 9876-2", null),
})); ]));
Assert.That(m.Iban, Is.EqualTo("AT971234567890123460")); Assert.That(m.Iban, Is.EqualTo("AT971234567890123460"));
Assert.That(m.Bic, Is.EqualTo("RLNWATWWWDF")); Assert.That(m.Bic, Is.EqualTo("RLNWATWWWDF"));
@@ -155,7 +155,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(m.BillingAddress?.PostalDest.AtPlz?.Plz, Is.EqualTo(2120)); Assert.That(m.BillingAddress?.PostalDest.AtPlz?.Plz, Is.EqualTo(2120));
Assert.That(m.BillingAddress?.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel")); Assert.That(m.BillingAddress?.PostalDest.AtPlz?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(m.BusinessShares, Is.EqualTo(10)); Assert.That(m.Shares, Is.EqualTo(10));
Assert.That(m.AccountingNr, Is.EqualTo("330999")); Assert.That(m.AccountingNr, Is.EqualTo("330999"));
Assert.That(m.DefaultKg?.Name, Is.EqualTo("Wolkersdorf")); Assert.That(m.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
Assert.That(m.Comment, Is.EqualTo("Ich bin eine Anmerkung")); Assert.That(m.Comment, Is.EqualTo("Ich bin eine Anmerkung"));
@@ -163,12 +163,12 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(m.ContactViaEmail, Is.True); Assert.That(m.ContactViaEmail, Is.True);
Assert.That(m.IsVollLieferant, Is.True); Assert.That(m.IsVollLieferant, Is.True);
Assert.That(m.IsFunktionär, Is.True); Assert.That(m.IsFunktionär, Is.True);
}); }
vm = new MemberAdminViewModel(); vm = new MemberAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m)); Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.MgNr, Is.EqualTo(999)); Assert.That(vm.MgNr, Is.EqualTo(999));
Assert.That(vm.IsJuridicalPerson, Is.True); Assert.That(vm.IsJuridicalPerson, Is.True);
Assert.That(vm.Name, Is.EqualTo("Neue GmbH")); Assert.That(vm.Name, Is.EqualTo("Neue GmbH"));
@@ -177,11 +177,11 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(vm.Plz, Is.EqualTo(2120)); Assert.That(vm.Plz, Is.EqualTo(2120));
Assert.That(vm.Ort?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel")); Assert.That(vm.Ort?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(vm.EmailAddresses, Is.EquivalentTo(new string?[] { Assert.That(vm.EmailAddresses, Is.EquivalentTo([
"neue.gmbh@mail.com", "neue.gmbh@mail.com",
"norbert.neuling@mail.com", "norbert.neuling@mail.com",
null, null, null, null, null, null, null null, null, null, null, null, null, null
})); ]));
Assert.That(vm.PhoneNrs, Is.EquivalentTo(new MemberAdminViewModel.PhoneNr?[] { Assert.That(vm.PhoneNrs, Is.EquivalentTo(new MemberAdminViewModel.PhoneNr?[] {
new(0, "+43 2245 9876", "Büro"), new(0, "+43 2245 9876", "Büro"),
new(1, "+43 664 123456789", "Hr. Neuling"), new(1, "+43 664 123456789", "Hr. Neuling"),
@@ -202,7 +202,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(vm.BillingPlz, Is.EqualTo(2120)); Assert.That(vm.BillingPlz, Is.EqualTo(2120));
Assert.That(vm.BillingOrt?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel")); Assert.That(vm.BillingOrt?.Ort.Name, Is.EqualTo("Wolkersdorf im Weinviertel"));
Assert.That(vm.BusinessShares, Is.EqualTo(10)); Assert.That(vm.BusinessShares1, Is.EqualTo(10));
Assert.That(vm.AccountingNr, Is.EqualTo("330999")); Assert.That(vm.AccountingNr, Is.EqualTo("330999"));
Assert.That(vm.DefaultKg?.Name, Is.EqualTo("Wolkersdorf")); Assert.That(vm.DefaultKg?.Name, Is.EqualTo("Wolkersdorf"));
Assert.That(vm.Comment, Is.EqualTo("Ich bin eine Anmerkung")); Assert.That(vm.Comment, Is.EqualTo("Ich bin eine Anmerkung"));
@@ -210,7 +210,7 @@ namespace Tests.UnitTests.ServiceTests {
Assert.That(vm.ContactViaEmail, Is.True); Assert.That(vm.ContactViaEmail, Is.True);
Assert.That(vm.IsVollLieferant, Is.True); Assert.That(vm.IsVollLieferant, Is.True);
Assert.That(vm.IsFunktionär, Is.True); Assert.That(vm.IsFunktionär, Is.True);
}); }
} }
[Test] [Test]
@@ -218,7 +218,7 @@ namespace Tests.UnitTests.ServiceTests {
var vm = new MemberAdminViewModel(); var vm = new MemberAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
vm.FillInputs(await ctx.FetchMembers(202, includeNotActive: true, includeContactInfo: true).SingleAsync()); vm.FillInputs(await ctx.FetchMembers(202, includeContactInfo: true).SingleAsync());
} }
Assert.That(vm.IsActive, Is.True); Assert.That(vm.IsActive, Is.True);
@@ -231,22 +231,22 @@ namespace Tests.UnitTests.ServiceTests {
Member m; Member m;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
m = await ctx.FetchMembers(202, includeNotActive: true, includeContactInfo: true).SingleAsync(); m = await ctx.FetchMembers(202, includeContactInfo: true).SingleAsync();
} }
Assert.That(m, Is.Not.Null); Assert.That(m, Is.Not.Null);
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(m.IsActive, Is.False); Assert.That(m.IsActive, Is.False);
Assert.That(m.ExitDateString, Is.EqualTo($"{exitDate:yyyy-MM-dd}")); Assert.That(m.ExitDateString, Is.EqualTo($"{exitDate:yyyy-MM-dd}"));
}); }
vm = new MemberAdminViewModel(); vm = new MemberAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m)); Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.IsActive, Is.False); Assert.That(vm.IsActive, Is.False);
Assert.That(vm.ExitDate, Is.EqualTo($"{exitDate:dd.MM.yyyy}")); Assert.That(vm.ExitDate, Is.EqualTo($"{exitDate:dd.MM.yyyy}"));
}); }
} }
[Test] [Test]
@@ -254,59 +254,59 @@ namespace Tests.UnitTests.ServiceTests {
var vm = new MemberAdminViewModel(); var vm = new MemberAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
vm.FillInputs(await ctx.FetchMembers(203, includeNotActive: true, includeContactInfo: true).SingleAsync()); vm.FillInputs(await ctx.FetchMembers(203, includeContactInfo: true).SingleAsync());
} }
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.MgNr, Is.EqualTo(203)); Assert.That(vm.MgNr, Is.EqualTo(203));
Assert.That(vm.EmailAddresses[0], Is.Not.Null); Assert.That(vm.EmailAddresses[0], Is.Not.Null);
Assert.That(vm.PhoneNrs[0], Is.Not.Null); Assert.That(vm.PhoneNrs[0], Is.Not.Null);
Assert.That(vm.BillingName, Is.Not.Null); Assert.That(vm.BillingName, Is.Not.Null);
}); }
vm.MgNr = 210; vm.MgNr = 210;
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203)); Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
Member m; Member m;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
m = await ctx.FetchMembers(210, includeNotActive: true, includeContactInfo: true).SingleAsync(); m = await ctx.FetchMembers(210, includeContactInfo: true).SingleAsync();
} }
Assert.That(m, Is.Not.Null); Assert.That(m, Is.Not.Null);
vm = new MemberAdminViewModel(); vm = new MemberAdminViewModel();
await InitViewModel(vm); await InitViewModel(vm);
Assert.DoesNotThrow(() => vm.FillInputs(m)); Assert.DoesNotThrow(() => vm.FillInputs(m));
Assert.Multiple(() => { using (Assert.EnterMultipleScope()) {
Assert.That(vm.MgNr, Is.EqualTo(210)); Assert.That(vm.MgNr, Is.EqualTo(210));
Assert.That(vm.EmailAddresses[0], Is.Not.Null); Assert.That(vm.EmailAddresses[0], Is.Not.Null);
Assert.That(vm.PhoneNrs[0], Is.Not.Null); Assert.That(vm.PhoneNrs[0], Is.Not.Null);
Assert.That(vm.BillingName, Is.Not.Null); Assert.That(vm.BillingName, Is.Not.Null);
}); }
} }
[Test] [Test]
public async Task TestDelete_01_NoReferences() { public async Task TestDelete_01_NoReferences() {
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
Assert.That(await ctx.FetchMembers(201, includeNotActive: true).SingleOrDefaultAsync(), Is.Not.Null); Assert.That(await ctx.FetchMembers(201).SingleOrDefaultAsync(), Is.Not.Null);
} }
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false)); Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false));
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
Assert.That(await ctx.FetchMembers(201, includeNotActive: true).SingleOrDefaultAsync(), Is.Null); Assert.That(await ctx.FetchMembers(201).SingleOrDefaultAsync(), Is.Null);
} }
} }
[Test] [Test]
public async Task TestDelete_02_AllReferences() { public async Task TestDelete_02_AllReferences() {
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
Assert.That(await ctx.FetchMembers(204, includeNotActive: true).SingleOrDefaultAsync(), Is.Not.Null); Assert.That(await ctx.FetchMembers(204).SingleOrDefaultAsync(), Is.Not.Null);
} }
for (int i = 0; i < 7; i++) { for (int i = 0; i < 7; i++) {
Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0)); Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0));
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
Assert.That(await ctx.FetchMembers(204, includeNotActive: true).SingleOrDefaultAsync(), Is.Not.Null); Assert.That(await ctx.FetchMembers(204).SingleOrDefaultAsync(), Is.Not.Null);
} }
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true)); Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true));
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
Assert.That(await ctx.FetchMembers(204, includeNotActive: true).SingleOrDefaultAsync(), Is.Null); Assert.That(await ctx.FetchMembers(204).SingleOrDefaultAsync(), Is.Null);
} }
} }
} }
+1 -1
View File
@@ -1 +1 @@
curl --fail -s -L "https://elwig.at/files/create.sql?v=39" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql" curl --fail -s -L "https://elwig.at/files/create.sql?v=40" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"