Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d91e8c7e99 | ||
|
|
09642e643c | ||
|
|
b262e17293 | ||
|
|
4f4d026b7b | ||
|
|
abb9e5a577 | ||
|
|
0e586cc438 | ||
|
|
829ad106cf | ||
|
|
ba7c37fd70 | ||
|
|
66a1185dc3 | ||
|
|
db8afa59b7 | ||
|
|
3d96c31a70 | ||
|
|
a18d687f18 | ||
|
|
5f2788eb9e | ||
|
|
4988081bfd | ||
|
|
03872ca5c2 | ||
|
|
b886abc632 | ||
|
|
cba949d2eb | ||
|
|
c2bc5b221a | ||
|
|
5845693f17 | ||
|
|
aea7c39734 | ||
|
|
c54a998c96 | ||
|
|
5bb84944bc | ||
|
|
34b40535a6 | ||
|
|
3dca099248 | ||
|
|
155a599878 | ||
|
|
fda337c3cb | ||
|
|
d8126e254d | ||
|
|
96441a6701 | ||
|
|
03867bcd74 | ||
|
|
83dfde9203 | ||
|
|
805c5efda8 | ||
|
|
e86edc080a | ||
|
|
0d5d1d4d3d | ||
|
|
ffd3dc9631 | ||
|
|
d592fef352 | ||
|
|
f2b84053e6 | ||
|
|
7fef895491 | ||
|
|
0e9121c462 | ||
|
|
15e191d74e | ||
|
|
abf06c558f | ||
|
|
6436762e8d | ||
|
|
6441fa4f50 | ||
|
|
6bed370eba | ||
|
|
4cc33b56c8 | ||
|
|
f4cc443521 | ||
|
|
8ba051198f | ||
|
|
fea779bd95 | ||
|
|
e66780ccd0 | ||
|
|
cc01f92005 | ||
|
|
0a93167ea7 | ||
|
|
848a6d1ce0 | ||
|
|
f0745eae4e | ||
|
|
8471ac9319 | ||
|
|
7add96dfd5 | ||
|
|
2360402124 | ||
|
|
cadac4302d | ||
|
|
c1690bf104 | ||
|
|
ca5b719630 | ||
|
|
163fe0fac8 | ||
|
|
edf3678154 | ||
|
|
f450dc35b1 | ||
|
|
0c4611024f | ||
|
|
46e596ae23 | ||
|
|
3366cc25eb | ||
|
|
ff71e9fb7f |
+499
-384
File diff suppressed because it is too large
Load Diff
+1
-8
@@ -2,18 +2,11 @@
|
|||||||
x:Class="Elwig.App"
|
x:Class="Elwig.App"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls">
|
||||||
Exit="Application_Exit">
|
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
<ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/>
|
<ctrl:BoolToStringConverter x:Key="BoolToStarConverter" FalseValue="" TrueValue="*"/>
|
||||||
<ctrl:WidthToMarginConverter x:Key="WidthToMarginConverter"/>
|
<ctrl:WidthToMarginConverter x:Key="WidthToMarginConverter"/>
|
||||||
|
|
||||||
<DataTemplate x:Key="PostalDestTemplate">
|
|
||||||
<StackPanel Orientation="Horizontal">
|
|
||||||
<TextBlock Text="{Binding Dest}"/>
|
|
||||||
<TextBlock Text="{Binding Ort.Name, StringFormat='{} ({0})'}"/>
|
|
||||||
</StackPanel>
|
|
||||||
</DataTemplate>
|
|
||||||
<DataTemplate x:Key="KgNrTemplate">
|
<DataTemplate x:Key="KgNrTemplate">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Name}"/>
|
<TextBlock Text="{Binding Name}"/>
|
||||||
|
|||||||
+59
-39
@@ -18,18 +18,18 @@ using System.Reflection;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Elwig {
|
namespace Elwig {
|
||||||
public partial class App : Application {
|
public partial class App : Application {
|
||||||
|
|
||||||
protected static App CurrentApp;
|
public static App CurrentApp;
|
||||||
public static int NumWindows => CurrentApp.Windows.Count;
|
public static int NumWindows => CurrentApp.Windows.Count;
|
||||||
public static bool ForceShutdown { get; private set; } = false;
|
public static bool ForceShutdown { get; set; } = false;
|
||||||
|
|
||||||
private readonly DispatcherTimer _autoUpdateTimer = new() { Interval = TimeSpan.FromHours(1) };
|
private readonly DispatcherTimer _autoUpdateTimer = new() { Interval = TimeSpan.FromHours(1) };
|
||||||
private readonly DispatcherTimer _autoBackupTimer = new() { Interval = TimeSpan.FromHours(1) };
|
private readonly DispatcherTimer _autoBackupTimer = new() { Interval = TimeSpan.FromMinutes(10) };
|
||||||
private DatabaseBackupService? _databaseBackupService;
|
|
||||||
public readonly SerialPortWatcher SerialPortWatcher = new();
|
public readonly SerialPortWatcher SerialPortWatcher = new();
|
||||||
|
|
||||||
public static readonly string DataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Elwig");
|
public static readonly string DataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Elwig");
|
||||||
@@ -76,7 +76,7 @@ namespace Elwig {
|
|||||||
Config = new(Path.GetFullPath(args[1]));
|
Config = new(Path.GetFullPath(args[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
ContextTimer.Tick += (object? sender, EventArgs evt) => {
|
ContextTimer.Tick += (sender, evt) => {
|
||||||
var ch = CurrentLastWrite;
|
var ch = CurrentLastWrite;
|
||||||
if (ch > LastChanged) {
|
if (ch > LastChanged) {
|
||||||
LastChanged = ch;
|
LastChanged = ch;
|
||||||
@@ -94,35 +94,33 @@ namespace Elwig {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
await AppDbUpdater.CheckDb();
|
await AppDbUpdater.CheckDb();
|
||||||
|
} catch (FileNotFoundException exc) {
|
||||||
|
InteractionService.ShowException("Datenbank nicht gefunden", "Die Datenbank konnte nicht gefunden werden", exc);
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
if (Config.UpdateUrl != null && Utils.HasInternetConnectivity()) {
|
if (Config.UpdateUrl != null && Utils.HasInternetConnectivity()) {
|
||||||
await CheckForUpdates();
|
await CheckForUpdates();
|
||||||
}
|
}
|
||||||
InteractionService.ShowException("Fehlerhafte Datenbank", "Fehlerhafte Datenbank", exc);
|
InteractionService.ShowException("Fehlerhafte Datenbank", "Schwerwiegender Fehler in der Datenbank, unbedingt den Programmierern melden!", exc);
|
||||||
Shutdown();
|
if (InteractionService.AskQuestion("Backup wiederherstellen", "Soll die Datenbank aus einem Backup wiederhergestellt werden?\n\nAchtung: Das kann zu Datenverlust führen!", false))
|
||||||
|
await BackupService.RestoreDatabase();
|
||||||
|
ShutdownNow();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.DatabaseBackup) {
|
|
||||||
_databaseBackupService = new DatabaseBackupService(Config.DatabaseFile);
|
|
||||||
await _databaseBackupService.RunIfNeededAsync();
|
|
||||||
_autoBackupTimer.Tick += OnAutoBackupTimer;
|
|
||||||
_autoBackupTimer.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
LastChanged = CurrentLastWrite;
|
LastChanged = CurrentLastWrite;
|
||||||
ContextTimer.Start();
|
ContextTimer.Start();
|
||||||
|
|
||||||
Dictionary<string, (string, string, int?, string?, string?, string?, string?, string?)> branches = [];
|
Dictionary<string, (string, string, int?, string?, string?, string?, string?, string?)> branches = [];
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
branches = ctx.FetchBranches()
|
branches = await ctx.FetchBranches()
|
||||||
.ToDictionaryAsync(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr))
|
.ToDictionaryAsync(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr));
|
||||||
.GetAwaiter().GetResult();
|
|
||||||
try {
|
try {
|
||||||
Client = new(ctx);
|
Client = new(ctx);
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
InteractionService.ShowException("Fehler", "Fehler beim Laden der Mandantendaten", exc);
|
InteractionService.ShowException("Fehler", "Fehler beim Laden der Mandantendaten, unbedingt den Programmierern melden!", exc);
|
||||||
Shutdown();
|
if (InteractionService.AskQuestion("Backup wiederherstellen", "Soll die Datenbank aus einem Backup wiederhergestellt werden?\n\nAchtung: Das kann zu Datenverlust führen!", false))
|
||||||
|
await BackupService.RestoreDatabase();
|
||||||
|
ShutdownNow();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BranchNum = branches.Count;
|
BranchNum = branches.Count;
|
||||||
@@ -133,9 +131,23 @@ namespace Elwig {
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.RunBackground("PDF Initialization", () => Pdf.Init());
|
Utils.RunBackground("PDF Initialization", async () => Pdf.Init());
|
||||||
Utils.RunBackground("JSON Schema Initialization", BillingData.Init);
|
Utils.RunBackground("JSON Schema Initialization", BillingData.Init);
|
||||||
|
|
||||||
|
if (Config.BackupAuto && !Config.Debug) {
|
||||||
|
Utils.RunBackground("Automatisches Backup", async () => {
|
||||||
|
Directory.CreateDirectory(Config.BackupPath);
|
||||||
|
await Task.Delay(500);
|
||||||
|
await BackupService.TryDatabaseBackup();
|
||||||
|
});
|
||||||
|
_autoBackupTimer.Tick += new EventHandler((sender, evt) => {
|
||||||
|
Utils.RunBackground("Automatisches Backup", async () => {
|
||||||
|
await BackupService.TryDatabaseBackup();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
_autoBackupTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
if (Config.UpdateAuto && Config.UpdateUrl != null) {
|
if (Config.UpdateAuto && Config.UpdateUrl != null) {
|
||||||
if (Utils.HasInternetConnectivity()) {
|
if (Utils.HasInternetConnectivity()) {
|
||||||
Utils.RunBackground("Auto Updater", async () => {
|
Utils.RunBackground("Auto Updater", async () => {
|
||||||
@@ -155,7 +167,7 @@ namespace Elwig {
|
|||||||
foreach (var s in Config.Scales) {
|
foreach (var s in Config.Scales) {
|
||||||
try {
|
try {
|
||||||
var scale = Scale.FromConfig(s);
|
var scale = Scale.FromConfig(s);
|
||||||
if (scale is ICommandScale cmd) {
|
if (s.SyncTime && scale is ICommandScale cmd) {
|
||||||
try {
|
try {
|
||||||
await cmd.SetDateAndTime(DateTime.Now);
|
await cmd.SetDateAndTime(DateTime.Now);
|
||||||
} catch { }
|
} catch { }
|
||||||
@@ -172,7 +184,7 @@ namespace Elwig {
|
|||||||
if (Config.Branch != null) {
|
if (Config.Branch != null) {
|
||||||
if (!branches.ContainsKey(Config.Branch.ToLower())) {
|
if (!branches.ContainsKey(Config.Branch.ToLower())) {
|
||||||
InteractionService.ShowError("Ungültige Zweigstelle", "Ungültige Zweigstelle in Konfigurationsdatei!");
|
InteractionService.ShowError("Ungültige Zweigstelle", "Ungültige Zweigstelle in Konfigurationsdatei!");
|
||||||
Shutdown();
|
ShutdownNow();
|
||||||
} else {
|
} else {
|
||||||
SetBranch(branches[Config.Branch.ToLower()]);
|
SetBranch(branches[Config.Branch.ToLower()]);
|
||||||
}
|
}
|
||||||
@@ -180,7 +192,7 @@ namespace Elwig {
|
|||||||
SetBranch(branches.First().Value);
|
SetBranch(branches.First().Value);
|
||||||
} else {
|
} else {
|
||||||
InteractionService.ShowError("Ungültige Zweigstelle", "Erkennen der lokalen Zweigstelle nicht möglich!");
|
InteractionService.ShowError("Ungültige Zweigstelle", "Erkennen der lokalen Zweigstelle nicht möglich!");
|
||||||
Shutdown();
|
ShutdownNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.WeighingMode == null) {
|
if (Config.WeighingMode == null) {
|
||||||
@@ -188,7 +200,7 @@ namespace Elwig {
|
|||||||
Config.WeighingMode = WeighingMode.Net;
|
Config.WeighingMode = WeighingMode.Net;
|
||||||
} else if (Client.IsHaugsdorf || Client.IsSitzendorf) {
|
} else if (Client.IsHaugsdorf || Client.IsSitzendorf) {
|
||||||
Config.WeighingMode = WeighingMode.Box;
|
Config.WeighingMode = WeighingMode.Box;
|
||||||
} else if (Client.IsBaden || Client.IsGrInzersdorf) {
|
} else if (Client.IsBaden || Client.IsGrInzersdorf || Client.IsPamhagen) {
|
||||||
Config.WeighingMode = WeighingMode.Gross;
|
Config.WeighingMode = WeighingMode.Gross;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -199,19 +211,29 @@ namespace Elwig {
|
|||||||
window.Show();
|
window.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void Application_Exit(object sender, ExitEventArgs evt) {
|
public static void ShutdownNow() {
|
||||||
_autoBackupTimer.Stop();
|
ForceShutdown = true;
|
||||||
|
Current.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async void ShutdownGracefully() {
|
||||||
|
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||||
|
|
||||||
|
if (Config.BackupAuto && !Config.Debug) {
|
||||||
|
try {
|
||||||
|
await BackupService.TryDatabaseBackup();
|
||||||
|
} catch (Exception exc) {
|
||||||
|
InteractionService.ShowException("Automatisches Backup", exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SerialPortWatcher.Dispose();
|
SerialPortWatcher.Dispose();
|
||||||
foreach (var s in EventScales) {
|
foreach (var s in EventScales) {
|
||||||
s.Dispose();
|
s.Dispose();
|
||||||
}
|
}
|
||||||
await Pdf.Cleanup();
|
Pdf.Cleanup();
|
||||||
}
|
|
||||||
|
|
||||||
private async void OnAutoBackupTimer(object? sender, EventArgs evt) {
|
Shutdown();
|
||||||
if (_databaseBackupService != null) {
|
|
||||||
await _databaseBackupService.RunIfNeededAsync();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SetBranch(Branch b) {
|
public static void SetBranch(Branch b) {
|
||||||
@@ -322,8 +344,7 @@ namespace Elwig {
|
|||||||
await MainDispatcher.BeginInvoke(() => {
|
await MainDispatcher.BeginInvoke(() => {
|
||||||
var d = new UpdateDialog(latest.Value.Version, latest.Value.Url, latest.Value.Size);
|
var d = new UpdateDialog(latest.Value.Version, latest.Value.Url, latest.Value.Size);
|
||||||
if (d.ShowDialog() == true) {
|
if (d.ShowDialog() == true) {
|
||||||
ForceShutdown = true;
|
ShutdownNow();
|
||||||
Current.Shutdown();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (showAlert) {
|
} else if (showAlert) {
|
||||||
@@ -341,8 +362,7 @@ namespace Elwig {
|
|||||||
await Database.Import(filename);
|
await Database.Import(filename);
|
||||||
});
|
});
|
||||||
InteractionService.ShowInformation("Datenbank ersetzen", "Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!");
|
InteractionService.ShowInformation("Datenbank ersetzen", "Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!");
|
||||||
ForceShutdown = true;
|
ShutdownNow();
|
||||||
Current.Shutdown();
|
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
InteractionService.ShowException("Datenbank ersetzen", "Fehler beim Ersetzen", exc);
|
InteractionService.ShowException("Datenbank ersetzen", "Fehler beim Ersetzen", exc);
|
||||||
}
|
}
|
||||||
@@ -374,15 +394,15 @@ namespace Elwig {
|
|||||||
return FocusWindow<DeliveryAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember?.MgNr == mgnr);
|
return FocusWindow<DeliveryAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember?.MgNr == mgnr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AreaComAdminWindow FocusMemberAreaComs(int mgnr) {
|
public static AreaCmtAdminWindow FocusMemberAreaCmts(int mgnr) {
|
||||||
return FocusWindow<AreaComAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember.MgNr == mgnr);
|
return FocusWindow<AreaCmtAdminWindow>(() => new(mgnr), w => w.ViewModel.FilterMember.MgNr == mgnr);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseDataWindow FocusBaseData() {
|
public static BaseDataWindow FocusBaseData() {
|
||||||
return FocusWindow<BaseDataWindow>(() => new());
|
return FocusWindow<BaseDataWindow>(() => new());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BaseDataWindow FocusBaseDataAreaComType() {
|
public static BaseDataWindow FocusBaseDataAreaCmtType() {
|
||||||
var w = FocusBaseData();
|
var w = FocusBaseData();
|
||||||
w.AreaCommitmentTypes.Focus();
|
w.AreaCommitmentTypes.Focus();
|
||||||
return w;
|
return w;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Window x:Class="Elwig.Dialogs.AreaComModifyDialog"
|
<Window x:Class="Elwig.Dialogs.AreaCmtModifyDialog"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
+2
-2
@@ -4,7 +4,7 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace Elwig.Dialogs {
|
namespace Elwig.Dialogs {
|
||||||
public partial class AreaComModifyDialog : Window {
|
public partial class AreaCmtModifyDialog : Window {
|
||||||
|
|
||||||
public int? YearTo { get; set; }
|
public int? YearTo { get; set; }
|
||||||
public bool ModifyRetroactively { get; set; }
|
public bool ModifyRetroactively { get; set; }
|
||||||
@@ -13,7 +13,7 @@ namespace Elwig.Dialogs {
|
|||||||
public string OrigYearTo { get; set; }
|
public string OrigYearTo { get; set; }
|
||||||
public string Area { get; set; }
|
public string Area { get; set; }
|
||||||
|
|
||||||
public AreaComModifyDialog(int? yearFrom, int? yearTo, int area, bool delete, bool forceRetroactive = false) {
|
public AreaCmtModifyDialog(int? yearFrom, int? yearTo, int area, bool delete, bool forceRetroactive = false) {
|
||||||
Area = $"{area:N0}";
|
Area = $"{area:N0}";
|
||||||
OrigYearFrom = $"{yearFrom}";
|
OrigYearFrom = $"{yearFrom}";
|
||||||
OrigYearTo = $"{yearTo}";
|
OrigYearTo = $"{yearTo}";
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<Window x:Class="Elwig.Dialogs.AreaComTransferDialog"
|
<Window x:Class="Elwig.Dialogs.AreaCmtTransferDialog"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
@@ -35,11 +35,11 @@
|
|||||||
<TextBlock x:Name="QuestionBlock1" TextAlignment="Center" Margin="0,10,0,0"
|
<TextBlock x:Name="QuestionBlock1" TextAlignment="Center" Margin="0,10,0,0"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||||
Sollen die aktiven Flächenbindungen des angegebenen Vorgängers<LineBreak/>
|
Sollen die aktiven Flächenbindungen des angegebenen Vorgängers<LineBreak/>
|
||||||
übernommen werden? (<Run Text="{Binding AreaComNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
übernommen werden? (<Run Text="{Binding AreaCmtNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
<TextBlock x:Name="QuestionBlock2" TextAlignment="Center" Margin="0,10,0,0" Visibility="Hidden"
|
<TextBlock x:Name="QuestionBlock2" TextAlignment="Center" Margin="0,10,0,0" Visibility="Hidden"
|
||||||
HorizontalAlignment="Center" VerticalAlignment="Top">
|
HorizontalAlignment="Center" VerticalAlignment="Top">
|
||||||
Sollen die aktiven Flächenbindungen gekündigt werden? (<Run Text="{Binding AreaComNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
Sollen die aktiven Flächenbindungen gekündigt werden? (<Run Text="{Binding AreaCmtNum}"/> FB, <Run Text="{Binding Area}"/> m²)
|
||||||
</TextBlock>
|
</TextBlock>
|
||||||
|
|
||||||
<Label x:Name="SeasonLabel" Content="Saison:" Margin="0,50,100,0"
|
<Label x:Name="SeasonLabel" Content="Saison:" Margin="0,50,100,0"
|
||||||
+6
-6
@@ -3,17 +3,17 @@ using System.Windows;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace Elwig.Dialogs {
|
namespace Elwig.Dialogs {
|
||||||
public partial class AreaComTransferDialog : Window {
|
public partial class AreaCmtTransferDialog : Window {
|
||||||
|
|
||||||
public int CancelSeason => SuccessorSeason - 1;
|
public int CancelSeason => SuccessorSeason - 1;
|
||||||
public int SuccessorSeason { get; set; }
|
public int SuccessorSeason { get; set; }
|
||||||
|
|
||||||
public string AreaComNum { get; set; }
|
public string AreaCmtNum { get; set; }
|
||||||
public string Area { get; set; }
|
public string Area { get; set; }
|
||||||
|
|
||||||
public AreaComTransferDialog(string name, int areaComNum, int area) {
|
public AreaCmtTransferDialog(string name, int areaCmtNum, int area) {
|
||||||
SuccessorSeason = Utils.FollowingSeason;
|
SuccessorSeason = Utils.FollowingSeason;
|
||||||
AreaComNum = $"{areaComNum:N0}";
|
AreaCmtNum = $"{areaCmtNum:N0}";
|
||||||
Area = $"{area:N0}";
|
Area = $"{area:N0}";
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SeasonInput.Text = $"{SuccessorSeason}";
|
SeasonInput.Text = $"{SuccessorSeason}";
|
||||||
@@ -28,9 +28,9 @@ namespace Elwig.Dialogs {
|
|||||||
SeasonLabel.Margin = new(0, 40, 100, 0);
|
SeasonLabel.Margin = new(0, 40, 100, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AreaComTransferDialog(string name, string successorName, int areaComNum, int area) {
|
public AreaCmtTransferDialog(string name, string successorName, int areaCmtNum, int area) {
|
||||||
SuccessorSeason = Utils.FollowingSeason;
|
SuccessorSeason = Utils.FollowingSeason;
|
||||||
AreaComNum = $"{areaComNum:N0}";
|
AreaCmtNum = $"{areaCmtNum:N0}";
|
||||||
Area = $"{area:N0}";
|
Area = $"{area:N0}";
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
SeasonInput.Text = $"{SuccessorSeason}";
|
SeasonInput.Text = $"{SuccessorSeason}";
|
||||||
@@ -47,9 +47,9 @@
|
|||||||
TextChanged="NameInput_TextChanged"/>
|
TextChanged="NameInput_TextChanged"/>
|
||||||
|
|
||||||
<Label Content="Beim Löschen müssen folgende Daten auch gelöscht werden:" Margin="10,120,10,10"/>
|
<Label Content="Beim Löschen müssen folgende Daten auch gelöscht werden:" Margin="10,120,10,10"/>
|
||||||
<CheckBox x:Name="AreaComInput" Content="Flächenbindungen" Margin="40,145,0,0"
|
<CheckBox x:Name="AreaCmtInput" Content="Flächenbindungen" Margin="40,145,0,0"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||||
IsChecked="{Binding DeleteAreaComs}"/>
|
IsChecked="{Binding DeleteAreaCmts}"/>
|
||||||
<CheckBox x:Name="DeliveryInput" Content="Lieferungen" Margin="40,165,0,0"
|
<CheckBox x:Name="DeliveryInput" Content="Lieferungen" Margin="40,165,0,0"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||||
IsChecked="{Binding DeleteDeliveries}"/>
|
IsChecked="{Binding DeleteDeliveries}"/>
|
||||||
|
|||||||
@@ -8,16 +8,16 @@ namespace Elwig.Dialogs {
|
|||||||
|
|
||||||
protected string[] NameParts;
|
protected string[] NameParts;
|
||||||
|
|
||||||
public bool DeleteAreaComs { get; set; }
|
public bool DeleteAreaCmts { get; set; }
|
||||||
public bool DeleteDeliveries { get; set; }
|
public bool DeleteDeliveries { get; set; }
|
||||||
public bool DeletePaymentData { get; set; }
|
public bool DeletePaymentData { get; set; }
|
||||||
|
|
||||||
public DeleteMemberDialog(int mgnr, string name, int numAreaComs, int numDeliveries, int numCredits) {
|
public DeleteMemberDialog(int mgnr, string name, int numAreaCmts, int numDeliveries, int numCredits) {
|
||||||
NameParts = name.ToLower().Split(' ').Where(p => p.Length > 0).Append($"{mgnr}").ToArray();
|
NameParts = name.ToLower().Split(' ').Where(p => p.Length > 0).Append($"{mgnr}").ToArray();
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Title += " - " + name;
|
Title += " - " + name;
|
||||||
AreaComInput.IsEnabled = numAreaComs != 0;
|
AreaCmtInput.IsEnabled = numAreaCmts != 0;
|
||||||
AreaComInput.Content += $" ({numAreaComs:N0})";
|
AreaCmtInput.Content += $" ({numAreaCmts:N0})";
|
||||||
DeliveryInput.IsEnabled = numDeliveries != 0;
|
DeliveryInput.IsEnabled = numDeliveries != 0;
|
||||||
DeliveryInput.Content += $" ({numDeliveries:N0})";
|
DeliveryInput.Content += $" ({numDeliveries:N0})";
|
||||||
PaymentInput.IsEnabled = numCredits != 0;
|
PaymentInput.IsEnabled = numCredits != 0;
|
||||||
@@ -43,7 +43,7 @@ namespace Elwig.Dialogs {
|
|||||||
private void Update() {
|
private void Update() {
|
||||||
var t = NameInput.Text.ToLower().Split(' ');
|
var t = NameInput.Text.ToLower().Split(' ');
|
||||||
var nameValid = NameParts.All(t.Contains);
|
var nameValid = NameParts.All(t.Contains);
|
||||||
UpdateCheckBox(AreaComInput);
|
UpdateCheckBox(AreaCmtInput);
|
||||||
UpdateCheckBox(DeliveryInput);
|
UpdateCheckBox(DeliveryInput);
|
||||||
UpdateCheckBox(PaymentInput);
|
UpdateCheckBox(PaymentInput);
|
||||||
if (!nameValid) {
|
if (!nameValid) {
|
||||||
@@ -52,7 +52,7 @@ namespace Elwig.Dialogs {
|
|||||||
ControlUtils.ClearInputState(NameInput);
|
ControlUtils.ClearInputState(NameInput);
|
||||||
}
|
}
|
||||||
ConfirmButton.IsEnabled =
|
ConfirmButton.IsEnabled =
|
||||||
(!AreaComInput.IsEnabled || DeleteAreaComs) &&
|
(!AreaCmtInput.IsEnabled || DeleteAreaCmts) &&
|
||||||
(!DeliveryInput.IsEnabled || DeleteDeliveries) &&
|
(!DeliveryInput.IsEnabled || DeleteDeliveries) &&
|
||||||
(!PaymentInput.IsEnabled || DeletePaymentData) &&
|
(!PaymentInput.IsEnabled || DeletePaymentData) &&
|
||||||
nameValid;
|
nameValid;
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
<TextBlock Text="{Binding Part.DPNr}" Width="20" TextAlignment="Right"
|
<TextBlock Text="{Binding Part.DPNr}" Width="20" TextAlignment="Right"
|
||||||
VerticalAlignment="Center" Margin="0,0,5,0" FontSize="14"/>
|
VerticalAlignment="Center" Margin="0,0,5,0" FontSize="14"/>
|
||||||
<TextBlock Text="{Binding Part.SortId}" Width="40" TextAlignment="Center"
|
<TextBlock Text="{Binding Part.SortId}" Foreground="{Binding Part.Variety.Color}" Width="40" TextAlignment="Center"
|
||||||
VerticalAlignment="Center" Margin="0,0,0,0" FontSize="14"/>
|
VerticalAlignment="Center" Margin="0,0,0,0" FontSize="14"/>
|
||||||
<TextBlock Text="{Binding Part.Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"
|
<TextBlock Text="{Binding Part.Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"
|
||||||
VerticalAlignment="Center"/>
|
VerticalAlignment="Center"/>
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ using Elwig.Helpers;
|
|||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Windows;
|
using Elwig.Windows;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using System;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
<Window x:Class="Elwig.Dialogs.ManualWeighingDialog"
|
<Window x:Class="Elwig.Dialogs.ManualWeighingDialog"
|
||||||
|
AutomationProperties.AutomationId="ManualWeighingDialog"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:Elwig.Dialogs"
|
xmlns:local="clr-namespace:Elwig.Dialogs"
|
||||||
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
||||||
WindowStartupLocation="CenterOwner"
|
WindowStartupLocation="CenterOwner"
|
||||||
FocusManager.FocusedElement="{Binding ElementName=WeightInput}"
|
FocusManager.FocusedElement="{Binding ElementName=WeightInput}"
|
||||||
@@ -37,11 +39,9 @@
|
|||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
<Label Content="Gewicht:" Margin="10,20,10,10"/>
|
<Label Content="Gewicht:" Margin="10,20,10,10"/>
|
||||||
<Grid Grid.Column="1" Width="70" Height="25" Margin="0,20,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
|
<ctrl:UnitTextBox x:Name="WeightInput" Grid.Column="1" Width="62" Height="25" Unit="kg"
|
||||||
<TextBox x:Name="WeightInput" TextAlignment="Right" Padding="2,2,17,2"
|
Margin="0,20,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" Padding="2"
|
||||||
TextChanged="WeightInput_TextChanged"/>
|
TextChanged="WeightInput_TextChanged"/>
|
||||||
<Label Content="kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10" Padding="2,4,2,4"/>
|
|
||||||
</Grid>
|
|
||||||
|
|
||||||
<Label Content="Grund:" Margin="10,50,10,10"/>
|
<Label Content="Grund:" Margin="10,50,10,10"/>
|
||||||
<TextBox x:Name="ReasonInput" Grid.Column="1" Margin="0,50,10,10"
|
<TextBox x:Name="ReasonInput" Grid.Column="1" Margin="0,50,10,10"
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ using System.Windows.Controls;
|
|||||||
namespace Elwig.Dialogs {
|
namespace Elwig.Dialogs {
|
||||||
public partial class ManualWeighingDialog : Window {
|
public partial class ManualWeighingDialog : Window {
|
||||||
|
|
||||||
public int Weight = 0;
|
public int Weight { get; private set; }
|
||||||
public string? Reason = null;
|
public string? Reason { get; private set; }
|
||||||
|
|
||||||
public ManualWeighingDialog(string? reason = null) {
|
public ManualWeighingDialog(string? reason = null) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<Window x:Class="Elwig.Dialogs.TareCorrectionDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:local="clr-namespace:Elwig.Dialogs"
|
||||||
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
|
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
FocusManager.FocusedElement="{Binding ElementName=TargetTareInput}"
|
||||||
|
Title="Tara korrigieren" Height="170" Width="300">
|
||||||
|
<Window.Resources>
|
||||||
|
<Style TargetType="Label">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||||
|
<Setter Property="Padding" Value="2,4,2,4"/>
|
||||||
|
<Setter Property="Height" Value="25"/>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="TextBox">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||||
|
<Setter Property="FontSize" Value="14"/>
|
||||||
|
<Setter Property="Padding" Value="2"/>
|
||||||
|
<Setter Property="Height" Value="25"/>
|
||||||
|
<Setter Property="TextWrapping" Value="NoWrap"/>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="Button">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||||
|
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||||
|
<Setter Property="Width" Value="100"/>
|
||||||
|
<Setter Property="Height" Value="25"/>
|
||||||
|
</Style>
|
||||||
|
</Window.Resources>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*"/>
|
||||||
|
<ColumnDefinition Width="70"/>
|
||||||
|
<ColumnDefinition Width="3*"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Label Content="Ist-Tara:" Margin="10,20,0,10" Grid.Column="1"/>
|
||||||
|
<ctrl:UnitTextBox x:Name="ActualTareInput" Grid.Column="2" Width="56" Height="25" Unit="kg" IsReadOnly="True"
|
||||||
|
Margin="0,20,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" Padding="2"
|
||||||
|
TextChanged="TareInput_TextChanged"/>
|
||||||
|
|
||||||
|
<Label Content="Soll-Tara:" Margin="10,50,0,10" Grid.Column="1"/>
|
||||||
|
<ctrl:UnitTextBox x:Name="TargetTareInput" Grid.Column="2" Width="56" Height="25" Unit="kg"
|
||||||
|
Margin="0,50,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" Padding="2"
|
||||||
|
TextChanged="TareInput_TextChanged"/>
|
||||||
|
|
||||||
|
<Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" Grid.ColumnSpan="3" IsEnabled="False" IsDefault="True"
|
||||||
|
Click="ConfirmButton_Click"/>
|
||||||
|
<Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" Grid.ColumnSpan="3" IsCancel="True"/>
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace Elwig.Dialogs {
|
||||||
|
public partial class TareCorrectionDialog : Window {
|
||||||
|
|
||||||
|
public int ActualTare { get; private set; }
|
||||||
|
public int TargetTare { get; private set; }
|
||||||
|
|
||||||
|
public TareCorrectionDialog(int? actualTare, int? targetTare = null) {
|
||||||
|
InitializeComponent();
|
||||||
|
ActualTare = actualTare ?? 0;
|
||||||
|
TargetTare = targetTare ?? actualTare ?? 0;
|
||||||
|
ActualTareInput.IsReadOnly = actualTare != null;
|
||||||
|
ActualTareInput.Text = ActualTare.ToString();
|
||||||
|
TargetTareInput.Text = TargetTare.ToString();
|
||||||
|
TargetTareInput.SelectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
DialogResult = true;
|
||||||
|
ActualTare = int.Parse(ActualTareInput.Text);
|
||||||
|
TargetTare = int.Parse(TargetTareInput.Text);
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateButtons() {
|
||||||
|
ConfirmButton.IsEnabled = ActualTareInput.Text.Length > 0 && TargetTareInput.Text.Length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TareInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
|
if (sender is not TextBox b) return;
|
||||||
|
Validator.CheckInteger(b, true, 4);
|
||||||
|
UpdateButtons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,23 +30,27 @@ namespace Elwig.Documents {
|
|||||||
get {
|
get {
|
||||||
IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member;
|
IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member;
|
||||||
var plz = addr.PostalDest.AtPlz;
|
var plz = addr.PostalDest.AtPlz;
|
||||||
return string.Join("\n", ((string?[])[Member.BillingAddress?.FullName, Member.AdministrativeName, Member.ForTheAttentionOf, addr.Address, $"{plz?.Plz} {plz?.Ort.Name.Split(",")[0]}", addr.PostalDest.Country.Name]).Where(s => !string.IsNullOrWhiteSpace(s)));
|
return string.Join("\n", ((string?[])[addr is BillingAddr ? addr.FullName : null, Member.AdministrativeName, Member.ForTheAttentionOf, addr.Address, $"{plz?.Plz} {plz?.Ort.Name.Split(",")[0]}", addr.PostalDest.Country.Name]).Where(s => !string.IsNullOrWhiteSpace(s)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Cell NewAsideCell(Paragraph text, int colspan = 1, bool isName = false) {
|
protected Cell NewAsideCell(Paragraph text, int colspan = 1, bool isName = false, bool right = false, bool center = false) {
|
||||||
var cell = NewCell(text, colspan: colspan).SetPaddingsMM(0.25f, 0.5f, 0.25f, isName ? 1 : 0);
|
var cell = NewCell(text, colspan: colspan).SetPaddingsMM(0.25f, center ? 0 : right ? 1 : 0.5f, 0.25f, isName ? 1 : 0);
|
||||||
if (colspan > 1) {
|
if (colspan == 26) {
|
||||||
cell.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
cell.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
||||||
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0))
|
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0))
|
||||||
.SetBorderTop(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
.SetBorderTop(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
||||||
.SetPaddingsMM(0.5f, 1, 0.5f, 1);
|
.SetPaddingsMM(0.5f, 1, 0.5f, 1);
|
||||||
|
} else if (isName) {
|
||||||
|
cell.SetBorderLeft(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness));
|
||||||
}
|
}
|
||||||
|
if (right) cell.SetTextAlignment(TextAlignment.RIGHT);
|
||||||
|
if (center) cell.SetTextAlignment(TextAlignment.CENTER);
|
||||||
return cell;
|
return cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Cell NewAsideCell(string text, int colspan = 1, bool isName = false) {
|
protected Cell NewAsideCell(string text, int colspan = 1, bool isName = false, bool right = false, bool center = false) {
|
||||||
return NewAsideCell(new KernedParagraph(text, 10), colspan, isName);
|
return NewAsideCell(new KernedParagraph(text, 10), colspan, isName, right, center);
|
||||||
}
|
}
|
||||||
|
|
||||||
public BusinessDocument(string title, Member m, DateOnly? dateFrom, bool includeSender = false) :
|
public BusinessDocument(string title, Member m, DateOnly? dateFrom, bool includeSender = false) :
|
||||||
@@ -60,16 +64,27 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.BeforeRenderBody(doc, pdf);
|
||||||
var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10);
|
Aside = new Table(ColsMM(2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5))
|
||||||
if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)"));
|
.SetWidth(UnitValue.CreatePointValue(65 * PtInMM)).SetFixedLayout()
|
||||||
Aside = new Table(ColsMM(22.5, 42.5))
|
|
||||||
.SetFont(NF).SetFontSize(10)
|
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
|
.SetFont(NF).SetFontSize(10)
|
||||||
.SetBorder(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
.SetBorder(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
||||||
.AddCell(NewAsideCell("Mitglied", 2))
|
.AddCell(NewAsideCell("Mitglied", 26));
|
||||||
.AddCell(NewAsideCell("Mitglieds-Nr.:", isName: true)).AddCell(NewAsideCell($"{Member.MgNr}"))
|
if (Member.IsOrganic) {
|
||||||
.AddCell(NewAsideCell("Betriebs-Nr.:", isName: true)).AddCell(NewAsideCell(Member.LfbisNr ?? ""))
|
Aside
|
||||||
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
.AddCell(NewAsideCell("Mitgl.-Nr.:", 8, isName: true)).AddCell(NewAsideCell($"{Member.MgNr}", 4, right: true))
|
||||||
|
.AddCell(NewAsideCell("Bio-KSt.:", 6, isName: true)).AddCell(NewAsideCell(Member.OrganicAuthorityCode ?? "-", 8, right: true, center: Member.OrganicAuthorityCode == null))
|
||||||
|
.AddCell(NewAsideCell("Betr.-Nr.:", 6, isName: true)).AddCell(NewAsideCell(Member.LfbisNr ?? "-", 6, right: true, center: Member.LfbisNr == null))
|
||||||
|
.AddCell(NewAsideCell("OOC-ID:", 6, isName: true)).AddCell(NewAsideCell(Member.OrganicOperatorId ?? "-", 8, right: true, center: Member.OrganicOperatorId == null))
|
||||||
|
.AddCell(NewAsideCell("UID:", 6, isName: true)).AddCell(NewAsideCell(Member.UstIdNr ?? "-", 10, right: true, center: Member.UstIdNr == null))
|
||||||
|
.AddCell(NewAsideCell(new KernedParagraph("", 10).Add(Italic(Member.IsAccounting ? "(buchführend)" : "(pauschaliert)")), 10, center: true));
|
||||||
|
} else {
|
||||||
|
Aside
|
||||||
|
.AddCell(NewAsideCell("Mitglieds-Nr.:", 12, isName: true)).AddCell(NewAsideCell($"{Member.MgNr}", 4, right: true)).AddCell(NewAsideCell("", 10))
|
||||||
|
.AddCell(NewAsideCell("Betriebs-Nr.:", 10, isName: true)).AddCell(NewAsideCell(Member.LfbisNr ?? "-", 6, right: true, center: Member.LfbisNr == null)).AddCell(NewAsideCell("", 10))
|
||||||
|
.AddCell(NewAsideCell("UID:", 6, isName: true)).AddCell(NewAsideCell(Member.UstIdNr ?? "-", 10, right: true, center: Member.UstIdNr == null))
|
||||||
|
.AddCell(NewAsideCell(new KernedParagraph("", 10).Add(Italic(Member.IsAccounting ? "(buchführend)" : "(pauschaliert)")), 10, center: true));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void RenderAddress(Canvas canvas, Rectangle pageSize) {
|
protected void RenderAddress(Canvas canvas, Rectangle pageSize) {
|
||||||
@@ -122,11 +137,15 @@ namespace Elwig.Documents {
|
|||||||
return new KernedParagraph(10)
|
return new KernedParagraph(10)
|
||||||
.AddAll(Utils.GenerateFooter("\n", " \u00b7 ")
|
.AddAll(Utils.GenerateFooter("\n", " \u00b7 ")
|
||||||
.Item(c.NameFull).NextLine()
|
.Item(c.NameFull).NextLine()
|
||||||
.Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextLine()
|
.Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").NextGroup()
|
||||||
.Item(c.EmailAddress != null ? link1 : null)
|
.Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextGroup()
|
||||||
.Item(c.Website != null ? link2 : null)
|
.Item(c.EmailAddress != null ? link1 : null).NextLine()
|
||||||
.Item("Betriebs-Nr.", c.LfbisNr).Item("Bio-KSt.", c.OrganicAuthority).NextLine()
|
.Item(c.Website != null ? link2 : null).NextGroup()
|
||||||
|
.Item("Betriebs-Nr.", c.LfbisNr).NextGroup()
|
||||||
|
.Item("Bio-KSt.", c.OrganicAuthorityCode).NextGroup()
|
||||||
|
.Item("OOC-ID", c.OrganicOperatorId).NextLine()
|
||||||
.Item("UID", c.UstIdNr).Item("BIC", c.Bic).Item("IBAN", c.Iban)
|
.Item("UID", c.UstIdNr).Item("BIC", c.Bic).Item("IBAN", c.Iban)
|
||||||
|
.RebalanceLines()
|
||||||
.ToLeafElements());
|
.ToLeafElements());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,10 +125,10 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.BeforeRenderBody(doc, pdf);
|
||||||
Aside?.AddCell(NewAsideCell("Gutschrift", 2))
|
Aside?.AddCell(NewAsideCell("Gutschrift", 26))
|
||||||
.AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-"))
|
.AddCell(NewAsideCell("Tr.-Gutschr.-Nr.:", 12, isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-", 14))
|
||||||
.AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}"))
|
.AddCell(NewAsideCell("Datum:", 12, isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}", 14))
|
||||||
.AddCell(NewAsideCell("Überw. am:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.TransferDate:dd.MM.yyyy}"));
|
.AddCell(NewAsideCell("Überwiesen am:", 12, isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.TransferDate:dd.MM.yyyy}", 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace Elwig.Documents {
|
|||||||
_year = year;
|
_year = year;
|
||||||
ShowDateAndLocation = true;
|
ShowDateAndLocation = true;
|
||||||
UseBillingAddress = true;
|
UseBillingAddress = true;
|
||||||
DocumentId = $"Anl.-Best. {_year}/{m.MgNr}";
|
DocumentId = $"Anlfrg.-Bstng. {_year}/{m.MgNr}";
|
||||||
Data = data;
|
Data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,10 +55,10 @@ namespace Elwig.Documents {
|
|||||||
base.BeforeRenderBody(doc, pdf);
|
base.BeforeRenderBody(doc, pdf);
|
||||||
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
||||||
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
||||||
Aside?.AddCell(NewAsideCell("Saison", 2))
|
Aside?.AddCell(NewAsideCell("Saison", 26))
|
||||||
.AddCell(NewAsideCell("Lieferungen:", isName: true)).AddCell(NewAsideCell($"{Data.Rows.DistinctBy(r => r.LsNr).Count():N0} (Teil-Lfrg.: {Data.RowNum:N0})"))
|
.AddCell(NewAsideCell("Lieferungen:", 12, isName: true)).AddCell(NewAsideCell($"{Data.Rows.DistinctBy(r => r.LsNr).Count():N0} (Teil-Lfrg.: {Data.RowNum:N0})", 14))
|
||||||
.AddCell(NewAsideCell("Zeitraum:", isName: true)).AddCell(NewAsideCell(firstDay == null || lastDay == null ? "-" : firstDay == lastDay ? $"{firstDay:dd.MM.} (1 Tag)" : $"{firstDay:dd.MM.}\u2013{lastDay:dd.MM.} ({lastDay?.DayNumber - firstDay?.DayNumber + 1:N0} Tage)"))
|
.AddCell(NewAsideCell("Zeitraum:", 8, isName: true)).AddCell(NewAsideCell(firstDay == null || lastDay == null ? "-" : firstDay == lastDay ? $"{firstDay:dd.MM.} (1 Tag)" : $"{firstDay:dd.MM.}\u2013{lastDay:dd.MM.} ({lastDay?.DayNumber - firstDay?.DayNumber + 1:N0} Tage)", 18, center: true))
|
||||||
.AddCell(NewAsideCell("Menge:", isName: true)).AddCell(NewAsideCell($"{MemberStats.Sum(s => s.Weight):N0} kg"));
|
.AddCell(NewAsideCell("Menge:", 12, isName: true)).AddCell(NewAsideCell($"{MemberStats.Sum(s => s.Weight):N0} kg", 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
|
|||||||
@@ -72,10 +72,10 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
base.BeforeRenderBody(doc, pdf);
|
base.BeforeRenderBody(doc, pdf);
|
||||||
Aside?.AddCell(NewAsideCell("Lieferung", 2))
|
Aside?.AddCell(NewAsideCell("Lieferung", 26))
|
||||||
.AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr))
|
.AddCell(NewAsideCell("Lieferschein-Nr.:", 12, isName: true)).AddCell(NewAsideCell(Delivery.LsNr, 14))
|
||||||
.AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}"))
|
.AddCell(NewAsideCell("Datum/Zeit:", 12, isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}", 14))
|
||||||
.AddCell(NewAsideCell("Zweigstelle:", isName: true)).AddCell(NewAsideCell(Delivery.Branch.Name));
|
.AddCell(NewAsideCell("Zweigstelle:", 12, isName: true)).AddCell(NewAsideCell(Delivery.Branch.Name, 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||||
@@ -121,7 +121,7 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewDeliveryTable() {
|
protected Table NewDeliveryTable() {
|
||||||
var tbl = new Table(ColsMM(10, 21, 25, 19.5, 19.5, 30, 12.5, 12.5, 15), true)
|
var tbl = new Table(ColsMM(10, 21, 25, 20, 20, 30, 12.5, 12.5, 14), true)
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorder(Border.NO_BORDER).SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
.SetBorder(Border.NO_BORDER).SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||||
|
|
||||||
@@ -130,15 +130,16 @@ namespace Elwig.Documents {
|
|||||||
.AddHeaderCell(NewTh("Attribut", colspan: 2, rowspan: 2, left: true))
|
.AddHeaderCell(NewTh("Attribut", colspan: 2, rowspan: 2, left: true))
|
||||||
.AddHeaderCell(NewTh("Qualitätsstufe", rowspan: 2, left: true))
|
.AddHeaderCell(NewTh("Qualitätsstufe", rowspan: 2, left: true))
|
||||||
.AddHeaderCell(NewTh("Gradation", colspan: 2))
|
.AddHeaderCell(NewTh("Gradation", colspan: 2))
|
||||||
.AddHeaderCell(NewTh("Menge"))
|
.AddHeaderCell(NewTh("Menge").SetPaddingRight(0))
|
||||||
.AddHeaderCell(NewTh("[°Oe]", 8))
|
.AddHeaderCell(NewTh("[°Oe]", 8))
|
||||||
.AddHeaderCell(NewTh("[°KMW]", 8))
|
.AddHeaderCell(NewTh("[°KMW]", 8))
|
||||||
.AddHeaderCell(NewTh("[kg]", 8));
|
.AddHeaderCell(NewTh("[kg]", 8).SetPaddingRight(0));
|
||||||
|
|
||||||
foreach (var part in Delivery.Parts.OrderBy(p => p.DPNr)) {
|
foreach (var part in Delivery.Parts.OrderBy(p => p.DPNr)) {
|
||||||
var sub = new Table(ColsMM(10, 21, 25, 19.5, 19.5, 30, 12.5, 12.5, 15), true)
|
var sub = new Table(ColsMM(10, 21, 25, 20, 20, 30, 12.5, 12.5, 14), true)
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||||
|
.SetKeepTogether(true);
|
||||||
|
|
||||||
int rowspan = 1 + (part.Cultivation != null ? 1 : 0) + 1 + part.Modifiers.Count() + 1 + (part.Comment != null ? 1 : 0) + (part.Temperature != null || part.Acid != null ? 1 : 0);
|
int rowspan = 1 + (part.Cultivation != null ? 1 : 0) + 1 + part.Modifiers.Count() + 1 + (part.Comment != null ? 1 : 0) + (part.Temperature != null || part.Acid != null ? 1 : 0);
|
||||||
sub.AddCell(NewDeliveryMainTd($"{part.DPNr:N0}", center: true))
|
sub.AddCell(NewDeliveryMainTd($"{part.DPNr:N0}", center: true))
|
||||||
@@ -147,11 +148,14 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewDeliveryMainTd(part.Quality.Name))
|
.AddCell(NewDeliveryMainTd(part.Quality.Name))
|
||||||
.AddCell(NewDeliveryMainTd($"{part.Oe:N0}", center: true))
|
.AddCell(NewDeliveryMainTd($"{part.Oe:N0}", center: true))
|
||||||
.AddCell(NewDeliveryMainTd($"{part.Kmw:N1}", center: true))
|
.AddCell(NewDeliveryMainTd($"{part.Kmw:N1}", center: true))
|
||||||
.AddCell(NewDeliveryMainTd($"{part.Weight:N0}", center: true));
|
.AddCell(NewDeliveryMainTd($"{part.Weight:N0}", right: true).SetPaddingRight(0));
|
||||||
|
|
||||||
if (part.Cultivation != null) {
|
if (part.Cultivation != null) {
|
||||||
var cult = new KernedParagraph(8);
|
var cult = new KernedParagraph(8);
|
||||||
cult.Add(Italic("Bewirtschaftung:")).Add(Normal(" " + part.Cultivation.Name + (part.Cultivation.Description != null ? $" ({part.Cultivation.Description})" : "")));
|
cult.Add(Italic("Bewirtschaftung:")).Add(Normal(" " + part.Cultivation.Name + (part.Cultivation.Description != null ? $" ({part.Cultivation.Description})" : "")));
|
||||||
|
if (part.Cultivation.IsOrganic) {
|
||||||
|
cult.Add(" \u2013 ").Add(Italic("Kontrollstelle:")).Add(Normal($" {Member.OrganicAuthorityCode ?? "?"}"));
|
||||||
|
}
|
||||||
sub.AddCell(NewTd())
|
sub.AddCell(NewTd())
|
||||||
.AddCell(NewTd(cult, colspan: 5))
|
.AddCell(NewTd(cult, colspan: 5))
|
||||||
.AddCell(NewTd(colspan: 3));
|
.AddCell(NewTd(colspan: 3));
|
||||||
@@ -196,9 +200,17 @@ namespace Elwig.Documents {
|
|||||||
.Add(Italic("Brutto:"))
|
.Add(Italic("Brutto:"))
|
||||||
.Add(Normal($" {info.Gross:N0} kg \u2013 "))
|
.Add(Normal($" {info.Gross:N0} kg \u2013 "))
|
||||||
.Add(Italic("Tara:"))
|
.Add(Italic("Tara:"))
|
||||||
.Add(Normal($" {info.Tare:N0} kg \u2013 "))
|
.Add(Normal($" {info.Tare:N0} kg "));
|
||||||
|
if (info.TareCorrection != null && info.TareCorrection != 0)
|
||||||
|
weighing.Add(Bold($"(Korr.: {Utils.GetSign(info.TareCorrection.Value)}{Math.Abs(info.TareCorrection.Value)} kg)")).Add(" ");
|
||||||
|
weighing
|
||||||
|
.Add(Normal("\u2013 "))
|
||||||
.Add(Italic("Netto:"))
|
.Add(Italic("Netto:"))
|
||||||
.Add(Normal($" {info.Net:N0} kg \u2013 "))
|
.Add(Normal($" {info.Net:N0} kg "));
|
||||||
|
if (info.TareCorrection != null && info.TareCorrection != 0)
|
||||||
|
weighing.Add(Normal($"({Utils.GetSign(-info.TareCorrection.Value)}{Math.Abs(info.TareCorrection.Value)} kg) "));
|
||||||
|
weighing
|
||||||
|
.Add(Normal("\u2013 "))
|
||||||
.Add(Italic(part.IsNetWeight ? "gerebelt gewogen" : "nicht gerebelt gewogen"));
|
.Add(Italic(part.IsNetWeight ? "gerebelt gewogen" : "nicht gerebelt gewogen"));
|
||||||
} else {
|
} else {
|
||||||
weighing.Add(" ")
|
weighing.Add(" ")
|
||||||
@@ -210,7 +222,7 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewCell(colspan: 3));
|
.AddCell(NewCell(colspan: 3));
|
||||||
if (part.Comment != null) {
|
if (part.Comment != null) {
|
||||||
sub.AddCell(NewCell())
|
sub.AddCell(NewCell())
|
||||||
.AddCell(NewCell(new KernedParagraph(8).Add(Italic("Anmerkung")).Add(Normal(" " + part.Comment)), colspan: 5))
|
.AddCell(NewCell(new KernedParagraph(8).Add(Italic("Anmerkung:")).Add(Normal(" " + part.Comment)), colspan: 5))
|
||||||
.AddCell(NewCell(colspan: 3));
|
.AddCell(NewCell(colspan: 3));
|
||||||
}
|
}
|
||||||
if (part.Temperature != null || part.Acid != null) {
|
if (part.Temperature != null || part.Acid != null) {
|
||||||
@@ -220,7 +232,7 @@ namespace Elwig.Documents {
|
|||||||
if (part.Temperature != null && part.Acid != null)
|
if (part.Temperature != null && part.Acid != null)
|
||||||
p.Add(Normal(", "));
|
p.Add(Normal(", "));
|
||||||
if (part.Acid != null)
|
if (part.Acid != null)
|
||||||
p.Add(Italic("Säure")).Add(Normal($" {part.Acid:N1} g/l"));
|
p.Add(Italic("Säure:")).Add(Normal($" {part.Acid:N1} g/l"));
|
||||||
sub.AddCell(NewCell())
|
sub.AddCell(NewCell())
|
||||||
.AddCell(NewCell(p, colspan: 5))
|
.AddCell(NewCell(p, colspan: 5))
|
||||||
.AddCell(NewCell(colspan: 3));
|
.AddCell(NewCell(colspan: 3));
|
||||||
@@ -229,10 +241,10 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Delivery.Parts.Count > 1) {
|
if (Delivery.Parts.Count > 1) {
|
||||||
tbl.AddCell(NewTd("Gesamt:", 12, bold: true, borderTop: true, colspan: 6).SetPaddingsMM(1, 1, 1, 1))
|
tbl.AddCell(NewTd("Gesamt:", 12, bold: true, borderTop: true, colspan: 6).SetPaddingsMM(1, 1, 1, 0))
|
||||||
.AddCell(NewTd($"{Delivery.Oe:N0}", 12, bold: true, center: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1))
|
.AddCell(NewTd($"{Delivery.Oe:N0}", 12, bold: true, center: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1))
|
||||||
.AddCell(NewTd($"{Delivery.Kmw:N1}", 12, bold: true, center: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1))
|
.AddCell(NewTd($"{Delivery.Kmw:N1}", 12, bold: true, center: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1))
|
||||||
.AddCell(NewTd($"{Delivery.Weight:N0}", 12, bold: true, right: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
.AddCell(NewTd($"{Delivery.Weight:N0}", 12, bold: true, right: true, borderTop: true).SetPaddingsMM(1, 0, 1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
return tbl;
|
return tbl;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace Elwig.Documents {
|
|||||||
public Document(string title) {
|
public Document(string title) {
|
||||||
Title = title;
|
Title = title;
|
||||||
Author = App.Client.NameFull;
|
Author = App.Client.NameFull;
|
||||||
Date = DateOnly.FromDateTime(Utils.Today);
|
Date = DateOnly.FromDateTime(DateTime.Today);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Document() {
|
~Document() {
|
||||||
@@ -252,7 +252,7 @@ namespace Elwig.Documents {
|
|||||||
|
|
||||||
public async Task Print(int copies = 1) {
|
public async Task Print(int copies = 1) {
|
||||||
if (PdfPath == null) throw new InvalidOperationException("Pdf file has not been generated yet");
|
if (PdfPath == null) throw new InvalidOperationException("Pdf file has not been generated yet");
|
||||||
await Pdf.Print(PdfPath, copies, IsDoublePaged);
|
Pdf.Print(PdfPath, copies, IsDoublePaged);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Show() {
|
public void Show() {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Elwig.Documents {
|
|||||||
public int MemberDeliveredWeightWhite;
|
public int MemberDeliveredWeightWhite;
|
||||||
public List<MemberHistory> MemberHistory = [];
|
public List<MemberHistory> MemberHistory = [];
|
||||||
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
public Dictionary<string, MemberBucket> MemberBuckets = [];
|
||||||
public List<AreaCom> ActiveAreaCommitments = [];
|
public List<AreaCmt> ActiveAreaCommitments = [];
|
||||||
|
|
||||||
public MemberDataSheet(Member m) :
|
public MemberDataSheet(Member m) :
|
||||||
base($"{Name} {m.AdministrativeName}", m, DateOnly.FromDateTime(m.ModifiedAt)) {
|
base($"{Name} {m.AdministrativeName}", m, DateOnly.FromDateTime(m.ModifiedAt)) {
|
||||||
@@ -68,9 +68,9 @@ namespace Elwig.Documents {
|
|||||||
firstOnPage = true;
|
firstOnPage = true;
|
||||||
}
|
}
|
||||||
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 6, 0));
|
doc.Add(new KernedParagraph(12).Add(Bold($"Flächenbindungen per {Date:dd.MM.yyyy}")).SetMargins(firstOnPage ? 0 : 24, 0, 6, 0));
|
||||||
doc.Add(NewAreaComTable(ActiveAreaCommitments));
|
doc.Add(NewAreaCmtTable(ActiveAreaCommitments));
|
||||||
}
|
}
|
||||||
if (App.Client.EnableMemberHistory) {
|
if (App.Client.EnableMemberHistory && App.Client.ModeMemberDataSheetShares > 0) {
|
||||||
bool firstOnPage = false;
|
bool firstOnPage = false;
|
||||||
if (pdf.GetNumberOfPages() == 1) {
|
if (pdf.GetNumberOfPages() == 1) {
|
||||||
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
|
||||||
@@ -158,28 +158,29 @@ namespace Elwig.Documents {
|
|||||||
.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))
|
||||||
.AddCell(NewDataTh("Stammgemeinde:")).AddCell(NewTd(Member.DefaultKg?.Name))
|
.AddCell(NewDataTh("Stammgemeinde:")).AddCell(NewTd(Member.DefaultKg?.Name))
|
||||||
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsAccounting ? "Ja " : "Nein ", 10)
|
||||||
.Add(Normal($"({(Member.IsBuchführend ? season.VatNormal : season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
.Add(Normal($"({(Member.IsAccounting ? season.VatNormal : season.VatFlatrate) * 100:N0}% USt.)", 8)), colspan: 2))
|
||||||
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
.AddCell(NewDataTh("(Katastralgemeinde mit dem größten Anteil an Weinbauflächen)", 8, colspan: 2))
|
||||||
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(Member.IsOrganic ? "Ja" : "Nein", colspan: 2))
|
.AddCell(NewDataTh("Bio:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsOrganic ? "Ja" : "Nein", 10)
|
||||||
|
.Add(Normal(Member.OrganicAuthorityCode != null || Member.OrganicOperatorId != null ? $" ({Member.OrganicAuthorityCode}{(Member.OrganicAuthorityCode != null && Member.OrganicOperatorId != null ? ", " : "")}{Member.OrganicOperatorId})" : "", 8)), colspan: 2))
|
||||||
.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(shares, 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("Vollablieferer:", colspan: 2)).AddCell(NewTd(Member.IsFullDelivery ? "Ja" : "Nein", colspan: 2))
|
||||||
.AddCell(NewDataTh("Zusendungen per\u2026")).AddCell(NewTd(new KernedParagraph(10)
|
.AddCell(NewDataTh("Zusendungen per\u2026")).AddCell(NewTd(new KernedParagraph(10)
|
||||||
.Add(Italic("Post:")).Add(Normal(Member.ContactViaPost ? " Ja \u2013 " : " Nein \u2013 "))
|
.Add(Italic("Post:")).Add(Normal(Member.ContactViaPost ? " Ja \u2013 " : " Nein \u2013 "))
|
||||||
.Add(Italic("E-Mail:")).Add(Normal(Member.ContactViaEmail ? " Ja" : " Nein"))))
|
.Add(Italic("E-Mail:")).Add(Normal(Member.ContactViaEmail ? " Ja" : " Nein"))))
|
||||||
.AddCell(NewDataTh("Funktionär:", colspan: 2)).AddCell(NewTd(Member.IsFunktionär ? "Ja" : "Nein", colspan: 2));
|
.AddCell(NewDataTh("Funktionär:", colspan: 2)).AddCell(NewTd(Member.IsOfficer ? "Ja" : "Nein", colspan: 2));
|
||||||
|
|
||||||
return tbl;
|
return tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewAreaComTable(IEnumerable<AreaCom> activeAreaComs) {
|
protected Table NewAreaCmtTable(IEnumerable<AreaCmt> activeAreaCmts) {
|
||||||
var areaComs = activeAreaComs.GroupBy(a => a.AreaComType).Select(group => new {
|
var areaCmts = activeAreaCmts.GroupBy(a => a.AreaCmtType).Select(group => new {
|
||||||
Type = group.Key,
|
Type = group.Key,
|
||||||
AreaComs = group.OrderBy(c => c.Contract.Kg.AtKg.Name).ToList(),
|
AreaCmts = group.OrderBy(c => c.Contract.Kg.AtKg.Name).ToList(),
|
||||||
Size = group.Sum(c => c.Area)
|
Size = group.Sum(c => c.Area)
|
||||||
}).OrderByDescending(a => a.Size).ToList();
|
}).OrderByDescending(a => a.Size).ToList();
|
||||||
|
|
||||||
@@ -198,7 +199,7 @@ namespace Elwig.Documents {
|
|||||||
.AddHeaderCell(NewTh("[m²]"));
|
.AddHeaderCell(NewTh("[m²]"));
|
||||||
|
|
||||||
var lastContract = "";
|
var lastContract = "";
|
||||||
foreach (var contractType in areaComs) {
|
foreach (var contractType in areaCmts) {
|
||||||
tbl.AddCell(NewCell(new KernedParagraph(10).Add(BoldItalic($"{contractType.Type.WineVar.Name} {(contractType.Type.WineAttr != null ? "(" + contractType.Type.WineAttr + ")" : "")}")), colspan: 3)
|
tbl.AddCell(NewCell(new KernedParagraph(10).Add(BoldItalic($"{contractType.Type.WineVar.Name} {(contractType.Type.WineAttr != null ? "(" + contractType.Type.WineAttr + ")" : "")}")), colspan: 3)
|
||||||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER))
|
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER))
|
||||||
.AddCell(NewCell(new KernedParagraph(10).Add(Bold($"{contractType.Size:N0}")).SetTextAlignment(TextAlignment.RIGHT))
|
.AddCell(NewCell(new KernedParagraph(10).Add(Bold($"{contractType.Size:N0}")).SetTextAlignment(TextAlignment.RIGHT))
|
||||||
@@ -206,20 +207,20 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewCell(colspan: 2)
|
.AddCell(NewCell(colspan: 2)
|
||||||
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER));
|
.SetBorderTop(contractType.Type.DisplayName != lastContract && lastContract != "" ? new SolidBorder(BorderThickness) : Border.NO_BORDER));
|
||||||
|
|
||||||
foreach (var areaCom in contractType.AreaComs) {
|
foreach (var areaCmt in contractType.AreaCmts) {
|
||||||
var c = areaCom.Contract;
|
var c = areaCmt.Contract;
|
||||||
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{c.Kg.AtKg.Name} ")).Add(Normal($"({c.Kg.AtKg.KgNr:00000})", 8))))
|
tbl.AddCell(NewTd(new KernedParagraph(10).Add(Normal($"{c.Kg.AtKg.Name} ")).Add(Normal($"({c.Kg.AtKg.KgNr:00000})", 8))))
|
||||||
.AddCell(NewTd(c.Rd?.Name))
|
.AddCell(NewTd(c.Rd?.Name))
|
||||||
.AddCell(NewTd(Regex.Replace(areaCom.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
.AddCell(NewTd(Regex.Replace(areaCmt.GstNr.Replace(",", ", ").Replace("-", "\u2013"), @"\s+", " "), 10))
|
||||||
.AddCell(NewTd($"{areaCom.Area:N0}", right: true))
|
.AddCell(NewTd($"{areaCmt.Area:N0}", right: true))
|
||||||
.AddCell(NewTd(areaCom.WineCult?.Name, center: true))
|
.AddCell(NewTd(areaCmt.WineCult?.Name, center: true))
|
||||||
.AddCell(NewTd(c.YearTo == null ? (c.YearFrom == null ? "unbefristet" : $"ab {c.YearFrom}") : (c.YearFrom == null ? $"bis {c.YearTo}" : $"{c.YearFrom}–{c.YearTo}"), center: true));
|
.AddCell(NewTd(c.YearTo == null ? (c.YearFrom == null ? "unbefristet" : $"ab {c.YearFrom}") : (c.YearFrom == null ? $"bis {c.YearTo}" : $"{c.YearFrom}–{c.YearTo}"), center: true));
|
||||||
lastContract = contractType.Type.DisplayName;
|
lastContract = contractType.Type.DisplayName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
tbl.AddCell(NewTd("Gesamt:", 12, colspan: 2, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||||
tbl.AddCell(NewTd($"{activeAreaComs.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
tbl.AddCell(NewTd($"{activeAreaCmts.Sum(a => a.Area):N0}", 12, colspan: 2, right: true, bold: true, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||||
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
tbl.AddCell(NewTd(colspan: 2, borderTop: true).SetPaddingsMM(1, 1, 1, 1));
|
||||||
|
|
||||||
return tbl;
|
return tbl;
|
||||||
@@ -274,10 +275,10 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var recorded = history.Aggregate(new MemberHistoryPoint(), (s, h) => new(
|
var recorded = history.Aggregate(new MemberHistoryPoint(), (s, h) => new(
|
||||||
s.Shares + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Normal ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Normal ? h.Shares : 0),
|
s.Shares + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Normal ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Normal && h.FromType == BusinessShareType.Normal ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Normal ? h.Shares : 0),
|
||||||
s.SharesRed + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Red ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Red ? h.Shares : 0),
|
s.SharesRed + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Red ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Red && h.FromType == BusinessShareType.Red ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Red ? h.Shares : 0),
|
||||||
s.SharesWhite + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.White ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.White ? h.Shares : 0),
|
s.SharesWhite + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.White ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.White && h.FromType == BusinessShareType.White ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.White ? h.Shares : 0),
|
||||||
s.SharesDormant + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Dormant ? h.Shares : 0) - (h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Dormant ? h.Shares : 0)));
|
s.SharesDormant + (h.ToMgNr == Member.MgNr && h.ToType == BusinessShareType.Dormant ? h.Shares : 0) - (h.ToMgNr == h.FromMgNr && h.ToType == BusinessShareType.Dormant && h.FromType == BusinessShareType.Dormant ? 0 : h.FromMgNr == Member.MgNr && h.FromType == BusinessShareType.Dormant ? h.Shares : 0)));
|
||||||
var cur = new MemberHistoryPoint(Member.Shares - recorded.Shares, Member.SharesRed - recorded.SharesRed, Member.SharesWhite - recorded.SharesWhite, Member.SharesDormant - recorded.SharesDormant);
|
var cur = new MemberHistoryPoint(Member.Shares - recorded.Shares, Member.SharesRed - recorded.SharesRed, Member.SharesWhite - recorded.SharesWhite, Member.SharesDormant - recorded.SharesDormant);
|
||||||
|
|
||||||
if (cur.Shares != 0 || cur.SharesRed != 0 || cur.SharesWhite != 0 || cur.SharesDormant != 0) {
|
if (cur.Shares != 0 || cur.SharesRed != 0 || cur.SharesWhite != 0 || cur.SharesDormant != 0) {
|
||||||
@@ -296,7 +297,7 @@ namespace Elwig.Documents {
|
|||||||
DateOnly? lastDate = null;
|
DateOnly? lastDate = null;
|
||||||
foreach (var row in history) {
|
foreach (var row in history) {
|
||||||
int s = 0, r = 0, w = 0, d = 0;
|
int s = 0, r = 0, w = 0, d = 0;
|
||||||
if (row.FromMgNr == Member.MgNr) {
|
if (row.FromMgNr == Member.MgNr && !(row.FromMgNr == row.ToMgNr && row.FromType == row.ToType)) {
|
||||||
switch (row.FromType) {
|
switch (row.FromType) {
|
||||||
case BusinessShareType.Normal: s -= row.Shares; break;
|
case BusinessShareType.Normal: s -= row.Shares; break;
|
||||||
case BusinessShareType.Red: r -= row.Shares; break;
|
case BusinessShareType.Red: r -= row.Shares; break;
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ namespace Elwig.Documents {
|
|||||||
public string Filter;
|
public string Filter;
|
||||||
public List<MemberListRow> Members;
|
public List<MemberListRow> Members;
|
||||||
|
|
||||||
public string[] AreaComFilters;
|
public string[] AreaCmtFilters;
|
||||||
public bool FilterAreaComs => AreaComFilters.Length > 0;
|
public bool FilterAreaCmts => AreaCmtFilters.Length > 0;
|
||||||
|
|
||||||
public MemberList(string filter, IEnumerable<MemberListRow> members) :
|
public MemberList(string filter, IEnumerable<MemberListRow> members) :
|
||||||
base(Name) {
|
base(Name) {
|
||||||
Filter = filter;
|
Filter = filter;
|
||||||
Members = [.. members];
|
Members = [.. members];
|
||||||
AreaComFilters = [..members
|
AreaCmtFilters = [..members
|
||||||
.SelectMany(m => m.AreaCommitmentsFiltered)
|
.SelectMany(m => m.AreaCommitmentsFiltered)
|
||||||
.Select(c => c.VtrgId)
|
.Select(c => c.VtrgId)
|
||||||
.Distinct()
|
.Distinct()
|
||||||
@@ -46,11 +46,11 @@ namespace Elwig.Documents {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Table NewMemberTable(List<MemberListRow> members) {
|
protected Table NewMemberTable(List<MemberListRow> members) {
|
||||||
var tbl = new Table(AreaComFilters.Length > 1 ? ColsMM(8, 38, 36, 8, 18, 12, 5, 16, 12, 12) : ColsMM(8, 42, 40, 8, 20, 12, 5, 18, 12), true)
|
var tbl = new Table(AreaCmtFilters.Length > 1 ? ColsMM(8, 38, 36, 8, 18, 12, 5, 16, 12, 12) : ColsMM(8, 42, 40, 8, 20, 12, 5, 18, 12), true)
|
||||||
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
.SetWidth(UnitValue.CreatePercentValue(100)).SetFixedLayout()
|
||||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||||
|
|
||||||
var headerSpan = FilterAreaComs ? 3 : 2;
|
var headerSpan = FilterAreaCmts ? 3 : 2;
|
||||||
tbl.AddHeaderCell(NewTh("Nr.", rowspan: headerSpan))
|
tbl.AddHeaderCell(NewTh("Nr.", rowspan: headerSpan))
|
||||||
.AddHeaderCell(NewTh("Name", rowspan: headerSpan, left: true))
|
.AddHeaderCell(NewTh("Name", rowspan: headerSpan, left: true))
|
||||||
.AddHeaderCell(NewTh("Adresse", rowspan: headerSpan, left: true))
|
.AddHeaderCell(NewTh("Adresse", rowspan: headerSpan, left: true))
|
||||||
@@ -59,21 +59,21 @@ namespace Elwig.Documents {
|
|||||||
.AddHeaderCell(NewTh("Betr.-Nr.", rowspan: headerSpan))
|
.AddHeaderCell(NewTh("Betr.-Nr.", rowspan: headerSpan))
|
||||||
.AddHeaderCell(NewTh("GA", rowspan: headerSpan).SetPaddingLeft(0).SetPaddingRight(0))
|
.AddHeaderCell(NewTh("GA", rowspan: headerSpan).SetPaddingLeft(0).SetPaddingRight(0))
|
||||||
.AddHeaderCell(NewTh("Stamm-KG", rowspan: headerSpan, left: true))
|
.AddHeaderCell(NewTh("Stamm-KG", rowspan: headerSpan, left: true))
|
||||||
.AddHeaderCell(NewTh("Geb. Fl.", colspan: FilterAreaComs ? AreaComFilters.Length : 1));
|
.AddHeaderCell(NewTh("Geb. Fl.", colspan: FilterAreaCmts ? AreaCmtFilters.Length : 1));
|
||||||
if (FilterAreaComs) {
|
if (FilterAreaCmts) {
|
||||||
foreach (var vtrgId in AreaComFilters) {
|
foreach (var vtrgId in AreaCmtFilters) {
|
||||||
tbl.AddHeaderCell(NewTh(vtrgId));
|
tbl.AddHeaderCell(NewTh(vtrgId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = 0; i < (FilterAreaComs ? AreaComFilters.Length : 1); i++) {
|
for (int i = 0; i < (FilterAreaCmts ? AreaCmtFilters.Length : 1); i++) {
|
||||||
tbl.AddHeaderCell(NewTh("[m²]"));
|
tbl.AddHeaderCell(NewTh("[m²]"));
|
||||||
}
|
}
|
||||||
|
|
||||||
string? lastBranch = members.Select(m => m.Branch).Distinct().Count() == 1 ? null : "";
|
string? lastBranch = members.Select(m => m.Branch).Distinct().Count() == 1 ? null : "";
|
||||||
foreach (var m in members) {
|
foreach (var m in members) {
|
||||||
if (lastBranch != null && m.Branch != lastBranch) {
|
if (lastBranch != null && m.Branch != lastBranch) {
|
||||||
tbl.AddCell(NewCell(colspan: 8 + Math.Max(AreaComFilters.Length, 1)).SetHeightMM(5).SetKeepWithNext(true));
|
tbl.AddCell(NewCell(colspan: 8 + Math.Max(AreaCmtFilters.Length, 1)).SetHeightMM(5).SetKeepWithNext(true));
|
||||||
tbl.AddCell(NewCell(new KernedParagraph(m.Branch ?? "", 16).SetFont(BF), colspan: 8 + Math.Max(AreaComFilters.Length, 1))
|
tbl.AddCell(NewCell(new KernedParagraph(m.Branch ?? "", 16).SetFont(BF), colspan: 8 + Math.Max(AreaCmtFilters.Length, 1))
|
||||||
.SetPaddingsMM(1, 2, 1, 2)
|
.SetPaddingsMM(1, 2, 1, 2)
|
||||||
.SetBorder(new SolidBorder(BorderThickness))
|
.SetBorder(new SolidBorder(BorderThickness))
|
||||||
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0)));
|
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0)));
|
||||||
@@ -88,8 +88,8 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewTd(m.LfbisNr ?? "", 8))
|
.AddCell(NewTd(m.LfbisNr ?? "", 8))
|
||||||
.AddCell(NewTd($"{m.SharesActive:N0}", 8, right: true).SetPaddingLeft(0).SetPaddingRight(0))
|
.AddCell(NewTd($"{m.SharesActive:N0}", 8, right: true).SetPaddingLeft(0).SetPaddingRight(0))
|
||||||
.AddCell(NewTd(m.DefaultKg ?? "", 6));
|
.AddCell(NewTd(m.DefaultKg ?? "", 6));
|
||||||
if (AreaComFilters.Length > 0) {
|
if (AreaCmtFilters.Length > 0) {
|
||||||
foreach (var v in AreaComFilters) {
|
foreach (var v in AreaCmtFilters) {
|
||||||
tbl.AddCell(NewTd($"{m.AreaCommitmentsFiltered.FirstOrDefault(c => c.VtrgId == v).Area:N0}", 8, right: true));
|
tbl.AddCell(NewTd($"{m.AreaCommitmentsFiltered.FirstOrDefault(c => c.VtrgId == v).Area:N0}", 8, right: true));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -101,7 +101,7 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewTd(m.BillingAddress ?? "", 8))
|
.AddCell(NewTd(m.BillingAddress ?? "", 8))
|
||||||
.AddCell(NewTd($"{m.BillingPlz}", 8))
|
.AddCell(NewTd($"{m.BillingPlz}", 8))
|
||||||
.AddCell(NewTd(m.BillingLocality ?? "", 6))
|
.AddCell(NewTd(m.BillingLocality ?? "", 6))
|
||||||
.AddCell(NewTd(colspan: 3 + Math.Max(AreaComFilters.Length, 1)));
|
.AddCell(NewTd(colspan: 3 + Math.Max(AreaCmtFilters.Length, 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -108,16 +108,16 @@ namespace Elwig.Documents {
|
|||||||
var totalSum = _credits.Sum(p => p.Amount);
|
var totalSum = _credits.Sum(p => p.Amount);
|
||||||
|
|
||||||
var weiRows = data.Rows.Where(r => r.QualityLevel == "Wein");
|
var weiRows = data.Rows.Where(r => r.QualityLevel == "Wein");
|
||||||
var minWei = weiRows.Min(r => r.Ungeb.MinPrice);
|
var minWei = weiRows.Min(r => r.UnCtrd.MinPrice);
|
||||||
var maxWei = weiRows.Max(r => r.Ungeb.MaxPrice);
|
var maxWei = weiRows.Max(r => r.UnCtrd.MaxPrice);
|
||||||
var quwRows = data.Rows.Where(r => r.QualityLevel != "Wein");
|
var quwRows = data.Rows.Where(r => r.QualityLevel != "Wein");
|
||||||
var minPrice = quwRows.Min(r => r.Ungeb.MinPrice);
|
var minPrice = quwRows.Min(r => r.UnCtrd.MinPrice);
|
||||||
var maxPrice = quwRows.Max(r => r.Ungeb.MaxPrice);
|
var maxPrice = quwRows.Max(r => r.UnCtrd.MaxPrice);
|
||||||
var gebRows = data.Rows
|
var ctrdRows = data.Rows
|
||||||
.Where(r => r.Geb.MaxPrice != null && r.Ungeb.MinPrice != null)
|
.Where(r => r.Ctrd.MaxPrice != null && r.UnCtrd.MinPrice != null)
|
||||||
.Select(r => r.Geb.MaxPrice - r.Ungeb.MinPrice);
|
.Select(r => r.Ctrd.MaxPrice - r.UnCtrd.MinPrice);
|
||||||
var minGeb = gebRows.Min();
|
var minCtrd = ctrdRows.Min();
|
||||||
var maxGeb = gebRows.Max();
|
var maxCtrd = ctrdRows.Max();
|
||||||
|
|
||||||
tbl.AddCell(NewSectionHdr("Allgemein", colspan: 5))
|
tbl.AddCell(NewSectionHdr("Allgemein", colspan: 5))
|
||||||
.AddCell(NewSectionHdr("Berücksichtigt", colspan: 3, borderLeft: true))
|
.AddCell(NewSectionHdr("Berücksichtigt", colspan: 3, borderLeft: true))
|
||||||
@@ -197,7 +197,7 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewTd(CurrencySymbol))
|
.AddCell(NewTd(CurrencySymbol))
|
||||||
.AddCell(NewTd($"{Math.Abs(vat):N2}", right: true))
|
.AddCell(NewTd($"{Math.Abs(vat):N2}", right: true))
|
||||||
.AddCell(NewSectionTh("Gebunden-Zuschlag:", borderLeft: true))
|
.AddCell(NewSectionTh("Gebunden-Zuschlag:", borderLeft: true))
|
||||||
.AddCell(NewTd(minGeb == null && maxGeb == null ? "-" : minGeb != maxGeb ? $"{minGeb:N4}\u2013{maxGeb:N4} {CurrencySymbol}/kg" : minGeb == 0 ? "-" : $"{minGeb:N4} {CurrencySymbol}/kg", colspan: 2, center: true))
|
.AddCell(NewTd(minCtrd == null && maxCtrd == null ? "-" : minCtrd != maxCtrd ? $"{minCtrd:N4}\u2013{maxCtrd:N4} {CurrencySymbol}/kg" : minCtrd == 0 ? "-" : $"{minCtrd:N4} {CurrencySymbol}/kg", colspan: 2, center: true))
|
||||||
|
|
||||||
.AddCell(NewSectionTh("Bruttosumme:", colspan: 2))
|
.AddCell(NewSectionTh("Bruttosumme:", colspan: 2))
|
||||||
.AddCell(NewTd(borderTop: true))
|
.AddCell(NewTd(borderTop: true))
|
||||||
@@ -211,21 +211,21 @@ namespace Elwig.Documents {
|
|||||||
.AddCell(NewTd(CurrencySymbol))
|
.AddCell(NewTd(CurrencySymbol))
|
||||||
.AddCell(NewTd($"{Math.Abs(totalMods):N2}", right: true))
|
.AddCell(NewTd($"{Math.Abs(totalMods):N2}", right: true))
|
||||||
.AddCell(NewSectionTh("Menge (ungebunden):", borderLeft: true, borderTop: true))
|
.AddCell(NewSectionTh("Menge (ungebunden):", borderLeft: true, borderTop: true))
|
||||||
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ungeb.Weight):N0} kg", colspan: 2, right: true, borderTop: true))
|
.AddCell(NewTd($"{data.Rows.Sum(r => r.UnCtrd.Weight):N0} kg", colspan: 2, right: true, borderTop: true))
|
||||||
|
|
||||||
.AddCell(NewSectionTh("Bereits berücksichtigte Abzüge:", colspan: 2))
|
.AddCell(NewSectionTh("Bereits berücksichtigte Abzüge:", colspan: 2))
|
||||||
.AddCell(NewTd(Utils.GetSign(considered)))
|
.AddCell(NewTd(Utils.GetSign(considered)))
|
||||||
.AddCell(NewTd(CurrencySymbol))
|
.AddCell(NewTd(CurrencySymbol))
|
||||||
.AddCell(NewTd($"{Math.Abs(considered):N2}", right: true))
|
.AddCell(NewTd($"{Math.Abs(considered):N2}", right: true))
|
||||||
.AddCell(NewSectionTh("Menge (gebunden):", borderLeft: true))
|
.AddCell(NewSectionTh("Menge (gebunden):", borderLeft: true))
|
||||||
.AddCell(NewTd($"{data.Rows.Sum(r => r.Geb.Weight + r.LowGeb.Weight):N0} kg", colspan: 2, right: true))
|
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ctrd.Weight + r.LowCtrd.Weight):N0} kg", colspan: 2, right: true))
|
||||||
|
|
||||||
.AddCell(NewSectionTh("Auszahlungsbetrag:", colspan: 2))
|
.AddCell(NewSectionTh("Auszahlungsbetrag:", colspan: 2))
|
||||||
.AddCell(NewTd(borderTop: true))
|
.AddCell(NewTd(borderTop: true))
|
||||||
.AddCell(NewTd(CurrencySymbol, borderTop: true))
|
.AddCell(NewTd(CurrencySymbol, borderTop: true))
|
||||||
.AddCell(NewTd($"{totalSum:N2}", right: true, borderTop: true))
|
.AddCell(NewTd($"{totalSum:N2}", right: true, borderTop: true))
|
||||||
.AddCell(NewSectionTh("Gesamtmenge:", borderLeft: true))
|
.AddCell(NewSectionTh("Gesamtmenge:", borderLeft: true))
|
||||||
.AddCell(NewTd($"{data.Rows.Sum(r => r.Ungeb.Weight + r.LowGeb.Weight + r.Geb.Weight):N0} kg", colspan: 2, right: true, borderTop: true));
|
.AddCell(NewTd($"{data.Rows.Sum(r => r.UnCtrd.Weight + r.LowCtrd.Weight + r.Ctrd.Weight):N0} kg", colspan: 2, right: true, borderTop: true));
|
||||||
|
|
||||||
return tbl;
|
return tbl;
|
||||||
}
|
}
|
||||||
@@ -290,22 +290,22 @@ namespace Elwig.Documents {
|
|||||||
.ToList();
|
.ToList();
|
||||||
var border = lastHdr != null;
|
var border = lastHdr != null;
|
||||||
tbl.AddCell(NewTd(hdr, colspan: 2, bold: true, italic: true, borderTop: border))
|
tbl.AddCell(NewTd(hdr, colspan: 2, bold: true, italic: true, borderTop: border))
|
||||||
.AddCell(NewTd($"{rows.Sum(r => r.Ungeb.Weight):N0}", right: true, bold: true, borderTop: border))
|
.AddCell(NewTd($"{rows.Sum(r => r.UnCtrd.Weight):N0}", right: true, bold: true, borderTop: border))
|
||||||
.AddCell(NewTd(borderTop: border))
|
.AddCell(NewTd(borderTop: border))
|
||||||
.AddCell(NewTd($"{rows.Sum(r => r.LowGeb.Weight):N0}", right: true, bold: true, borderTop: border))
|
.AddCell(NewTd($"{rows.Sum(r => r.LowCtrd.Weight):N0}", right: true, bold: true, borderTop: border))
|
||||||
.AddCell(NewTd(borderTop: border))
|
.AddCell(NewTd(borderTop: border))
|
||||||
.AddCell(NewTd($"{rows.Sum(r => r.Geb.Weight):N0}", right: true, bold: true, borderTop: border))
|
.AddCell(NewTd($"{rows.Sum(r => r.Ctrd.Weight):N0}", right: true, bold: true, borderTop: border))
|
||||||
.AddCell(NewTd(borderTop: border))
|
.AddCell(NewTd(borderTop: border))
|
||||||
.AddCell(NewTd($"{rows.Sum(r => r.Amount):N2}", right: true, bold: true, borderTop: border));
|
.AddCell(NewTd($"{rows.Sum(r => r.Amount):N2}", right: true, bold: true, borderTop: border));
|
||||||
}
|
}
|
||||||
tbl.AddCell(NewTd(row.QualityLevel))
|
tbl.AddCell(NewTd(row.QualityLevel))
|
||||||
.AddCell(NewTd($"{row.Oe:N0}", center: true))
|
.AddCell(NewTd($"{row.Oe:N0}", center: true))
|
||||||
.AddCell(NewTd(row.Ungeb.Weight != 0 ? $"{row.Ungeb.Weight:N0}" : "-", right: true))
|
.AddCell(NewTd(row.UnCtrd.Weight != 0 ? $"{row.UnCtrd.Weight:N0}" : "-", right: true))
|
||||||
.AddCell(NewTd(row.Ungeb.MaxPrice != null ? $"{row.Ungeb.MaxPrice:N4}" : "-", right: true))
|
.AddCell(NewTd(row.UnCtrd.MaxPrice != null ? $"{row.UnCtrd.MaxPrice:N4}" : "-", right: true))
|
||||||
.AddCell(NewTd(row.LowGeb.Weight != 0 ? $"{row.LowGeb.Weight:N0}" : "-", right: true))
|
.AddCell(NewTd(row.LowCtrd.Weight != 0 ? $"{row.LowCtrd.Weight:N0}" : "-", right: true))
|
||||||
.AddCell(NewTd(row.LowGeb.MaxPrice != null ? $"{row.LowGeb.MaxPrice:N4}" : "-", right: true))
|
.AddCell(NewTd(row.LowCtrd.MaxPrice != null ? $"{row.LowCtrd.MaxPrice:N4}" : "-", right: true))
|
||||||
.AddCell(NewTd(row.Geb.Weight != 0 ? $"{row.Geb.Weight:N0}" : "-", right: true))
|
.AddCell(NewTd(row.Ctrd.Weight != 0 ? $"{row.Ctrd.Weight:N0}" : "-", right: true))
|
||||||
.AddCell(NewTd(row.Geb.MaxPrice != null ? $"{row.Geb.MaxPrice:N4}" : "-", right: true))
|
.AddCell(NewTd(row.Ctrd.MaxPrice != null ? $"{row.Ctrd.MaxPrice:N4}" : "-", right: true))
|
||||||
.AddCell(NewTd($"{row.Amount:N2}", right: true));
|
.AddCell(NewTd($"{row.Amount:N2}", right: true));
|
||||||
lastHdr = hdr;
|
lastHdr = hdr;
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -9,7 +9,7 @@
|
|||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||||
<Version>1.1.1.1</Version>
|
<Version>1.2.0.0</Version>
|
||||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<ApplicationManifest>App.manifest</ApplicationManifest>
|
<ApplicationManifest>App.manifest</ApplicationManifest>
|
||||||
@@ -23,21 +23,21 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="153.0.8009" />
|
<PackageReference Include="bblanchon.PDFium.Win32" Version="156.0.8076" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||||
<PackageReference Include="itext" Version="9.7.0" />
|
<PackageReference Include="itext" Version="9.8.0" />
|
||||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.7.0" />
|
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.8.0" />
|
||||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
<PackageReference Include="MailKit" Version="4.18.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.11" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.11" />
|
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.12" />
|
||||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4129.50" />
|
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4258.31" />
|
||||||
<PackageReference Include="NJsonSchema" Version="11.6.1" />
|
<PackageReference Include="NJsonSchema" Version="11.6.1" />
|
||||||
<PackageReference Include="ScottPlot.WPF" Version="5.1.59" />
|
<PackageReference Include="ScottPlot.WPF" Version="5.1.59" />
|
||||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.5" />
|
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.5" />
|
||||||
<PackageReference Include="System.IO.Hashing" Version="10.0.11" />
|
<PackageReference Include="System.IO.Hashing" Version="10.0.12" />
|
||||||
<PackageReference Include="System.IO.Ports" Version="10.0.11" />
|
<PackageReference Include="System.IO.Ports" Version="10.0.12" />
|
||||||
<PackageReference Include="System.Management" Version="10.0.11" />
|
<PackageReference Include="System.Management" Version="10.0.12" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Elwig.Models;
|
||||||
using Elwig.Models.Dtos;
|
using Elwig.Models.Dtos;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using Elwig.Services;
|
using Elwig.Services;
|
||||||
@@ -15,7 +16,7 @@ using System.Threading.Tasks;
|
|||||||
namespace Elwig.Helpers {
|
namespace Elwig.Helpers {
|
||||||
|
|
||||||
public record struct MemberHistoryPoint(int Shares, int SharesRed, int SharesWhite, int SharesDormant);
|
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 AreaCmtBucket(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);
|
||||||
public record struct MemberStat(string Variety, string Discr, int Weight);
|
public record struct MemberStat(string Variety, string Discr, int Weight);
|
||||||
@@ -43,14 +44,14 @@ namespace Elwig.Helpers {
|
|||||||
public DbSet<WineAttr> WineAttributes { get; private set; }
|
public DbSet<WineAttr> WineAttributes { get; private set; }
|
||||||
public DbSet<WineCult> WineCultivations { get; private set; }
|
public DbSet<WineCult> WineCultivations { get; private set; }
|
||||||
public DbSet<Branch> Branches { get; private set; }
|
public DbSet<Branch> Branches { get; private set; }
|
||||||
public DbSet<AreaComType> AreaCommitmentTypes { get; private set; }
|
public DbSet<AreaCmtType> AreaCommitmentTypes { get; private set; }
|
||||||
public DbSet<Member> Members { get; private set; }
|
public DbSet<Member> Members { get; private set; }
|
||||||
public DbSet<BillingAddr> BillingAddresses { get; private set; }
|
public DbSet<BillingAddr> BillingAddresses { get; private set; }
|
||||||
public DbSet<MemberTelNr> MemberTelephoneNrs { get; private set; }
|
public DbSet<MemberTelNr> MemberTelephoneNrs { get; private set; }
|
||||||
public DbSet<MemberEmailAddr> MemberEmailAddrs { get; private set; }
|
public DbSet<MemberEmailAddr> MemberEmailAddrs { get; private set; }
|
||||||
public DbSet<MemberHistory> MemberHistory { get; private set; }
|
public DbSet<MemberHistory> MemberHistory { get; private set; }
|
||||||
public DbSet<AreaComContract> AreaCommitmentContracts { get; private set; }
|
public DbSet<AreaCmtContract> AreaCommitmentContracts { get; private set; }
|
||||||
public DbSet<AreaCom> AreaCommitments { get; private set; }
|
public DbSet<AreaCmt> AreaCommitments { get; private set; }
|
||||||
public DbSet<Season> Seasons { get; private set; }
|
public DbSet<Season> Seasons { get; private set; }
|
||||||
public DbSet<DeliverySchedule> DeliverySchedules { get; private set; }
|
public DbSet<DeliverySchedule> DeliverySchedules { get; private set; }
|
||||||
public DbSet<DeliveryScheduleWineVar> DeliveryScheduleWineVarieties { get; private set; }
|
public DbSet<DeliveryScheduleWineVar> DeliveryScheduleWineVarieties { get; private set; }
|
||||||
@@ -67,10 +68,10 @@ namespace Elwig.Helpers {
|
|||||||
public DbSet<DeliveryPartBucket> DeliveryPartBuckets { get; private set; }
|
public DbSet<DeliveryPartBucket> DeliveryPartBuckets { get; private set; }
|
||||||
|
|
||||||
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
|
||||||
public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
|
public DbSet<AreaCmtUnderDeliveryRowSingle> AreaCmtUnderDeliveryRows { get; private set; }
|
||||||
public DbSet<MemberDeliveryPerVarietyRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
public DbSet<MemberDeliveryPerVarietyRowSingle> MemberDeliveryPerVariantRows { get; private set; }
|
||||||
public DbSet<MemberAreaComTotalsRowSingle> MemberAreaComTotalsRows { get; private set; }
|
public DbSet<MemberAreaCmtTotalsRowSingle> MemberAreaCmtTotalsRows { get; private set; }
|
||||||
public DbSet<MemberAreaComsRow> MemberAreaComsRows { get; private set; }
|
public DbSet<MemberAreaCmtsRow> MemberAreaCmtsRows { get; private set; }
|
||||||
public DbSet<CreditNoteDeliveryRowSingle> CreditNoteDeliveryRows { get; private set; }
|
public DbSet<CreditNoteDeliveryRowSingle> CreditNoteDeliveryRows { get; private set; }
|
||||||
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
|
||||||
public DbSet<WeightBreakdownRow> WeightBreakDownRows { get; private set; }
|
public DbSet<WeightBreakdownRow> WeightBreakDownRows { get; private set; }
|
||||||
@@ -132,8 +133,8 @@ namespace Elwig.Helpers {
|
|||||||
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr)
|
.OrderBy(m => m.Name).ThenBy(m => m.GivenName).ThenBy(m => m.MgNr)
|
||||||
.AsSplitQuery());
|
.AsSplitQuery());
|
||||||
|
|
||||||
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<AreaCom>> _compiledQueryAreaCommitments =
|
private static readonly Func<AppDbContext, int?, IAsyncEnumerable<AreaCmt>> _compiledQueryAreaCommitments =
|
||||||
EF.CompileAsyncQuery<AppDbContext, int?, AreaCom>((ctx, fbnr) => ctx.AreaCommitments
|
EF.CompileAsyncQuery<AppDbContext, int?, AreaCmt>((ctx, fbnr) => ctx.AreaCommitments
|
||||||
.Where(c => fbnr == null || c.FbNr == fbnr)
|
.Where(c => fbnr == null || c.FbNr == fbnr)
|
||||||
.OrderBy(c => c.FbNr).ThenBy(c => c.RevNr));
|
.OrderBy(c => c.FbNr).ThenBy(c => c.RevNr));
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ namespace Elwig.Helpers {
|
|||||||
.OrderByDescending(s => s.Year));
|
.OrderByDescending(s => s.Year));
|
||||||
|
|
||||||
private readonly Dictionary<int, Dictionary<int, MemberHistoryPoint>> _memberHistory = [];
|
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, AreaCmtBucket>>> _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 = [];
|
||||||
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = [];
|
private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = [];
|
||||||
@@ -170,16 +171,25 @@ namespace Elwig.Helpers {
|
|||||||
SavedChanges += OnSavedChanges;
|
SavedChanges += OnSavedChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CreateFunctions(SqliteConnection cnx) {
|
||||||
|
cnx.CreateFunction<string, string?, bool?>("REGEXP", (pattern, value) => {
|
||||||
|
return value == null ? null : Regex.IsMatch(value, pattern);
|
||||||
|
}, true);
|
||||||
|
cnx.CreateFunction<string?, string?, string?>("NORMALIZE_ADDRESS", (address, locality) => {
|
||||||
|
return string.IsNullOrWhiteSpace(address) ? null : Normalizer.NormalizeAddress(address, locality);
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static SqliteConnection Connect(string? connectionString = null) {
|
public static SqliteConnection Connect(string? connectionString = null) {
|
||||||
var cnx = new SqliteConnection(connectionString ?? ConnectionString);
|
var cnx = new SqliteConnection(connectionString ?? ConnectionString);
|
||||||
cnx.CreateFunction<string, string?, bool?>("REGEXP", (pattern, value) => value == null ? null : Regex.Match(value, pattern).Success, true);
|
CreateFunctions(cnx);
|
||||||
cnx.Open();
|
cnx.Open();
|
||||||
return cnx;
|
return cnx;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<SqliteConnection> ConnectAsync(string? connectionString = null) {
|
public static async Task<SqliteConnection> ConnectAsync(string? connectionString = null) {
|
||||||
var cnx = new SqliteConnection(connectionString ?? ConnectionString);
|
var cnx = new SqliteConnection(connectionString ?? ConnectionString);
|
||||||
cnx.CreateFunction<string, string?, bool?>("REGEXP", (pattern, value) => value == null ? null : Regex.Match(value, pattern).Success, true);
|
CreateFunctions(cnx);
|
||||||
await cnx.OpenAsync();
|
await cnx.OpenAsync();
|
||||||
return cnx;
|
return cnx;
|
||||||
}
|
}
|
||||||
@@ -220,13 +230,13 @@ namespace Elwig.Helpers {
|
|||||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Kg).AutoInclude();
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Kg).AutoInclude();
|
||||||
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Rd).AutoInclude();
|
modelBuilder.Entity<DeliveryPart>().Navigation(p => p.Rd).AutoInclude();
|
||||||
modelBuilder.Entity<DeliveryPartModifier>().Navigation(m => m.Modifier).AutoInclude();
|
modelBuilder.Entity<DeliveryPartModifier>().Navigation(m => m.Modifier).AutoInclude();
|
||||||
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Kg).AutoInclude();
|
modelBuilder.Entity<AreaCmtContract>().Navigation(c => c.Kg).AutoInclude();
|
||||||
modelBuilder.Entity<AreaComContract>().Navigation(c => c.Rd).AutoInclude();
|
modelBuilder.Entity<AreaCmtContract>().Navigation(c => c.Rd).AutoInclude();
|
||||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.Contract).AutoInclude();
|
modelBuilder.Entity<AreaCmt>().Navigation(c => c.Contract).AutoInclude();
|
||||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.WineCult).AutoInclude();
|
modelBuilder.Entity<AreaCmt>().Navigation(c => c.WineCult).AutoInclude();
|
||||||
modelBuilder.Entity<AreaCom>().Navigation(c => c.AreaComType).AutoInclude();
|
modelBuilder.Entity<AreaCmt>().Navigation(c => c.AreaCmtType).AutoInclude();
|
||||||
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineVar).AutoInclude();
|
modelBuilder.Entity<AreaCmtType>().Navigation(c => c.WineVar).AutoInclude();
|
||||||
modelBuilder.Entity<AreaComType>().Navigation(c => c.WineAttr).AutoInclude();
|
modelBuilder.Entity<AreaCmtType>().Navigation(c => c.WineAttr).AutoInclude();
|
||||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Credit).AutoInclude();
|
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Credit).AutoInclude();
|
||||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Member).AutoInclude();
|
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Member).AutoInclude();
|
||||||
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Variant).AutoInclude();
|
modelBuilder.Entity<PaymentMember>().Navigation(c => c.Variant).AutoInclude();
|
||||||
@@ -234,6 +244,8 @@ 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<DeliverySchedule>().Navigation(s => s.Attribute).AutoInclude();
|
||||||
|
modelBuilder.Entity<DeliverySchedule>().Navigation(s => s.Cultivation).AutoInclude();
|
||||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.FromMember).AutoInclude();
|
modelBuilder.Entity<MemberHistory>().Navigation(s => s.FromMember).AutoInclude();
|
||||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.ToMember).AutoInclude();
|
modelBuilder.Entity<MemberHistory>().Navigation(s => s.ToMember).AutoInclude();
|
||||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.Currency).AutoInclude();
|
modelBuilder.Entity<MemberHistory>().Navigation(s => s.Currency).AutoInclude();
|
||||||
@@ -427,7 +439,7 @@ namespace Elwig.Helpers {
|
|||||||
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();
|
||||||
var buckets = new Dictionary<int, Dictionary<string, AreaComBucket>>();
|
var buckets = new Dictionary<int, Dictionary<string, AreaCmtBucket>>();
|
||||||
using (var cmd = cnx.CreateCommand()) {
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
cmd.CommandText = $"SELECT mgnr, bucket, area, min_kg, max_kg FROM v_area_commitment_bucket WHERE year = {year}";
|
cmd.CommandText = $"SELECT mgnr, bucket, area, min_kg, max_kg FROM v_area_commitment_bucket WHERE year = {year}";
|
||||||
using var reader = await cmd.ExecuteReaderAsync();
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
@@ -520,7 +532,45 @@ namespace Elwig.Helpers {
|
|||||||
return _memberHistory[year].GetValueOrDefault(mgnr, new());
|
return _memberHistory[year].GetValueOrDefault(mgnr, new());
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Dictionary<string, AreaComBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
public async Task<Dictionary<int, SortedDictionary<DateOnly, MemberHistoryPoint>>> GetMemberHistory() {
|
||||||
|
var today = DateOnly.FromDateTime(DateTime.Today).AddDays(1);
|
||||||
|
var history = new Dictionary<int, SortedDictionary<DateOnly, MemberHistoryPoint>>();
|
||||||
|
|
||||||
|
var members = await Members.ToListAsync();
|
||||||
|
foreach (var m in members) {
|
||||||
|
history[m.MgNr] = new() {
|
||||||
|
[today] = new(m.Shares, m.SharesRed, m.SharesWhite, m.SharesDormant),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var hist = await MemberHistory.OrderByDescending(h => h.DateNoticeString).ToListAsync();
|
||||||
|
foreach (var h in hist) {
|
||||||
|
if (h.FromMgNr is int from) {
|
||||||
|
var latest = history[from].Last().Value;
|
||||||
|
switch (h.FromType) {
|
||||||
|
case BusinessShareType.Normal: latest.Shares += h.Shares; break;
|
||||||
|
case BusinessShareType.Red: latest.SharesRed += h.Shares; break;
|
||||||
|
case BusinessShareType.White: latest.SharesWhite += h.Shares; break;
|
||||||
|
case BusinessShareType.Dormant: latest.SharesDormant += h.Shares; break;
|
||||||
|
}
|
||||||
|
history[from][h.DateNotice] = latest;
|
||||||
|
}
|
||||||
|
if (h.ToMgNr is int to) {
|
||||||
|
var latest = history[to].Last().Value;
|
||||||
|
switch (h.ToType) {
|
||||||
|
case BusinessShareType.Normal: latest.Shares -= h.Shares; break;
|
||||||
|
case BusinessShareType.Red: latest.SharesRed -= h.Shares; break;
|
||||||
|
case BusinessShareType.White: latest.SharesWhite -= h.Shares; break;
|
||||||
|
case BusinessShareType.Dormant: latest.SharesDormant -= h.Shares; break;
|
||||||
|
}
|
||||||
|
history[to][h.DateNotice] = latest;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return history;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Dictionary<string, AreaCmtBucket>> GetMemberAreaCommitmentBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
|
||||||
if (!_memberAreaCommitmentBuckets.ContainsKey(year))
|
if (!_memberAreaCommitmentBuckets.ContainsKey(year))
|
||||||
await FetchMemberAreaCommitmentBuckets(year, cnx);
|
await FetchMemberAreaCommitmentBuckets(year, cnx);
|
||||||
return _memberAreaCommitmentBuckets[year].GetValueOrDefault(mgnr, []);
|
return _memberAreaCommitmentBuckets[year].GetValueOrDefault(mgnr, []);
|
||||||
|
|||||||
@@ -1,23 +1,33 @@
|
|||||||
|
using Elwig.Services;
|
||||||
|
using Microsoft.Data.Sqlite;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
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 = 41;
|
public static readonly int RequiredSchemaVersion = 42;
|
||||||
|
|
||||||
private static int VersionOffset = 0;
|
private static int VersionOffset = 0;
|
||||||
|
|
||||||
public static async Task<Version> CheckDb() {
|
public static async Task<Version> CheckDb() {
|
||||||
|
if (!File.Exists(App.Config.DatabaseFile))
|
||||||
|
throw new FileNotFoundException($"Die Datei \"{App.Config.DatabaseFile}\" exisitiert nicht");
|
||||||
|
|
||||||
long? applId, schemaVers;
|
long? applId, schemaVers;
|
||||||
using (var cnx = await AppDbContext.ConnectAsync()) {
|
using (var cnx = await AppDbContext.ConnectAsync()) {
|
||||||
|
|
||||||
|
await cnx.QuickCheck();
|
||||||
|
|
||||||
applId = (long?)await cnx.ExecuteScalar("PRAGMA application_id") ?? 0;
|
applId = (long?)await cnx.ExecuteScalar("PRAGMA application_id") ?? 0;
|
||||||
if (applId != 0x454C5747) throw new Exception($"Invalid application_id in database (0x{applId:X08})");
|
if (applId != 0x454C5747)
|
||||||
|
throw new FileFormatException($"Invalid application_id in database (0x{applId:X08})");
|
||||||
|
|
||||||
schemaVers = (long?)await cnx.ExecuteScalar("PRAGMA schema_version") ?? 0;
|
schemaVers = (long?)await cnx.ExecuteScalar("PRAGMA schema_version") ?? 0;
|
||||||
VersionOffset = (int)(schemaVers % 100);
|
VersionOffset = (int)(schemaVers % 100);
|
||||||
@@ -61,11 +71,11 @@ namespace Elwig.Helpers {
|
|||||||
})
|
})
|
||||||
.OrderBy(s => s.Item1).ThenBy(s => s.Item2)];
|
.OrderBy(s => s.Item1).ThenBy(s => s.Item2)];
|
||||||
|
|
||||||
List<string> toExecute = [];
|
List<(int ToVersion, string File)> toExecute = [];
|
||||||
var vers = fromVersion;
|
var vers = fromVersion;
|
||||||
while (vers < toVersion) {
|
while (vers < toVersion) {
|
||||||
var (_, to, name) = scripts.Last(s => s.From == vers);
|
var (_, to, name) = scripts.Last(s => s.From == vers);
|
||||||
toExecute.Add(name);
|
toExecute.Add((to, name));
|
||||||
vers = to;
|
vers = to;
|
||||||
}
|
}
|
||||||
if (toExecute.Count == 0)
|
if (toExecute.Count == 0)
|
||||||
@@ -76,16 +86,19 @@ namespace Elwig.Helpers {
|
|||||||
try {
|
try {
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
await cnx.ExecuteBatch("PRAGMA locking_mode = EXCLUSIVE");
|
await cnx.ExecuteBatch("PRAGMA locking_mode = EXCLUSIVE");
|
||||||
foreach (var script in toExecute) {
|
|
||||||
|
await cnx.IntegrityCheck();
|
||||||
|
await cnx.ForeignKeyCheck();
|
||||||
|
|
||||||
|
foreach (var (to, script) in toExecute) {
|
||||||
await cnx.ExecuteEmbeddedScript(asm, script);
|
await cnx.ExecuteEmbeddedScript(asm, script);
|
||||||
|
if (to == 42) {
|
||||||
|
await UpdateDbSchema_41_To_42(cnx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var violations = await cnx.ForeignKeyCheck();
|
await cnx.IntegrityCheck();
|
||||||
if (violations.Length > 0) {
|
await cnx.ForeignKeyCheck();
|
||||||
throw new Exception($"Foreign key violations ({violations.Length}):\n" + string.Join("\n", violations
|
|
||||||
.Take(50)
|
|
||||||
.Select(v => $"{v.Table} - {v.RowId} - {v.Parent} - {v.FkId}")));
|
|
||||||
}
|
|
||||||
|
|
||||||
await cnx.ExecuteBatch("VACUUM");
|
await cnx.ExecuteBatch("VACUUM");
|
||||||
await cnx.ExecuteBatch($"PRAGMA schema_version = {toVersion * 100 + VersionOffset}");
|
await cnx.ExecuteBatch($"PRAGMA schema_version = {toVersion * 100 + VersionOffset}");
|
||||||
@@ -96,5 +109,57 @@ namespace Elwig.Helpers {
|
|||||||
File.Delete(backup);
|
File.Delete(backup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task UpdateDbSchema_41_To_42(SqliteConnection cnx) {
|
||||||
|
List<(int MgNr, string LfbisNr, string Name, string Address, int Plz)> members = [];
|
||||||
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
|
cmd.CommandText = """
|
||||||
|
SELECT m.mgnr, m.lfbis_nr,
|
||||||
|
COALESCE(a.name, (COALESCE(m.prefix || ' ', '') || COALESCE(m.given_name || ' ', '') || m.name || COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, ''))),
|
||||||
|
COALESCE(a.address, m.address),
|
||||||
|
COALESCE(aplz.plz, mplz.plz)
|
||||||
|
FROM member m
|
||||||
|
JOIN postal_dest mp ON (mp.country, mp.id) = (m.country, m.postal_dest)
|
||||||
|
JOIN AT_plz_dest ma ON (ma.country, ma.id) = (mp.country, mp.id)
|
||||||
|
JOIN AT_plz mplz ON mplz.plz = ma.plz
|
||||||
|
LEFT JOIN member_billing_address a ON a.mgnr = m.mgnr
|
||||||
|
LEFT JOIN postal_dest ap ON (ap.country, ap.id) = (a.country, a.postal_dest)
|
||||||
|
LEFT JOIN AT_plz_dest aa ON (aa.country, aa.id) = (ap.country, mp.id)
|
||||||
|
LEFT JOIN AT_plz aplz ON aplz.plz = aa.plz
|
||||||
|
WHERE organic
|
||||||
|
""";
|
||||||
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
|
var header = await reader.GetColumnSchemaAsync();
|
||||||
|
while (await reader.ReadAsync()) {
|
||||||
|
members.Add((reader.GetInt32(0), reader.GetString(1), reader.GetString(2), reader.GetString(3), reader.GetInt32(4)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (members.Count > 0)
|
||||||
|
InteractionService.ShowInformation("Datenbank-Update", "Es wird versucht, die Bio-Kontrollstellen-Informationen der Mitglieder automatisch abzurufen. Dies könnte einen kurzen Moment dauern.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
|
foreach (var m in members) {
|
||||||
|
string? oocId = null;
|
||||||
|
string? authCode = null;
|
||||||
|
|
||||||
|
var certs = await OrganicService.FetchTracesCertificates(lfbisNr: m.LfbisNr, address: (m.Name, m.Address, m.Plz.ToString()));
|
||||||
|
|
||||||
|
if (certs.Length > 0) {
|
||||||
|
oocId = certs[0].OperatorId;
|
||||||
|
authCode = certs[0].AuthorityCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oocId != null || authCode != null) {
|
||||||
|
oocId = oocId == null ? "NULL" : $"'{oocId}'";
|
||||||
|
authCode = authCode == null ? "NULL" : $"'{authCode}'";
|
||||||
|
await cnx.ExecuteBatch($"UPDATE member SET ooc_id = {oocId}, org_auth_code = {authCode} WHERE mgnr = {m.MgNr}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,32 +13,32 @@ namespace Elwig.Helpers.Billing {
|
|||||||
protected readonly Season Season;
|
protected readonly Season Season;
|
||||||
protected readonly Dictionary<string, string> Attributes;
|
protected readonly Dictionary<string, string> Attributes;
|
||||||
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
protected readonly Dictionary<string, (decimal?, decimal?)> Modifiers;
|
||||||
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaComTypes;
|
protected readonly Dictionary<string, (string, string?, string?, int?, decimal?)> AreaCmtTypes;
|
||||||
|
|
||||||
protected Billing(int year, Season season,
|
protected Billing(int year, Season season,
|
||||||
Dictionary<string, string> attributes,
|
Dictionary<string, string> attributes,
|
||||||
Dictionary<string, (decimal?, decimal?)> modifiers,
|
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes
|
Dictionary<string, (string, string?, string?, int?, decimal?)> areaCmtTypes
|
||||||
) {
|
) {
|
||||||
Year = year;
|
Year = year;
|
||||||
Season = season;
|
Season = season;
|
||||||
Attributes = attributes;
|
Attributes = attributes;
|
||||||
Modifiers = modifiers;
|
Modifiers = modifiers;
|
||||||
AreaComTypes = areaComTypes;
|
AreaCmtTypes = areaCmtTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static async Task<(Season, Dictionary<string, string>, Dictionary<string, (decimal?, decimal?)>, Dictionary<string, (string, string?, string?, int?, decimal?)>)> LoadData(AppDbContext ctx, int year) {
|
protected static async Task<(Season, Dictionary<string, string>, Dictionary<string, (decimal?, decimal?)>, Dictionary<string, (string, string?, string?, int?, decimal?)>)> LoadData(AppDbContext ctx, int year) {
|
||||||
var season = await ctx.FetchSeasons(year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
var season = await ctx.FetchSeasons(year).SingleOrDefaultAsync() ?? throw new ArgumentException("Invalid season");
|
||||||
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a.Name);
|
var attributes = await ctx.FetchWineAttributes().ToDictionaryAsync(a => a.AttrId, a => a.Name);
|
||||||
var modifiers = await ctx.FetchModifiers(year).ToDictionaryAsync(m => m.ModId, m => (m.Abs, m.Rel));
|
var modifiers = await ctx.FetchModifiers(year).ToDictionaryAsync(m => m.ModId, m => (m.Abs, m.Rel));
|
||||||
var areaComTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
var areaCmtTypes = ctx.AreaCommitmentTypes.ToDictionary(v => v.VtrgId, v => (v.SortId, v.AttrId, v.Discriminator, v.MinKgPerHa, v.PenaltyAmount));
|
||||||
return (season, attributes, modifiers, areaComTypes);
|
return (season, attributes, modifiers, areaCmtTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<Billing> Create(int year) {
|
public static async Task<Billing> Create(int year) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
var (season, attributes, modifiers, areaCmtTypes) = await LoadData(ctx, year);
|
||||||
return new Billing(year, season, attributes, modifiers, areaComTypes);
|
return new Billing(year, season, attributes, modifiers, areaCmtTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task FinishSeason() {
|
public async Task FinishSeason() {
|
||||||
@@ -77,13 +77,13 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async Task CalculateBuckets(
|
public async Task CalculateBuckets(
|
||||||
bool? honorGebundenField = null,
|
bool? honorContractedField = null,
|
||||||
bool? allowAttributesIntoLower = null,
|
bool? allowAttributesIntoLower = null,
|
||||||
bool? avoidUnderDeliveries = null,
|
bool? avoidUnderDeliveries = null,
|
||||||
SqliteConnection? cnx = null
|
SqliteConnection? cnx = null
|
||||||
) {
|
) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var honorGebunden = honorGebundenField ?? Season.Billing_HonorGebunden;
|
var honorContracted = honorContractedField ?? Season.Billing_HonorContracted;
|
||||||
var allowAttrsIntoLower = allowAttributesIntoLower ?? Season.Billing_AllowAttrsIntoLower;
|
var allowAttrsIntoLower = allowAttributesIntoLower ?? Season.Billing_AllowAttrsIntoLower;
|
||||||
var avoidUnderDlvrs = avoidUnderDeliveries ?? Season.Billing_AvoidUnderDeliveries;
|
var avoidUnderDlvrs = avoidUnderDeliveries ?? Season.Billing_AvoidUnderDeliveries;
|
||||||
var attrVals = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => (a.IsStrict, a.FillLower));
|
var attrVals = ctx.WineAttributes.ToDictionary(a => a.AttrId, a => (a.IsStrict, a.FillLower));
|
||||||
@@ -96,10 +96,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
var deliveries = new List<(int, int, int, string, int, double, string, string?, string[], bool?)>();
|
var deliveries = new List<(int, int, int, string, int, double, string, string?, string[], bool?)>();
|
||||||
using (var cmd = cnx.CreateCommand()) {
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
cmd.CommandText = $"""
|
cmd.CommandText = $"""
|
||||||
SELECT mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, gebunden
|
SELECT mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, contracted
|
||||||
FROM v_delivery
|
FROM v_delivery
|
||||||
WHERE year = {Year}
|
WHERE year = {Year}
|
||||||
ORDER BY mgnr, sortid, abgewertet ASC, {(honorGebunden ? "gebunden IS NOT NULL DESC, gebunden DESC," : "")}
|
ORDER BY mgnr, sortid, abgewertet ASC, {(honorContracted ? "contracted IS NOT NULL DESC, contracted DESC," : "")}
|
||||||
attribute_prio DESC, COALESCE(attrid, '~'), kmw DESC, lsnr, dpnr
|
attribute_prio DESC, COALESCE(attrid, '~'), kmw DESC, lsnr, dpnr
|
||||||
""";
|
""";
|
||||||
using var reader = await cmd.ExecuteReaderAsync();
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
@@ -115,14 +115,14 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int lastMgNr = 0;
|
int lastMgNr = 0;
|
||||||
Dictionary<string, AreaComBucket>? rightsAndObligations = null;
|
Dictionary<string, AreaCmtBucket>? rightsAndObligations = null;
|
||||||
Dictionary<string, int> used = [];
|
Dictionary<string, int> used = [];
|
||||||
foreach (var (mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, gebunden) in deliveries) {
|
foreach (var (mgnr, did, dpnr, sortid, weight, kmw, qualid, attrid, modifiers, contracted) in deliveries) {
|
||||||
if (lastMgNr != mgnr) {
|
if (lastMgNr != mgnr) {
|
||||||
rightsAndObligations = await ctx.GetMemberAreaCommitmentBuckets(Year, mgnr);
|
rightsAndObligations = await ctx.GetMemberAreaCommitmentBuckets(Year, mgnr);
|
||||||
used = [];
|
used = [];
|
||||||
}
|
}
|
||||||
if ((honorGebunden && gebunden == false) ||
|
if ((honorContracted && contracted == false) ||
|
||||||
rightsAndObligations == null || rightsAndObligations.Count == 0 ||
|
rightsAndObligations == null || rightsAndObligations.Count == 0 ||
|
||||||
qualid == "WEI" || qualid == "RSW" || qualid == "LDW")
|
qualid == "WEI" || qualid == "RSW" || qualid == "LDW")
|
||||||
{
|
{
|
||||||
@@ -140,7 +140,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
foreach (var p in Utils.Permutate(attributes, attributes.Intersect(attrForced))) {
|
foreach (var p in Utils.Permutate(attributes, attributes.Intersect(attrForced))) {
|
||||||
var c = p.Count();
|
var c = p.Count();
|
||||||
var key = sortid + string.Join("", p);
|
var key = sortid + string.Join("", p);
|
||||||
if (rightsAndObligations.TryGetValue(key, out AreaComBucket value)) {
|
if (rightsAndObligations.TryGetValue(key, out AreaCmtBucket value)) {
|
||||||
int i = (c == 0) ? 1 : 2;
|
int i = (c == 0) ? 1 : 2;
|
||||||
var u = used.GetValueOrDefault(key, 0);
|
var u = used.GetValueOrDefault(key, 0);
|
||||||
var vr = Math.Max(0, Math.Min(value.Right - u, w));
|
var vr = Math.Max(0, Math.Min(value.Right - u, w));
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
public enum CalculationMode { Elwig, WgMaster }
|
public enum CalculationMode { Elwig, WgMaster }
|
||||||
public enum CurveMode { Oe, Kmw }
|
public enum CurveMode { Oe, Kmw }
|
||||||
public record struct Curve(CurveMode Mode, Dictionary<double, decimal> Normal, Dictionary<double, decimal>? Gebunden);
|
public record struct Curve(CurveMode Mode, Dictionary<double, decimal> Normal, Dictionary<double, decimal>? Contracted);
|
||||||
|
|
||||||
public static JsonSchema? Schema { get; private set; }
|
public static JsonSchema? Schema { get; private set; }
|
||||||
|
|
||||||
@@ -179,10 +179,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
} else {
|
} else {
|
||||||
throw new InvalidOperationException();
|
throw new InvalidOperationException();
|
||||||
}
|
}
|
||||||
var geb = obj["geb"];
|
var ctrd = obj["ctrd"] ?? obj["geb"];
|
||||||
if (geb is JsonObject) {
|
if (ctrd is JsonObject) {
|
||||||
c2 = GetCurveData(geb.AsObject(), cMode);
|
c2 = GetCurveData(ctrd.AsObject(), cMode);
|
||||||
} else if (geb?.AsValue().TryGetValue(out decimal v) == true) {
|
} else if (ctrd?.AsValue().TryGetValue(out decimal v) == true) {
|
||||||
var splitVal = GetCurveValueAt(c1, quw);
|
var splitVal = GetCurveValueAt(c1, quw);
|
||||||
c2 = c1.ToDictionary(e => e.Key, e => e.Value + (e.Key >= quw ? v : 0));
|
c2 = c1.ToDictionary(e => e.Key, e => e.Value + (e.Key >= quw ? v : 0));
|
||||||
c2[quw] = splitVal + v;
|
c2[quw] = splitVal + v;
|
||||||
@@ -274,7 +274,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
protected static JsonNode GraphEntryToJson(GraphEntry entry) {
|
protected static JsonNode GraphEntryToJson(GraphEntry entry) {
|
||||||
try {
|
try {
|
||||||
if (entry.GebundenFlatBonus == null) {
|
if (entry.ContractedFlatBonus == null) {
|
||||||
return JsonValue.Create((decimal)entry.DataGraph.DataY.Distinct().Single());
|
return JsonValue.Create((decimal)entry.DataGraph.DataY.Distinct().Single());
|
||||||
}
|
}
|
||||||
} catch { }
|
} catch { }
|
||||||
@@ -286,10 +286,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
curve["data"] = GraphToJson(entry.DataGraph, entry.Mode.ToString().ToLower());
|
curve["data"] = GraphToJson(entry.DataGraph, entry.Mode.ToString().ToLower());
|
||||||
|
|
||||||
if (entry.GebundenFlatBonus != null) {
|
if (entry.ContractedFlatBonus != null) {
|
||||||
curve["geb"] = (decimal)entry.GebundenFlatBonus;
|
curve["ctrd"] = (decimal)entry.ContractedFlatBonus;
|
||||||
} else if (entry.GebundenGraph != null) {
|
} else if (entry.ContractedGraph != null) {
|
||||||
curve["geb"] = GraphToJson(entry.GebundenGraph, entry.Mode.ToString().ToLower());
|
curve["ctrd"] = GraphToJson(entry.ContractedGraph, entry.Mode.ToString().ToLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
return curve;
|
return curve;
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace Elwig.Helpers.Billing {
|
|||||||
protected BillingVariant(int year, int avnr, Season season,
|
protected BillingVariant(int year, int avnr, Season season,
|
||||||
Dictionary<string, string> attributes,
|
Dictionary<string, string> attributes,
|
||||||
Dictionary<string, (decimal?, decimal?)> modifiers,
|
Dictionary<string, (decimal?, decimal?)> modifiers,
|
||||||
Dictionary<string, (string, string?, string?, int?, decimal?)> areaComTypes,
|
Dictionary<string, (string, string?, string?, int?, decimal?)> areaCmtTypes,
|
||||||
PaymentVar paymentVar, PaymentBillingData data) :
|
PaymentVar paymentVar, PaymentBillingData data) :
|
||||||
base(year, season, attributes, modifiers, areaComTypes) {
|
base(year, season, attributes, modifiers, areaCmtTypes) {
|
||||||
AvNr = avnr;
|
AvNr = avnr;
|
||||||
PaymentVariant = paymentVar;
|
PaymentVariant = paymentVar;
|
||||||
Data = data;
|
Data = data;
|
||||||
@@ -32,16 +32,16 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
public static async Task<BillingVariant> Create(int year, int avnr) {
|
public static async Task<BillingVariant> Create(int year, int avnr) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var (season, attributes, modifiers, areaComTypes) = await LoadData(ctx, year);
|
var (season, attributes, modifiers, areaCmtTypes) = await LoadData(ctx, year);
|
||||||
var (paymentVar, data) = await LoadData(ctx, year, avnr);
|
var (paymentVar, data) = await LoadData(ctx, year, avnr);
|
||||||
return new BillingVariant(year, avnr, season, attributes, modifiers, areaComTypes, paymentVar, data);
|
return new BillingVariant(year, avnr, season, attributes, modifiers, areaCmtTypes, paymentVar, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Calculate(bool strictPrices = true, bool? honorGebunden = null, bool? allowAttrsIntoLower = null, bool? avoidUnderDeliveries = null) {
|
public async Task Calculate(bool strictPrices = true, bool? honorContracted = null, bool? allowAttrsIntoLower = null, bool? avoidUnderDeliveries = null) {
|
||||||
if (PaymentVariant == null || Data == null) throw new Exception("Call Load before Calculate");
|
if (PaymentVariant == null || Data == null) throw new Exception("Call Load before Calculate");
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
using var tx = await cnx.BeginTransactionAsync();
|
using var tx = await cnx.BeginTransactionAsync();
|
||||||
await CalculateBuckets(honorGebunden, allowAttrsIntoLower, avoidUnderDeliveries, cnx);
|
await CalculateBuckets(honorContracted, allowAttrsIntoLower, avoidUnderDeliveries, cnx);
|
||||||
await DeleteInDb(cnx);
|
await DeleteInDb(cnx);
|
||||||
await SetCalcTime(cnx);
|
await SetCalcTime(cnx);
|
||||||
KeyNotFoundException? exception = null;
|
KeyNotFoundException? exception = null;
|
||||||
@@ -73,7 +73,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
v.avnr,
|
v.avnr,
|
||||||
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
|
ROUND(p.amount / POW(10, s.precision - 2)) AS net_amount,
|
||||||
IIF(lc.amount < 0, 0, ROUND(lp.amount / POW(10, s.precision - 2))) AS prev_net_amount,
|
IIF(lc.amount < 0, 0, ROUND(lp.amount / POW(10, s.precision - 2))) AS prev_net_amount,
|
||||||
IIF(m.buchführend, s.vat_normal, s.vat_flatrate) AS vat,
|
IIF(m.accounting, 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)) +
|
ROUND(IIF({Data.ConsiderAutoBusinessShares}, -COALESCE(a.total_amount, 0), 0)) +
|
||||||
@@ -170,7 +170,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
|
|
||||||
protected async Task CalculatePrices(SqliteConnection cnx, bool strict = true) {
|
protected async Task CalculatePrices(SqliteConnection cnx, bool strict = true) {
|
||||||
var invalid = new HashSet<string>();
|
var invalid = new HashSet<string>();
|
||||||
var parts = new List<(int Year, int DId, int DPNr, int BktNr, string SortId, string? AttrId, string? CultId, string Discr, int Value, double Oe, double Kmw, string QualId, bool AttrAreaCom)>();
|
var parts = new List<(int Year, int DId, int DPNr, int BktNr, string SortId, string? AttrId, string? CultId, string Discr, int Value, double Oe, double Kmw, string QualId, bool AttrAreaCmt)>();
|
||||||
using (var cmd = cnx.CreateCommand()) {
|
using (var cmd = cnx.CreateCommand()) {
|
||||||
cmd.CommandText = $"""
|
cmd.CommandText = $"""
|
||||||
SELECT d.year, d.did, d.dpnr, b.bktnr, d.sortid, d.attrid, d.cultid, b.discr, b.value, d.oe, d.kmw, d.qualid, COALESCE(a.area_com, TRUE)
|
SELECT d.year, d.did, d.dpnr, b.bktnr, d.sortid, d.attrid, d.cultid, b.discr, b.value, d.oe, d.kmw, d.qualid, COALESCE(a.area_com, TRUE)
|
||||||
@@ -195,13 +195,13 @@ namespace Elwig.Helpers.Billing {
|
|||||||
foreach (var part in parts) {
|
foreach (var part in parts) {
|
||||||
if (part.Value == 0)
|
if (part.Value == 0)
|
||||||
continue;
|
continue;
|
||||||
var ungeb = part.Discr == "_";
|
var unctrd = part.Discr == "_";
|
||||||
var payAttrId = (part.Discr is "" or "_") ? null : part.Discr;
|
var payAttrId = (part.Discr is "" or "_") ? null : part.Discr;
|
||||||
var attrId = part.AttrAreaCom ? payAttrId : part.AttrId;
|
var attrId = part.AttrAreaCmt ? payAttrId : part.AttrId;
|
||||||
var geb = !ungeb && (payAttrId == attrId || !part.AttrAreaCom);
|
var ctrd = !unctrd && (payAttrId == attrId || !part.AttrAreaCmt);
|
||||||
decimal price = 0;
|
decimal price = 0;
|
||||||
try {
|
try {
|
||||||
price = Data.CalculatePrice(part.SortId, attrId, part.CultId, part.QualId, geb, part.Oe, part.Kmw);
|
price = Data.CalculatePrice(part.SortId, attrId, part.CultId, part.QualId, ctrd, part.Oe, part.Kmw);
|
||||||
} catch (KeyNotFoundException e) {
|
} catch (KeyNotFoundException e) {
|
||||||
invalid.Add(e.Message.Split('\'')[1]);
|
invalid.Add(e.Message.Split('\'')[1]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public class GraphEntry {
|
public class GraphEntry {
|
||||||
|
|
||||||
public const int MinX = 50;
|
public const int MinX = 50;
|
||||||
public const int MinXGeb = 73;
|
public const int MinXCtrd = 73;
|
||||||
public const int MaxX = 120;
|
public const int MaxX = 120;
|
||||||
|
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
@@ -15,11 +15,11 @@ namespace Elwig.Helpers.Billing {
|
|||||||
public bool Abgewertet { get; set; }
|
public bool Abgewertet { get; set; }
|
||||||
|
|
||||||
public Graph DataGraph { get; set; }
|
public Graph DataGraph { get; set; }
|
||||||
public Graph? GebundenGraph { get; set; }
|
public Graph? ContractedGraph { get; set; }
|
||||||
public double? GebundenFlatBonus {
|
public double? ContractedFlatBonus {
|
||||||
get {
|
get {
|
||||||
try {
|
try {
|
||||||
var val = GebundenGraph?.DataX.Zip(GebundenGraph.DataY)
|
var val = ContractedGraph?.DataX.Zip(ContractedGraph.DataY)
|
||||||
.Select(e => Math.Round(e.Second - DataGraph.GetPriceAtOe(e.First), Precision))
|
.Select(e => Math.Round(e.Second - DataGraph.GetPriceAtOe(e.First), Precision))
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.Single();
|
.Single();
|
||||||
@@ -30,10 +30,10 @@ namespace Elwig.Helpers.Billing {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if (value is not double v) return;
|
if (value is not double v) return;
|
||||||
var values = Enumerable.Range(MinXGeb, MaxX - MinXGeb + 1)
|
var values = Enumerable.Range(MinXCtrd, MaxX - MinXCtrd + 1)
|
||||||
.Select(i => Math.Round(DataGraph.GetPriceAtOe(i) + v, Precision))
|
.Select(i => Math.Round(DataGraph.GetPriceAtOe(i) + v, Precision))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
GebundenGraph = new Graph(values, Precision, MinXGeb, MaxX);
|
ContractedGraph = new Graph(values, Precision, MinXCtrd, MaxX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,39 +52,39 @@ namespace Elwig.Helpers.Billing {
|
|||||||
Vaributes = [];
|
Vaributes = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? gebunden) :
|
public GraphEntry(int id, int precision, BillingData.CurveMode mode, Dictionary<double, decimal> data, Dictionary<double, decimal>? contracted) :
|
||||||
this(id, precision, mode) {
|
this(id, precision, mode) {
|
||||||
DataGraph = new Graph(data, precision, MinX, MaxX);
|
DataGraph = new Graph(data, precision, MinX, MaxX);
|
||||||
if (gebunden != null) GebundenGraph = new Graph(gebunden, precision, MinXGeb, MaxX);
|
if (contracted != null) ContractedGraph = new Graph(contracted, precision, MinXCtrd, MaxX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphEntry(int id, int precision, BillingData.Curve curve, List<Varibute> vaributes) :
|
public GraphEntry(int id, int precision, BillingData.Curve curve, List<Varibute> vaributes) :
|
||||||
this(id, precision, curve.Mode) {
|
this(id, precision, curve.Mode) {
|
||||||
DataGraph = new Graph(curve.Normal, precision, MinX, MaxX);
|
DataGraph = new Graph(curve.Normal, precision, MinX, MaxX);
|
||||||
if (curve.Gebunden != null)
|
if (curve.Contracted != null)
|
||||||
GebundenGraph = new Graph(curve.Gebunden, precision, MinXGeb, MaxX);
|
ContractedGraph = new Graph(curve.Contracted, precision, MinXCtrd, MaxX);
|
||||||
Vaributes = vaributes;
|
Vaributes = vaributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? gebundenGraph, List<Varibute> vaributes) {
|
private GraphEntry(int id, int precision, BillingData.CurveMode mode, Graph dataGraph, Graph? contractedGraph, List<Varibute> vaributes) {
|
||||||
Id = id;
|
Id = id;
|
||||||
Precision = precision;
|
Precision = precision;
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
DataGraph = dataGraph;
|
DataGraph = dataGraph;
|
||||||
GebundenGraph = gebundenGraph;
|
ContractedGraph = contractedGraph;
|
||||||
Vaributes = vaributes;
|
Vaributes = vaributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddGebundenGraph() {
|
public void AddContractedGraph() {
|
||||||
GebundenGraph ??= new Graph(Precision, MinXGeb, MaxX);
|
ContractedGraph ??= new Graph(Precision, MinXCtrd, MaxX);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveGebundenGraph() {
|
public void RemoveContractedGraph() {
|
||||||
GebundenGraph = null;
|
ContractedGraph = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GraphEntry Copy(int id) {
|
public GraphEntry Copy(int id) {
|
||||||
return new GraphEntry(id, Precision, Mode, (Graph)DataGraph.Clone(), (Graph?)GebundenGraph?.Clone(), []);
|
return new GraphEntry(id, Precision, Mode, (Graph)DataGraph.Clone(), (Graph?)ContractedGraph?.Clone(), []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ namespace Elwig.Helpers.Billing {
|
|||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
public decimal CalculatePrice(string sortid, string? attrid, string? cultid, string qualid, bool gebunden, double oe, double kmw) {
|
public decimal CalculatePrice(string sortid, string? attrid, string? cultid, string qualid, bool contracted, double oe, double kmw) {
|
||||||
var curve = GetQualityCurve(qualid, sortid, attrid, cultid) ?? GetCurve(sortid, attrid, cultid);
|
var curve = GetQualityCurve(qualid, sortid, attrid, cultid) ?? GetCurve(sortid, attrid, cultid);
|
||||||
return GetCurveValueAt((gebunden ? curve.Gebunden : null) ?? curve.Normal, curve.Mode == CurveMode.Oe ? oe : kmw);
|
return GetCurveValueAt((contracted ? curve.Contracted : null) ?? curve.Normal, curve.Mode == CurveMode.Oe ? oe : kmw);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Curve LookupCurve(JsonValue val) {
|
private Curve LookupCurve(JsonValue val) {
|
||||||
|
|||||||
@@ -49,7 +49,8 @@ namespace Elwig.Helpers {
|
|||||||
public string? Bic;
|
public string? Bic;
|
||||||
public string? UstIdNr;
|
public string? UstIdNr;
|
||||||
public string? LfbisNr;
|
public string? LfbisNr;
|
||||||
public string? OrganicAuthority;
|
public string? OrganicOperatorId;
|
||||||
|
public string? OrganicAuthorityCode;
|
||||||
|
|
||||||
public string? PhoneNr;
|
public string? PhoneNr;
|
||||||
public string? FaxNr;
|
public string? FaxNr;
|
||||||
@@ -60,6 +61,7 @@ namespace Elwig.Helpers {
|
|||||||
public int ModeBusinessShares;
|
public int ModeBusinessShares;
|
||||||
public bool HasRedWhite => ModeBusinessShares == 1;
|
public bool HasRedWhite => ModeBusinessShares == 1;
|
||||||
|
|
||||||
|
public int ModeMemberDataSheetShares;
|
||||||
public int ModeDeliveryNoteStats;
|
public int ModeDeliveryNoteStats;
|
||||||
public int ModeWineQualityStatistics;
|
public int ModeWineQualityStatistics;
|
||||||
public int OrderingMemberList;
|
public int OrderingMemberList;
|
||||||
@@ -114,7 +116,8 @@ namespace Elwig.Helpers {
|
|||||||
UstIdNr = parameters.GetValueOrDefault("CLIENT_USTIDNR");
|
UstIdNr = parameters.GetValueOrDefault("CLIENT_USTIDNR");
|
||||||
Bic = parameters.GetValueOrDefault("CLIENT_BIC");
|
Bic = parameters.GetValueOrDefault("CLIENT_BIC");
|
||||||
Iban = parameters.GetValueOrDefault("CLIENT_IBAN");
|
Iban = parameters.GetValueOrDefault("CLIENT_IBAN");
|
||||||
OrganicAuthority = parameters.GetValueOrDefault("CLIENT_ORGANIC_AUTHORITY");
|
OrganicOperatorId = parameters.GetValueOrDefault("CLIENT_ORGANIC_OPERATORID");
|
||||||
|
OrganicAuthorityCode = parameters.GetValueOrDefault("CLIENT_ORGANIC_AUTHORITYCODE");
|
||||||
|
|
||||||
EnableMemberHistory = (parameters.GetValueOrDefault("ENABLE_MEMBERHISTORY")?.ToUpper()) switch {
|
EnableMemberHistory = (parameters.GetValueOrDefault("ENABLE_MEMBERHISTORY")?.ToUpper()) switch {
|
||||||
"1" or "TRUE" or "YES" or "JA" => true,
|
"1" or "TRUE" or "YES" or "JA" => true,
|
||||||
@@ -125,6 +128,10 @@ namespace Elwig.Helpers {
|
|||||||
case "SIMPLE": ModeBusinessShares = 0; break;
|
case "SIMPLE": ModeBusinessShares = 0; break;
|
||||||
case "RED_WHITE": ModeBusinessShares = 1; break;
|
case "RED_WHITE": ModeBusinessShares = 1; break;
|
||||||
}
|
}
|
||||||
|
switch (parameters.GetValueOrDefault("MODE_MEMBERDATASHEET_SHARES", "FULL")?.ToUpper()) {
|
||||||
|
case "NONE": ModeMemberDataSheetShares = 0; break;
|
||||||
|
case "FULL": ModeMemberDataSheetShares = 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;
|
||||||
@@ -207,6 +214,11 @@ namespace Elwig.Helpers {
|
|||||||
case 0: businessShares = "SIMPLE"; break;
|
case 0: businessShares = "SIMPLE"; break;
|
||||||
case 1: businessShares = "RED_WHITE"; break;
|
case 1: businessShares = "RED_WHITE"; break;
|
||||||
}
|
}
|
||||||
|
string memberDataSheetShares = "FULL";
|
||||||
|
switch (ModeMemberDataSheetShares) {
|
||||||
|
case 0: memberDataSheetShares = "NONE"; break;
|
||||||
|
case 1: memberDataSheetShares = "FULL"; break;
|
||||||
|
}
|
||||||
string deliveryNoteStats = "SHORT";
|
string deliveryNoteStats = "SHORT";
|
||||||
switch (ModeDeliveryNoteStats) {
|
switch (ModeDeliveryNoteStats) {
|
||||||
case 0: deliveryNoteStats = "NONE"; break;
|
case 0: deliveryNoteStats = "NONE"; break;
|
||||||
@@ -273,9 +285,11 @@ namespace Elwig.Helpers {
|
|||||||
("CLIENT_USTIDNR", UstIdNr),
|
("CLIENT_USTIDNR", UstIdNr),
|
||||||
("CLIENT_BIC", Bic),
|
("CLIENT_BIC", Bic),
|
||||||
("CLIENT_IBAN", Iban),
|
("CLIENT_IBAN", Iban),
|
||||||
("CLIENT_ORGANIC_AUTHORITY", OrganicAuthority),
|
("CLIENT_ORGANIC_OPERATORID", OrganicOperatorId),
|
||||||
|
("CLIENT_ORGANIC_AUTHORITYCODE", OrganicAuthorityCode),
|
||||||
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
|
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
|
||||||
("MODE_BUSINESSSHARES", businessShares),
|
("MODE_BUSINESSSHARES", businessShares),
|
||||||
|
("MODE_MEMBERDATASHEET_SHARES", memberDataSheetShares),
|
||||||
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
|
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
|
||||||
("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics),
|
("MODE_WINEQUALITYSTATISTICS", modeWineQualityStatistics),
|
||||||
("ORDERING_MEMBERLIST", orderingMemberList),
|
("ORDERING_MEMBERLIST", orderingMemberList),
|
||||||
|
|||||||
+24
-5
@@ -17,10 +17,11 @@ namespace Elwig.Helpers {
|
|||||||
public string? Filling;
|
public string? Filling;
|
||||||
public string? Limit;
|
public string? Limit;
|
||||||
public bool Required;
|
public bool Required;
|
||||||
|
public bool SyncTime;
|
||||||
public string? Log;
|
public string? Log;
|
||||||
public string? _Log;
|
public string? _Log;
|
||||||
|
|
||||||
public ScaleConfig(string id, string? type, string? model, string? cnx, string? empty, string? filling, string? limit, bool? required, string? log) {
|
public ScaleConfig(string id, string? type, string? model, string? cnx, string? empty, string? filling, string? limit, bool? required, bool? syncTime, string? log) {
|
||||||
Id = id;
|
Id = id;
|
||||||
Type = type;
|
Type = type;
|
||||||
Model = model;
|
Model = model;
|
||||||
@@ -29,6 +30,7 @@ namespace Elwig.Helpers {
|
|||||||
Filling = filling;
|
Filling = filling;
|
||||||
Limit = limit;
|
Limit = limit;
|
||||||
Required = required ?? true;
|
Required = required ?? true;
|
||||||
|
SyncTime = syncTime ?? true;
|
||||||
_Log = log;
|
_Log = log;
|
||||||
Log = log != null ? Path.Combine(App.DataPath, log) : null;
|
Log = log != null ? Path.Combine(App.DataPath, log) : null;
|
||||||
}
|
}
|
||||||
@@ -37,17 +39,26 @@ namespace Elwig.Helpers {
|
|||||||
public class Config {
|
public class Config {
|
||||||
|
|
||||||
private static readonly string[] TrueValues = ["1", "true", "yes", "on"];
|
private static readonly string[] TrueValues = ["1", "true", "yes", "on"];
|
||||||
|
private static readonly string[] FalseValues = ["0", "false", "no", "off"];
|
||||||
|
|
||||||
private readonly string FileName;
|
private readonly string FileName;
|
||||||
|
|
||||||
public bool Debug;
|
public bool Debug;
|
||||||
public string DatabaseFile = App.DataPath + "database.sqlite3";
|
public string DatabaseFile = Path.Combine(App.DataPath, "database.sqlite3");
|
||||||
public bool DatabaseBackup = true;
|
|
||||||
public string? DatabaseLog = null;
|
public string? DatabaseLog = null;
|
||||||
public string? Branch = null;
|
public string? Branch = null;
|
||||||
public WeighingMode? WeighingMode;
|
public WeighingMode? WeighingMode;
|
||||||
|
|
||||||
|
public bool BackupAuto = true;
|
||||||
|
public string BackupPath = Path.Combine(App.DataPath, "backups");
|
||||||
|
public int BackupRetainHours = 36;
|
||||||
|
public int BackupRetainDays = 8;
|
||||||
|
public int BackupRetainWeeks = 6;
|
||||||
|
public int BackupRetainMonths = 18;
|
||||||
|
|
||||||
public string? UpdateUrl = null;
|
public string? UpdateUrl = null;
|
||||||
public bool UpdateAuto = false;
|
public bool UpdateAuto = false;
|
||||||
|
|
||||||
public string? SyncUrl = null;
|
public string? SyncUrl = null;
|
||||||
public string SyncUsername = "";
|
public string SyncUsername = "";
|
||||||
public string SyncPassword = "";
|
public string SyncPassword = "";
|
||||||
@@ -77,16 +88,23 @@ namespace Elwig.Helpers {
|
|||||||
var config = new ConfigurationBuilder().AddIniFile(FileName).Build();
|
var config = new ConfigurationBuilder().AddIniFile(FileName).Build();
|
||||||
|
|
||||||
DatabaseFile = Path.Combine(Path.GetDirectoryName(FileName) ?? App.DataPath, config["database:file"] ?? "database.sqlite3");
|
DatabaseFile = Path.Combine(Path.GetDirectoryName(FileName) ?? App.DataPath, config["database:file"] ?? "database.sqlite3");
|
||||||
var backup = config["database:backup"];
|
|
||||||
DatabaseBackup = backup == null || TrueValues.Contains(backup.ToLower());
|
|
||||||
var log = config["database:log"];
|
var log = config["database:log"];
|
||||||
DatabaseLog = log != null ? Path.Combine(Path.GetDirectoryName(FileName) ?? App.DataPath, log) : null;
|
DatabaseLog = log != null ? Path.Combine(Path.GetDirectoryName(FileName) ?? App.DataPath, log) : null;
|
||||||
Branch = config["general:branch"];
|
Branch = config["general:branch"];
|
||||||
Debug = TrueValues.Contains(config["general:debug"]?.ToLower());
|
Debug = TrueValues.Contains(config["general:debug"]?.ToLower());
|
||||||
var weighing = config["general:weighing"];
|
var weighing = config["general:weighing"];
|
||||||
WeighingMode = weighing != null && Enum.TryParse<WeighingMode>(weighing, true, out var w) ? w : null;
|
WeighingMode = weighing != null && Enum.TryParse<WeighingMode>(weighing, true, out var w) ? w : null;
|
||||||
|
|
||||||
|
BackupAuto = !FalseValues.Contains(config["backup:auto"]?.ToLower());
|
||||||
|
BackupPath = Path.Combine(Path.GetDirectoryName(DatabaseFile) ?? App.DataPath, config["backup:path"] ?? "backups");
|
||||||
|
BackupRetainHours = int.TryParse(config["backup:retain_hours"], out var hours) ? hours : 36;
|
||||||
|
BackupRetainDays = int.TryParse(config["backup:retain_days"], out var days) ? days : 8;
|
||||||
|
BackupRetainWeeks = int.TryParse(config["backup:retain_weeks"], out var weeks) ? weeks : 6;
|
||||||
|
BackupRetainMonths = int.TryParse(config["backup:retain_months"], out var months) ? months : 18;
|
||||||
|
|
||||||
UpdateUrl = config["update:url"];
|
UpdateUrl = config["update:url"];
|
||||||
UpdateAuto = TrueValues.Contains(config["update:auto"]?.ToLower());
|
UpdateAuto = TrueValues.Contains(config["update:auto"]?.ToLower());
|
||||||
|
|
||||||
SyncUrl = config["sync:url"];
|
SyncUrl = config["sync:url"];
|
||||||
SyncUsername = config["sync:username"] ?? "";
|
SyncUsername = config["sync:username"] ?? "";
|
||||||
SyncPassword = config["sync:password"] ?? "";
|
SyncPassword = config["sync:password"] ?? "";
|
||||||
@@ -108,6 +126,7 @@ namespace Elwig.Helpers {
|
|||||||
s, config[$"scale.{s}:type"], config[$"scale.{s}:model"], config[$"scale.{s}:connection"],
|
s, config[$"scale.{s}:type"], config[$"scale.{s}:model"], config[$"scale.{s}:connection"],
|
||||||
config[$"scale.{s}:empty"], config[$"scale.{s}:filling"], config[$"scale.{s}:limit"],
|
config[$"scale.{s}:empty"], config[$"scale.{s}:filling"], config[$"scale.{s}:limit"],
|
||||||
config[$"scale.{s}:required"] != null ? TrueValues.Contains(config[$"scale.{s}:required"]?.ToLower()) : null,
|
config[$"scale.{s}:required"] != null ? TrueValues.Contains(config[$"scale.{s}:required"]?.ToLower()) : null,
|
||||||
|
config[$"scale.{s}:synctime"] != null ? !FalseValues.Contains(config[$"scale.{s}:synctime"]?.ToLower()) : null,
|
||||||
config[$"scale.{s}:log"]
|
config[$"scale.{s}:log"]
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,201 +0,0 @@
|
|||||||
using Microsoft.Data.Sqlite;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.IO.Compression;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
|
||||||
internal sealed class DatabaseBackupService {
|
|
||||||
|
|
||||||
private const int DailyBackupCount = 7;
|
|
||||||
private const int WeeklyBackupCount = 5;
|
|
||||||
|
|
||||||
private readonly string DatabaseFile;
|
|
||||||
private readonly string BackupDirectory;
|
|
||||||
private readonly string DatabaseName;
|
|
||||||
private readonly string BackupPrefix;
|
|
||||||
private readonly string LockFile;
|
|
||||||
private readonly Func<DateTime> Now;
|
|
||||||
private readonly SemaphoreSlim Gate = new(1, 1);
|
|
||||||
|
|
||||||
internal DatabaseBackupService(string databaseFile, Func<DateTime>? now = null) {
|
|
||||||
DatabaseFile = Path.GetFullPath(databaseFile);
|
|
||||||
BackupDirectory = Path.Combine(Path.GetDirectoryName(DatabaseFile)!, "backup");
|
|
||||||
DatabaseName = Path.GetFileNameWithoutExtension(DatabaseFile);
|
|
||||||
BackupPrefix = $"{DatabaseName}_";
|
|
||||||
LockFile = Path.Combine(BackupDirectory, $".{DatabaseName}.backup.lock");
|
|
||||||
Now = now ?? (() => DateTime.Now);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal async Task RunIfNeededAsync() {
|
|
||||||
if (!await Gate.WaitAsync(0)) return;
|
|
||||||
try {
|
|
||||||
var slotDate = GetSlotDate(Now());
|
|
||||||
await Task.Run(() => Run(slotDate));
|
|
||||||
} catch {
|
|
||||||
// Automatic backups dont prevent Elwig from starting or running.
|
|
||||||
} finally {
|
|
||||||
Gate.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Run(DateOnly slotDate) {
|
|
||||||
Directory.CreateDirectory(BackupDirectory);
|
|
||||||
|
|
||||||
FileStream lockStream;
|
|
||||||
try {
|
|
||||||
lockStream = new FileStream(LockFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
|
|
||||||
} catch (IOException) {
|
|
||||||
// Another Elwig instance is currently creating/pruning backups.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
using (lockStream) {
|
|
||||||
CleanupTemporaryFiles();
|
|
||||||
|
|
||||||
var backupFile = GetBackupFile(slotDate);
|
|
||||||
if (!File.Exists(backupFile)) {
|
|
||||||
CreateBackup(backupFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (File.Exists(backupFile)) {
|
|
||||||
PruneBackups(slotDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CreateBackup(string backupFile) {
|
|
||||||
var id = Guid.NewGuid().ToString("N");
|
|
||||||
var temporaryDatabase = Path.Combine(BackupDirectory, $".{DatabaseName}.backup-{id}.sqlite3.tmp");
|
|
||||||
var temporaryArchive = Path.Combine(BackupDirectory, $".{DatabaseName}.backup-{id}.zip.tmp");
|
|
||||||
|
|
||||||
try {
|
|
||||||
var sourceConnectionString = new SqliteConnectionStringBuilder {
|
|
||||||
DataSource = DatabaseFile,
|
|
||||||
Mode = SqliteOpenMode.ReadOnly,
|
|
||||||
Cache = SqliteCacheMode.Default,
|
|
||||||
Pooling = false,
|
|
||||||
}.ToString();
|
|
||||||
var destinationConnectionString = new SqliteConnectionStringBuilder {
|
|
||||||
DataSource = temporaryDatabase,
|
|
||||||
Mode = SqliteOpenMode.ReadWriteCreate,
|
|
||||||
Cache = SqliteCacheMode.Default,
|
|
||||||
Pooling = false,
|
|
||||||
}.ToString();
|
|
||||||
|
|
||||||
using (var source = new SqliteConnection(sourceConnectionString))
|
|
||||||
using (var destination = new SqliteConnection(destinationConnectionString)) {
|
|
||||||
source.Open();
|
|
||||||
destination.Open();
|
|
||||||
source.BackupDatabase(destination);
|
|
||||||
|
|
||||||
using var check = destination.CreateCommand();
|
|
||||||
check.CommandText = "PRAGMA quick_check";
|
|
||||||
if (!string.Equals(check.ExecuteScalar()?.ToString(), "ok", StringComparison.OrdinalIgnoreCase)) {
|
|
||||||
throw new InvalidDataException("The automatic database backup failed its SQLite integrity check.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using (var archive = ZipFile.Open(temporaryArchive, ZipArchiveMode.Create)) {
|
|
||||||
archive.CreateEntryFromFile(temporaryDatabase, "database.sqlite3", CompressionLevel.SmallestSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
File.Move(temporaryArchive, backupFile, false);
|
|
||||||
} catch (IOException) when (File.Exists(backupFile)) {
|
|
||||||
// A completed backup won a publish race. Its time slot is satisfied.
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
DeleteFile(temporaryDatabase);
|
|
||||||
DeleteFile(temporaryArchive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void CleanupTemporaryFiles() {
|
|
||||||
foreach (var file in Directory.EnumerateFiles(BackupDirectory, $".{DatabaseName}.backup-*.tmp")) {
|
|
||||||
DeleteFile(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void PruneBackups(DateOnly slotDate) {
|
|
||||||
var backups = GetManagedBackups().ToArray();
|
|
||||||
var retained = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
var dailyStart = slotDate.AddDays(-(DailyBackupCount - 1));
|
|
||||||
foreach (var backup in backups.Where(b => b.Date >= dailyStart && b.Date <= slotDate)) {
|
|
||||||
retained.Add(backup.File);
|
|
||||||
}
|
|
||||||
|
|
||||||
var daysSinceMonday = ((int)slotDate.DayOfWeek + 6) % 7;
|
|
||||||
var currentWeekStart = slotDate.AddDays(-daysSinceMonday);
|
|
||||||
for (var i = 1; i <= WeeklyBackupCount; i++) {
|
|
||||||
var weekStart = currentWeekStart.AddDays(-7 * i);
|
|
||||||
RetainNewest(backups, retained, weekStart, weekStart.AddDays(7));
|
|
||||||
}
|
|
||||||
|
|
||||||
var currentMonthStart = new DateOnly(slotDate.Year, slotDate.Month, 1);
|
|
||||||
foreach (var month in backups
|
|
||||||
.Where(b => b.Date < currentMonthStart)
|
|
||||||
.GroupBy(b => (b.Date.Year, b.Date.Month))) {
|
|
||||||
retained.Add(month.OrderByDescending(b => b.Date).First().File);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clock corrections should not cause future-dated backups to be deleted.
|
|
||||||
foreach (var backup in backups.Where(b => b.Date > slotDate)) {
|
|
||||||
retained.Add(backup.File);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var backup in backups.Where(b => !retained.Contains(b.File))) {
|
|
||||||
DeleteFile(backup.File);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RetainNewest(
|
|
||||||
IEnumerable<(string File, DateOnly Date)> backups,
|
|
||||||
ISet<string> retained,
|
|
||||||
DateOnly start,
|
|
||||||
DateOnly end
|
|
||||||
) {
|
|
||||||
var newest = backups
|
|
||||||
.Where(b => b.Date >= start && b.Date < end)
|
|
||||||
.OrderByDescending(b => b.Date)
|
|
||||||
.FirstOrDefault();
|
|
||||||
if (newest.File != null) retained.Add(newest.File);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IEnumerable<(string File, DateOnly Date)> GetManagedBackups() {
|
|
||||||
foreach (var file in Directory.EnumerateFiles(BackupDirectory, $"{BackupPrefix}*.sqlite3.zip")) {
|
|
||||||
var name = Path.GetFileName(file);
|
|
||||||
if (!name.StartsWith(BackupPrefix, StringComparison.OrdinalIgnoreCase) ||
|
|
||||||
!name.EndsWith(".sqlite3.zip", StringComparison.OrdinalIgnoreCase)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var dateText = name[BackupPrefix.Length..^".sqlite3.zip".Length];
|
|
||||||
if (DateOnly.TryParseExact(dateText, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None, out var date)) {
|
|
||||||
yield return (file, date);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private string GetBackupFile(DateOnly date) {
|
|
||||||
return Path.Combine(BackupDirectory, $"{BackupPrefix}{date:yyyy-MM-dd}.sqlite3.zip");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void DeleteFile(string file) {
|
|
||||||
try {
|
|
||||||
File.Delete(file);
|
|
||||||
} catch {
|
|
||||||
// Cleanup and retention are best-effort and will be retried later.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal static DateOnly GetSlotDate(DateTime timestamp) {
|
|
||||||
return DateOnly.FromDateTime(timestamp.Hour >= 3 ? timestamp : timestamp.AddDays(-1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -8,7 +8,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
using Row = Tuple<(string?, string?, string?, string?, string, int, string, bool, int), (string, int, string, string, string, int, string, double, double)>;
|
using Row = Tuple<(string?, string?, string?, string?, string, int, string, bool, int), (string, int, string, string, string, int, string, double, double)>;
|
||||||
|
|
||||||
public class Bki : Csv<Row> {
|
public class Bki : CsvFile<Row> {
|
||||||
|
|
||||||
private readonly string _clientData;
|
private readonly string _clientData;
|
||||||
|
|
||||||
@@ -46,10 +46,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
await ExportAsync(rows);
|
await ExportAsync(rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Export(int year) {
|
|
||||||
ExportAsync(year).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string FormatRow(Row row) {
|
public override string FormatRow(Row row) {
|
||||||
var (member, delivery) = row;
|
var (member, delivery) = row;
|
||||||
var (lfBisNr, familyName, name, billingName, address, plz, ort, vollablieferer, area) = member;
|
var (lfBisNr, familyName, name, billingName, address, plz, ort, vollablieferer, area) = member;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using System.Text;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
namespace Elwig.Helpers.Export {
|
||||||
public abstract class Csv<T> : IExporter<T> {
|
public abstract class CsvFile<T> : IExporter<T> {
|
||||||
|
|
||||||
public static string FileExtension => "csv";
|
public static string FileExtension => "csv";
|
||||||
|
|
||||||
@@ -15,11 +15,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
protected readonly char Separator;
|
protected readonly char Separator;
|
||||||
protected string? Header;
|
protected string? Header;
|
||||||
|
|
||||||
public Csv(string filename, char separator = ';') :
|
public CsvFile(string filename, char separator = ';') :
|
||||||
this(filename, separator, Utils.UTF8) {
|
this(filename, separator, Utils.UTF8) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Csv(string filename, char separator, Encoding encoding) {
|
public CsvFile(string filename, char separator, Encoding encoding) {
|
||||||
_writer = new StreamWriter(filename, false, encoding);
|
_writer = new StreamWriter(filename, false, encoding);
|
||||||
Separator = separator;
|
Separator = separator;
|
||||||
}
|
}
|
||||||
@@ -29,11 +29,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
_writer.Dispose();
|
_writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask DisposeAsync() {
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
return _writer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExportAsync(IEnumerable<T> data, IProgress<double>? progress = null) {
|
public async Task ExportAsync(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
int count = data.Count() + 2, i = 0;
|
int count = data.Count() + 2, i = 0;
|
||||||
@@ -50,10 +45,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
progress?.Report(100.0);
|
progress?.Report(100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
|
||||||
ExportAsync(data, progress).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public string FormatRow(IEnumerable row) {
|
public string FormatRow(IEnumerable row) {
|
||||||
return string.Join(Separator, row);
|
return string.Join(Separator, row);
|
||||||
}
|
}
|
||||||
@@ -61,7 +52,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
public abstract string FormatRow(T row);
|
public abstract string FormatRow(T row);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CsvSimple : Csv<IEnumerable<object?>> {
|
public class CsvSimple : CsvFile<IEnumerable<object?>> {
|
||||||
|
|
||||||
public CsvSimple(string filename, char separator, Encoding encoding) :
|
public CsvSimple(string filename, char separator, Encoding encoding) :
|
||||||
base(filename, separator, encoding) {
|
base(filename, separator, encoding) {
|
||||||
@@ -18,9 +18,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ExportSqlite(string filename, bool zipFile) {
|
public static async Task ExportSqlite(string filename, bool zipFile) {
|
||||||
|
var tmp = filename + ".tmp";
|
||||||
|
try {
|
||||||
|
File.Delete(tmp);
|
||||||
if (zipFile) {
|
if (zipFile) {
|
||||||
File.Delete(filename);
|
using var zip = ZipFile.Open(tmp, ZipArchiveMode.Create);
|
||||||
using var zip = ZipFile.Open(filename, ZipArchiveMode.Create);
|
|
||||||
|
|
||||||
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
||||||
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
||||||
@@ -46,14 +48,20 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
var db = zip.CreateEntryFromFile(App.Config.DatabaseFile, "database.sqlite3", CompressionLevel.SmallestSize);
|
var db = zip.CreateEntryFromFile(App.Config.DatabaseFile, "database.sqlite3", CompressionLevel.SmallestSize);
|
||||||
} else {
|
} else {
|
||||||
File.Copy(App.Config.DatabaseFile, filename, true);
|
File.Copy(App.Config.DatabaseFile, tmp);
|
||||||
|
}
|
||||||
|
File.Move(tmp, filename, true);
|
||||||
|
} finally {
|
||||||
|
File.Delete(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ExportSql(string filename, bool zipFile) {
|
public static async Task ExportSql(string filename, bool zipFile) {
|
||||||
|
var tmp = filename + ".tmp";
|
||||||
|
try {
|
||||||
|
File.Delete(tmp);
|
||||||
if (zipFile) {
|
if (zipFile) {
|
||||||
File.Delete(filename);
|
using var zip = ZipFile.Open(tmp, ZipArchiveMode.Create);
|
||||||
using var zip = ZipFile.Open(filename, ZipArchiveMode.Create);
|
|
||||||
|
|
||||||
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
||||||
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
||||||
@@ -82,10 +90,14 @@ namespace Elwig.Helpers.Export {
|
|||||||
await ExportSql(writer);
|
await ExportSql(writer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
using var stream = File.OpenWrite(filename);
|
using var stream = File.OpenWrite(tmp);
|
||||||
using var writer = new StreamWriter(stream, Utils.UTF8);
|
using var writer = new StreamWriter(stream, Utils.UTF8);
|
||||||
await ExportSql(writer);
|
await ExportSql(writer);
|
||||||
}
|
}
|
||||||
|
File.Move(tmp, filename, true);
|
||||||
|
} finally {
|
||||||
|
File.Delete(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ExportSql(StreamWriter writer) {
|
public static async Task ExportSql(StreamWriter writer) {
|
||||||
@@ -200,7 +212,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task ImportSqlite(string filename, bool zipFile = false) {
|
public static async Task ImportSqlite(string filename, bool zipFile = false, bool keepSource = true) {
|
||||||
if (zipFile) {
|
if (zipFile) {
|
||||||
var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
|
var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
|
||||||
try {
|
try {
|
||||||
@@ -209,7 +221,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
foreach (var entry in zip.Entries) {
|
foreach (var entry in zip.Entries) {
|
||||||
if (entry.Name.EndsWith(".sqlite3")) {
|
if (entry.Name.EndsWith(".sqlite3")) {
|
||||||
entry.ExtractToFile(newName);
|
entry.ExtractToFile(newName);
|
||||||
await ImportSqlite(newName);
|
await ImportSqlite(newName, keepSource: false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,7 +233,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
|
var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
|
||||||
File.Move(App.Config.DatabaseFile, oldName, true);
|
File.Move(App.Config.DatabaseFile, oldName, true);
|
||||||
|
if (keepSource) {
|
||||||
|
File.Copy(filename, App.Config.DatabaseFile, false);
|
||||||
|
} else {
|
||||||
File.Move(filename, App.Config.DatabaseFile, false);
|
File.Move(filename, App.Config.DatabaseFile, false);
|
||||||
|
}
|
||||||
|
|
||||||
using var cnx = await AppDbContext.ConnectAsync();
|
using var cnx = await AppDbContext.ConnectAsync();
|
||||||
await cnx.ExecuteBatch("VACUUM");
|
await cnx.ExecuteBatch("VACUUM");
|
||||||
@@ -234,7 +250,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
using (var cnx = await AppDbContext.ConnectAsync($"Data Source=\"{newName}\"; Mode=ReadWriteCreate; Foreign Keys=False; Cache=Default; Pooling=False")) {
|
using (var cnx = await AppDbContext.ConnectAsync($"Data Source=\"{newName}\"; Mode=ReadWriteCreate; Foreign Keys=False; Cache=Default; Pooling=False")) {
|
||||||
await cnx.ExecuteBatch(await reader.ReadToEndAsync());
|
await cnx.ExecuteBatch(await reader.ReadToEndAsync());
|
||||||
}
|
}
|
||||||
await ImportSqlite(newName);
|
await ImportSqlite(newName, keepSource: false);
|
||||||
} finally {
|
} finally {
|
||||||
if (File.Exists(newName)) File.Delete(newName);
|
if (File.Exists(newName)) File.Delete(newName);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ using System.Security;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
namespace Elwig.Helpers.Export {
|
||||||
public class Ebics(PaymentVar variant, string filename, int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) : IBankingExporter {
|
public class Ebics(PaymentVar variant, string filename, int version, Ebics.AddressMode mode = Ebics.AddressMode.Full) : IExporter<Transaction> {
|
||||||
|
|
||||||
public enum AddressMode { Omit = 0, Lines = 1, Full = 2 }
|
public enum AddressMode { Omit = 0, Lines = 1, Full = 2 }
|
||||||
|
|
||||||
@@ -28,15 +28,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
Writer.Dispose();
|
Writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask DisposeAsync() {
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
return Writer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Export(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
|
||||||
ExportAsync(transactions, progress).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExportAsync(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
public async Task ExportAsync(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
||||||
if (transactions.Any(tx => tx.Amount < 0)) {
|
if (transactions.Any(tx => tx.Amount < 0)) {
|
||||||
throw new ArgumentException("Tranaction amount may not be negative");
|
throw new ArgumentException("Tranaction amount may not be negative");
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
using Elwig.Models.Dtos;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
|
||||||
public class Elba : Csv<Transaction>, IBankingExporter {
|
|
||||||
|
|
||||||
public static new string FileExtension => "elba";
|
|
||||||
|
|
||||||
public Elba(string filename) : base(filename) { }
|
|
||||||
|
|
||||||
public override string FormatRow(Transaction row) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,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 {
|
||||||
@@ -36,14 +35,16 @@ namespace Elwig.Helpers.Export {
|
|||||||
public static async Task Import(IEnumerable<string> filenames, ImportMode mode) {
|
public static async Task Import(IEnumerable<string> filenames, ImportMode mode) {
|
||||||
try {
|
try {
|
||||||
Dictionary<string, Branch> branches;
|
Dictionary<string, Branch> branches;
|
||||||
|
Dictionary<int, AT_Kg> kgs;
|
||||||
Dictionary<int, int> currentDids;
|
Dictionary<int, int> currentDids;
|
||||||
Dictionary<string, int> currentLsNrs;
|
Dictionary<string, int> currentLsNrs;
|
||||||
Dictionary<int, List<WbRd>> currentWbRde;
|
Dictionary<int, List<WbRd>> currentWbRde;
|
||||||
Dictionary<int, AT_Kg> kgs;
|
Dictionary<int, WbKg> currentWbKgs;
|
||||||
List<WbGl> currentWbGls;
|
List<WbGl> currentWbGls;
|
||||||
|
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
branches = await ctx.FetchBranches().ToDictionaryAsync(b => b.ZwstId);
|
branches = await ctx.FetchBranches().ToDictionaryAsync(b => b.ZwstId);
|
||||||
|
kgs = await ctx.Katastralgemeinden.ToDictionaryAsync(k => k.KgNr);
|
||||||
currentDids = await ctx.Deliveries
|
currentDids = await ctx.Deliveries
|
||||||
.GroupBy(d => d.Year)
|
.GroupBy(d => d.Year)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.Max(d => d.DId));
|
.ToDictionaryAsync(g => g.Key, g => g.Max(d => d.DId));
|
||||||
@@ -52,8 +53,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
currentWbRde = await ctx.WbRde
|
currentWbRde = await ctx.WbRde
|
||||||
.GroupBy(r => r.KgNr)
|
.GroupBy(r => r.KgNr)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.ToList());
|
.ToDictionaryAsync(g => g.Key, g => g.ToList());
|
||||||
|
currentWbKgs = await ctx.WbKgs.ToDictionaryAsync(k => k.KgNr);
|
||||||
currentWbGls = await ctx.WbGls.ToListAsync();
|
currentWbGls = await ctx.WbGls.ToListAsync();
|
||||||
kgs = await ctx.Katastralgemeinden.Include(k => k.WbKg).ToDictionaryAsync(k => k.KgNr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = new List<(
|
var data = new List<(
|
||||||
@@ -62,8 +63,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
List<MemberTelNr> TelephoneNumbers,
|
List<MemberTelNr> TelephoneNumbers,
|
||||||
List<MemberEmailAddr> EmailAddresses,
|
List<MemberEmailAddr> EmailAddresses,
|
||||||
List<MemberHistory> MemberHistory,
|
List<MemberHistory> MemberHistory,
|
||||||
List<AreaCom> AreaCommitments,
|
List<AreaCmt> AreaCommitments,
|
||||||
List<AreaComContract> Contracts,
|
List<AreaCmtContract> Contracts,
|
||||||
List<WbRd> Riede,
|
List<WbRd> Riede,
|
||||||
List<WbKg> WbKgs,
|
List<WbKg> WbKgs,
|
||||||
List<WbGl> WbGls,
|
List<WbGl> WbGls,
|
||||||
@@ -74,7 +75,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
var metaData = new List<(string FileName, string ZwstId, string Device,
|
var metaData = new List<(string FileName, string ZwstId, string Device,
|
||||||
int? MemberNum, string? MemberFilters,
|
int? MemberNum, string? MemberFilters,
|
||||||
int? AreaComNum, string? AreaComFilters,
|
int? AreaCmtNum, string? AreaCmtFilters,
|
||||||
int? DeliveryNum, string? DeliveryFilters)>();
|
int? DeliveryNum, string? DeliveryFilters)>();
|
||||||
|
|
||||||
foreach (var filename in filenames) {
|
foreach (var filename in filenames) {
|
||||||
@@ -104,14 +105,14 @@ namespace Elwig.Helpers.Export {
|
|||||||
var meta = await JsonNode.ParseAsync(metaJson!.Open());
|
var meta = await JsonNode.ParseAsync(metaJson!.Open());
|
||||||
var memberCount = meta!["members"]?["count"]?.AsValue().GetValue<int>();
|
var memberCount = meta!["members"]?["count"]?.AsValue().GetValue<int>();
|
||||||
var memberFilters = meta!["members"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
var memberFilters = meta!["members"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||||
var areaComCount = meta!["area_commitment_contracts"]?["count"]?.AsValue().GetValue<int>();
|
var areaCmtCount = meta!["area_commitment_contracts"]?["count"]?.AsValue().GetValue<int>();
|
||||||
var areaComFilters = meta!["area_commitment_contracts"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
var areaCmtFilters = meta!["area_commitment_contracts"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||||
var deliveryCount = meta!["deliveries"]?["count"]?.AsValue().GetValue<int>();
|
var deliveryCount = meta!["deliveries"]?["count"]?.AsValue().GetValue<int>();
|
||||||
var deliveryFilters = meta!["deliveries"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
var deliveryFilters = meta!["deliveries"]?["filters"]?.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
||||||
metaData.Add((Path.GetFileName(filename),
|
metaData.Add((Path.GetFileName(filename),
|
||||||
meta["zwstid"]!.AsValue().GetValue<string>(), meta["device"]!.AsValue().GetValue<string>(),
|
meta["zwstid"]!.AsValue().GetValue<string>(), meta["device"]!.AsValue().GetValue<string>(),
|
||||||
memberCount, memberFilters != null ? string.Join(" / ", memberFilters) : null,
|
memberCount, memberFilters != null ? string.Join(" / ", memberFilters) : null,
|
||||||
areaComCount, areaComFilters != null ? string.Join(" / ", areaComFilters) : null,
|
areaCmtCount, areaCmtFilters != null ? string.Join(" / ", areaCmtFilters) : null,
|
||||||
deliveryCount, deliveryFilters != null ? string.Join(" / ", deliveryFilters) : null));
|
deliveryCount, deliveryFilters != null ? string.Join(" / ", deliveryFilters) : null));
|
||||||
|
|
||||||
var wbKgsJson = zip.GetEntry("wb_kgs.json");
|
var wbKgsJson = zip.GetEntry("wb_kgs.json");
|
||||||
@@ -122,6 +123,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (k, g) = obj.ToWbKg(currentWbGls);
|
var (k, g) = obj.ToWbKg(currentWbGls);
|
||||||
r.WbKgs.Add(k);
|
r.WbKgs.Add(k);
|
||||||
|
currentWbKgs[k.KgNr] = k;
|
||||||
if (g != null) {
|
if (g != null) {
|
||||||
currentWbGls[g.GlNr] = g;
|
currentWbGls[g.GlNr] = g;
|
||||||
r.WbGls.Add(g);
|
r.WbGls.Add(g);
|
||||||
@@ -135,7 +137,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
string? line;
|
string? line;
|
||||||
while ((line = await reader.ReadLineAsync()) != null) {
|
while ((line = await reader.ReadLineAsync()) != null) {
|
||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (m, b, telNrs, emailAddrs, timestamps) = obj.ToMember(kgs);
|
var (m, b, telNrs, emailAddrs, timestamps) = obj.ToMember(kgs, currentWbKgs);
|
||||||
r.Members.Add(m);
|
r.Members.Add(m);
|
||||||
if (b != null) r.BillingAddresses.Add(b);
|
if (b != null) r.BillingAddresses.Add(b);
|
||||||
r.TelephoneNumbers.AddRange(telNrs);
|
r.TelephoneNumbers.AddRange(telNrs);
|
||||||
@@ -157,21 +159,21 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// legacy area commitments
|
// legacy area commitments
|
||||||
var areaComsJson = zip.GetEntry("area_commitments.json");
|
var areaCmtsJson = zip.GetEntry("area_commitments.json");
|
||||||
if (areaComsJson != null) {
|
if (areaCmtsJson != null) {
|
||||||
using var reader = new StreamReader(areaComsJson.Open(), Utils.UTF8);
|
using var reader = new StreamReader(areaCmtsJson.Open(), Utils.UTF8);
|
||||||
string? line;
|
string? line;
|
||||||
while ((line = await reader.ReadLineAsync()) != null) {
|
while ((line = await reader.ReadLineAsync()) != null) {
|
||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (contract, areaCom, wbrd, timestamps) = obj.ToAreaCom(currentWbRde);
|
var (contract, areaCmt, wbrd, timestamps) = obj.ToAreaCmt(kgs, currentWbKgs, currentWbRde);
|
||||||
r.Contracts.Add(contract);
|
r.Contracts.Add(contract);
|
||||||
r.AreaCommitments.Add(areaCom);
|
r.AreaCommitments.Add(areaCmt);
|
||||||
if (wbrd != null) {
|
if (wbrd != null) {
|
||||||
r.Riede.Add(wbrd);
|
r.Riede.Add(wbrd);
|
||||||
}
|
}
|
||||||
if (timestamps.HasValue) {
|
if (timestamps.HasValue) {
|
||||||
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
r.Timestamps["area_commitment"].Add((areaCom.FbNr, areaCom.RevNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
r.Timestamps["area_commitment"].Add((areaCmt.FbNr, areaCmt.RevNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,17 +184,17 @@ namespace Elwig.Helpers.Export {
|
|||||||
string? line;
|
string? line;
|
||||||
while ((line = await reader.ReadLineAsync()) != null) {
|
while ((line = await reader.ReadLineAsync()) != null) {
|
||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (contract, areaComs, wbrd, timestamps) = obj.ToAreaComContract(currentWbRde);
|
var (contract, areaCmts, wbrd, timestamps) = obj.ToAreaCmtContract(kgs, currentWbKgs, currentWbRde);
|
||||||
r.Contracts.Add(contract);
|
r.Contracts.Add(contract);
|
||||||
r.AreaCommitments.AddRange(areaComs.Select(v => v.Item1));
|
r.AreaCommitments.AddRange(areaCmts.Select(v => v.Item1));
|
||||||
if (wbrd != null) {
|
if (wbrd != null) {
|
||||||
r.Riede.Add(wbrd);
|
r.Riede.Add(wbrd);
|
||||||
}
|
}
|
||||||
if (timestamps.HasValue)
|
if (timestamps.HasValue)
|
||||||
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
r.Timestamps["area_commitment_contract"].Add((contract.FbNr, 0, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
|
||||||
foreach (var (areaCom, ts) in areaComs) {
|
foreach (var (areaCmt, ts) in areaCmts) {
|
||||||
if (!ts.HasValue) continue;
|
if (!ts.HasValue) continue;
|
||||||
r.Timestamps["area_commitment"].Add((areaCom.FbNr, areaCom.RevNr, 0, ts.Value.CreatedAt, ts.Value.ModifiedAt));
|
r.Timestamps["area_commitment"].Add((areaCmt.FbNr, areaCmt.RevNr, 0, ts.Value.CreatedAt, ts.Value.ModifiedAt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -203,7 +205,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
string? line;
|
string? line;
|
||||||
while ((line = await reader.ReadLineAsync()) != null) {
|
while ((line = await reader.ReadLineAsync()) != null) {
|
||||||
var obj = JsonNode.Parse(line)!.AsObject();
|
var obj = JsonNode.Parse(line)!.AsObject();
|
||||||
var (d, parts, mods, rde, timestamps) = obj.ToDelivery(currentLsNrs, currentDids, kgs, currentWbRde);
|
var (d, parts, mods, rde, timestamps) = obj.ToDelivery(currentLsNrs, currentDids, kgs, currentWbKgs, currentWbRde);
|
||||||
r.Deliveries.Add(d);
|
r.Deliveries.Add(d);
|
||||||
r.DeliveryParts.AddRange(parts.Select(p => p.Item1));
|
r.DeliveryParts.AddRange(parts.Select(p => p.Item1));
|
||||||
r.Modifiers.AddRange(mods);
|
r.Modifiers.AddRange(mods);
|
||||||
@@ -233,7 +235,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var importedMembers = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string? Filters)>();
|
var importedMembers = 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 importedAreaCmts = 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, history, 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)) {
|
||||||
@@ -363,7 +365,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
ctx.AddRange(riede);
|
ctx.AddRange(riede);
|
||||||
var n = importNewContracts ? contracts.Count - duplicateFbNrs.Count : 0;
|
var n = importNewContracts ? contracts.Count - duplicateFbNrs.Count : 0;
|
||||||
var o = importDuplicateContracts ? duplicateFbNrs.Count : 0;
|
var o = importDuplicateContracts ? duplicateFbNrs.Count : 0;
|
||||||
importedAreaComs.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, contracts.Count - n - o, meta.AreaComFilters));
|
importedAreaCmts.Add((meta.FileName, meta.ZwstId, meta.Device, n, o, contracts.Count - n - o, meta.AreaCmtFilters));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowedDuplicateLsNrs.Count > 0) {
|
if (allowedDuplicateLsNrs.Count > 0) {
|
||||||
@@ -445,8 +447,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
$" ({d.New} neu, {d.Overwritten} überschrieben, {d.NotImported} nicht importiert)\n" +
|
$" ({d.New} neu, {d.Overwritten} überschrieben, {d.NotImported} nicht importiert)\n" +
|
||||||
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
||||||
$" Filter: {d.Filters}"),
|
$" Filter: {d.Filters}"),
|
||||||
$"Flächenbindungen: {importedAreaComs.Sum(d => d.New + d.Overwritten)}",
|
$"Flächenbindungen: {importedAreaCmts.Sum(d => d.New + d.Overwritten)}",
|
||||||
..importedAreaComs.Select(d =>
|
..importedAreaCmts.Select(d =>
|
||||||
$" {d.FileName} ({d.New + d.Overwritten})\n" +
|
$" {d.FileName} ({d.New + d.Overwritten})\n" +
|
||||||
$" ({d.New} importiert, {d.Overwritten} überschreiben, {d.NotImported} nicht importiert)\n" +
|
$" ({d.New} importiert, {d.Overwritten} überschreiben, {d.NotImported} nicht importiert)\n" +
|
||||||
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
$" Zweigstelle: {branches[d.ZwstId].Name} (Gerät {d.Device})\n" +
|
||||||
@@ -479,11 +481,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
}.Export(filename);
|
}.Export(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<AreaComContract> areaComs, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
|
public static Task Export(string filename, IEnumerable<Member> members, IEnumerable<MemberHistory> history, IEnumerable<AreaCmtContract> areaCmts, IEnumerable<WbKg> wbKgs, IEnumerable<string> filters) {
|
||||||
return new ElwigExport {
|
return new ElwigExport {
|
||||||
Members = (members, filters),
|
Members = (members, filters),
|
||||||
History = (history, ["von exportierten Mitgliedern"]),
|
History = (history, ["von exportierten Mitgliedern"]),
|
||||||
AreaComs = (areaComs, ["von exportierten Mitgliedern"]),
|
AreaCmts = (areaCmts, ["von exportierten Mitgliedern"]),
|
||||||
WbKgs = (wbKgs, ["von exportierten Mitgliedern und Flächenbindungen"]),
|
WbKgs = (wbKgs, ["von exportierten Mitgliedern und Flächenbindungen"]),
|
||||||
}.Export(filename);
|
}.Export(filename);
|
||||||
}
|
}
|
||||||
@@ -499,7 +501,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
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<MemberHistory> History, IEnumerable<string> Filters)? History { get; set; }
|
||||||
public (IEnumerable<AreaComContract> AreaComs, IEnumerable<string> Filters)? AreaComs { get; set; }
|
public (IEnumerable<AreaCmtContract> AreaCmts, IEnumerable<string> Filters)? AreaCmts { get; set; }
|
||||||
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
|
public (IEnumerable<Delivery> Deliveries, IEnumerable<string> Filters)? Deliveries { get; set; }
|
||||||
|
|
||||||
public async Task Export(string filename) {
|
public async Task Export(string filename) {
|
||||||
@@ -533,11 +535,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
["count"] = History.Value.History.Count(),
|
["count"] = History.Value.History.Count(),
|
||||||
["filters"] = new JsonArray(History.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
["filters"] = new JsonArray(History.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||||
};
|
};
|
||||||
if (AreaComs != null)
|
if (AreaCmts != null)
|
||||||
obj["area_commitment_contracts"] = new JsonObject {
|
obj["area_commitment_contracts"] = new JsonObject {
|
||||||
["count"] = AreaComs.Value.AreaComs.Count(),
|
["count"] = AreaCmts.Value.AreaCmts.Count(),
|
||||||
["revisions"] = AreaComs.Value.AreaComs.Sum(c => c.Revisions.Count),
|
["revisions"] = AreaCmts.Value.AreaCmts.Sum(c => c.Revisions.Count),
|
||||||
["filters"] = new JsonArray(AreaComs.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
["filters"] = new JsonArray(AreaCmts.Value.Filters.Select(f => (JsonNode)f).ToArray()),
|
||||||
};
|
};
|
||||||
if (Deliveries != null)
|
if (Deliveries != null)
|
||||||
obj["deliveries"] = new JsonObject {
|
obj["deliveries"] = new JsonObject {
|
||||||
@@ -570,10 +572,10 @@ namespace Elwig.Helpers.Export {
|
|||||||
await writer.WriteLineAsync(h.ToJson().ToJsonString(Utils.JsonOpts));
|
await writer.WriteLineAsync(h.ToJson().ToJsonString(Utils.JsonOpts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (AreaComs != null) {
|
if (AreaCmts != 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);
|
||||||
foreach (var c in AreaComs.Value.AreaComs) {
|
foreach (var c in AreaCmts.Value.AreaCmts) {
|
||||||
await writer.WriteLineAsync(c.ToJson().ToJsonString(Utils.JsonOpts));
|
await writer.WriteLineAsync(c.ToJson().ToJsonString(Utils.JsonOpts));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,11 +638,13 @@ namespace Elwig.Helpers.Export {
|
|||||||
["zwstid"] = m.ZwstId,
|
["zwstid"] = m.ZwstId,
|
||||||
["lfbis_nr"] = m.LfbisNr,
|
["lfbis_nr"] = m.LfbisNr,
|
||||||
["ustid_nr"] = m.UstIdNr,
|
["ustid_nr"] = m.UstIdNr,
|
||||||
|
["ooc_id"] = m.OrganicOperatorId,
|
||||||
|
["org_auth_code"] = m.OrganicAuthorityCode,
|
||||||
["juridical_pers"] = m.IsJuridicalPerson,
|
["juridical_pers"] = m.IsJuridicalPerson,
|
||||||
["volllieferant"] = m.IsVollLieferant,
|
["full_delivery"] = m.IsFullDelivery,
|
||||||
["buchführend"] = m.IsBuchführend,
|
["accounting"] = m.IsAccounting,
|
||||||
["organic"] = m.IsOrganic,
|
["organic"] = m.IsOrganic,
|
||||||
["funktionär"] = m.IsFunktionär,
|
["officer"] = m.IsOfficer,
|
||||||
["active"] = m.IsActive,
|
["active"] = m.IsActive,
|
||||||
["deceased"] = m.IsDeceased,
|
["deceased"] = m.IsDeceased,
|
||||||
["iban"] = m.Iban,
|
["iban"] = m.Iban,
|
||||||
@@ -680,11 +684,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (Member, BillingAddr?, List<MemberTelNr>, List<MemberEmailAddr>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToMember(this JsonNode json, Dictionary<int, AT_Kg> kgs) {
|
public static (Member, BillingAddr?, List<MemberTelNr>, List<MemberEmailAddr>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToMember(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs) {
|
||||||
var mgnr = json["mgnr"]!.AsValue().GetValue<int>();
|
var mgnr = json["mgnr"]!.AsValue().GetValue<int>();
|
||||||
var kgnr = json["default_kgnr"]?.AsValue().GetValue<int>();
|
var kgnr = json["default_kgnr"]?.AsValue().GetValue<int>();
|
||||||
if (kgnr != null && !kgs.Values.Any(k => k.WbKg?.KgNr == kgnr)) {
|
if (kgnr != null && !currentWbKgs.Values.Any(k => k.KgNr == kgnr)) {
|
||||||
throw new ArgumentException($"Für KG {(kgs.TryGetValue(kgnr.Value, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten → Herkunftshierarchie)");
|
throw new KeyNotFoundException($"Für KG {(kgs.TryGetValue(kgnr.Value, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten \u2192 Herkunftshierarchie)");
|
||||||
}
|
}
|
||||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
@@ -708,11 +712,13 @@ namespace Elwig.Helpers.Export {
|
|||||||
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>(),
|
||||||
UstIdNr = json["ustid_nr"]?.AsValue().GetValue<string>(),
|
UstIdNr = json["ustid_nr"]?.AsValue().GetValue<string>(),
|
||||||
|
OrganicOperatorId = json["ooc_id"]?.AsValue().GetValue<string>(),
|
||||||
|
OrganicAuthorityCode = json["org_auth_code"]?.AsValue().GetValue<string>(),
|
||||||
IsJuridicalPerson = json["juridical_pers"]?.AsValue().GetValue<bool>() ?? false,
|
IsJuridicalPerson = json["juridical_pers"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsVollLieferant = json["volllieferant"]?.AsValue().GetValue<bool>() ?? false,
|
IsFullDelivery = json["full_delivery"]?.AsValue().GetValue<bool>() ?? json["volllieferant"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsBuchführend = json["buchführend"]?.AsValue().GetValue<bool>() ?? false,
|
IsAccounting = json["accounting"]?.AsValue().GetValue<bool>() ?? json["buchführend"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsOrganic = json["organic"]?.AsValue().GetValue<bool>() ?? false,
|
IsOrganic = json["organic"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsFunktionär = json["funktionär"]?.AsValue().GetValue<bool>() ?? false,
|
IsOfficer = json["officer"]?.AsValue().GetValue<bool>() ?? json["funktionär"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsActive = json["active"]?.AsValue().GetValue<bool>() ?? false,
|
IsActive = json["active"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsDeceased = json["deceased"]?.AsValue().GetValue<bool>() ?? false,
|
IsDeceased = json["deceased"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
Iban = json["iban"]?.AsValue().GetValue<string>(),
|
Iban = json["iban"]?.AsValue().GetValue<string>(),
|
||||||
@@ -760,7 +766,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
["reason"] = h.Reason,
|
["reason"] = h.Reason,
|
||||||
["source"] = h.Source,
|
["source"] = h.Source,
|
||||||
["shares"] = h.Shares,
|
["shares"] = h.Shares,
|
||||||
["signed"] = h.MemberHasSigned,
|
["signed_company"] = h.CompanyHasSigned,
|
||||||
|
["signed_member"] = h.MemberHasSigned,
|
||||||
["value_per_share"] = h.ValuePerShare,
|
["value_per_share"] = h.ValuePerShare,
|
||||||
["currency"] = h.CurrencyCode,
|
["currency"] = h.CurrencyCode,
|
||||||
["deduct_year"] = h.DeductYear,
|
["deduct_year"] = h.DeductYear,
|
||||||
@@ -780,7 +787,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
Reason = json["reason"]!.AsValue().GetValue<string>(),
|
Reason = json["reason"]!.AsValue().GetValue<string>(),
|
||||||
Source = json["source"]!.AsValue().GetValue<string>(),
|
Source = json["source"]!.AsValue().GetValue<string>(),
|
||||||
Shares = json["shares"]!.AsValue().GetValue<int>(),
|
Shares = json["shares"]!.AsValue().GetValue<int>(),
|
||||||
MemberHasSigned = json["signed"]?.AsValue().GetValue<bool>() ?? false,
|
CompanyHasSigned = json["signed_company"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
|
MemberHasSigned = json["signed_member"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
ValuePerShare = json["value_per_share"]?.AsValue().GetValue<decimal>(),
|
ValuePerShare = json["value_per_share"]?.AsValue().GetValue<decimal>(),
|
||||||
CurrencyCode = json["currency"]?.AsValue().GetValue<string>(),
|
CurrencyCode = json["currency"]?.AsValue().GetValue<string>(),
|
||||||
DeductYear = json["deduct_year"]?.AsValue().GetValue<int>(),
|
DeductYear = json["deduct_year"]?.AsValue().GetValue<int>(),
|
||||||
@@ -788,7 +796,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JsonObject ToJson(this AreaComContract c) {
|
public static JsonObject ToJson(this AreaCmtContract c) {
|
||||||
return new JsonObject {
|
return new JsonObject {
|
||||||
["fbnr"] = c.FbNr,
|
["fbnr"] = c.FbNr,
|
||||||
["kgnr"] = c.KgNr,
|
["kgnr"] = c.KgNr,
|
||||||
@@ -800,7 +808,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static JsonObject ToJson(this AreaCom c) {
|
private static JsonObject ToJson(this AreaCmt c) {
|
||||||
return new JsonObject {
|
return new JsonObject {
|
||||||
["revnr"] = c.RevNr,
|
["revnr"] = c.RevNr,
|
||||||
["mgnr"] = c.MgNr,
|
["mgnr"] = c.MgNr,
|
||||||
@@ -815,10 +823,13 @@ namespace Elwig.Helpers.Export {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (AreaComContract, List<(AreaCom, (DateTime CreatedAt, DateTime ModifiedAt)?)>, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaComContract(this JsonNode json, Dictionary<int, List<WbRd>> riede) {
|
public static (AreaCmtContract, List<(AreaCmt, (DateTime CreatedAt, DateTime ModifiedAt)?)>, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCmtContract(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||||
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
||||||
var ried = json["ried"]?.AsValue().GetValue<string>();
|
var ried = json["ried"]?.AsValue().GetValue<string>();
|
||||||
var fbnr = json["fbnr"]!.AsValue()!.GetValue<int>();
|
var fbnr = json["fbnr"]!.AsValue()!.GetValue<int>();
|
||||||
|
if (!currentWbKgs.Values.Any(k => k.KgNr == kgnr)) {
|
||||||
|
throw new KeyNotFoundException($"Für KG {(kgs.TryGetValue(kgnr, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten \u2192 Herkunftshierarchie)");
|
||||||
|
}
|
||||||
WbRd? rd = null;
|
WbRd? rd = null;
|
||||||
bool newRd = false;
|
bool newRd = false;
|
||||||
if (ried != null) {
|
if (ried != null) {
|
||||||
@@ -837,16 +848,16 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
return (new AreaComContract {
|
return (new AreaCmtContract {
|
||||||
FbNr = fbnr,
|
FbNr = fbnr,
|
||||||
KgNr = kgnr,
|
KgNr = kgnr,
|
||||||
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
||||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||||
ImportedAt = DateTime.Now,
|
ImportedAt = DateTime.Now,
|
||||||
}, [.. json["revisions"]!.AsArray().Select(r => r!.AsObject()).Select<JsonObject, (AreaCom, (DateTime, DateTime)?)>(r => {
|
}, [.. json["revisions"]!.AsArray().Select(r => r!.AsObject()).Select<JsonObject, (AreaCmt, (DateTime, DateTime)?)>(r => {
|
||||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
return (new AreaCom {
|
return (new AreaCmt {
|
||||||
FbNr = fbnr,
|
FbNr = fbnr,
|
||||||
RevNr = r["revnr"]!.AsValue().GetValue<int>(),
|
RevNr = r["revnr"]!.AsValue().GetValue<int>(),
|
||||||
MgNr = r["mgnr"]!.AsValue().GetValue<int>(),
|
MgNr = r["mgnr"]!.AsValue().GetValue<int>(),
|
||||||
@@ -866,9 +877,12 @@ 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 (AreaComContract, AreaCom, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCom(this JsonNode json, Dictionary<int, List<WbRd>> riede) {
|
public static (AreaCmtContract, AreaCmt, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCmt(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||||
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
|
||||||
var ried = json["ried"]?.AsValue().GetValue<string>();
|
var ried = json["ried"]?.AsValue().GetValue<string>();
|
||||||
|
if (!currentWbKgs.Values.Any(k => k.KgNr == kgnr)) {
|
||||||
|
throw new KeyNotFoundException($"Für KG {(kgs.TryGetValue(kgnr, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten \u2192 Herkunftshierarchie)");
|
||||||
|
}
|
||||||
WbRd? rd = null;
|
WbRd? rd = null;
|
||||||
bool newRd = false;
|
bool newRd = false;
|
||||||
if (ried != null) {
|
if (ried != null) {
|
||||||
@@ -887,13 +901,13 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
|
||||||
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
|
||||||
return (new AreaComContract {
|
return (new AreaCmtContract {
|
||||||
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
||||||
KgNr = kgnr,
|
KgNr = kgnr,
|
||||||
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
RdNr = rd?.RdNr ?? json["rdnr"]?.AsValue().GetValue<int>(),
|
||||||
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
||||||
ImportedAt = DateTime.Now,
|
ImportedAt = DateTime.Now,
|
||||||
}, new AreaCom {
|
}, new AreaCmt {
|
||||||
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
|
||||||
RevNr = 1,
|
RevNr = 1,
|
||||||
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
||||||
@@ -947,7 +961,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
};
|
};
|
||||||
if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck;
|
if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck;
|
||||||
if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked;
|
if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked;
|
||||||
if (p.IsGebunden != null) obj["gebunden"] = p.IsGebunden;
|
if (p.IsContracted != null) obj["contracted"] = p.IsContracted;
|
||||||
if (p.Unloading != null) obj["unloading"] = p.Unloading;
|
if (p.Unloading != null) obj["unloading"] = p.Unloading;
|
||||||
if (p.Temperature != null) obj["temperature"] = p.Temperature;
|
if (p.Temperature != null) obj["temperature"] = p.Temperature;
|
||||||
if (p.Acid != null) obj["acid"] = p.Acid;
|
if (p.Acid != null) obj["acid"] = p.Acid;
|
||||||
@@ -957,7 +971,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (Delivery, List<(DeliveryPart, (DateTime CreatedAt, DateTime ModifiedAt)?)>, List<DeliveryPartModifier>, List<WbRd>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToDelivery(this JsonNode json, Dictionary<string, int> currentLsNrs, Dictionary<int, int> currentDids, Dictionary<int, AT_Kg> kgs, Dictionary<int, List<WbRd>> riede) {
|
public static (Delivery, List<(DeliveryPart, (DateTime CreatedAt, DateTime ModifiedAt)?)>, List<DeliveryPartModifier>, List<WbRd>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToDelivery(this JsonNode json, Dictionary<string, int> currentLsNrs, Dictionary<int, int> currentDids, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, Dictionary<int, List<WbRd>> riede) {
|
||||||
var year = json["year"]!.AsValue().GetValue<int>();
|
var year = json["year"]!.AsValue().GetValue<int>();
|
||||||
var lsnr = json["lsnr"]!.AsValue().GetValue<string>();
|
var lsnr = json["lsnr"]!.AsValue().GetValue<string>();
|
||||||
var did = currentLsNrs.GetValueOrDefault(lsnr, -1);
|
var did = currentLsNrs.GetValueOrDefault(lsnr, -1);
|
||||||
@@ -983,6 +997,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
}, [.. json["parts"]!.AsArray().Select(p => p!.AsObject()).Select<JsonObject, (DeliveryPart, (DateTime, DateTime)?)>(p => {
|
}, [.. json["parts"]!.AsArray().Select(p => p!.AsObject()).Select<JsonObject, (DeliveryPart, (DateTime, DateTime)?)>(p => {
|
||||||
var kgnr = p["kgnr"]?.AsValue().GetValue<int>();
|
var kgnr = p["kgnr"]?.AsValue().GetValue<int>();
|
||||||
var ried = p["ried"]?.AsValue().GetValue<string>();
|
var ried = p["ried"]?.AsValue().GetValue<string>();
|
||||||
|
if (kgnr != null && !currentWbKgs.Values.Any(k => k.KgNr == kgnr)) {
|
||||||
|
throw new KeyNotFoundException($"Für KG {(kgs.TryGetValue(kgnr.Value, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten \u2192 Herkunftshierarchie)");
|
||||||
|
}
|
||||||
WbRd? rd = null;
|
WbRd? rd = null;
|
||||||
if (ried != null && kgnr != null) {
|
if (ried != null && kgnr != null) {
|
||||||
var rde = riede.GetValueOrDefault(kgnr.Value, []);
|
var rde = riede.GetValueOrDefault(kgnr.Value, []);
|
||||||
@@ -1018,7 +1035,7 @@ namespace Elwig.Helpers.Export {
|
|||||||
Comment = p["comment"]?.AsValue().GetValue<string>(),
|
Comment = p["comment"]?.AsValue().GetValue<string>(),
|
||||||
IsSplCheck = p["spl_check"]?.AsValue().GetValue<bool>() ?? false,
|
IsSplCheck = p["spl_check"]?.AsValue().GetValue<bool>() ?? false,
|
||||||
IsHandPicked = p["hand_picked"]?.AsValue().GetValue<bool>(),
|
IsHandPicked = p["hand_picked"]?.AsValue().GetValue<bool>(),
|
||||||
IsGebunden = p["gebunden"]?.AsValue().GetValue<bool>(),
|
IsContracted = p["contracted"]?.AsValue().GetValue<bool>() ?? p["gebunden"]?.AsValue().GetValue<bool>(),
|
||||||
Unloading = p["unloading"]?.AsValue().GetValue<string>() ?? ((p["lesewagen"]?.AsValue().GetValue<bool>() ?? false) ? DeliveryPart.Pumped : null),
|
Unloading = p["unloading"]?.AsValue().GetValue<string>() ?? ((p["lesewagen"]?.AsValue().GetValue<bool>() ?? false) ? DeliveryPart.Pumped : null),
|
||||||
Temperature = p["temperature"]?.AsValue().GetValue<double>(),
|
Temperature = p["temperature"]?.AsValue().GetValue<double>(),
|
||||||
Acid = p["acid"]?.AsValue().GetValue<double>(),
|
Acid = p["acid"]?.AsValue().GetValue<double>(),
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
using Elwig.Models.Dtos;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for exporting banking data
|
|
||||||
/// </summary>
|
|
||||||
public interface IBankingExporter : IExporter<Transaction> { }
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Helpers.Export {
|
namespace Elwig.Helpers.Export {
|
||||||
public interface IExporter<T> : IDisposable, IAsyncDisposable {
|
public interface IExporter<T> : IDisposable {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The default file extension of the exported files to be used (whithout a preceding ".")
|
/// The default file extension of the exported files to be used (whithout a preceding ".")
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -14,7 +14,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="data">The data to be exported</param>
|
/// <param name="data">The data to be exported</param>
|
||||||
/// <param name="progress">The progress object to report to</param>
|
/// <param name="progress">The progress object to report to</param>
|
||||||
void Export(IEnumerable<T> data, IProgress<double>? progress = null);
|
void Export(IEnumerable<T> data, IProgress<double>? progress = null) {
|
||||||
|
ExportAsync(data, progress).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Asynchronosly export the given data to the given file.
|
/// Asynchronosly export the given data to the given file.
|
||||||
|
|||||||
@@ -109,8 +109,13 @@ namespace Elwig.Helpers.Export {
|
|||||||
<style:paragraph-properties fo:text-align="center"/>
|
<style:paragraph-properties fo:text-align="center"/>
|
||||||
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
||||||
</style:style>
|
</style:style>
|
||||||
|
<style:style style:name="sectionheader" style:family="table-cell" style:parent-style-name="default">
|
||||||
|
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false"/>
|
||||||
|
<style:paragraph-properties fo:text-align="left"/>
|
||||||
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold" fo:font-size="14pt"/>
|
||||||
|
</style:style>
|
||||||
<style:style style:name="th" style:family="table-cell" style:parent-style-name="default">
|
<style:style style:name="th" style:family="table-cell" style:parent-style-name="default">
|
||||||
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle"/>
|
<style:table-cell-properties style:text-align-source="fix" style:repeat-content="false" style:vertical-align="middle" fo:wrap-option="wrap"/>
|
||||||
<style:paragraph-properties fo:text-align="center"/>
|
<style:paragraph-properties fo:text-align="center"/>
|
||||||
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
<style:text-properties fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"/>
|
||||||
</style:style>
|
</style:style>
|
||||||
@@ -211,17 +216,39 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await Content.WriteAsync(
|
await Content.WriteAsync($"""
|
||||||
$" <table:table-row>\r\n" +
|
<table:table-row>
|
||||||
FormatCell(table.FullName, colSpan: totalSpan, style: "header") +
|
{FormatCell(table.FullName, colSpan: totalSpan, style: "header")}
|
||||||
$" </table:table-row>\r\n" +
|
</table:table-row>
|
||||||
$" <table:table-row>\r\n" +
|
<table:table-row>
|
||||||
FormatCell(table.Subtitle, colSpan: totalSpan, style: "subheader") +
|
{FormatCell(table.Subtitle, colSpan: totalSpan, style: "subheader")}
|
||||||
$" </table:table-row>\r\n" +
|
</table:table-row>
|
||||||
$" <table:table-row>\r\n" +
|
<table:table-row>
|
||||||
$" <table:table-cell table:number-columns-repeated=\"{totalSpan}\"/>\r\n" +
|
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||||
$" </table:table-row>\r\n" +
|
</table:table-row>
|
||||||
$" <table:table-row>\r\n");
|
""");
|
||||||
|
|
||||||
|
var firstSection = true;
|
||||||
|
foreach (var sec in table.GetData()) {
|
||||||
|
if (!firstSection) {
|
||||||
|
await Content.WriteAsync($"""
|
||||||
|
<table:table-row>
|
||||||
|
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||||
|
</table:table-row>
|
||||||
|
<table:table-row>
|
||||||
|
<table:table-cell table:number-columns-repeated="{totalSpan}"/>
|
||||||
|
</table:table-row>
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
if (sec.Name != null) {
|
||||||
|
await Content.WriteAsync($"""
|
||||||
|
<table:table-row>
|
||||||
|
{FormatCell(sec.Name, colSpan: totalSpan, style: "sectionheader")}
|
||||||
|
</table:table-row>
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
await Content.WriteAsync(" <table:table-row>\r\n");
|
||||||
foreach (var (name, span, units) in table.ColumnNames.Zip(table.ColumnSpans, table.ColumnUnits)) {
|
foreach (var (name, span, units) in table.ColumnNames.Zip(table.ColumnSpans, table.ColumnUnits)) {
|
||||||
var hasUnits = units.Length > 0;
|
var hasUnits = units.Length > 0;
|
||||||
await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
|
await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
|
||||||
@@ -238,9 +265,11 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
await Content.WriteAsync(" </table:table-row>\r\n");
|
await Content.WriteAsync(" </table:table-row>\r\n");
|
||||||
|
|
||||||
foreach (var row in table.GetData()) {
|
foreach (var row in sec.Rows) {
|
||||||
await FormatRow(row, table.ColumnUnits, mergeSubRowCells);
|
await FormatRow(row, table.ColumnUnits, mergeSubRowCells);
|
||||||
}
|
}
|
||||||
|
firstSection = false;
|
||||||
|
}
|
||||||
|
|
||||||
await Content.WriteAsync(" </table:table>\r\n");
|
await Content.WriteAsync(" </table:table>\r\n");
|
||||||
}
|
}
|
||||||
@@ -314,7 +343,8 @@ namespace Elwig.Helpers.Export {
|
|||||||
}
|
}
|
||||||
c = $"<{ct} office:value-type=\"float\" calcext:value-type=\"float\" office:value=\"{v.ToString(CultureInfo.InvariantCulture)}\"{add}><text:p>{data}</text:p></{ct}>";
|
c = $"<{ct} office:value-type=\"float\" calcext:value-type=\"float\" office:value=\"{v.ToString(CultureInfo.InvariantCulture)}\"{add}><text:p>{data}</text:p></{ct}>";
|
||||||
} else {
|
} else {
|
||||||
c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}><text:p>{SecurityElement.Escape(data.ToString())}</text:p></{ct}>";
|
var lines = string.Join("", data.ToString()?.Split('\n').Select(l => $"<text:p>{SecurityElement.Escape(l)}</text:p>") ?? []);
|
||||||
|
c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}>{lines}</{ct}>";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-columns-repeated=\"{colSpan - 1}\"/>\r\n" : "");
|
return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-columns-repeated=\"{colSpan - 1}\"/>\r\n" : "");
|
||||||
@@ -13,7 +13,9 @@ namespace Elwig.Helpers.Export {
|
|||||||
|
|
||||||
private readonly StreamWriter _writer;
|
private readonly StreamWriter _writer;
|
||||||
|
|
||||||
public VCard(string filename) : this(filename, Utils.UTF8) { }
|
public VCard(string filename) :
|
||||||
|
this(filename, Utils.UTF8) {
|
||||||
|
}
|
||||||
|
|
||||||
public VCard(string filename, Encoding encoding) {
|
public VCard(string filename, Encoding encoding) {
|
||||||
_writer = new StreamWriter(filename, false, encoding);
|
_writer = new StreamWriter(filename, false, encoding);
|
||||||
@@ -24,11 +26,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
_writer.Dispose();
|
_writer.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask DisposeAsync() {
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
return _writer.DisposeAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task ExportAsync(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
public async Task ExportAsync(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
||||||
progress?.Report(0.0);
|
progress?.Report(0.0);
|
||||||
int count = data.Count() + 1, i = 0;
|
int count = data.Count() + 1, i = 0;
|
||||||
@@ -58,10 +55,6 @@ namespace Elwig.Helpers.Export {
|
|||||||
progress?.Report(100.0);
|
progress?.Report(100.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Export(IEnumerable<Member> data, IProgress<double>? progress = null) {
|
|
||||||
ExportAsync(data, progress).GetAwaiter().GetResult();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string? Escape(string? text) {
|
private static string? Escape(string? text) {
|
||||||
return text?.Replace("\\", "\\\\").Replace(",", "\\,").Replace(";", "\\;").Replace("\n", "\\n").Replace("\r", "");
|
return text?.Replace("\\", "\\\\").Replace(",", "\\,").Replace(";", "\\;").Replace("\n", "\\n").Replace("\r", "");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using Microsoft.Data.Sqlite;
|
using Microsoft.Data.Sqlite;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.IO.Hashing;
|
using System.IO.Hashing;
|
||||||
@@ -12,6 +13,7 @@ using System.Threading;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace Elwig.Helpers {
|
namespace Elwig.Helpers {
|
||||||
public static partial class Extensions {
|
public static partial class Extensions {
|
||||||
@@ -134,11 +136,39 @@ namespace Elwig.Helpers {
|
|||||||
return await cmd.ExecuteScalarAsync();
|
return await cmd.ExecuteScalarAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(string Table, long RowId, string Parent, long FkId)[]> ForeignKeyCheck(this SqliteConnection cnx) {
|
public static async Task QuickCheck(this SqliteConnection cnx) {
|
||||||
|
using var cmd = cnx.CreateCommand();
|
||||||
|
cmd.CommandText = "PRAGMA quick_check";
|
||||||
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
|
var list = new List<string>();
|
||||||
|
while (await reader.ReadAsync()) {
|
||||||
|
list.Add(reader.GetString(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.Count != 1 || list[0] != "ok") {
|
||||||
|
throw new FileFormatException($"Integrity problems ({list.Count}):\n" + string.Join("\n", list.Take(50)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task IntegrityCheck(this SqliteConnection cnx) {
|
||||||
|
using var cmd = cnx.CreateCommand();
|
||||||
|
cmd.CommandText = "PRAGMA integrity_check";
|
||||||
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
|
var list = new List<string>();
|
||||||
|
while (await reader.ReadAsync()) {
|
||||||
|
list.Add(reader.GetString(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.Count != 1 || list[0] != "ok") {
|
||||||
|
throw new FileFormatException($"Integrity problems ({list.Count}):\n" + string.Join("\n", list.Take(50)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task ForeignKeyCheck(this SqliteConnection cnx) {
|
||||||
using var cmd = cnx.CreateCommand();
|
using var cmd = cnx.CreateCommand();
|
||||||
cmd.CommandText = "PRAGMA foreign_key_check";
|
cmd.CommandText = "PRAGMA foreign_key_check";
|
||||||
using var reader = await cmd.ExecuteReaderAsync();
|
using var reader = await cmd.ExecuteReaderAsync();
|
||||||
var list = new List<(string, long, string, long)>();
|
var list = new List<(string Table, long RowId, string Parent, long FkId)>();
|
||||||
while (await reader.ReadAsync()) {
|
while (await reader.ReadAsync()) {
|
||||||
var table = reader.GetString(0);
|
var table = reader.GetString(0);
|
||||||
var rowid = reader.GetInt64(1);
|
var rowid = reader.GetInt64(1);
|
||||||
@@ -146,7 +176,11 @@ namespace Elwig.Helpers {
|
|||||||
var fkid = reader.GetInt64(3);
|
var fkid = reader.GetInt64(3);
|
||||||
list.Add((table, rowid, parent, fkid));
|
list.Add((table, rowid, parent, fkid));
|
||||||
}
|
}
|
||||||
return [.. list];
|
|
||||||
|
if (list.Count > 0) {
|
||||||
|
throw new InvalidDataException($"Foreign key violations ({list.Count}):\n" + string.Join("\n", list.Take(50)
|
||||||
|
.Select(v => $"{v.Table} - {v.RowId} - {v.Parent} - {v.FkId}")));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<T> Join<T>(this IEnumerable<T> src, Func<T> separatorFactory) {
|
public static IEnumerable<T> Join<T>(this IEnumerable<T> src, Func<T> separatorFactory) {
|
||||||
@@ -159,17 +193,25 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AddToolTipCell(this Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
|
public static void AddToolTipCell(this Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false, Brush? color = null) {
|
||||||
var tb = new TextBlock() {
|
var tb = new TextBlock() {
|
||||||
Text = text,
|
Text = text,
|
||||||
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
|
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
|
||||||
Margin = new(0, 12 * row, 0, 0),
|
Margin = new(0, 12 * row, 0, 0),
|
||||||
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
|
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
|
||||||
};
|
};
|
||||||
|
if (color != null) tb.Foreground = color;
|
||||||
tb.SetValue(Grid.ColumnProperty, col);
|
tb.SetValue(Grid.ColumnProperty, col);
|
||||||
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
|
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
|
||||||
grid.Children.Add(tb);
|
grid.Children.Add(tb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static (int Year, int Week) GetYearAndWeek(this DateTime date) {
|
||||||
|
return (ISOWeek.GetYear(date), ISOWeek.GetWeekOfYear(date));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static (int Year, int Tertial) GetYearAndTertial(this DateTime date) {
|
||||||
|
return (date.Month <= 7 ? date.Year - 1 : date.Year, date.Month == 12 || date.Month <= 3 ? 2 : date.Month <= 7 ? 3 : 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,303 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace Elwig.Helpers {
|
||||||
|
public static partial class Normalizer {
|
||||||
|
|
||||||
|
[GeneratedRegex(@"(?=(?:(?:bundes)?straße|gasse|weg|platz|allee|ring|zeile?|steig|hof|markt|kai|ufer|brücke|tor|stiege|promenade|gang|siedlung)\b)|[\s-]+", RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase)]
|
||||||
|
private static partial Regex GeneratedStreetNameWordsRegex();
|
||||||
|
private static readonly Regex StreetNameWordsRegex = GeneratedStreetNameWordsRegex();
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetTypes = [
|
||||||
|
"Straße", "Gasse", "Weg", "Platz", "Allee", "Ring", "Zeile", "Zeil", "Steig", "Hof",
|
||||||
|
"Markt", "Kai", "Ufer", "Brücke", "Tor", "Stiege", "Promenade", "Gang", "Siedlung"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetArticles = ["der", "die", "das", "des", "dem", "den"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetPrepositions = [
|
||||||
|
"an", "am", "auf", "aus", "bei", "beim", "hinter", "hinterm", "in", "im", "ins", "nach",
|
||||||
|
"neben", "über", "unter", "von", "vom", "van", "vor", "zu", "zum", "zur", "zwischen",
|
||||||
|
"durch", "mit"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetNumbers = [ "Zwei", "Drei", "Vier", "Fünf", "Sechs", "Sieben" ];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetAdjectives = [
|
||||||
|
"alter", "alte", "alten", "altem", "altes",
|
||||||
|
"äußere", "äußere", "äußeren", "äußerem", "äußeres",
|
||||||
|
// "breiter", "breite", "breiten", "breitem", "breites",
|
||||||
|
"dritter", "dritte", "dritten", "drittem", "drittes",
|
||||||
|
"erster", "erste", "ersten", "erstem", "erstes",
|
||||||
|
"großer", "große", "großen", "großem", "großes",
|
||||||
|
"hoher", "hohe", "hohen", "hohem", "hohes",
|
||||||
|
"innerer", "innere", "inneren", "innerem", "inneres",
|
||||||
|
"kleiner", "kleine", "kleinen", "kleinem", "kleines",
|
||||||
|
"kurzer", "kurze", "kurzen", "kurzem", "kurzes",
|
||||||
|
"langer", "lange", "langen", "langem", "langes",
|
||||||
|
"linker", "linke", "linken", "linkem", "linkes",
|
||||||
|
"mittlerer", "mittlere", "mittleren", "mittlerem", "mittleres",
|
||||||
|
"neuer", "neue", "neuen", "neuem", "neues",
|
||||||
|
"oberer", "obere", "oberen", "oberem", "oberes",
|
||||||
|
"rechter", "rechte", "rechten", "rechtem", "rechtes",
|
||||||
|
"schmaler", "schmale", "schmalen", "schmalem", "schmales",
|
||||||
|
"schöner", "schöne", "schönen", "schönem", "schönes",
|
||||||
|
"unterer", "untere", "unteren", "unterem", "unteres",
|
||||||
|
"hinterer", "hintere", "hinteren", "hinterem", "hinteres",
|
||||||
|
"vorderer", "vordere", "vorderen", "vorderem", "vorderes",
|
||||||
|
"runder", "runde", "runden", "rundem", "rundes",
|
||||||
|
"kalter", "kalte", "kalten", "kaltem", "kaltes"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetLastNames = [
|
||||||
|
"Habsburger", "Lothringer", "Leitzenberger", "Luyderer", "Preiner", "Radinger", "Seefelder", "Staribacher", "Gschmeidler",
|
||||||
|
"Hannover", "Münster", "Salzgitter", "Speyer", "Trier"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetPersonTitles = [
|
||||||
|
"St.", "Familie",
|
||||||
|
"Dr.", "DDr.", "Hofrat", "Baurat", "Kommerzialrat", "Dir.", "Ing.", "Prof.", "Mag.", "DI", "OSR", "Präsident",
|
||||||
|
"Landeshauptmann", "LH", "Bürgermeister", "Bgm.", "Minister",
|
||||||
|
"Kaiser", "Kaiserin", "König", "Königin", "Erzherzog", "Erzherzogin", "Herzog", "Fürst", "Graf", "Gräfin", "Markgraf", "Kronprinz", "Prinz", "Ritter", "Freiherr", "Lord",
|
||||||
|
"Abt", "Bischof", "Propst", "Dechant", "Kardinal", "Monsignore", "Pfarrer", "Pater", "Prälat",
|
||||||
|
"Oberst"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> StreetGivenNames = [
|
||||||
|
"Adalbert", "Adam", "Adele", "Adelheid", "Adolf", "Adolph", "Adrian", "Albert", "Albrecht", "Alexander", "Alfons", "Alfred", "Alois", "Aloisia",
|
||||||
|
"Andreas", "Andrea", "Andre", "Anna", "Anton", "Arnold", "Arthur", "August", "Augustin", "Augustine", "Agnes", "Angelika", "Ada", "Adelheid", "Anni", "Anita",
|
||||||
|
"Barbara", "Beate", "Beatrix", "Benedikt", "Bernhard", "Berta", "Bertha", "Berthold", "Brüder", "Bruno", "Brigitte",
|
||||||
|
"Camillo", "Carl", "Caspar", "Catharina", "Christian", "Christine", "Christof", "Christoph", "Clara", "Clemens", "Conrad", "Claus", "Camillo", "Claudia",
|
||||||
|
"Daniel", "Dietmar", "Dietrich",
|
||||||
|
"Edgar", "Edi", "Edith", "Edmund", "Egon", "Elsa", "Eduard", "Emmerich", "Erhard", "Erich", "Ernst", "Erwin", "Eugen", "Ewald", "Eberhard",
|
||||||
|
"Elisabeth", "Emanuel", "Emerich", "Emil", "Emma", "Engelbert", "Elias",
|
||||||
|
"Franz", "Ferdinand", "Friedrich", "Felix", "Florian", "Fritz", "Franziska", "Fred",
|
||||||
|
"Georg", "Gregor", "Gustav", "Gabriel", "Gebrüder", "Gabriele", "Gerhard", "Gerhart", "Gertrude", "Gottfried", "Gottlieb", "Grete",
|
||||||
|
"Günther", "Günter",
|
||||||
|
"Hans", "Hanns", "Heinrich", "Heinz", "Helmut", "Helmuth", "Hermann", "Herta", "Herbert", "Hubert", "Harald", "Horst", "Helene", "Helga",
|
||||||
|
"Hieronymus", "Hilde", "Hugo",
|
||||||
|
"Isabelle", "Ignaz", "Ilse", "Ingeborg", "Isidor",
|
||||||
|
"Josef", "Josefine", "Joseph", "Johann", "Johanna", "Johan", "Johannes", "Hannes", "Harry", "Jakob", "Jacob", "Jan", "Julian", "Julius", "Julia", "Jürgen",
|
||||||
|
"Karl", "Kasimir", "Konrad", "Klemens", "Klara", "Katharina", "Kurt", "Kaspar", "Klaus", "Koloman", "Konstantin", "Killian",
|
||||||
|
"Leopold", "Leo", "Lorenz", "Lothar", "Louise", "Ludmilla", "Ludwig", "Lukas", "Ladislaus", "Lambert", "Laurenz", "Liese",
|
||||||
|
"Lise", "Lilly", "Lina", "Lothar", "Lotte", "Luise", "Leonhard", "Lotte", "Martha",
|
||||||
|
"Maria", "Marie", "Michael", "Martin", "Max", "Maximilian", "Manuel", "Manuela", "Moritz", "Marianne", "Manfred", "Marc",
|
||||||
|
"Mathias", "Matthias", "Matthäus",
|
||||||
|
"Margarete", "Margarethe",
|
||||||
|
"Nico", "Niko", "Niklas", "Niclas", "Nikolaus", "Norbert",
|
||||||
|
"Otto", "Ottokar", "Oskar", "Olga", "Oswald", "Othmar",
|
||||||
|
"Paul", "Pauline", "Patrick", "Pepi", "Peter", "Philipp", "Philip", "Petrus",
|
||||||
|
"Robert", "Rudolf", "Richard", "Ruprecht", "Raffael", "Rolf", "Roman", "Rosa", "Rosalia", "Rupert", "Raimund",
|
||||||
|
"Sigmund", "Siegfried", "Simon", "Stanislaus", "Stefan", "Stephan", "Sepp", "Samuel", "Sebastian", "Susi",
|
||||||
|
"Theodor", "Thomas", "Theresia", "Thaddäus", "Theo", "Theophil", "Tina", "Titus", "Toni", "Trude",
|
||||||
|
"Ullrich", "Ulrich", "Udo",
|
||||||
|
"Viktor", "Vinzenz", "Victor",
|
||||||
|
"Wolfgang", "Willibald", "Wilhelm", "Willhelm", "Wilhelmine", "Walter", "Walther", "Wenzel", "Werner", "Willi",
|
||||||
|
"Zacharias"];
|
||||||
|
|
||||||
|
private static readonly HashSet<string> LocalityNames = [
|
||||||
|
"Groß-Enzersdorf",
|
||||||
|
"Groß Burgstall", "Klein Eberharts", "Klein-Engersdorf", "Groß-Enzersdorf", "Klein-Erlauf",
|
||||||
|
"Groß Gerungs", "Klein Gundholz", "Klein-Harras", "Klein-Heinrichschlag", "Groß-Höbarten",
|
||||||
|
"Klein-Jetzelsdorf", "Klein-Mariazell", "Groß Meinharts", "Klein-Meiseldorf", "Groß-Neusiedl", "Klein-Neusiedl", "Klein-Pöchlarn",
|
||||||
|
"Groß-Radischen", "Klein-Radischen", "Groß Raßberg", "Klein Reinprechts", "Klein-Reinprechtsdorf", "Groß-Reipersdorf", "Klein-Ruprechts",
|
||||||
|
"Groß-Schollach", "Klein-Schollach", "Groß-Schweinbarth", "Groß-Siegharts", "Klein-Siegharts", "Groß Sierning",
|
||||||
|
"Klein-Ulrichschlag", "Klein Weinberg", "Klein Wetzles", "Klein-Wien",
|
||||||
|
];
|
||||||
|
|
||||||
|
private static bool IsGivenName(this string word) {
|
||||||
|
return StreetGivenNames.Contains(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsFamilyName(this string word) {
|
||||||
|
if (StreetLastNames.Contains(word))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPersonalName(this string word) {
|
||||||
|
return word.IsGivenName() || word.IsFamilyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsGeographicalDerivativeName(this string word) {
|
||||||
|
if (!word.EndsWith("er") || word.IsPersonalName() || word == "Weißer")
|
||||||
|
return false;
|
||||||
|
return word.StartsWith("St. ") || word.StartsWith("Ober ") || word.StartsWith("Unter ") || word.StartsWith("Maria") ||
|
||||||
|
word.EndsWith("sdorfer") || word.EndsWith("ndorfer") || word.EndsWith("ldorfer") ||
|
||||||
|
word.EndsWith("felder") ||
|
||||||
|
word.EndsWith("sthaler") || word.EndsWith("nthaler") || word.EndsWith("lthaler") ||
|
||||||
|
word.EndsWith("dauer") || word.EndsWith("lauer") || word.EndsWith("mauer") || word.EndsWith("nauer") || word.EndsWith("ßauer") ||
|
||||||
|
word.EndsWith("lbacher") || word.EndsWith("nbacher") || word.EndsWith("ßbacher") ||
|
||||||
|
word.EndsWith("ringer") || word.EndsWith("singer") ||
|
||||||
|
word.EndsWith("sbrunner") || word.EndsWith("nbrunner") || word.EndsWith("lbrunner") || word.EndsWith("abrunner") || word.EndsWith("ingbrunner") ||
|
||||||
|
word.EndsWith("sburger") || word.EndsWith("nburger") || word.EndsWith("mburger") || word.EndsWith("lburger") || word.EndsWith("neuburger") ||
|
||||||
|
word.EndsWith("berger") ||
|
||||||
|
word.EndsWith("winkler") ||
|
||||||
|
word.EndsWith("lsteiner") || word.EndsWith("nsteiner") ||
|
||||||
|
word.EndsWith("städter") ||
|
||||||
|
word.EndsWith("stättner") || word.EndsWith("stettner") ||
|
||||||
|
word.EndsWith("brücker") ||
|
||||||
|
word.EndsWith("further") || word.EndsWith("furter") ||
|
||||||
|
word.EndsWith("aaer") ||
|
||||||
|
word.EndsWith("seer") || word.EndsWith("leer") ||
|
||||||
|
word.EndsWith("tzner") ||
|
||||||
|
word.EndsWith("zeller") ||
|
||||||
|
word.EndsWith("rther") ||
|
||||||
|
word.EndsWith("sdner") ||
|
||||||
|
word.EndsWith("gerner") || word.EndsWith("berner") ||
|
||||||
|
word.EndsWith("frieder") ||
|
||||||
|
word.EndsWith("litzer") || word.EndsWith("mitzer") || word.EndsWith("eutzer") ||
|
||||||
|
word.EndsWith("loner") ||
|
||||||
|
word.EndsWith("skirchner") || word.EndsWith("nkirchner") || word.EndsWith("ingkirchner") ||
|
||||||
|
word.EndsWith("ziger") ||
|
||||||
|
word.EndsWith("ließer") ||
|
||||||
|
word.EndsWith("gerer") ||
|
||||||
|
word.EndsWith("kreuzer") ||
|
||||||
|
word == "Wiener" || word == "Brünner" || word == "Znaimer" || word == "Triester" || word == "Prager" || word == "Berliner" || word == "Basler" ||
|
||||||
|
word == "Retzer" || word == "Tullner" || word == "Badner" ||
|
||||||
|
word == "Gruber" || word == "Sulzer" || word == "Harraser" || word == "Dörfleser" || word == "Neusiedler" ||
|
||||||
|
word == "Dornauer" || word == "Siebenhauser" || word == "Alser" ||
|
||||||
|
word == "Bockenheimer";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string NormalizeAddress(string address, string? locality = null) {
|
||||||
|
var idx = address.IndexOf(',');
|
||||||
|
if (idx >= 0) address = address[..idx];
|
||||||
|
var (name, nr) = Utils.SplitAddress(address);
|
||||||
|
return (NormalizeStreetName(name, locality) + " " + nr).Trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string NormalizeStreetName(string name, string? locality = null) {
|
||||||
|
name = name.Trim().ToLowerInvariant();
|
||||||
|
if (name == "") {
|
||||||
|
return "";
|
||||||
|
} else if (name == "nr.") {
|
||||||
|
if (locality == null)
|
||||||
|
return "Nr.";
|
||||||
|
name = locality.Trim().ToLowerInvariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
name = name.Replace("hautp", "haupt")
|
||||||
|
.Replace("leop.", "leopold ").Replace("ferd.", "ferdinand ").Replace("gottfr.", "gottfried ")
|
||||||
|
.Replace("heinr.", "heinrich").Replace("joh.", "johann ").Replace("jos.", "josef ")
|
||||||
|
.Replace("msgr.", "monsignore ").Replace("pf.", "pfarrer ")
|
||||||
|
.Replace("präs.", "präsident ");
|
||||||
|
name = name.Replace("str.", "straße").Replace("strasse", "straße")
|
||||||
|
.Replace("bruecke", "brücke").Replace("pl.", "platz")
|
||||||
|
.Replace("gr.", "groß").Replace("kl.", "klein")
|
||||||
|
.Replace("sankt-", "st.").Replace("sankt ", "st.")
|
||||||
|
.Replace("wr.", "wiener ")
|
||||||
|
.Replace(".", ". ");
|
||||||
|
List<string> words = [.. StreetNameWordsRegex.Split(name)
|
||||||
|
.Where(w => !string.IsNullOrWhiteSpace(w))
|
||||||
|
.Select(w => StreetArticles.Contains(w) || StreetPrepositions.Contains(w) ? w : string.Concat(w[0..1].ToUpper(), w.AsSpan(1)))
|
||||||
|
.Select(w => w == "Ddr." ? "DDr." : w == "Lh" || w == "Osr" ? w.ToUpper() : w)
|
||||||
|
];
|
||||||
|
if (words[0] == "Di") words[0] = "DI";
|
||||||
|
|
||||||
|
var temp = "|" + string.Join('|', words) + "|";
|
||||||
|
temp = temp.Replace("|Dipl.|Ing.|", "|DI|").Replace("|Dipl|Ing.|", "|DI|")
|
||||||
|
.Replace("|Kaiser|Ebersdorf|", "|Kaiser-Ebersdorf|")
|
||||||
|
.Replace("|Kalk|Deutz|", "|Kalk-Deutz|").Replace("|Kalk|Deutzer|", "|Kalk-Deutzer|")
|
||||||
|
.Replace("|Hohe|Wand|", "|Hohe Wand|").Replace("|Hohen|Wand|", "|Hohen Wand|").Replace("|Hohewand|", "|Hohe Wand|")
|
||||||
|
.Replace("|Alten|Markt|", "|Altenmarkt|")
|
||||||
|
.Replace("|Kirch|Hof|", "|Kirchhof|").Replace("|Bisc|Hof|", "|Bischof|")
|
||||||
|
.Replace("|Wiener|Neustadt|", "|Wiener Neustadt|").Replace("|Wiener|Neustädter|", "|Wiener Neustädter|")
|
||||||
|
.Replace("|St.|Pölten|", "|St. Pölten|").Replace("|St.|Pöltner|", "|St. Pöltner|")
|
||||||
|
.Replace("|Gross|", "|Groß|")
|
||||||
|
.Replace("|Nr|", "|Nr.|").Replace("|Und|", "|und|");
|
||||||
|
words = [.. temp.Trim('|').Split('|')];
|
||||||
|
|
||||||
|
if (words.Count > 1 && (words[0] == "Groß" || words[0] == "Klein") && !StreetTypes.Contains(words[1])) {
|
||||||
|
var w = words[0] + words[1].ToLowerInvariant();
|
||||||
|
words.RemoveRange(0, 2);
|
||||||
|
words.Insert(0, w);
|
||||||
|
}
|
||||||
|
if (words[0].StartsWith("Groß") || words[0].StartsWith("Klein")) {
|
||||||
|
var repl = LocalityNames.FirstOrDefault(n => n.Replace(" ", "").Replace("-", "").Equals(words[0], StringComparison.InvariantCultureIgnoreCase));
|
||||||
|
if (repl != null) words[0] = repl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (words.Count > 2 && words[^2] == "in") {
|
||||||
|
// remove suffix "in ..."
|
||||||
|
words.RemoveRange(words.Count - 2, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
char sep = name.Contains('-') ? '-' : ' ';
|
||||||
|
if (words.Count <= 1) {
|
||||||
|
// single word
|
||||||
|
} else if (StreetTypes.Contains(words[0]) && !StreetTypes.Contains(words[^1])) {
|
||||||
|
// "Straße der ..." / "Straße des ..."
|
||||||
|
sep = ' ';
|
||||||
|
} else if (StreetTypes.Contains(words[^1])) {
|
||||||
|
// "... Straße" / "...straße"
|
||||||
|
var type = words[^1];
|
||||||
|
var isCompound = true;
|
||||||
|
var isAdjective = StreetAdjectives.Contains(words[^2].ToLowerInvariant());
|
||||||
|
var isGeographical = false;
|
||||||
|
var isPerson = false;
|
||||||
|
|
||||||
|
var geo = words.FindLastIndex(IsGeographicalDerivativeName);
|
||||||
|
if (geo >= 0 && geo < words.Count - 2 && words[^2] != "Haupt" && words[^2] != "Bundes" && words[^2] != "Keller") {
|
||||||
|
isPerson = true;
|
||||||
|
isGeographical = true;
|
||||||
|
} else if (words.Any(w => w.Contains(' ') && !w.IsGeographicalDerivativeName())) {
|
||||||
|
isPerson = true;
|
||||||
|
isGeographical = true;
|
||||||
|
} else if (StreetNumbers.Contains(words[0])) {
|
||||||
|
isPerson = true;
|
||||||
|
isGeographical = true;
|
||||||
|
} else if (!StreetPrepositions.Contains(words[0]) && !StreetArticles.Contains(words[0]) && words.FindIndex(StreetPrepositions.Contains) > 0) {
|
||||||
|
isPerson = true;
|
||||||
|
isGeographical = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (words.Count(w => w.Contains('.')) >= 2 || words.Contains("van") || words.Contains("von") || words.Contains("St.") ||
|
||||||
|
StreetPersonTitles.Contains(words[0]) || words.Any(w => w.IsGivenName()))
|
||||||
|
{
|
||||||
|
isPerson = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isPerson && isAdjective || StreetArticles.Contains(words[^2]) || StreetPrepositions.Contains(words[^2])) {
|
||||||
|
isCompound = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isPerson && words[^2].EndsWith("er") && !StreetLastNames.Contains(words[^2])) {
|
||||||
|
isGeographical = IsGeographicalDerivativeName(words[^2]);
|
||||||
|
} else if (words.Count >= 3 && words.Contains("Bad")) {
|
||||||
|
isPerson = true;
|
||||||
|
isGeographical = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sep = isPerson ? '-' : ' ';
|
||||||
|
|
||||||
|
if (isPerson && words.Count == 2 && !isGeographical) {
|
||||||
|
isPerson = false;
|
||||||
|
isCompound = true;
|
||||||
|
}
|
||||||
|
if (isGeographical || isPerson) {
|
||||||
|
isCompound = false;
|
||||||
|
}
|
||||||
|
if (isCompound) {
|
||||||
|
var w = words[^2] + type.ToLowerInvariant();
|
||||||
|
words.RemoveRange(words.Count - 2, 2);
|
||||||
|
words.Add(w);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPerson) {
|
||||||
|
words = [.. words.Select(w => w.Replace(' ', '-'))];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sep == '-' && StreetPrepositions.Contains(words[0]) && words[0] != "von" && words[0] != "van") {
|
||||||
|
sep = ' ';
|
||||||
|
int i;
|
||||||
|
for (i = 0; StreetPrepositions.Contains(words[i]) && i < words.Count; i++);
|
||||||
|
var word = string.Join('-', words.Skip(i));
|
||||||
|
words = [.. words.Take(i).Append(word)];
|
||||||
|
}
|
||||||
|
|
||||||
|
var norm = string.Join(sep, words);
|
||||||
|
return string.Concat(norm[0..1].ToUpperInvariant(), norm.AsSpan(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,20 +1,17 @@
|
|||||||
using Elwig.Services;
|
using Elwig.Services;
|
||||||
using Elwig.Windows;
|
using Elwig.Windows;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Elwig.Helpers.Printing {
|
namespace Elwig.Helpers.Printing {
|
||||||
public static class Pdf {
|
public static class Pdf {
|
||||||
|
|
||||||
public static Task Init(Action? evtHandler = null) {
|
public static void Init(Action? evtHandler = null) {
|
||||||
PdfiumNative.FPDF_InitLibrary();
|
PdfiumNative.FPDF_InitLibrary();
|
||||||
evtHandler?.Invoke();
|
evtHandler?.Invoke();
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task Cleanup() {
|
public static void Cleanup() {
|
||||||
PdfiumNative.FPDF_DestroyLibrary();
|
PdfiumNative.FPDF_DestroyLibrary();
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Show(TempFile file, string title) {
|
public static void Show(TempFile file, string title) {
|
||||||
@@ -31,14 +28,13 @@ namespace Elwig.Helpers.Printing {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Task Print(string path, int copies = 1, bool doublePaged = false) {
|
public static void Print(string path, int copies = 1, bool doublePaged = false) {
|
||||||
try {
|
try {
|
||||||
var printer = new PdfPrinter();
|
var printer = new PdfPrinter();
|
||||||
printer.Print(path, copies, doublePaged);
|
printer.Print(path, copies, doublePaged);
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
InteractionService.ShowException("Fehler beim Drucken", "Beim Drucken ist ein Fehler aufgetreten", exc);
|
InteractionService.ShowException("Fehler beim Drucken", "Beim Drucken ist ein Fehler aufgetreten", exc);
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+50
-13
@@ -45,7 +45,6 @@ namespace Elwig.Helpers {
|
|||||||
public static int CurrentNextSeason => DateTime.Now.Year - (DateTime.Now.Month <= 3 ? 1 : 0);
|
public static int CurrentNextSeason => DateTime.Now.Year - (DateTime.Now.Month <= 3 ? 1 : 0);
|
||||||
public static int CurrentLastSeason => DateTime.Now.Year - (DateTime.Now.Month <= 6 ? 1 : 0);
|
public static int CurrentLastSeason => DateTime.Now.Year - (DateTime.Now.Month <= 6 ? 1 : 0);
|
||||||
public static int FollowingSeason => DateTime.Now.Year + (DateTime.Now.Month >= 11 ? 1 : 0);
|
public static int FollowingSeason => DateTime.Now.Year + (DateTime.Now.Month >= 11 ? 1 : 0);
|
||||||
public static DateTime Today => (DateTime.Now.Hour >= 3) ? DateTime.Today : DateTime.Today.AddDays(-1);
|
|
||||||
|
|
||||||
[GeneratedRegex("^serial://([A-Za-z0-9]+):([0-9]+)(,([5-9]),([NOEMSnoems]),(0|1|1\\.5|2|))?$", RegexOptions.Compiled)]
|
[GeneratedRegex("^serial://([A-Za-z0-9]+):([0-9]+)(,([5-9]),([NOEMSnoems]),(0|1|1\\.5|2|))?$", RegexOptions.Compiled)]
|
||||||
private static partial Regex GeneratedSerialRegex();
|
private static partial Regex GeneratedSerialRegex();
|
||||||
@@ -304,6 +303,11 @@ namespace Elwig.Helpers {
|
|||||||
return d.ShowDialog() == true ? (d.Weight, d.Reason) : null;
|
return d.ShowDialog() == true ? (d.Weight, d.Reason) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int? ShowTareCorrectionDialog(int? actualTare, int? targetTare = null) {
|
||||||
|
var d = new TareCorrectionDialog(actualTare, targetTare);
|
||||||
|
return d.ShowDialog() == true ? d.TargetTare - d.ActualTare : null;
|
||||||
|
}
|
||||||
|
|
||||||
public static (string?, int[])? ShowDeliverySplittingDialog(Delivery delivery) {
|
public static (string?, int[])? ShowDeliverySplittingDialog(Delivery delivery) {
|
||||||
var d = new DeliverySplittingDialog(delivery);
|
var d = new DeliverySplittingDialog(delivery);
|
||||||
return d.ShowDialog() == true ? (d.MgNr?.ToString() ?? d.LsNr, d.Weights ?? []) : null;
|
return d.ShowDialog() == true ? (d.MgNr?.ToString() ?? d.LsNr, d.Weights ?? []) : null;
|
||||||
@@ -319,7 +323,7 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class Footer {
|
public class Footer {
|
||||||
private readonly List<List<object>> Items = [[]];
|
private readonly List<List<List<object>>> Items = [[[]]];
|
||||||
private readonly string LineBreak;
|
private readonly string LineBreak;
|
||||||
private readonly string Separator;
|
private readonly string Separator;
|
||||||
|
|
||||||
@@ -330,7 +334,7 @@ namespace Elwig.Helpers {
|
|||||||
|
|
||||||
public Footer Item(object? text) {
|
public Footer Item(object? text) {
|
||||||
if (text == null) return this;
|
if (text == null) return this;
|
||||||
Items[^1].Add(text);
|
Items[^1][^1].Add(text);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,13 +342,38 @@ namespace Elwig.Helpers {
|
|||||||
return text == null ? this : Item($"{name}: {text}");
|
return text == null ? this : Item($"{name}: {text}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Footer NextGroup() {
|
||||||
|
Items[^1].Add([]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public Footer NextLine() {
|
public Footer NextLine() {
|
||||||
Items.Add([]);
|
Items.Add([[]]);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Footer RebalanceLines() {
|
||||||
|
for (int i = 0; i < Items.Count - 1; i++) {
|
||||||
|
var groups = Items[i];
|
||||||
|
var nextGroups = Items[i + 1];
|
||||||
|
if (groups.Count <= 1) continue;
|
||||||
|
var g = groups[^1];
|
||||||
|
var gl = g.Sum(i => (i is Text txt ? txt.GetText().Length : i.ToString()?.Length ?? 0) + Separator.Length);
|
||||||
|
var l1a = groups.SelectMany(g => g).Sum(i => (i is Text txt ? txt.GetText().Length : i.ToString()?.Length ?? 0) + Separator.Length) - Separator.Length;
|
||||||
|
var l2a = nextGroups.SelectMany(g => g).Sum(i => (i is Text txt ? txt.GetText().Length : i.ToString()?.Length ?? 0) + Separator.Length) - Separator.Length;
|
||||||
|
var l1b = l1a - gl;
|
||||||
|
var l2b = l2a + gl;
|
||||||
|
if (Math.Abs(l1b - l2b) <= Math.Abs(l1a - l2a)) {
|
||||||
|
Items[i].Remove(g);
|
||||||
|
Items[i + 1].Insert(0, g);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return string.Join(LineBreak, Items.Select(l => string.Join(Separator, l.ToString())));
|
return string.Join(LineBreak, Items.Select(l => string.Join(Separator, l.SelectMany(g => g).ToString())));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IList<ILeafElement> ToLeafElements() {
|
public IList<ILeafElement> ToLeafElements() {
|
||||||
@@ -353,11 +382,13 @@ namespace Elwig.Helpers {
|
|||||||
foreach (var line in Items) {
|
foreach (var line in Items) {
|
||||||
if (!first1) l.Add(new Text(LineBreak));
|
if (!first1) l.Add(new Text(LineBreak));
|
||||||
var first2 = true;
|
var first2 = true;
|
||||||
foreach (var item in line) {
|
foreach (var group in line) {
|
||||||
|
foreach (var item in group) {
|
||||||
if (!first2) l.Add(new Text(Separator));
|
if (!first2) l.Add(new Text(Separator));
|
||||||
l.Add(item as ILeafElement ?? new Text(item.ToString() ?? ""));
|
l.Add(item as ILeafElement ?? new Text(item.ToString() ?? ""));
|
||||||
first2 = false;
|
first2 = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
first1 = false;
|
first1 = false;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
@@ -536,6 +567,7 @@ namespace Elwig.Helpers {
|
|||||||
msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From));
|
msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From));
|
||||||
msg.To.AddRange(member.EmailAddresses.OrderBy(a => a.Nr).Select(a => new MailboxAddress(member.AdministrativeName, a.Address)));
|
msg.To.AddRange(member.EmailAddresses.OrderBy(a => a.Nr).Select(a => new MailboxAddress(member.AdministrativeName, a.Address)));
|
||||||
msg.Subject = subject;
|
msg.Subject = subject;
|
||||||
|
msg.Date = DateTime.Now;
|
||||||
var body = new Multipart("mixed") {
|
var body = new Multipart("mixed") {
|
||||||
new TextPart("plain") { Text = text }
|
new TextPart("plain") { Text = text }
|
||||||
};
|
};
|
||||||
@@ -630,16 +662,16 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Expression<Func<AreaCom, bool>> ActiveAreaCommitments() => ActiveAreaCommitments(CurrentYear);
|
public static Expression<Func<AreaCmt, bool>> ActiveAreaCommitments() => ActiveAreaCommitments(CurrentYear);
|
||||||
public static Expression<Func<AreaCom, bool>> ActiveAreaCommitments(int year) =>
|
public static Expression<Func<AreaCmt, bool>> ActiveAreaCommitments(int year) =>
|
||||||
c => (c.YearFrom == null || c.YearFrom <= year) && (c.YearTo == null || c.YearTo >= year);
|
c => (c.YearFrom == null || c.YearFrom <= year) && (c.YearTo == null || c.YearTo >= year);
|
||||||
|
|
||||||
public static IQueryable<AreaCom> ActiveAreaCommitments(IQueryable<AreaCom> query) => ActiveAreaCommitments(query, CurrentYear);
|
public static IQueryable<AreaCmt> ActiveAreaCommitments(IQueryable<AreaCmt> query) => ActiveAreaCommitments(query, CurrentYear);
|
||||||
public static IQueryable<AreaCom> ActiveAreaCommitments(IQueryable<AreaCom> query, int year) =>
|
public static IQueryable<AreaCmt> ActiveAreaCommitments(IQueryable<AreaCmt> query, int year) =>
|
||||||
query.Where(ActiveAreaCommitments(year));
|
query.Where(ActiveAreaCommitments(year));
|
||||||
|
|
||||||
public static IEnumerable<AreaCom> ActiveAreaCommitments(IEnumerable<AreaCom> query) => ActiveAreaCommitments(query, CurrentYear);
|
public static IEnumerable<AreaCmt> ActiveAreaCommitments(IEnumerable<AreaCmt> query) => ActiveAreaCommitments(query, CurrentYear);
|
||||||
public static IEnumerable<AreaCom> ActiveAreaCommitments(IEnumerable<AreaCom> query, int year) =>
|
public static IEnumerable<AreaCmt> ActiveAreaCommitments(IEnumerable<AreaCmt> query, int year) =>
|
||||||
query.Where(c => ActiveAreaCommitments(year).Invoke(c));
|
query.Where(c => ActiveAreaCommitments(year).Invoke(c));
|
||||||
|
|
||||||
public static async Task<(DateTime DateTime, string Type, int MgNr, string Name, string[] Addresses, string Subject, string[] Attachments)[]> GetSentMails(DateOnly? fromDate = null, DateOnly? toDate = null) {
|
public static async Task<(DateTime DateTime, string Type, int MgNr, string Name, string[] Addresses, string Subject, string[] Attachments)[]> GetSentMails(DateOnly? fromDate = null, DateOnly? toDate = null) {
|
||||||
@@ -670,7 +702,7 @@ namespace Elwig.Helpers {
|
|||||||
p[2],
|
p[2],
|
||||||
int.Parse(p[3]),
|
int.Parse(p[3]),
|
||||||
p[4],
|
p[4],
|
||||||
p[5].Split(',').Select(a => a.Replace(" | ", "\n")).ToArray(),
|
[.. p[5].Split(',').Select(a => a.Replace(" | ", "\n"))],
|
||||||
p[6],
|
p[6],
|
||||||
p[7].Split(',')
|
p[7].Split(',')
|
||||||
));
|
));
|
||||||
@@ -712,5 +744,10 @@ namespace Elwig.Helpers {
|
|||||||
var filename = Path.Combine(App.MailsPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{NormalizeFileName(subject)}.txt");
|
var filename = Path.Combine(App.MailsPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{NormalizeFileName(subject)}.txt");
|
||||||
await File.WriteAllTextAsync(filename, $"# {subject}\r\n# Vorgesehene Empfänger: {recipients}\r\n\r\n" + body, Utils.UTF8);
|
await File.WriteAllTextAsync(filename, $"# {subject}\r\n# Vorgesehene Empfänger: {recipients}\r\n\r\n" + body, Utils.UTF8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string GetTitle(string window, IEnumerable<string> filterNames, IEnumerable<string> filter) {
|
||||||
|
var f = string.Join(" / ", filterNames.Union(filter.Select(f => $"\"{f}\"")));
|
||||||
|
return window + (f.Length == 0 ? "" : ": " + f) + " - Elwig";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -577,7 +577,7 @@ namespace Elwig.Helpers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckFbNr(TextBox input, bool required, AreaComContract? c) {
|
public static ValidationResult CheckFbNr(TextBox input, bool required, AreaCmtContract? c) {
|
||||||
var res = CheckInteger(input, required);
|
var res = CheckInteger(input, required);
|
||||||
if (!res.IsValid) {
|
if (!res.IsValid) {
|
||||||
return res;
|
return res;
|
||||||
@@ -623,6 +623,37 @@ namespace Elwig.Helpers {
|
|||||||
return new(true, null);
|
return new(true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ValidationResult CheckOrganicOperatorId(TextBox input, bool required) {
|
||||||
|
string text = "";
|
||||||
|
int pos = input.CaretIndex;
|
||||||
|
for (int i = 0, v = 0; i < input.Text.Length; i++) {
|
||||||
|
char ch = input.Text[i];
|
||||||
|
if (char.IsAsciiDigit(ch)) {
|
||||||
|
if (v == 3 && text[^1] != '-')
|
||||||
|
text += "-";
|
||||||
|
v++;
|
||||||
|
text += ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == input.CaretIndex - 1) {
|
||||||
|
pos = text.Length;
|
||||||
|
} else if (v >= 10) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input.Text = text;
|
||||||
|
input.CaretIndex = pos;
|
||||||
|
|
||||||
|
if (text.Length == 0) {
|
||||||
|
return required ? new(false, "OOC-ID ist nicht optional") : new(true, null);
|
||||||
|
} else if (!text.StartsWith("040-") || text.Length != 11) {
|
||||||
|
return new(false, "OOC-ID ist ungültig");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new(true, null);
|
||||||
|
}
|
||||||
|
|
||||||
public static ValidationResult CheckOrganicAuthorityCode(TextBox input, bool required) {
|
public static ValidationResult CheckOrganicAuthorityCode(TextBox input, bool required) {
|
||||||
string text = "";
|
string text = "";
|
||||||
int pos = input.CaretIndex;
|
int pos = input.CaretIndex;
|
||||||
@@ -631,15 +662,18 @@ namespace Elwig.Helpers {
|
|||||||
if (v < 2 && char.IsAsciiLetter(ch)) {
|
if (v < 2 && char.IsAsciiLetter(ch)) {
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
} else if ((v == 2 || v == 6) && ch == '-') {
|
} else if ((v == 2 || v == 5) && ch == '-' && text[^1] != '-') {
|
||||||
v++;
|
|
||||||
text += ch;
|
text += ch;
|
||||||
} else if (v >= 2 && char.IsLetterOrDigit(ch)) {
|
} else if (v >= 2 && v <= 4 && char.IsLetter(ch)) {
|
||||||
|
if (v == 2 && text[^1] != '-')
|
||||||
|
text += "-";
|
||||||
if (text.StartsWith("AT")) {
|
if (text.StartsWith("AT")) {
|
||||||
if (v == 3 && ch == 'B' || v == 4 && ch == 'I' || v == 5 && ch == 'O') {
|
if (v == 2 && ch == 'B' || v == 3 && ch == 'I' || v == 4 && ch == 'O') {
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
} else if (v > 6 && char.IsAsciiDigit(ch)) {
|
}
|
||||||
|
} else if (text.StartsWith("DE")) {
|
||||||
|
if (v == 2 && ch == 'Ö' || v == 3 && ch == 'K' || v == 4 && ch == 'O') {
|
||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
}
|
}
|
||||||
@@ -647,11 +681,16 @@ namespace Elwig.Helpers {
|
|||||||
v++;
|
v++;
|
||||||
text += ch;
|
text += ch;
|
||||||
}
|
}
|
||||||
|
} else if (v >= 5 && v <= 7 && char.IsAsciiDigit(ch)) {
|
||||||
|
if (v == 5 && text[^1] != '-')
|
||||||
|
text += "-";
|
||||||
|
v++;
|
||||||
|
text += ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == input.CaretIndex - 1) {
|
if (i == input.CaretIndex - 1) {
|
||||||
pos = text.Length;
|
pos = text.Length;
|
||||||
} else if (text.StartsWith("AT") && v >= 10) {
|
} else if ((text.StartsWith("AT") || text.StartsWith("DE")) && v >= 10) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,7 +701,7 @@ namespace Elwig.Helpers {
|
|||||||
if (text.Length == 0)
|
if (text.Length == 0)
|
||||||
return required ? new(false, "Bio-Kontrollstellen-Code ist nicht optional") : new(true, null);
|
return required ? new(false, "Bio-Kontrollstellen-Code ist nicht optional") : new(true, null);
|
||||||
|
|
||||||
if (text.StartsWith("AT")) {
|
if (text.StartsWith("AT") || text.StartsWith("DE")) {
|
||||||
if (text.Length != 10) {
|
if (text.Length != 10) {
|
||||||
return new(false, "Bio-Kontrollstellen-Code ist ungültig");
|
return new(false, "Bio-Kontrollstellen-Code ist ungültig");
|
||||||
}
|
}
|
||||||
@@ -672,5 +711,25 @@ namespace Elwig.Helpers {
|
|||||||
|
|
||||||
return new(true, null);
|
return new(true, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ValidationResult CheckAddress(TextBox input, bool required, string? locality = null) {
|
||||||
|
var text = input.Text;
|
||||||
|
var (name, nr) = Utils.SplitAddress(text);
|
||||||
|
if (!string.IsNullOrWhiteSpace(nr)) {
|
||||||
|
var street = Normalizer.NormalizeStreetName(name.Replace(",", ""), locality);
|
||||||
|
var idx = input.CaretIndex;
|
||||||
|
input.Text = $"{street} {nr}".Trim();
|
||||||
|
if (idx >= (text.Length - nr.Length)) {
|
||||||
|
input.CaretIndex = street.Length + (idx - (text.Length - nr.Length)) + 1;
|
||||||
|
} else if (idx > 0) {
|
||||||
|
input.CaretIndex = idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.Length == 0)
|
||||||
|
return required ? new(false, "Adresse ist nicht optional") : new(true, null);
|
||||||
|
|
||||||
|
return new(true, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ namespace Elwig.Helpers.Weighing {
|
|||||||
throw new WeighingException($"Fehler {error}: {msg}");
|
throw new WeighingException($"Fehler {error}: {msg}");
|
||||||
} else if (error[0] == '3') {
|
} else if (error[0] == '3') {
|
||||||
switch (error[1]) {
|
switch (error[1]) {
|
||||||
case '1': msg = "Übertragunsfehler"; break;
|
case '1': msg = "Übertragungsfehler"; break;
|
||||||
case '2': msg = "Ungültiger Befehl"; break;
|
case '2': msg = "Ungültiger Befehl"; break;
|
||||||
case '3': msg = "Ungültiger Parameter"; break;
|
case '3': msg = "Ungültiger Parameter"; break;
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
public class AreaComUnderDeliveryData : DataTable<AreaComUnderDeliveryRow> {
|
public class AreaCmtUnderDeliveryData : DataTable<AreaCmtUnderDeliveryRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = [
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
@@ -21,19 +21,19 @@ namespace Elwig.Models.Dtos {
|
|||||||
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
("UnderDeliveries", "Unterliefert", "kg|%", 34),
|
||||||
];
|
];
|
||||||
|
|
||||||
public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
|
public AreaCmtUnderDeliveryData(IEnumerable<AreaCmtUnderDeliveryRow> rows, int year) :
|
||||||
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
base($"Unterlieferungen FB", $"Unterlieferungen laut Flächenbindungen {year}", rows, FieldNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<AreaComUnderDeliveryData> ForSeason(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
|
public static async Task<AreaCmtUnderDeliveryData> ForSeason(DbSet<AreaCmtUnderDeliveryRowSingle> table, int year) {
|
||||||
return new AreaComUnderDeliveryData(
|
return new AreaCmtUnderDeliveryData(
|
||||||
(await FromDbSet(table, year)).GroupBy(
|
(await FromDbSet(table, year)).GroupBy(
|
||||||
r => r.MgNr,
|
r => r.MgNr,
|
||||||
(k, g) => new AreaComUnderDeliveryRow(g)
|
(k, g) => new AreaCmtUnderDeliveryRow(g)
|
||||||
), year);
|
), year);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<AreaComUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaComUnderDeliveryRowSingle> table, int year) {
|
private static async Task<IEnumerable<AreaCmtUnderDeliveryRowSingle>> FromDbSet(DbSet<AreaCmtUnderDeliveryRowSingle> table, int year) {
|
||||||
return await table.FromSql($"""
|
return 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 ||
|
||||||
@@ -51,7 +51,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AreaComUnderDeliveryRow {
|
public class AreaCmtUnderDeliveryRow {
|
||||||
public int MgNr;
|
public int MgNr;
|
||||||
public string Name1;
|
public string Name1;
|
||||||
public string? Name2;
|
public string? Name2;
|
||||||
@@ -66,7 +66,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
.Select(v => v.First < v.Second ? ((int?, double?))(v.First - v.Second, v.First * 100.0 / v.Second - 100.0) : (null, null))
|
.Select(v => v.First < v.Second ? ((int?, double?))(v.First - v.Second, v.First * 100.0 / v.Second - 100.0) : (null, null))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
public AreaComUnderDeliveryRow(IEnumerable<AreaComUnderDeliveryRowSingle> rows) {
|
public AreaCmtUnderDeliveryRow(IEnumerable<AreaCmtUnderDeliveryRowSingle> rows) {
|
||||||
var f = rows.First();
|
var f = rows.First();
|
||||||
MgNr = f.MgNr;
|
MgNr = f.MgNr;
|
||||||
Name1 = f.Name1;
|
Name1 = f.Name1;
|
||||||
@@ -82,7 +82,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Keyless]
|
[Keyless]
|
||||||
public class AreaComUnderDeliveryRowSingle {
|
public class AreaCmtUnderDeliveryRowSingle {
|
||||||
[Column("mgnr")]
|
[Column("mgnr")]
|
||||||
public int MgNr { get; set; }
|
public int MgNr { get; set; }
|
||||||
[Column("name_1")]
|
[Column("name_1")]
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
@@ -9,13 +10,14 @@ namespace Elwig.Models.Dtos {
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string FullName { get; set; }
|
public string FullName { get; set; }
|
||||||
public string? Subtitle { get; set; }
|
public string? Subtitle { get; set; }
|
||||||
public IEnumerable<T> Rows { get; private set; }
|
public IEnumerable<(string? Name, IEnumerable<T> Rows)> Sections { get; private set; }
|
||||||
|
public IEnumerable<T> Rows => Sections.SelectMany(s => s.Rows);
|
||||||
public int RowNum => Rows.Count();
|
public int RowNum => Rows.Count();
|
||||||
public int ColNum => ColumnNames.Count();
|
public int ColNum => ColumnNames.Count();
|
||||||
|
|
||||||
public IEnumerable<(string, Type?)> ColumnDefs => _map.Select(m => (m.Item1, m.Item2?.PropertyType ?? m.Item3?.FieldType));
|
public IEnumerable<(string Name, Type? Type)> ColumnDefs => _map.Select(m => (m.Name, m.PInfo?.PropertyType ?? m.FInfo?.FieldType));
|
||||||
public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Item1);
|
public IEnumerable<string> ColumnNames => ColumnDefs.Select(m => m.Name);
|
||||||
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Item2);
|
public IEnumerable<Type?> ColumnTypes => ColumnDefs.Select(m => m.Type);
|
||||||
public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
|
public IEnumerable<Type?> ColumnFlatTypes { get; private set; }
|
||||||
public IEnumerable<int> ColumnSpans { get; private set; }
|
public IEnumerable<int> ColumnSpans { get; private set; }
|
||||||
public IEnumerable<int?> ColumnWidths { get; private set; }
|
public IEnumerable<int?> ColumnWidths { get; private set; }
|
||||||
@@ -23,70 +25,87 @@ namespace Elwig.Models.Dtos {
|
|||||||
|
|
||||||
private readonly PropertyInfo[] _properties;
|
private readonly PropertyInfo[] _properties;
|
||||||
private readonly FieldInfo[] _fields;
|
private readonly FieldInfo[] _fields;
|
||||||
private readonly (string, PropertyInfo?, FieldInfo?)[] _map;
|
private readonly (string Name, PropertyInfo? PInfo, FieldInfo? FInfo)[] _map;
|
||||||
|
|
||||||
public DataTable(string name, string fullName, string subtitle, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
|
public DataTable(string name, string fullName, string subtitle, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
this(name, fullName, rows, colNames) {
|
this(name, fullName, sections, colNames) {
|
||||||
Subtitle = subtitle;
|
Subtitle = subtitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) {
|
public DataTable(string name, string fullName, string subtitle, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
|
this(name, fullName, subtitle, [(null, rows)], colNames) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) {
|
||||||
_fields = typeof(T).GetFields();
|
_fields = typeof(T).GetFields();
|
||||||
_properties = typeof(T).GetProperties();
|
_properties = typeof(T).GetProperties();
|
||||||
colNames ??= _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null)).ToList();
|
colNames ??= [.. _properties.Select(p => p.Name).Union(_fields.Select(f => f.Name)).Select(i => (i, i, (string?)null, (int?)null))];
|
||||||
_map = colNames.Select(n => (n.Item2, _properties.FirstOrDefault(p => p?.Name == n.Item1, null), _fields.FirstOrDefault(f => f?.Name == n.Item1, null))).ToArray();
|
_map = [.. colNames.Select(n => (n.Name, _properties.FirstOrDefault(p => p?.Name == n.Property, null), _fields.FirstOrDefault(f => f?.Name == n.Property, null)))];
|
||||||
Name = name;
|
Name = name;
|
||||||
FullName = fullName;
|
FullName = fullName;
|
||||||
Rows = rows;
|
Sections = sections;
|
||||||
ColumnFlatTypes = ColumnTypes.SelectMany(type => {
|
ColumnFlatTypes = [.. ColumnTypes.SelectMany(type => {
|
||||||
var elType = type?.GetElementType();
|
var elType = type?.GetElementType();
|
||||||
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => f.FieldType) :
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Select(f => (Type?)f.FieldType) :
|
||||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => f.FieldType) :
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Select(f => (Type?)f.FieldType) :
|
||||||
[type];
|
[type];
|
||||||
}).ToList();
|
})];
|
||||||
ColumnSpans = ColumnTypes.Select(type => {
|
ColumnSpans = [.. ColumnTypes.Select(type => {
|
||||||
var elType = type?.GetElementType();
|
var elType = type?.GetElementType();
|
||||||
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Length :
|
return type != null && type.IsValueType && type.Name.StartsWith("ValueTuple") ? type.GetFields().Length :
|
||||||
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length : 1;
|
type != null && elType != null && type.IsArray && elType.IsValueType && elType.Name.StartsWith("ValueTuple") ? elType.GetFields().Length :
|
||||||
}).ToList();
|
1;
|
||||||
ColumnWidths = colNames.Select(c => c.Item4).ToList();
|
})];
|
||||||
ColumnUnits = colNames.Select(c => c.Item3?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? []).ToList();
|
ColumnWidths = [.. colNames.Select(c => c.Width)];
|
||||||
|
ColumnUnits = [.. colNames.Select(c => c.Unit?.Split("|").Select(p => p.Length == 0 ? null : p).ToArray() ?? [])];
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)null))) {
|
this(name, fullName, [(null, rows)], colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?)>? colNames = null) :
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||||
|
this(name, fullName, rows, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||||
|
this(name, fullName, rows, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int? Width)>? colNames = null) :
|
||||||
this(name, name, rows, colNames) {
|
this(name, name, rows, colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int?)>? colNames = null) :
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||||
this(name, name, rows, colNames) {
|
this(name, name, rows, colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
|
public DataTable(string name, IEnumerable<T> rows, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||||
this(name, name, rows, colNames) {
|
this(name, name, rows, colNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DataTable(string name, string fullName, IEnumerable<T> rows, IEnumerable<(string, string, string?, int)>? colNames = null) :
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit)>? colNames = null) :
|
||||||
this(name, fullName, rows, colNames?.Select(c => (c.Item1, c.Item2, c.Item3, (int?)c.Item4))) {
|
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)null))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<(string, object?)> GetNamedRowData(T row) {
|
public DataTable(string name, string fullName, IEnumerable<(string? Name, IEnumerable<T> Rows)> sections, IEnumerable<(string Property, string Name, string? Unit, int Width)>? colNames = null) :
|
||||||
return _map.Select(i => (i.Item1, i.Item2?.GetValue(row) ?? i.Item3?.GetValue(row)));
|
this(name, fullName, sections, colNames?.Select(c => (c.Property, c.Name, c.Unit, (int?)c.Width))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected IEnumerable<object?> GetRowData(T row) {
|
protected IEnumerable<(string Name, object? Value)> GetNamedRowValues(T row) {
|
||||||
return GetNamedRowData(row).Select(i => i.Item2);
|
return _map.Select(i => (i.Name, i.PInfo?.GetValue(row) ?? i.FInfo?.GetValue(row)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IEnumerable<object?>> GetData() {
|
protected IEnumerable<object?> GetRowValues(T row) {
|
||||||
return Rows.Select(GetRowData);
|
return GetNamedRowValues(row).Select(i => i.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IEnumerable<(string, object?)>> GetNamedData() {
|
public IEnumerable<(string? Name, IEnumerable<IEnumerable<object?>> Rows)> GetData() {
|
||||||
return Rows.Select(GetNamedRowData);
|
return Sections.Select(s => (s.Name, s.Rows.Select(GetRowValues)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<(string? Name, IEnumerable<IEnumerable<(string Name, object? Value)>> Rows)> GetNamedData() {
|
||||||
|
return Sections.Select(s => (s.Name, s.Rows.Select(GetNamedRowValues)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
class MemberAreaComTotalsData : DataTable<MemberAreaComTotalsRow> {
|
class MemberAreaCmtTotalsData : DataTable<MemberAreaCmtTotalsRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = [
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
@@ -21,19 +21,19 @@ namespace Elwig.Models.Dtos {
|
|||||||
("DeliveryRights", "Lieferrecht", "kg", 22),
|
("DeliveryRights", "Lieferrecht", "kg", 22),
|
||||||
];
|
];
|
||||||
|
|
||||||
public MemberAreaComTotalsData(IEnumerable<MemberAreaComTotalsRow> rows, int year) :
|
public MemberAreaCmtTotalsData(IEnumerable<MemberAreaCmtTotalsRow> rows, int year) :
|
||||||
base($"Gebundene Fläche", $"Gebundene Fläche pro Mitglied {year}", rows, FieldNames) {
|
base($"Gebundene Fläche", $"Gebundene Fläche pro Mitglied {year}", rows, FieldNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<MemberAreaComTotalsData> ForSeason(DbSet<MemberAreaComTotalsRowSingle> table, int year) {
|
public static async Task<MemberAreaCmtTotalsData> ForSeason(DbSet<MemberAreaCmtTotalsRowSingle> table, int year) {
|
||||||
return new MemberAreaComTotalsData(
|
return new MemberAreaCmtTotalsData(
|
||||||
(await FromDbSet(table, year)).GroupBy(
|
(await FromDbSet(table, year)).GroupBy(
|
||||||
r => r.MgNr,
|
r => r.MgNr,
|
||||||
(k, g) => new MemberAreaComTotalsRow(g)
|
(k, g) => new MemberAreaCmtTotalsRow(g)
|
||||||
), year);
|
), year);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<MemberAreaComTotalsRowSingle>> FromDbSet(DbSet<MemberAreaComTotalsRowSingle> table, int year) {
|
private static async Task<IEnumerable<MemberAreaCmtTotalsRowSingle>> FromDbSet(DbSet<MemberAreaCmtTotalsRowSingle> table, int year) {
|
||||||
return await table.FromSql($"""
|
return 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 ||
|
||||||
@@ -50,7 +50,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MemberAreaComTotalsRow {
|
public class MemberAreaCmtTotalsRow {
|
||||||
public int MgNr;
|
public int MgNr;
|
||||||
public string Name1;
|
public string Name1;
|
||||||
public string? Name2;
|
public string? Name2;
|
||||||
@@ -63,7 +63,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
public int[] DeliveryObligations;
|
public int[] DeliveryObligations;
|
||||||
public int[] DeliveryRights;
|
public int[] DeliveryRights;
|
||||||
|
|
||||||
public MemberAreaComTotalsRow(IEnumerable<MemberAreaComTotalsRowSingle> rows) {
|
public MemberAreaCmtTotalsRow(IEnumerable<MemberAreaCmtTotalsRowSingle> rows) {
|
||||||
var f = rows.First();
|
var f = rows.First();
|
||||||
MgNr = f.MgNr;
|
MgNr = f.MgNr;
|
||||||
Name1 = f.Name1;
|
Name1 = f.Name1;
|
||||||
@@ -80,7 +80,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Keyless]
|
[Keyless]
|
||||||
public class MemberAreaComTotalsRowSingle {
|
public class MemberAreaCmtTotalsRowSingle {
|
||||||
[Column("mgnr")]
|
[Column("mgnr")]
|
||||||
public int MgNr { get; set; }
|
public int MgNr { get; set; }
|
||||||
[Column("name_1")]
|
[Column("name_1")]
|
||||||
@@ -5,7 +5,7 @@ using System.Linq;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Models.Dtos {
|
namespace Elwig.Models.Dtos {
|
||||||
class MemberAreaComsData : DataTable<MemberAreaComsRow> {
|
class MemberAreaCmtsData : DataTable<MemberAreaCmtsRow> {
|
||||||
|
|
||||||
private static readonly (string, string, string?, int)[] FieldNames = [
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
("MgNr", "MgNr.", null, 12),
|
("MgNr", "MgNr.", null, 12),
|
||||||
@@ -23,15 +23,15 @@ namespace Elwig.Models.Dtos {
|
|||||||
("MaxKg", "Lieferrecht", "kg", 22),
|
("MaxKg", "Lieferrecht", "kg", 22),
|
||||||
];
|
];
|
||||||
|
|
||||||
public MemberAreaComsData(IEnumerable<MemberAreaComsRow> rows, int year) :
|
public MemberAreaCmtsData(IEnumerable<MemberAreaCmtsRow> rows, int year) :
|
||||||
base($"Flächenbindungen", $"Flächenbindungen pro Mitglied {year}", rows, FieldNames) {
|
base($"Flächenbindungen", $"Flächenbindungen pro Mitglied {year}", rows, FieldNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<MemberAreaComsData> ForSeason(DbSet<MemberAreaComsRow> table, int year) {
|
public static async Task<MemberAreaCmtsData> ForSeason(DbSet<MemberAreaCmtsRow> table, int year) {
|
||||||
return new MemberAreaComsData(await FromDbSet(table, year), year);
|
return new MemberAreaCmtsData(await FromDbSet(table, year), year);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<MemberAreaComsRow>> FromDbSet(DbSet<MemberAreaComsRow> table, int year) {
|
private static async Task<IEnumerable<MemberAreaCmtsRow>> FromDbSet(DbSet<MemberAreaCmtsRow> table, int year) {
|
||||||
return await table.FromSql($"""
|
return 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 ||
|
||||||
@@ -56,7 +56,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Keyless]
|
[Keyless]
|
||||||
public class MemberAreaComsRow {
|
public class MemberAreaCmtsRow {
|
||||||
[Column("mgnr")]
|
[Column("mgnr")]
|
||||||
public int MgNr { get; set; }
|
public int MgNr { get; set; }
|
||||||
[Column("name_1")]
|
[Column("name_1")]
|
||||||
@@ -25,7 +25,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
("BillingPlz", "PLZ", null, 10),
|
("BillingPlz", "PLZ", null, 10),
|
||||||
("BillingLocality", "Ort", null, 60),
|
("BillingLocality", "Ort", null, 60),
|
||||||
("LfbisNr", "Betr.-Nr.", null, 20),
|
("LfbisNr", "Betr.-Nr.", null, 20),
|
||||||
("IsBuchführend", "buchf.", null, 15),
|
("IsAccounting", "buchf.", null, 15),
|
||||||
("IsOrganic", "Bio", null, 15),
|
("IsOrganic", "Bio", null, 15),
|
||||||
("IsActive", "aktiv", null, 15),
|
("IsActive", "aktiv", null, 15),
|
||||||
("EntryDate", "Eintritt", null, 20),
|
("EntryDate", "Eintritt", null, 20),
|
||||||
@@ -46,15 +46,15 @@ namespace Elwig.Models.Dtos {
|
|||||||
base(MemberList.Name, MemberList.Name, string.Join(" / ", filterNames), rows, FieldNames) {
|
base(MemberList.Name, MemberList.Name, string.Join(" / ", filterNames), rows, FieldNames) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCom) {
|
public static async Task<MemberListData> FromQuery(IQueryable<Member> query, List<string> filterNames, IEnumerable<string> filterAreaCmt) {
|
||||||
var areaComs = await query.Include(m => m.AreaCommitments).ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
var areaCmts = await query.Include(m => m.AreaCommitments).ToDictionaryAsync(m => m.MgNr, m => Utils.ActiveAreaCommitments(m.AreaCommitments));
|
||||||
return new((await query
|
return new((await query
|
||||||
.Include(m => m.Branch)
|
.Include(m => m.Branch)
|
||||||
.Include(m => m.TelephoneNumbers)
|
.Include(m => m.TelephoneNumbers)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.ToListAsync()).Select(m => new MemberListRow(m,
|
.ToListAsync()).Select(m => new MemberListRow(m,
|
||||||
areaComs[m.MgNr].Sum(c => c.Area),
|
areaCmts[m.MgNr].Sum(c => c.Area),
|
||||||
areaComs[m.MgNr].Where(c => filterAreaCom.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
areaCmts[m.MgNr].Where(c => filterAreaCmt.Contains(c.VtrgId)).GroupBy(c => c.VtrgId).ToDictionary(g => g.Key, g => g.Sum(c => c.Area)))),
|
||||||
filterNames);
|
filterNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +83,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
public string? Bic;
|
public string? Bic;
|
||||||
public int? AreaCommitment;
|
public int? AreaCommitment;
|
||||||
public (string VtrgId, int Area)[] AreaCommitmentsFiltered;
|
public (string VtrgId, int Area)[] AreaCommitmentsFiltered;
|
||||||
public bool IsBuchführend;
|
public bool IsAccounting;
|
||||||
public bool IsOrganic;
|
public bool IsOrganic;
|
||||||
public bool IsActive;
|
public bool IsActive;
|
||||||
public DateOnly? EntryDate;
|
public DateOnly? EntryDate;
|
||||||
@@ -94,7 +94,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
public string? AdditionalContact;
|
public string? AdditionalContact;
|
||||||
public string? Comment;
|
public string? Comment;
|
||||||
|
|
||||||
public MemberListRow(Member m, int? areaCom = null, Dictionary<string, int>? filtered = null) {
|
public MemberListRow(Member m, int? areaCmt = null, Dictionary<string, int>? filtered = null) {
|
||||||
MgNr = m.MgNr;
|
MgNr = m.MgNr;
|
||||||
Name1 = m.Name;
|
Name1 = m.Name;
|
||||||
AdminName1 = m.AdministrativeName1;
|
AdminName1 = m.AdministrativeName1;
|
||||||
@@ -118,7 +118,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
UstIdNr = m.UstIdNr;
|
UstIdNr = m.UstIdNr;
|
||||||
Iban = m.Iban != null ? Utils.FormatIban(m.Iban) : null;
|
Iban = m.Iban != null ? Utils.FormatIban(m.Iban) : null;
|
||||||
Bic = m.Bic;
|
Bic = m.Bic;
|
||||||
IsBuchführend = m.IsBuchführend;
|
IsAccounting = m.IsAccounting;
|
||||||
IsOrganic = m.IsOrganic;
|
IsOrganic = m.IsOrganic;
|
||||||
IsActive = m.IsActive;
|
IsActive = m.IsActive;
|
||||||
EntryDate = m.EntryDate;
|
EntryDate = m.EntryDate;
|
||||||
@@ -133,7 +133,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
.Distinct()
|
.Distinct()
|
||||||
.Concat(m.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).Except([EmailAddress])));
|
.Concat(m.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).Except([EmailAddress])));
|
||||||
Comment = m.Comment;
|
Comment = m.Comment;
|
||||||
AreaCommitment = areaCom == 0 ? null : areaCom;
|
AreaCommitment = areaCmt == 0 ? null : areaCmt;
|
||||||
AreaCommitmentsFiltered = filtered != null ? filtered.OrderBy(f => f.Key).Select(f => (f.Key, f.Value)).ToArray() : [];
|
AreaCommitmentsFiltered = filtered != null ? filtered.OrderBy(f => f.Key).Select(f => (f.Key, f.Value)).ToArray() : [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Models.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Elwig.Models.Dtos {
|
||||||
|
public class MemberMovementData : DataTable<MemberMovementDataRow> {
|
||||||
|
|
||||||
|
private static readonly (string, string, string?, int)[] FieldNames = [
|
||||||
|
("Type", "\u2026 durch", null, 30),
|
||||||
|
("MgNr", "MgNr.", null, 12),
|
||||||
|
("Name1", "Name", null, 40),
|
||||||
|
("Name2", "Vorname", null, 25),
|
||||||
|
("Address", "Adresse", null, 50),
|
||||||
|
("Plz", "PLZ", null, 10),
|
||||||
|
("Locality", "Ort", null, 50),
|
||||||
|
("Date", "Datum", null, 20),
|
||||||
|
("SharesOld", "GA\nalt", null, 10),
|
||||||
|
("SharesDiff", "GA\nDiff.", null, 10),
|
||||||
|
("SharesNew", "GA\nneu", null, 10),
|
||||||
|
("Costs", "Kosten", "€", 15),
|
||||||
|
];
|
||||||
|
|
||||||
|
private MemberMovementData(string name, IEnumerable<(string? Name, IEnumerable<MemberMovementDataRow> Rows)> sections) :
|
||||||
|
base("Mitgl.-Bewegungen", name, sections, FieldNames) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MemberMovementData FromMemberHistory(string name, IEnumerable<MemberHistory> rows, Dictionary<int, SortedDictionary<DateOnly, MemberHistoryPoint>> history) {
|
||||||
|
(string? Name, List<MemberMovementDataRow> Rows)[] sections = [
|
||||||
|
("Beitritt", []),
|
||||||
|
("Nachzeichnung (GA)", []),
|
||||||
|
("Überschreibung", []),
|
||||||
|
("Kündigung (GA)", []),
|
||||||
|
("Austritt", []),
|
||||||
|
];
|
||||||
|
foreach (var h in rows.OrderBy(r => r.DateNotice).ThenBy(r => r.ToMgNr).ThenBy(r => r.FromMgNr)) {
|
||||||
|
|
||||||
|
int cat;
|
||||||
|
if (h.ToMgNr == h.FromMgNr) {
|
||||||
|
// Umwandlung
|
||||||
|
if (h.ToType == BusinessShareType.Dormant) {
|
||||||
|
// Kündigung (GA)
|
||||||
|
cat = 3;
|
||||||
|
} else if (h.FromType == h.ToType) {
|
||||||
|
// Überschreibung
|
||||||
|
cat = 2;
|
||||||
|
} else {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
} else if (h.DateNotice <= h.ToMember?.EntryDate && h.DateNotice >= h.FromMember?.ExitDate) {
|
||||||
|
// Überschreibung
|
||||||
|
cat = 2;
|
||||||
|
} else if (h.DateNotice <= h.ToMember?.EntryDate) {
|
||||||
|
// Beitritt
|
||||||
|
cat = 0;
|
||||||
|
} else if (h.DateNotice >= h.FromMember?.ExitDate) {
|
||||||
|
// Austritt
|
||||||
|
cat = 4;
|
||||||
|
} else if (h.ToMember == null) {
|
||||||
|
// Auszahlung
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
// Nachzeichnung (GA)
|
||||||
|
cat = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Member a;
|
||||||
|
Member? b = null;
|
||||||
|
if (h.FromMember != null && h.ToMember != null) {
|
||||||
|
if (cat <= 1) {
|
||||||
|
a = h.ToMember;
|
||||||
|
b = h.FromMember;
|
||||||
|
} else {
|
||||||
|
a = h.FromMember;
|
||||||
|
b = h.ToMember;
|
||||||
|
}
|
||||||
|
} else if (h.FromMember != null) {
|
||||||
|
a = h.FromMember;
|
||||||
|
} else if (h.ToMember != null) {
|
||||||
|
a = h.ToMember;
|
||||||
|
} else {
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
var oldA = history[a.MgNr].GetValueOrDefault(h.DateNotice);
|
||||||
|
var d = new MemberMovementDataRow {
|
||||||
|
Type = [h.ReasonPretty],
|
||||||
|
|
||||||
|
MgNr = [a.MgNr],
|
||||||
|
Name1 = [a.Name],
|
||||||
|
Name2 = [a.AdministrativeName2],
|
||||||
|
Address = [a.Address],
|
||||||
|
Plz = [a.PostalDest.AtPlz!.Plz],
|
||||||
|
Locality = [a.PostalDest.AtPlz.Ort.Name],
|
||||||
|
|
||||||
|
Date = h.DateNotice,
|
||||||
|
SharesOld = [oldA.Shares + oldA.SharesRed + oldA.SharesWhite],
|
||||||
|
SharesDiff = [cat != 3 && a == h.ToMember ? h.Shares : -h.Shares],
|
||||||
|
Costs = [h.FromMember == null ? h.TotalValue : null],
|
||||||
|
};
|
||||||
|
d.SharesNew = [d.SharesOld[^1] + (h.FromMgNr == h.ToMgNr ? 0 : d.SharesDiff[^1])];
|
||||||
|
|
||||||
|
if (b != null) {
|
||||||
|
var oldB = history[b.MgNr].GetValueOrDefault(h.DateNotice);
|
||||||
|
d.Type = [..d.Type, "\u2026 " + (cat <= 1 ? "von" : "an")];
|
||||||
|
|
||||||
|
d.MgNr = [.. d.MgNr, b.MgNr];
|
||||||
|
d.Name1 = [.. d.Name1, b.Name];
|
||||||
|
d.Name2 = [.. d.Name2, b.AdministrativeName2];
|
||||||
|
d.Address = [.. d.Address, b.Address];
|
||||||
|
d.Plz = [.. d.Plz, b.PostalDest.AtPlz!.Plz];
|
||||||
|
d.Locality = [.. d.Locality, b.PostalDest.AtPlz.Ort.Name];
|
||||||
|
|
||||||
|
d.SharesOld = [.. d.SharesOld, oldB.Shares + oldB.SharesRed + oldB.SharesWhite];
|
||||||
|
d.SharesDiff = [.. d.SharesDiff, b == h.ToMember ? h.Shares : -h.Shares];
|
||||||
|
d.SharesNew = [.. d.SharesNew, d.SharesOld[^1] + d.SharesDiff[^1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
sections[cat].Rows.Add(d);
|
||||||
|
}
|
||||||
|
return new MemberMovementData($"Mitglieder-Bewegungen {name}", sections.Select(s => (s.Name, (IEnumerable<MemberMovementDataRow>)s.Rows)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MemberMovementDataRow {
|
||||||
|
public string[] Type = [];
|
||||||
|
|
||||||
|
public int[] MgNr = [];
|
||||||
|
public string[] Name1 = [];
|
||||||
|
public string?[] Name2 = [];
|
||||||
|
public string[] Address = [];
|
||||||
|
public int[] Plz = [];
|
||||||
|
public string[] Locality = [];
|
||||||
|
|
||||||
|
public DateOnly Date;
|
||||||
|
public int?[] SharesOld = [];
|
||||||
|
public int[] SharesDiff = [];
|
||||||
|
public int?[] SharesNew = [];
|
||||||
|
public decimal?[] Costs = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,9 +18,9 @@ namespace Elwig.Models.Dtos {
|
|||||||
("Cultivation", "Bewirt.", null, 20),
|
("Cultivation", "Bewirt.", null, 20),
|
||||||
("QualityLevel", "Qualitätsstufe", null, 30),
|
("QualityLevel", "Qualitätsstufe", null, 30),
|
||||||
("Oe", "Gradation", "°Oe", 20),
|
("Oe", "Gradation", "°Oe", 20),
|
||||||
("Ungeb", "ungebunden", "kg|€/kg|€/kg", 60),
|
("UnCtrd", "ungebunden", "kg|€/kg|€/kg", 60),
|
||||||
("LowGeb", "attributlos gebunden", "kg|€/kg|€/kg", 60),
|
("LowCtrd", "attributlos gebunden", "kg|€/kg|€/kg", 60),
|
||||||
("Geb", "gebunden", "kg|€/kg|€/kg", 60),
|
("Ctrd", "gebunden", "kg|€/kg|€/kg", 60),
|
||||||
("Amount", "Gesamt", "€", 25),
|
("Amount", "Gesamt", "€", 25),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -31,9 +31,9 @@ namespace Elwig.Models.Dtos {
|
|||||||
string? Cultivation,
|
string? Cultivation,
|
||||||
string QualityLevel,
|
string QualityLevel,
|
||||||
double Oe,
|
double Oe,
|
||||||
(int Weight, decimal? MinPrice, decimal? MaxPrice) Ungeb,
|
(int Weight, decimal? MinPrice, decimal? MaxPrice) UnCtrd,
|
||||||
(int Weight, decimal? MinPrice, decimal? MaxPrice) LowGeb,
|
(int Weight, decimal? MinPrice, decimal? MaxPrice) LowCtrd,
|
||||||
(int Weight, decimal? MinPrice, decimal? MaxPrice) Geb,
|
(int Weight, decimal? MinPrice, decimal? MaxPrice) Ctrd,
|
||||||
decimal Amount
|
decimal Amount
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -44,9 +44,9 @@ namespace Elwig.Models.Dtos {
|
|||||||
public static async Task<PaymentVariantSummaryData> ForPaymentVariant(PaymentVar v, DbSet<PaymentVariantSummaryRow> table) {
|
public static async Task<PaymentVariantSummaryData> ForPaymentVariant(PaymentVar v, DbSet<PaymentVariantSummaryRow> table) {
|
||||||
return new(v, (await FromDbSet(table, v.Year, v.AvNr))
|
return new(v, (await FromDbSet(table, v.Year, v.AvNr))
|
||||||
.Select(r => new PaymentRow(r.Type, r.Variety, r.Attribute, r.Cultivation, r.QualityLevel, r.Oe,
|
.Select(r => new PaymentRow(r.Type, r.Variety, r.Attribute, r.Cultivation, r.QualityLevel, r.Oe,
|
||||||
(r.WeightUngeb, r.MinPriceUngeb != null ? Utils.DecFromDb(r.MinPriceUngeb.Value, v.Season.Precision) : null, r.MaxPriceUngeb != null ? Utils.DecFromDb(r.MaxPriceUngeb.Value, v.Season.Precision) : null),
|
(r.WeightUnCtrd, r.MinPriceUnCtrd != null ? Utils.DecFromDb(r.MinPriceUnCtrd.Value, v.Season.Precision) : null, r.MaxPriceUnCtrd != null ? Utils.DecFromDb(r.MaxPriceUnCtrd.Value, v.Season.Precision) : null),
|
||||||
(r.WeightLowGeb, r.MinPriceLowGeb != null ? Utils.DecFromDb(r.MinPriceLowGeb.Value, v.Season.Precision) : null, r.MaxPriceLowGeb != null ? Utils.DecFromDb(r.MaxPriceLowGeb.Value, v.Season.Precision) : null),
|
(r.WeightLowCtrd, r.MinPriceLowCtrd != null ? Utils.DecFromDb(r.MinPriceLowCtrd.Value, v.Season.Precision) : null, r.MaxPriceLowCtrd != null ? Utils.DecFromDb(r.MaxPriceLowCtrd.Value, v.Season.Precision) : null),
|
||||||
(r.WeightGeb, r.MinPriceGeb != null ? Utils.DecFromDb(r.MinPriceGeb.Value, v.Season.Precision) : null, r.MaxPriceGeb != null ? Utils.DecFromDb(r.MaxPriceGeb.Value, v.Season.Precision) : null),
|
(r.WeightCtrd, r.MinPriceCtrd != null ? Utils.DecFromDb(r.MinPriceCtrd.Value, v.Season.Precision) : null, r.MaxPriceCtrd != null ? Utils.DecFromDb(r.MaxPriceCtrd.Value, v.Season.Precision) : null),
|
||||||
Utils.DecFromDb(r.Amount, v.Season.Precision)))
|
Utils.DecFromDb(r.Amount, v.Season.Precision)))
|
||||||
.ToArray());
|
.ToArray());
|
||||||
}
|
}
|
||||||
@@ -59,15 +59,15 @@ namespace Elwig.Models.Dtos {
|
|||||||
c.name AS cultivation,
|
c.name AS cultivation,
|
||||||
q.name AS quality_level,
|
q.name AS quality_level,
|
||||||
ROUND(kmw * (4.54 + 0.022 * kmw)) AS oe,
|
ROUND(kmw * (4.54 + 0.022 * kmw)) AS oe,
|
||||||
SUM(IIF(w.discr = '_', w.value, 0)) AS weight_ungeb,
|
SUM(IIF(w.discr = '_', w.value, 0)) AS weight_unctrd,
|
||||||
MIN(IIF(w.discr = '_', b.price, NULL)) AS min_price_ungeb,
|
MIN(IIF(w.discr = '_', b.price, NULL)) AS min_price_unctrd,
|
||||||
MAX(IIF(w.discr = '_', b.price, NULL)) AS max_price_ungeb,
|
MAX(IIF(w.discr = '_', b.price, NULL)) AS max_price_unctrd,
|
||||||
SUM(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), w.value, 0)) AS weight_lowgeb,
|
SUM(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), w.value, 0)) AS weight_lowctrd,
|
||||||
MIN(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), b.price, NULL)) AS min_price_lowgeb,
|
MIN(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), b.price, NULL)) AS min_price_lowctrd,
|
||||||
MAX(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), b.price, NULL)) AS max_price_lowgeb,
|
MAX(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), b.price, NULL)) AS max_price_lowctrd,
|
||||||
SUM(IIF(w.discr = COALESCE(p.attrid, ''), w.value, 0)) AS weight_geb,
|
SUM(IIF(w.discr = COALESCE(p.attrid, ''), w.value, 0)) AS weight_ctrd,
|
||||||
MIN(IIF(w.discr = COALESCE(p.attrid, ''), b.price, NULL)) AS min_price_geb,
|
MIN(IIF(w.discr = COALESCE(p.attrid, ''), b.price, NULL)) AS min_price_ctrd,
|
||||||
MAX(IIF(w.discr = COALESCE(p.attrid, ''), b.price, NULL)) AS max_price_geb,
|
MAX(IIF(w.discr = COALESCE(p.attrid, ''), b.price, NULL)) AS max_price_ctrd,
|
||||||
SUM(b.amount) AS amount
|
SUM(b.amount) AS amount
|
||||||
FROM payment_delivery_part_bucket b
|
FROM payment_delivery_part_bucket b
|
||||||
LEFT JOIN delivery_part_bucket w ON (w.year, w.did, w.dpnr, w.bktnr) = (b.year, b.did, b.dpnr, b.bktnr)
|
LEFT JOIN delivery_part_bucket w ON (w.year, w.did, w.dpnr, w.bktnr) = (b.year, b.did, b.dpnr, b.bktnr)
|
||||||
@@ -97,24 +97,24 @@ namespace Elwig.Models.Dtos {
|
|||||||
public required string QualityLevel { get; set; }
|
public required string QualityLevel { get; set; }
|
||||||
[Column("oe")]
|
[Column("oe")]
|
||||||
public double Oe { get; set; }
|
public double Oe { get; set; }
|
||||||
[Column("weight_ungeb")]
|
[Column("weight_unctrd")]
|
||||||
public int WeightUngeb { get; set; }
|
public int WeightUnCtrd { get; set; }
|
||||||
[Column("min_price_ungeb")]
|
[Column("min_price_unctrd")]
|
||||||
public long? MinPriceUngeb { get; set; }
|
public long? MinPriceUnCtrd { get; set; }
|
||||||
[Column("max_price_ungeb")]
|
[Column("max_price_unctrd")]
|
||||||
public long? MaxPriceUngeb { get; set; }
|
public long? MaxPriceUnCtrd { get; set; }
|
||||||
[Column("weight_lowgeb")]
|
[Column("weight_lowctrd")]
|
||||||
public int WeightLowGeb { get; set; }
|
public int WeightLowCtrd { get; set; }
|
||||||
[Column("min_price_lowgeb")]
|
[Column("min_price_lowctrd")]
|
||||||
public long? MinPriceLowGeb { get; set; }
|
public long? MinPriceLowCtrd { get; set; }
|
||||||
[Column("max_price_lowgeb")]
|
[Column("max_price_lowctrd")]
|
||||||
public long? MaxPriceLowGeb { get; set; }
|
public long? MaxPriceLowCtrd { get; set; }
|
||||||
[Column("weight_geb")]
|
[Column("weight_ctrd")]
|
||||||
public int WeightGeb { get; set; }
|
public int WeightCtrd { get; set; }
|
||||||
[Column("min_price_geb")]
|
[Column("min_price_ctrd")]
|
||||||
public long? MinPriceGeb { get; set; }
|
public long? MinPriceCtrd { get; set; }
|
||||||
[Column("max_price_geb")]
|
[Column("max_price_ctrd")]
|
||||||
public long? MaxPriceGeb { get; set; }
|
public long? MaxPriceCtrd { get; set; }
|
||||||
[Column("amount")]
|
[Column("amount")]
|
||||||
public long Amount { get; set; }
|
public long Amount { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace Elwig.Models.Dtos {
|
|||||||
("AttrId", "Attr.", null, 10),
|
("AttrId", "Attr.", null, 10),
|
||||||
("CultId", "Bewirt.", null, 15),
|
("CultId", "Bewirt.", null, 15),
|
||||||
("QualId", "Qual.", null, 15),
|
("QualId", "Qual.", null, 15),
|
||||||
("Geb", "gebunden", null, 20),
|
("Contracted", "gebunden", null, 20),
|
||||||
("Weight", "Menge", "kg", 20),
|
("Weight", "Menge", "kg", 20),
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -28,12 +28,12 @@ namespace Elwig.Models.Dtos {
|
|||||||
private static async Task<IEnumerable<WeightBreakdownRow>> FromDbSet(DbSet<WeightBreakdownRow> table, int year, string? zwstid) {
|
private static async Task<IEnumerable<WeightBreakdownRow>> FromDbSet(DbSet<WeightBreakdownRow> table, int year, string? zwstid) {
|
||||||
zwstid = zwstid == null ? "NULL" : $"'{zwstid}'";
|
zwstid = zwstid == null ? "NULL" : $"'{zwstid}'";
|
||||||
return await table.FromSqlRaw($"""
|
return await table.FromSqlRaw($"""
|
||||||
SELECT type, sortid, attrid, cultid, v.qualid, geb, SUM(weight) AS weight
|
SELECT type, sortid, attrid, cultid, v.qualid, contracted, SUM(weight) AS weight
|
||||||
FROM v_stat_total v
|
FROM v_stat_total v
|
||||||
LEFT JOIN wine_quality_level q ON q.qualid = v.qualid
|
LEFT JOIN wine_quality_level q ON q.qualid = v.qualid
|
||||||
WHERE year = {year} AND ({zwstid} IS NULL OR zwstid = {zwstid})
|
WHERE year = {year} AND ({zwstid} IS NULL OR zwstid = {zwstid})
|
||||||
GROUP BY type, sortid, attrid, cultid, v.qualid, geb
|
GROUP BY type, sortid, attrid, cultid, v.qualid, contracted
|
||||||
ORDER BY type DESC, sortid, attrid, cultid, q.min_kmw, geb
|
ORDER BY type DESC, sortid, attrid, cultid, q.min_kmw, contracted
|
||||||
""").ToListAsync();
|
""").ToListAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,8 +50,8 @@ namespace Elwig.Models.Dtos {
|
|||||||
public string? CultId { get; set; }
|
public string? CultId { get; set; }
|
||||||
[Column("qualid")]
|
[Column("qualid")]
|
||||||
public required string QualId { get; set; }
|
public required string QualId { get; set; }
|
||||||
[Column("geb")]
|
[Column("contracted")]
|
||||||
public required string Geb { get; set; }
|
public required string Contracted { get; set; }
|
||||||
[Column("weight")]
|
[Column("weight")]
|
||||||
public int Weight { get; set; }
|
public int Weight { get; set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("dest")]
|
[Column("dest")]
|
||||||
public string Dest { get; private set; } = null!;
|
public string Dest { get; private set; } = null!;
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public string FullDest => $"{Ort.Name} ({Dest})";
|
||||||
|
|
||||||
[ForeignKey("Plz")]
|
[ForeignKey("Plz")]
|
||||||
public virtual AT_Plz AtPlz { get; private set; } = null!;
|
public virtual AT_Plz AtPlz { get; private set; } = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||||||
|
|
||||||
namespace Elwig.Models.Entities {
|
namespace Elwig.Models.Entities {
|
||||||
[Table("area_commitment"), PrimaryKey("FbNr", "RevNr")]
|
[Table("area_commitment"), PrimaryKey("FbNr", "RevNr")]
|
||||||
public class AreaCom {
|
public class AreaCmt {
|
||||||
[Column("fbnr")]
|
[Column("fbnr")]
|
||||||
public int FbNr { get; set; }
|
public int FbNr { get; set; }
|
||||||
|
|
||||||
@@ -65,13 +65,13 @@ namespace Elwig.Models.Entities {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ForeignKey("FbNr")]
|
[ForeignKey("FbNr")]
|
||||||
public virtual AreaComContract Contract { get; private set; } = null!;
|
public virtual AreaCmtContract Contract { get; private set; } = null!;
|
||||||
|
|
||||||
[ForeignKey("MgNr")]
|
[ForeignKey("MgNr")]
|
||||||
public virtual Member Member { get; private set; } = null!;
|
public virtual Member Member { get; private set; } = null!;
|
||||||
|
|
||||||
[ForeignKey("VtrgId")]
|
[ForeignKey("VtrgId")]
|
||||||
public virtual AreaComType AreaComType { get; private set; } = null!;
|
public virtual AreaCmtType AreaCmtType { get; private set; } = null!;
|
||||||
|
|
||||||
[ForeignKey("CultId")]
|
[ForeignKey("CultId")]
|
||||||
public virtual WineCult? WineCult { get; private set; }
|
public virtual WineCult? WineCult { get; private set; }
|
||||||
@@ -7,7 +7,7 @@ using System.Linq;
|
|||||||
|
|
||||||
namespace Elwig.Models.Entities {
|
namespace Elwig.Models.Entities {
|
||||||
[Table("area_commitment_contract"), PrimaryKey("FbNr")]
|
[Table("area_commitment_contract"), PrimaryKey("FbNr")]
|
||||||
public class AreaComContract {
|
public class AreaCmtContract {
|
||||||
[Column("fbnr")]
|
[Column("fbnr")]
|
||||||
public int FbNr { get; set; }
|
public int FbNr { get; set; }
|
||||||
|
|
||||||
@@ -58,11 +58,11 @@ namespace Elwig.Models.Entities {
|
|||||||
[ForeignKey("KgNr, RdNr")]
|
[ForeignKey("KgNr, RdNr")]
|
||||||
public virtual WbRd? Rd { get; private set; }
|
public virtual WbRd? Rd { get; private set; }
|
||||||
|
|
||||||
[InverseProperty(nameof(AreaCom.Contract))]
|
[InverseProperty(nameof(AreaCmt.Contract))]
|
||||||
public virtual ICollection<AreaCom> Revisions { get; private set; } = null!;
|
public virtual ICollection<AreaCmt> Revisions { get; private set; } = null!;
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public AreaCom? Latest => Revisions.OrderBy(r => r.RevNr).LastOrDefault();
|
public AreaCmt? Latest => Revisions.OrderBy(r => r.RevNr).LastOrDefault();
|
||||||
|
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public int? YearFrom => Revisions.Any(r => r.YearFrom == null) ? null : Revisions.Min(r => r.YearFrom);
|
public int? YearFrom => Revisions.Any(r => r.YearFrom == null) ? null : Revisions.Min(r => r.YearFrom);
|
||||||
@@ -5,7 +5,7 @@ using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
|
|||||||
|
|
||||||
namespace Elwig.Models.Entities {
|
namespace Elwig.Models.Entities {
|
||||||
[Table("area_commitment_type"), PrimaryKey("VtrgId"), Index("SortId", "AttrId", "Discriminator", IsUnique = true)]
|
[Table("area_commitment_type"), PrimaryKey("VtrgId"), Index("SortId", "AttrId", "Discriminator", IsUnique = true)]
|
||||||
public class AreaComType {
|
public class AreaCmtType {
|
||||||
[Column("vtrgid")]
|
[Column("vtrgid")]
|
||||||
public required string VtrgId { get; set; }
|
public required string VtrgId { get; set; }
|
||||||
|
|
||||||
@@ -91,8 +91,8 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("hand_picked")]
|
[Column("hand_picked")]
|
||||||
public bool? IsHandPicked { get; set; }
|
public bool? IsHandPicked { get; set; }
|
||||||
|
|
||||||
[Column("gebunden")]
|
[Column("contracted")]
|
||||||
public bool? IsGebunden { get; set; }
|
public bool? IsContracted { get; set; }
|
||||||
|
|
||||||
[Column("unloading")]
|
[Column("unloading")]
|
||||||
public string? Unloading { get; set; }
|
public string? Unloading { get; set; }
|
||||||
@@ -124,7 +124,7 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("weighing_data")]
|
[Column("weighing_data")]
|
||||||
public string? WeighingData { get; set; }
|
public string? WeighingData { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public (string? ScaleId, string? Id, int? Gross, int? Tare, int? Net, DateOnly? Date, TimeOnly? Time) WeighingInfo {
|
public (string? ScaleId, string? Id, int? Gross, int? Tare, int? TareCorrection, int? Net, DateOnly? Date, TimeOnly? Time) WeighingInfo {
|
||||||
get {
|
get {
|
||||||
try {
|
try {
|
||||||
var obj = JsonNode.Parse(WeighingData!)!.AsObject();
|
var obj = JsonNode.Parse(WeighingData!)!.AsObject();
|
||||||
@@ -133,12 +133,13 @@ namespace Elwig.Models.Entities {
|
|||||||
obj["id"]?.AsValue().GetValue<string>(),
|
obj["id"]?.AsValue().GetValue<string>(),
|
||||||
obj["gross_weight"]?.AsValue().GetValue<int>(),
|
obj["gross_weight"]?.AsValue().GetValue<int>(),
|
||||||
obj["tare_weight"]?.AsValue().GetValue<int>(),
|
obj["tare_weight"]?.AsValue().GetValue<int>(),
|
||||||
|
obj["tare_correction"]?.AsValue().GetValue<int>(),
|
||||||
obj["net_weight"]?.AsValue().GetValue<int>(),
|
obj["net_weight"]?.AsValue().GetValue<int>(),
|
||||||
DateOnly.TryParseExact(obj["date"]?.AsValue().GetValue<string>(), "yyyy-MM-dd", out var d) ? d : null,
|
DateOnly.TryParseExact(obj["date"]?.AsValue().GetValue<string>(), "yyyy-MM-dd", out var d) ? d : null,
|
||||||
TimeOnly.TryParseExact(obj["time"]?.AsValue().GetValue<string>(), ["HH:mm:ss", "HH:mm"], out var t) ? t : null
|
TimeOnly.TryParseExact(obj["time"]?.AsValue().GetValue<string>(), ["HH:mm:ss", "HH:mm"], out var t) ? t : null
|
||||||
);
|
);
|
||||||
} catch {
|
} catch {
|
||||||
return (null, null, null, null, null, null, null);
|
return (null, null, null, null, null, null, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ namespace Elwig.Models.Entities {
|
|||||||
|
|
||||||
[Column("cultid")]
|
[Column("cultid")]
|
||||||
public string? CultId { get; set; }
|
public string? CultId { get; set; }
|
||||||
|
[NotMapped]
|
||||||
|
public bool IsOrganic => Cultivation?.IsOrganic ?? false;
|
||||||
|
|
||||||
[Column("max_weight")]
|
[Column("max_weight")]
|
||||||
public int? MaxWeight { get; set; }
|
public int? MaxWeight { get; set; }
|
||||||
|
|||||||
@@ -96,20 +96,26 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("ustid_nr")]
|
[Column("ustid_nr")]
|
||||||
public string? UstIdNr { get; set; }
|
public string? UstIdNr { get; set; }
|
||||||
|
|
||||||
|
[Column("ooc_id")]
|
||||||
|
public string? OrganicOperatorId { get; set; }
|
||||||
|
|
||||||
|
[Column("org_auth_code")]
|
||||||
|
public string? OrganicAuthorityCode { get; set; }
|
||||||
|
|
||||||
[Column("juridical_pers")]
|
[Column("juridical_pers")]
|
||||||
public bool IsJuridicalPerson { get; set; }
|
public bool IsJuridicalPerson { get; set; }
|
||||||
|
|
||||||
[Column("volllieferant")]
|
[Column("full_delivery")]
|
||||||
public bool IsVollLieferant { get; set; }
|
public bool IsFullDelivery { get; set; }
|
||||||
|
|
||||||
[Column("buchführend")]
|
[Column("accounting")]
|
||||||
public bool IsBuchführend { get; set; }
|
public bool IsAccounting { get; set; }
|
||||||
|
|
||||||
[Column("organic")]
|
[Column("organic")]
|
||||||
public bool IsOrganic { get; set; }
|
public bool IsOrganic { get; set; }
|
||||||
|
|
||||||
[Column("funktionär")]
|
[Column("officer")]
|
||||||
public bool IsFunktionär { get; set; }
|
public bool IsOfficer { get; set; }
|
||||||
|
|
||||||
[Column("active")]
|
[Column("active")]
|
||||||
public bool IsActive { get; set; }
|
public bool IsActive { get; set; }
|
||||||
@@ -193,10 +199,10 @@ namespace Elwig.Models.Entities {
|
|||||||
[ForeignKey("ZwstId")]
|
[ForeignKey("ZwstId")]
|
||||||
public virtual Branch? Branch { get; private set; }
|
public virtual Branch? Branch { get; private set; }
|
||||||
|
|
||||||
[InverseProperty(nameof(AreaCom.Member))]
|
[InverseProperty(nameof(AreaCmt.Member))]
|
||||||
public virtual ICollection<AreaCom> AreaCommitments { get; private set; } = null!;
|
public virtual ICollection<AreaCmt> AreaCommitments { get; private set; } = null!;
|
||||||
|
|
||||||
public IQueryable<AreaCom> ActiveAreaCommitments(AppDbContext ctx, int? year = null) {
|
public IQueryable<AreaCmt> ActiveAreaCommitments(AppDbContext ctx, int? year = null) {
|
||||||
return ctx.AreaCommitments.Where(c => c.MgNr == MgNr).Where(Utils.ActiveAreaCommitments(year ?? Utils.CurrentYear));
|
return ctx.AreaCommitments.Where(c => c.MgNr == MgNr).Where(Utils.ActiveAreaCommitments(year ?? Utils.CurrentYear));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,10 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("shares")]
|
[Column("shares")]
|
||||||
public int Shares { get; set; }
|
public int Shares { get; set; }
|
||||||
|
|
||||||
[Column("signed")]
|
[Column("signed_company")]
|
||||||
|
public bool CompanyHasSigned { get; set; }
|
||||||
|
|
||||||
|
[Column("signed_member")]
|
||||||
public bool MemberHasSigned { get; set; }
|
public bool MemberHasSigned { get; set; }
|
||||||
|
|
||||||
[Column("value_per_share")]
|
[Column("value_per_share")]
|
||||||
@@ -101,10 +104,10 @@ namespace Elwig.Models.Entities {
|
|||||||
|
|
||||||
public string FormatReasonPhrase(int mgnr) {
|
public string FormatReasonPhrase(int mgnr) {
|
||||||
if (Reason == REASON_TRANSFER) {
|
if (Reason == REASON_TRANSFER) {
|
||||||
if (FromMgNr == mgnr) {
|
if (ToMgNr == mgnr) {
|
||||||
return $"{ReasonPretty} an {ToMember?.FullAdministrativeName ?? "Nachfolger"}" + (Comment != null ? $", {Comment}" : "");
|
|
||||||
} else if (ToMgNr == mgnr) {
|
|
||||||
return $"{ReasonPretty} von {FromMember?.FullAdministrativeName ?? "Vorgänger"}" + (Comment != null ? $", {Comment}" : "");
|
return $"{ReasonPretty} von {FromMember?.FullAdministrativeName ?? "Vorgänger"}" + (Comment != null ? $", {Comment}" : "");
|
||||||
|
} else if (FromMgNr == mgnr) {
|
||||||
|
return $"{ReasonPretty} an {ToMember?.FullAdministrativeName ?? "Nachfolger"}" + (Comment != null ? $", {Comment}" : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ReasonPretty + (Comment != null ? $", {Comment}" : "");
|
return ReasonPretty + (Comment != null ? $", {Comment}" : "");
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("calc_mode")]
|
[Column("calc_mode")]
|
||||||
public int CalcMode { get; set; }
|
public int CalcMode { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public bool Billing_HonorGebunden {
|
public bool Billing_HonorContracted {
|
||||||
get => (CalcMode & 0x1) != 0;
|
get => (CalcMode & 0x1) != 0;
|
||||||
set => CalcMode = value ? CalcMode | 0x1 : CalcMode & ~0x1;
|
set => CalcMode = value ? CalcMode | 0x1 : CalcMode & ~0x1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ namespace Elwig.Models.Entities {
|
|||||||
[Column("name")]
|
[Column("name")]
|
||||||
public required string Name { get; set; }
|
public required string Name { get; set; }
|
||||||
|
|
||||||
|
[Column("organic")]
|
||||||
|
public bool IsOrganic { get; set; }
|
||||||
|
|
||||||
[Column("description")]
|
[Column("description")]
|
||||||
public string? Description { get; set; }
|
public string? Description { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -92,6 +92,12 @@
|
|||||||
{"$ref": "#/definitions/curve_data"}
|
{"$ref": "#/definitions/curve_data"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"ctrd": {
|
||||||
|
"anyOf": [
|
||||||
|
{"type": "number"},
|
||||||
|
{"$ref": "#/definitions/curve_data"}
|
||||||
|
]
|
||||||
|
},
|
||||||
"geb": {
|
"geb": {
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
{"type": "number"},
|
{"type": "number"},
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
-- schema version 41 to 42
|
||||||
|
|
||||||
|
ALTER TABLE member ADD COLUMN ooc_id TEXT CHECK (ooc_id REGEXP '^[0-9]{3}-[0-9]{7}$') DEFAULT NULL;
|
||||||
|
ALTER TABLE member ADD COLUMN org_auth_code TEXT CHECK (org_auth_code REGEXP '^[A-Z]{2}-[A-ZÖØ]{3}-[0-9]{2,3}(-[A-Z]{2})?$') DEFAULT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE wine_cultivation ADD COLUMN organic INTEGER NOT NULL CHECK (organic IN (TRUE, FALSE)) DEFAULT FALSE;
|
||||||
|
|
||||||
|
ALTER TABLE member_history RENAME COLUMN signed TO signed_member;
|
||||||
|
ALTER TABLE member_history ADD COLUMN signed_company INTEGER NOT NULL CHECK (signed_company IN (TRUE, FALSE)) DEFAULT FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
PRAGMA writable_schema = ON;
|
||||||
|
|
||||||
|
UPDATE sqlite_schema SET sql = REPLACE(REPLACE(REPLACE(sql, 'funktionär', 'officer '), 'buchführend', 'accounting '), 'volllieferant', 'full_delivery')
|
||||||
|
WHERE type = 'table' AND name = 'member';
|
||||||
|
|
||||||
|
UPDATE sqlite_schema SET sql = REPLACE(sql, 'gebunden', 'contracted')
|
||||||
|
WHERE type = 'table' AND name = 'delivery_part';
|
||||||
|
|
||||||
|
UPDATE sqlite_schema SET sql = REPLACE(sql, 'gebunden', 'contracted')
|
||||||
|
WHERE type = 'view' AND name = 'v_delivery';
|
||||||
|
|
||||||
|
UPDATE sqlite_schema SET sql = REPLACE(sql, 'volllieferant', 'full_delivery')
|
||||||
|
WHERE type = 'view' AND name = 'v_bki_member';
|
||||||
|
|
||||||
|
UPDATE sqlite_schema SET sql = REPLACE(sql, ' geb', ' contracted')
|
||||||
|
WHERE type = 'view' AND name = 'v_stat_total';
|
||||||
|
|
||||||
|
UPDATE sqlite_schema SET sql = REPLACE(sql, 'gebunden', 'contracted')
|
||||||
|
WHERE type = 'view' AND (name = 'v_payment_bucket_strict' OR name = 'v_payment_bucket' OR name = 'v_under_delivery_bucket');
|
||||||
|
|
||||||
|
PRAGMA schema_version = 4101;
|
||||||
|
PRAGMA writable_schema = OFF;
|
||||||
|
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
|
|
||||||
|
UPDATE member SET org_auth_code = UPPER(SUBSTR(a.name, -11, 10))
|
||||||
|
FROM member m JOIN member_billing_address a ON a.mgnr = m.mgnr
|
||||||
|
WHERE m.mgnr = member.mgnr AND a.name LIKE '%AT-BIO-___)';
|
||||||
|
UPDATE member SET org_auth_code = UPPER(suffix) WHERE suffix LIKE 'AT-BIO-___';
|
||||||
|
|
||||||
|
UPDATE wine_cultivation SET organic = TRUE WHERE name LIKE '%bio%' OR name LIKE '%org%' OR description LIKE '%AT-BIO-%';
|
||||||
|
UPDATE wine_cultivation SET description = NULL WHERE description LIKE '%AT-BIO-%';
|
||||||
|
UPDATE wine_cultivation SET description = 'Biologische Produktion' WHERE organic;
|
||||||
|
|
||||||
|
UPDATE delivery_schedule SET cultid = (SELECT cultid FROM wine_cultivation WHERE organic LIMIT 1) WHERE description LIKE '%Bio%';
|
||||||
|
|
||||||
|
UPDATE client_parameter SET param = 'CLIENT_ORGANIC_AUTHORITYCODE' WHERE param = 'CLIENT_ORGANIC_AUTHORITY';
|
||||||
|
|
||||||
|
|
||||||
|
UPDATE member_telephone_number SET comment = NULL WHERE comment = '';
|
||||||
|
UPDATE member_email_address SET comment = NULL WHERE comment = '';
|
||||||
|
|
||||||
|
UPDATE member SET address = CONCAT('Untere Weißgerberstraße ', SUBSTR(address, 21)) WHERE address LIKE 'U. Weißgasse Straße %';
|
||||||
|
UPDATE member SET address = CONCAT('Edgar-Penzig-Franz-Straße ', SUBSTR(address, 28)) WHERE address LIKE 'Edgar-Penzing-Franz-Straße %';
|
||||||
|
|
||||||
|
UPDATE member
|
||||||
|
SET address = NORMALIZE_ADDRESS(address, (SELECT o.name FROM AT_plz_dest p JOIN AT_ort o ON o.okz = p.okz WHERE p.id = member.postal_dest))
|
||||||
|
WHERE address != NORMALIZE_ADDRESS(address, (SELECT o.name FROM AT_plz_dest p JOIN AT_ort o ON o.okz = p.okz WHERE p.id = member.postal_dest));
|
||||||
|
UPDATE member_billing_address
|
||||||
|
SET address = NORMALIZE_ADDRESS(address, (SELECT o.name FROM AT_plz_dest p JOIN AT_ort o ON o.okz = p.okz WHERE p.id = member_billing_address.postal_dest))
|
||||||
|
WHERE address != NORMALIZE_ADDRESS(address, (SELECT o.name FROM AT_plz_dest p JOIN AT_ort o ON o.okz = p.okz WHERE p.id = member_billing_address.postal_dest));
|
||||||
|
|
||||||
|
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
|
||||||
@@ -8,9 +8,9 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace Elwig.Services {
|
namespace Elwig.Services {
|
||||||
public static class AreaComService {
|
public static class AreaCmtService {
|
||||||
|
|
||||||
public static async Task InitInputs(this AreaComAdminViewModel vm) {
|
public static async Task InitInputs(this AreaCmtAdminViewModel vm) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
vm.FbNr = await ctx.NextFbNr();
|
vm.FbNr = await ctx.NextFbNr();
|
||||||
vm.MgNr = vm.FilterMember.MgNr;
|
vm.MgNr = vm.FilterMember.MgNr;
|
||||||
@@ -18,11 +18,11 @@ namespace Elwig.Services {
|
|||||||
vm.WineCult = null;
|
vm.WineCult = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void ClearInputs(this AreaComAdminViewModel vm) {
|
public static void ClearInputs(this AreaCmtAdminViewModel vm) {
|
||||||
vm.Period = null;
|
vm.Period = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FillInputs(this AreaComAdminViewModel vm, AreaComContract c) {
|
public static void FillInputs(this AreaCmtAdminViewModel vm, AreaCmtContract c) {
|
||||||
vm.FbNr = c.FbNr;
|
vm.FbNr = c.FbNr;
|
||||||
vm.Period = c.YearTo == null ? $"ab {c.YearFrom}" : $"{c.YearFrom}\u2013{c.YearTo}";
|
vm.Period = c.YearTo == null ? $"ab {c.YearFrom}" : $"{c.YearFrom}\u2013{c.YearTo}";
|
||||||
vm.Comment = c.Comment;
|
vm.Comment = c.Comment;
|
||||||
@@ -30,21 +30,23 @@ namespace Elwig.Services {
|
|||||||
vm.Rd = ControlUtils.GetItemFromSourceWithPk(vm.RdSource, c.KgNr, c.RdNr) as WbRd;
|
vm.Rd = ControlUtils.GetItemFromSourceWithPk(vm.RdSource, c.KgNr, c.RdNr) as WbRd;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FillInputs(this AreaComAdminViewModel vm, AreaCom a) {
|
public static void FillInputs(this AreaCmtAdminViewModel vm, AreaCmt a) {
|
||||||
vm.MgNr = a.MgNr;
|
vm.MgNr = a.MgNr;
|
||||||
vm.YearFrom = a.YearFrom;
|
vm.YearFrom = a.YearFrom;
|
||||||
vm.YearTo = a.YearTo;
|
vm.YearTo = a.YearTo;
|
||||||
vm.AreaComType = ControlUtils.GetItemFromSourceWithPk(vm.AreaComTypeSource, a.VtrgId) as AreaComType;
|
vm.AreaCmtType = ControlUtils.GetItemFromSourceWithPk(vm.AreaCmtTypeSource, a.VtrgId) as AreaCmtType;
|
||||||
vm.WineCult = ControlUtils.GetItemFromSourceWithPk(vm.WineCultSource, a.CultId) as WineCult;
|
vm.WineCult = ControlUtils.GetItemFromSourceWithPk(vm.WineCultSource, a.CultId) as WineCult;
|
||||||
vm.GstNr = a.GstNr;
|
vm.GstNr = a.GstNr;
|
||||||
vm.Area = a.Area;
|
vm.Area = a.Area;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(List<string>, IQueryable<AreaComContract>, IQueryable<AreaCom>, List<string>)> GetFilters(this AreaComAdminViewModel vm, AppDbContext ctx) {
|
public static async Task<(List<string>, IQueryable<AreaCmtContract>, IQueryable<AreaCmt>, List<string>)> GetFilters(this AreaCmtAdminViewModel vm, AppDbContext ctx) {
|
||||||
List<string> filterNames = [];
|
List<string> filterNames = [];
|
||||||
IQueryable<AreaCom> areaComQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
IQueryable<AreaCmt> areaCmtQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
||||||
|
filterNames.Add(vm.FilterMember.AdministrativeName);
|
||||||
|
|
||||||
if (vm.FilterSeason is int season) {
|
if (vm.FilterSeason is int season) {
|
||||||
areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, season);
|
areaCmtQuery = Utils.ActiveAreaCommitments(areaCmtQuery, season);
|
||||||
filterNames.Add($"laufend {season}");
|
filterNames.Add($"laufend {season}");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,37 +96,37 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filterVar.Count > 0) areaComQuery = areaComQuery.Where(a => filterVar.Contains(a.AreaComType.WineVar.SortId));
|
if (filterVar.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => filterVar.Contains(a.AreaCmtType.WineVar.SortId));
|
||||||
if (filterNotVar.Count > 0) areaComQuery = areaComQuery.Where(a => !filterNotVar.Contains(a.AreaComType.WineVar.SortId));
|
if (filterNotVar.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => !filterNotVar.Contains(a.AreaCmtType.WineVar.SortId));
|
||||||
if (filterAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
if (filterAttr.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => a.AreaCmtType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaCmtType.WineAttr.AttrId));
|
||||||
if (filterNotAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
if (filterNotAttr.Count > 0) areaCmtQuery = areaCmtQuery.Where(a => a.AreaCmtType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaCmtType.WineAttr.AttrId));
|
||||||
}
|
}
|
||||||
|
|
||||||
IQueryable<AreaComContract> contracts = areaComQuery
|
IQueryable<AreaCmtContract> contracts = areaCmtQuery
|
||||||
.Select(c => c.Contract).Distinct()
|
.Select(c => c.Contract).Distinct()
|
||||||
.OrderBy(c => c.FbNr);
|
.OrderBy(c => c.FbNr);
|
||||||
|
|
||||||
return (filterNames, contracts, areaComQuery, filter);
|
return (filterNames, contracts, areaCmtQuery, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(int FbNr, int RevNr)> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr, int? revNr) {
|
public static async Task<(int FbNr, int RevNr)> UpdateAreaCommitment(this AreaCmtAdminViewModel vm, int? oldFbNr, int? revNr) {
|
||||||
int newFbNr = vm.FbNr!.Value;
|
int newFbNr = vm.FbNr!.Value;
|
||||||
|
|
||||||
return await Task.Run(async () => {
|
return await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var c = new AreaComContract {
|
var c = new AreaCmtContract {
|
||||||
FbNr = oldFbNr ?? newFbNr,
|
FbNr = oldFbNr ?? newFbNr,
|
||||||
Comment = string.IsNullOrWhiteSpace(vm.Comment) ? null : vm.Comment,
|
Comment = string.IsNullOrWhiteSpace(vm.Comment) ? null : vm.Comment,
|
||||||
KgNr = vm.Kg!.KgNr,
|
KgNr = vm.Kg!.KgNr,
|
||||||
RdNr = vm.Rd?.RdNr,
|
RdNr = vm.Rd?.RdNr,
|
||||||
};
|
};
|
||||||
var a = new AreaCom {
|
var a = new AreaCmt {
|
||||||
FbNr = oldFbNr ?? newFbNr,
|
FbNr = oldFbNr ?? newFbNr,
|
||||||
RevNr = revNr ?? await ctx.NextRevNr(oldFbNr ?? newFbNr),
|
RevNr = revNr ?? await ctx.NextRevNr(oldFbNr ?? newFbNr),
|
||||||
MgNr = vm.MgNr!.Value,
|
MgNr = vm.MgNr!.Value,
|
||||||
YearFrom = vm.YearFrom,
|
YearFrom = vm.YearFrom,
|
||||||
YearTo = vm.YearTo,
|
YearTo = vm.YearTo,
|
||||||
VtrgId = vm.AreaComType!.VtrgId,
|
VtrgId = vm.AreaCmtType!.VtrgId,
|
||||||
CultId = vm.WineCult?.CultId,
|
CultId = vm.WineCult?.CultId,
|
||||||
GstNr = vm.GstNr?.Trim() ?? "-",
|
GstNr = vm.GstNr?.Trim() ?? "-",
|
||||||
Area = vm.Area!.Value,
|
Area = vm.Area!.Value,
|
||||||
@@ -166,53 +168,53 @@ namespace Elwig.Services {
|
|||||||
grid.AddToolTipCell(max == null ? "" : $"{max:N0} kg", row, 4, bold: bold, alignRight: true);
|
grid.AddToolTipCell(max == null ? "" : $"{max:N0} kg", row, 4, bold: bold, alignRight: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(string, (string?, string?, int, int?, int?)[])> GenerateToolTipData(IQueryable<AreaCom> areaComs, int maxKgPerHa) {
|
public static async Task<(string, (string?, string?, int, int?, int?)[])> GenerateToolTipData(IQueryable<AreaCmt> areaCmts, int maxKgPerHa) {
|
||||||
var grid = new List<(string?, string?, int, int?, int?)>();
|
var grid = new List<(string?, string?, int, int?, int?)>();
|
||||||
var text = "-";
|
var text = "-";
|
||||||
|
|
||||||
var area = await areaComs.SumAsync(p => p.Area);
|
var area = await areaCmts.SumAsync(p => p.Area);
|
||||||
text = $"{area:N0} m²";
|
text = $"{area:N0} m²";
|
||||||
grid.Add(("Geb. Fläche", null, area, null, null));
|
grid.Add(("Geb. Fläche", null, area, null, null));
|
||||||
|
|
||||||
if (await areaComs.AnyAsync()) {
|
if (await areaCmts.AnyAsync()) {
|
||||||
var attrGroups = await areaComs
|
var attrGroups = await areaCmts
|
||||||
.Where(c => c.AreaComType.WineAttr != null)
|
.Where(c => c.AreaCmtType.WineAttr != null)
|
||||||
.GroupBy(c => c.AreaComType.WineAttr!.Name)
|
.GroupBy(c => c.AreaCmtType.WineAttr!.Name)
|
||||||
.Select(g => new {
|
.Select(g => new {
|
||||||
Attr = g.Key,
|
Attr = g.Key,
|
||||||
Area = g.Sum(c => c.Area),
|
Area = g.Sum(c => c.Area),
|
||||||
Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000),
|
Min = g.Sum(c => c.Area * (c.AreaCmtType.MinKgPerHa ?? 0) / 10_000),
|
||||||
Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
Max = g.Sum(c => c.Area * (c.AreaCmtType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||||
})
|
})
|
||||||
.OrderByDescending(g => g.Area)
|
.OrderByDescending(g => g.Area)
|
||||||
.ThenBy(g => g.Attr)
|
.ThenBy(g => g.Attr)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var groups = await areaComs
|
var groups = await areaCmts
|
||||||
.Where(c => c.AreaComType.WineAttr != null)
|
.Where(c => c.AreaCmtType.WineAttr != null)
|
||||||
.GroupBy(c => new {
|
.GroupBy(c => new {
|
||||||
Attr = c.AreaComType.WineAttr!.Name,
|
Attr = c.AreaCmtType.WineAttr!.Name,
|
||||||
c.AreaComType.SortId,
|
c.AreaCmtType.SortId,
|
||||||
})
|
})
|
||||||
.Select(g => new {
|
.Select(g => new {
|
||||||
g.Key.Attr,
|
g.Key.Attr,
|
||||||
g.Key.SortId,
|
g.Key.SortId,
|
||||||
Area = g.Sum(c => c.Area),
|
Area = g.Sum(c => c.Area),
|
||||||
Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000),
|
Min = g.Sum(c => c.Area * (c.AreaCmtType.MinKgPerHa ?? 0) / 10_000),
|
||||||
Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
Max = g.Sum(c => c.Area * (c.AreaCmtType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||||
})
|
})
|
||||||
.OrderByDescending(g => g.Area)
|
.OrderByDescending(g => g.Area)
|
||||||
.ThenBy(g => g.Attr)
|
.ThenBy(g => g.Attr)
|
||||||
.ThenBy(g => g.SortId)
|
.ThenBy(g => g.SortId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
var noAttr = await areaComs
|
var noAttr = await areaCmts
|
||||||
.Where(c => c.AreaComType.WineAttr == null || !c.AreaComType.WineAttr.IsStrict)
|
.Where(c => c.AreaCmtType.WineAttr == null || !c.AreaCmtType.WineAttr.IsStrict)
|
||||||
.GroupBy(c => c.AreaComType.SortId)
|
.GroupBy(c => c.AreaCmtType.SortId)
|
||||||
.Select(g => new {
|
.Select(g => new {
|
||||||
SortId = g.Key,
|
SortId = g.Key,
|
||||||
Area = g.Sum(c => c.Area),
|
Area = g.Sum(c => c.Area),
|
||||||
Min = g.Sum(c => c.Area * (c.AreaComType.MinKgPerHa ?? 0) / 10_000),
|
Min = g.Sum(c => c.Area * (c.AreaCmtType.MinKgPerHa ?? 0) / 10_000),
|
||||||
Max = g.Sum(c => c.Area * (c.AreaComType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
Max = g.Sum(c => c.Area * (c.AreaCmtType.WineAttr!.MaxKgPerHa ?? maxKgPerHa) / 10_000),
|
||||||
})
|
})
|
||||||
.OrderByDescending(g => g.Area)
|
.OrderByDescending(g => g.Area)
|
||||||
.ThenBy(g => g.SortId)
|
.ThenBy(g => g.SortId)
|
||||||
@@ -252,7 +254,7 @@ namespace Elwig.Services {
|
|||||||
return grid;
|
return grid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task DeleteAreaCom(int fbnr) {
|
public static async Task DeleteAreaCmt(int fbnr) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var l = (await ctx.AreaCommitmentContracts.FindAsync(fbnr))!;
|
var l = (await ctx.AreaCommitmentContracts.FindAsync(fbnr))!;
|
||||||
@@ -261,7 +263,7 @@ namespace Elwig.Services {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task DeleteAreaComRevision(int fbnr, int revnr) {
|
public static async Task DeleteAreaCmtRevision(int fbnr, int revnr) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var l = (await ctx.AreaCommitments.FindAsync(fbnr, revnr))!;
|
var l = (await ctx.AreaCommitments.FindAsync(fbnr, revnr))!;
|
||||||
@@ -0,0 +1,133 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Export;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace Elwig.Services {
|
||||||
|
public static class BackupService {
|
||||||
|
|
||||||
|
public static bool IsAnyBackupUpToDate {
|
||||||
|
get {
|
||||||
|
var lastDbWrite = File.GetLastWriteTime(App.Config.DatabaseFile);
|
||||||
|
lastDbWrite += new TimeSpan(0, 0, -1);
|
||||||
|
return Directory.GetFiles(App.Config.BackupPath, "????-??-??_??-??-??.*.zip")
|
||||||
|
.Any(n => DateTime.ParseExact(Path.GetFileName(n)[..19], "yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.None) >= lastDbWrite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task TryDatabaseBackup() {
|
||||||
|
if (IsAnyBackupUpToDate) return;
|
||||||
|
await BackupDatabase();
|
||||||
|
PruneBackups();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task BackupDatabase() {
|
||||||
|
await Database.ExportSql(Path.Combine(App.Config.BackupPath, $"{File.GetLastWriteTime(App.Config.DatabaseFile):yyyy-MM-dd_HH-mm-ss}.sql.zip"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PruneBackups() {
|
||||||
|
var retain = new HashSet<string>();
|
||||||
|
var backups = Directory.GetFiles(App.Config.BackupPath, "????-??-??_??-??-??.*.zip")
|
||||||
|
.Select(n => (FileName: n, Timestamp: DateTime.ParseExact(Path.GetFileName(n)[..19], "yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture, DateTimeStyles.None)))
|
||||||
|
.OrderByDescending(t => t.Timestamp).ToArray();
|
||||||
|
|
||||||
|
DateTime now;
|
||||||
|
|
||||||
|
// retain hourly backups
|
||||||
|
now = DateTime.Now;
|
||||||
|
for (int i = 0; i < App.Config.BackupRetainHours; i++, now = now.AddHours(-1)) {
|
||||||
|
foreach (var b in backups) {
|
||||||
|
if (b.Timestamp.Date == now.Date && b.Timestamp.Hour == now.Hour) {
|
||||||
|
retain.Add(b.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// retain daily backups
|
||||||
|
now = DateTime.Now;
|
||||||
|
for (int i = 0; i < App.Config.BackupRetainDays; i++, now = now.AddDays(-1)) {
|
||||||
|
foreach (var b in backups) {
|
||||||
|
if (b.Timestamp.Date == now.Date) {
|
||||||
|
retain.Add(b.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// retain weekly backups
|
||||||
|
now = DateTime.Now;
|
||||||
|
for (int i = 0; i < App.Config.BackupRetainWeeks; i++, now = now.AddDays(-7)) {
|
||||||
|
foreach (var b in backups) {
|
||||||
|
if (b.Timestamp.GetYearAndWeek() == now.GetYearAndWeek()) {
|
||||||
|
retain.Add(b.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// retain monthly backups
|
||||||
|
now = DateTime.Now;
|
||||||
|
for (int i = 0; i < App.Config.BackupRetainMonths; i++, now = now.AddMonths(-1)) {
|
||||||
|
foreach (var b in backups) {
|
||||||
|
if (b.Timestamp.Year == now.Year && b.Timestamp.Month == now.Month) {
|
||||||
|
retain.Add(b.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// retain tertial backups
|
||||||
|
now = new DateTime(DateTime.Now.Year + 1, 3, 1);
|
||||||
|
for (int i = 0; i < 600; i++, now = now.AddMonths(-4)) {
|
||||||
|
foreach (var b in backups) {
|
||||||
|
if (b.Timestamp.GetYearAndTertial() == now.GetYearAndTertial()) {
|
||||||
|
retain.Add(b.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete non-retained files
|
||||||
|
foreach (var b in backups) {
|
||||||
|
if (retain.Contains(b.FileName)) continue;
|
||||||
|
try {
|
||||||
|
File.Delete(b.FileName);
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
// delete temp files
|
||||||
|
foreach (var f in Directory.GetFiles(App.Config.BackupPath, "*.tmp")) {
|
||||||
|
try {
|
||||||
|
File.Delete(f);
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task RestoreDatabase() {
|
||||||
|
try {
|
||||||
|
var d = new OpenFileDialog() {
|
||||||
|
Title = "Datenbank wiederherstellen - Elwig",
|
||||||
|
DefaultDirectory = App.Config.BackupPath,
|
||||||
|
InitialDirectory = App.Config.BackupPath,
|
||||||
|
DefaultExt = "sql.zip",
|
||||||
|
Filter = "SQLite-Datenbank (*.sqlite3, *.sqlite3.zip, *.sql, *.sql.zip)|*.sqlite3;*.sqlite3.zip;*.sql;*.sql.zip",
|
||||||
|
};
|
||||||
|
if (d.ShowDialog() == true) {
|
||||||
|
if (!InteractionService.AskContinue("Datenbank wiederherstellen", "Soll die Datenbank wirklich unwiederruflich durch die wiederhergestellte Version ersetzt werden?"))
|
||||||
|
return;
|
||||||
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
|
await App.ReplaceDatabase(d.FileName);
|
||||||
|
}
|
||||||
|
} catch (Exception exc) {
|
||||||
|
InteractionService.ShowException(exc);
|
||||||
|
}
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,7 +45,8 @@ namespace Elwig.Services {
|
|||||||
deliveryAncmtQuery = deliveryAncmtQuery.Where(a => a.Year == s.Year && a.DsNr == s.DsNr);
|
deliveryAncmtQuery = deliveryAncmtQuery.Where(a => a.Year == s.Year && a.DsNr == s.DsNr);
|
||||||
filterNames.Add($"{s.Date:dd.MM.yyyy} – {s.Branch.Name} – {s.Description}");
|
filterNames.Add($"{s.Date:dd.MM.yyyy} – {s.Branch.Name} – {s.Description}");
|
||||||
} else {
|
} else {
|
||||||
deliveryAncmtQuery = deliveryAncmtQuery.Where(a => a.Year == vm.FilterSeason && (!vm.FilterOnlyUpcoming || a.Schedule.DateString.CompareTo(Utils.Today.ToString("yyyy-MM-dd")) >= 0));
|
var today = DateTime.Today;
|
||||||
|
deliveryAncmtQuery = deliveryAncmtQuery.Where(a => a.Year == vm.FilterSeason && (!vm.FilterOnlyUpcoming || a.Schedule.DateString.CompareTo(today.ToString("yyyy-MM-dd")) >= 0));
|
||||||
filterNames.Add($"{vm.FilterSeason}");
|
filterNames.Add($"{vm.FilterSeason}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,9 @@ namespace Elwig.Services {
|
|||||||
filterNames.Add($"{vm.FilterSeason}");
|
filterNames.Add($"{vm.FilterSeason}");
|
||||||
}
|
}
|
||||||
if (vm.FilterOnlyUpcoming) {
|
if (vm.FilterOnlyUpcoming) {
|
||||||
deliveryScheduleQuery = deliveryScheduleQuery.Where(s => s.DateString.CompareTo(Utils.Today.ToString("yyyy-MM-dd")) >= 0);
|
var today = DateTime.Today;
|
||||||
filterNames.Add($"ab {Utils.Today:dd.MM.yyyy}");
|
deliveryScheduleQuery = deliveryScheduleQuery.Where(s => s.DateString.CompareTo(today.ToString("yyyy-MM-dd")) >= 0);
|
||||||
|
filterNames.Add($"ab {today:dd.MM.yyyy}");
|
||||||
}
|
}
|
||||||
|
|
||||||
var filterVar = new List<string>();
|
var filterVar = new List<string>();
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
using Elwig.Documents;
|
using Elwig.Documents;
|
||||||
using Elwig.Helpers.Export;
|
|
||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Export;
|
||||||
using Elwig.Models.Dtos;
|
using Elwig.Models.Dtos;
|
||||||
using Elwig.Models.Entities;
|
using Elwig.Models.Entities;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System;
|
|
||||||
using Elwig.ViewModels;
|
using Elwig.ViewModels;
|
||||||
|
using iText.Commons.Internal.Runtime;
|
||||||
using LinqKit;
|
using LinqKit;
|
||||||
using System.Globalization;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace Elwig.Services {
|
namespace Elwig.Services {
|
||||||
public static class DeliveryService {
|
public static class DeliveryService {
|
||||||
@@ -35,8 +37,13 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
vm.SortId = "";
|
vm.SortId = "";
|
||||||
vm.GradationKmwString = "";
|
vm.GradationKmwString = "";
|
||||||
vm.WeightString = "";
|
|
||||||
|
vm.Weight = null;
|
||||||
|
vm.ActualTare = null;
|
||||||
|
vm.TargetTare = null;
|
||||||
|
vm.Tare = null;
|
||||||
vm.IsManualWeighing = false;
|
vm.IsManualWeighing = false;
|
||||||
|
|
||||||
vm.PartComment = "";
|
vm.PartComment = "";
|
||||||
vm.TemperatureString = "";
|
vm.TemperatureString = "";
|
||||||
vm.AcidString = "";
|
vm.AcidString = "";
|
||||||
@@ -51,7 +58,11 @@ namespace Elwig.Services {
|
|||||||
vm.WineKg = ControlUtils.GetItemFromSourceWithPk(vm.WineKgSource, p.KgNr) as AT_Kg;
|
vm.WineKg = ControlUtils.GetItemFromSourceWithPk(vm.WineKgSource, p.KgNr) as AT_Kg;
|
||||||
vm.WineRd = ControlUtils.GetItemFromSourceWithPk(vm.WineRdSource, p.KgNr, p.RdNr) as WbRd;
|
vm.WineRd = ControlUtils.GetItemFromSourceWithPk(vm.WineRdSource, p.KgNr, p.RdNr) as WbRd;
|
||||||
vm.WineOrigin = ControlUtils.GetItemFromSourceWithPk(vm.WineOriginSource, p.HkId) as WineOrigin;
|
vm.WineOrigin = ControlUtils.GetItemFromSourceWithPk(vm.WineOriginSource, p.HkId) as WineOrigin;
|
||||||
vm.WeightString = $"{p.Weight:N0}";
|
|
||||||
|
vm.Weight = p.Weight;
|
||||||
|
vm.ActualTare = p.WeighingInfo.Tare;
|
||||||
|
vm.TargetTare = vm.ActualTare + p.WeighingInfo.TareCorrection;
|
||||||
|
vm.Tare = vm.TargetTare ?? (vm.ActualTare is int t && t != 0 ? t : null);
|
||||||
vm.IsManualWeighing = p.IsManualWeighing;
|
vm.IsManualWeighing = p.IsManualWeighing;
|
||||||
vm.IsNetWeight = p.IsNetWeight;
|
vm.IsNetWeight = p.IsNetWeight;
|
||||||
|
|
||||||
@@ -64,7 +75,7 @@ namespace Elwig.Services {
|
|||||||
vm.TemperatureString = (p.Temperature != null) ? $"{p.Temperature:N1}" : "";
|
vm.TemperatureString = (p.Temperature != null) ? $"{p.Temperature:N1}" : "";
|
||||||
vm.AcidString = (p.Acid != null) ? $"{p.Acid:N1}" : "";
|
vm.AcidString = (p.Acid != null) ? $"{p.Acid:N1}" : "";
|
||||||
vm.IsHandPicked = p.IsHandPicked;
|
vm.IsHandPicked = p.IsHandPicked;
|
||||||
vm.IsGebunden = p.IsGebunden;
|
vm.IsContracted = p.IsContracted;
|
||||||
vm.Unloading = p.Unloading;
|
vm.Unloading = p.Unloading;
|
||||||
|
|
||||||
vm.ScaleTerminalId = p.ScaleTerminalId;
|
vm.ScaleTerminalId = p.ScaleTerminalId;
|
||||||
@@ -72,6 +83,45 @@ namespace Elwig.Services {
|
|||||||
vm.ManualWeighingReason = p.WeighingReason;
|
vm.ManualWeighingReason = p.WeighingReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static (DateTime From, DateTime To)? GetFilterToday(DateTime today, IEnumerable<DateTime> timestamps) {
|
||||||
|
var filtered = timestamps.Where(t => t >= today.AddDays(-1) && t < today.AddDays(1)).Order().ToArray();
|
||||||
|
if (filtered.Length == 0) return null;
|
||||||
|
|
||||||
|
var latest = filtered.Last();
|
||||||
|
var since = filtered.Cast<DateTime>().Reverse().Aggregate(latest, (s, c) => s.Subtract(c).TotalHours <= 6 ? c : s);
|
||||||
|
latest += new TimeSpan(0, 1, -latest.Minute, -latest.Second, -latest.Millisecond, -latest.Microsecond);
|
||||||
|
since += new TimeSpan(0, 0, -since.Minute, -since.Second, -since.Millisecond, -since.Microsecond);
|
||||||
|
|
||||||
|
if (since.Subtract(today) <= new TimeSpan(-6, 0, 0) && latest.Subtract(today) < new TimeSpan(0, 0, 0))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (since, latest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task<(Expression<Func<Delivery, bool>>, string)> GetFilterToday(AppDbContext ctx) {
|
||||||
|
var today = DateTime.Today;
|
||||||
|
var timestamps = (await ctx.Deliveries
|
||||||
|
.Where(d => d.DateString.CompareTo(today.AddDays(-1).ToString("yyyy-MM-dd")) >= 0)
|
||||||
|
.OrderBy(d => d.DateString).ThenBy(d => d.TimeString)
|
||||||
|
.Select(d => d.DateString + " " + d.TimeString)
|
||||||
|
.ToListAsync())
|
||||||
|
.Select(s => DateTime.TryParseExact(s, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? (DateTime?)dt : null)
|
||||||
|
.Where(t => t.HasValue)
|
||||||
|
.Cast<DateTime>()
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
var res = GetFilterToday(today, timestamps);
|
||||||
|
if (!res.HasValue) {
|
||||||
|
return (_ => false, today.ToString("dd.MM.yyyy"));
|
||||||
|
} else {
|
||||||
|
var from = res.Value.From;
|
||||||
|
var to = res.Value.To;
|
||||||
|
return (d => (d.DateString == from.ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo(from.ToString("HH:mm:ss")) >= 0)) ||
|
||||||
|
(d.DateString.CompareTo(from.ToString("yyyy-MM-dd")) > 0),
|
||||||
|
from.Date == to.Date ? from.ToString("dd.MM.yyyy") : $"{from:dd.MM.yyyy \\a\\b HH:mm} / {to:dd.MM.yyyy \\b\\i\\s HH:mm}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, Predicate<DeliveryPart>, List<string>)> GetFilters(this DeliveryAdminViewModel vm, AppDbContext ctx) {
|
public static async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, Predicate<DeliveryPart>, List<string>)> GetFilters(this DeliveryAdminViewModel vm, AppDbContext ctx) {
|
||||||
List<string> filterNames = [];
|
List<string> filterNames = [];
|
||||||
IQueryable<Delivery> deliveryQuery = ctx.Deliveries;
|
IQueryable<Delivery> deliveryQuery = ctx.Deliveries;
|
||||||
@@ -84,10 +134,9 @@ namespace Elwig.Services {
|
|||||||
filterNames.Add(vm.FilterMember.AdministrativeName);
|
filterNames.Add(vm.FilterMember.AdministrativeName);
|
||||||
}
|
}
|
||||||
if (vm.FilterTodayOnly) {
|
if (vm.FilterTodayOnly) {
|
||||||
deliveryQuery = deliveryQuery
|
var (pred, name) = await GetFilterToday(ctx);
|
||||||
.Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") > 0)) ||
|
deliveryQuery = deliveryQuery.Where(pred);
|
||||||
(d.DateString == Utils.Today.AddDays(1).ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") <= 0)));
|
filterNames.Add(name);
|
||||||
filterNames.Add(Utils.Today.ToString("dd.MM.yyyy"));
|
|
||||||
} else if (!vm.FilterAllSeasons) {
|
} else if (!vm.FilterAllSeasons) {
|
||||||
deliveryQuery = deliveryQuery.Where(d => d.Year == vm.FilterSeason);
|
deliveryQuery = deliveryQuery.Where(d => d.Year == vm.FilterSeason);
|
||||||
filterNames.Add($"{vm.FilterSeason}");
|
filterNames.Add($"{vm.FilterSeason}");
|
||||||
@@ -132,19 +181,19 @@ namespace Elwig.Services {
|
|||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("Weißweinsorten");
|
filterNames.Add("Weißweinsorten");
|
||||||
} else if (e.Length >= 3 && e.Length <= 8 && "gebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 3 && e.Length <= 8 && "gebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
prd = prd.And(p => p.IsGebunden == true);
|
prd = prd.And(p => p.IsContracted == true);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("gebunden");
|
filterNames.Add("gebunden");
|
||||||
} else if (e.Length >= 4 && e.Length <= 9 && "!gebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 4 && e.Length <= 9 && "!gebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
prd = prd.And(p => p.IsGebunden != true);
|
prd = prd.And(p => p.IsContracted != true);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("nicht gebunden");
|
filterNames.Add("nicht gebunden");
|
||||||
} else if (e.Length >= 5 && e.Length <= 10 && "ungebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 5 && e.Length <= 10 && "ungebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
prd = prd.And(p => p.IsGebunden == false);
|
prd = prd.And(p => p.IsContracted == false);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("ungebunden");
|
filterNames.Add("ungebunden");
|
||||||
} else if (e.Length >= 6 && e.Length <= 11 && "!ungebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 6 && e.Length <= 11 && "!ungebunden".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
prd = prd.And(p => p.IsGebunden != false);
|
prd = prd.And(p => p.IsContracted != false);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("nicht ungebunden");
|
filterNames.Add("nicht ungebunden");
|
||||||
} else if (e.Length >= 5 && e.Length <= 8 && "handlese".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 5 && e.Length <= 8 && "handlese".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
@@ -507,7 +556,7 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
IsNetWeight = vm.IsNetWeight,
|
IsNetWeight = vm.IsNetWeight,
|
||||||
IsHandPicked = vm.IsHandPicked,
|
IsHandPicked = vm.IsHandPicked,
|
||||||
IsGebunden = vm.IsGebunden,
|
IsContracted = vm.IsContracted,
|
||||||
Unloading = vm.Unloading,
|
Unloading = vm.Unloading,
|
||||||
Temperature = vm.Temperature,
|
Temperature = vm.Temperature,
|
||||||
Acid = vm.Acid,
|
Acid = vm.Acid,
|
||||||
@@ -730,10 +779,9 @@ namespace Elwig.Services {
|
|||||||
query = q;
|
query = q;
|
||||||
filterNames.AddRange(f);
|
filterNames.AddRange(f);
|
||||||
} else if (subject == ExportSubject.FromToday) {
|
} else if (subject == ExportSubject.FromToday) {
|
||||||
var date = $"{Utils.Today:yyyy-MM-dd}";
|
var (pred, name) = await GetFilterToday(ctx);
|
||||||
query = ctx.DeliveryParts
|
query = ctx.Deliveries.Where(pred).SelectMany(d => d.Parts);
|
||||||
.Where(p => p.Delivery.DateString == date);
|
filterNames.Add(name);
|
||||||
filterNames.Add($"{Utils.Today:dd.MM.yyyy}");
|
|
||||||
} else if (subject == ExportSubject.FromSeasonAndBranch) {
|
} else if (subject == ExportSubject.FromSeasonAndBranch) {
|
||||||
query = ctx.DeliveryParts
|
query = ctx.DeliveryParts
|
||||||
.Where(p => p.Year == Utils.CurrentLastSeason && p.Delivery.ZwstId == App.ZwstId);
|
.Where(p => p.Year == Utils.CurrentLastSeason && p.Delivery.ZwstId == App.ZwstId);
|
||||||
@@ -805,10 +853,9 @@ namespace Elwig.Services {
|
|||||||
query = q;
|
query = q;
|
||||||
filterNames.AddRange(f);
|
filterNames.AddRange(f);
|
||||||
} else if (subject == ExportSubject.FromToday) {
|
} else if (subject == ExportSubject.FromToday) {
|
||||||
var date = $"{Utils.Today:yyyy-MM-dd}";
|
var (pred, name) = await GetFilterToday(ctx);
|
||||||
query = ctx.DeliveryParts
|
query = ctx.Deliveries.Where(pred).SelectMany(d => d.Parts);
|
||||||
.Where(p => p.Delivery.DateString == date);
|
filterNames.Add(name);
|
||||||
filterNames.Add($"{Utils.Today:dd.MM.yyyy}");
|
|
||||||
} else {
|
} else {
|
||||||
throw new ArgumentException("Invalid value for ExportSubject");
|
throw new ArgumentException("Invalid value for ExportSubject");
|
||||||
}
|
}
|
||||||
@@ -930,30 +977,40 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddWeightToolTipRow(Grid grid, int row, string? h1, string? h2, int weight, int? total1, int total2) {
|
private static void AddWeightToolTipRow(Grid grid, int row, string? h1, string? h2, string? h3, int weight, int? total1, int? total2, int total3, string? type) {
|
||||||
var bold = h2 == null;
|
var bold = h3 == null;
|
||||||
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
|
var color = type == "R" ? Brushes.Firebrick : type == "W" ? Brushes.ForestGreen : null;
|
||||||
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, 1, bold);
|
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? (h3 == null) ? 3 : 2 : 1, bold: bold, color: color);
|
||||||
grid.AddToolTipCell($"{weight:N0} kg", row, 2, bold: bold, alignRight: true);
|
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, (h3 == null) ? 2 : 1, bold: bold, color: color);
|
||||||
|
if (h3 != null) grid.AddToolTipCell(h3 + ":", row, 2, 1, bold: bold, color: color);
|
||||||
|
grid.AddToolTipCell($"{weight:N0} kg", row, 3, bold: bold, alignRight: true, color: color);
|
||||||
if (total1 != null && total1 != 0)
|
if (total1 != null && total1 != 0)
|
||||||
grid.AddToolTipCell($"{weight * 100.0 / total1:N1} %", row, 3, bold: bold, alignRight: true);
|
grid.AddToolTipCell($"{weight * 100.0 / total1:N1} %", row, 4, bold: bold, alignRight: true, color: color);
|
||||||
if (total2 != 0)
|
if (total2 != null && total2 != 0)
|
||||||
grid.AddToolTipCell($"{weight * 100.0 / total2:N1} %", row, 4, bold: bold, alignRight: true);
|
grid.AddToolTipCell($"{weight * 100.0 / total2:N1} %", row, 5, bold: bold, alignRight: true, color: color);
|
||||||
|
if (total3 != 0)
|
||||||
|
grid.AddToolTipCell($"{weight * 100.0 / total3:N1} %", row, 6, bold: bold, alignRight: true, color: color);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void AddGradationToolTipRow(Grid grid, int row, string? h1, string? h2, double min, double avg, double max) {
|
private static void AddGradationToolTipRow(Grid grid, int row, string? h1, string? h2, string? h3, double min, double avg, double max, string? type) {
|
||||||
var bold = h2 == null;
|
var bold = h3 == null;
|
||||||
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
|
var color = type == "R" ? Brushes.Firebrick : type == "W" ? Brushes.ForestGreen : null;
|
||||||
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, bold: bold);
|
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? (h3 == null) ? 3 : 2 : 1, bold: bold, color: color);
|
||||||
grid.AddToolTipCell($"{min:N1}°", row, 2, bold: bold, alignRight: true);
|
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, (h3 == null) ? 2 : 1, bold: bold, color: color);
|
||||||
grid.AddToolTipCell($"{avg:N1}°", row, 3, bold: bold, alignRight: true);
|
if (h3 != null) grid.AddToolTipCell(h3 + ":", row, 2, bold: bold, color: color);
|
||||||
grid.AddToolTipCell($"{max:N1}°", row, 4, bold: bold, alignRight: true);
|
grid.AddToolTipCell($"{min:N1}°", row, 3, bold: bold, alignRight: true, color: color);
|
||||||
|
grid.AddToolTipCell($"{avg:N1}°", row, 4, bold: bold, alignRight: true, color: color);
|
||||||
|
grid.AddToolTipCell($"{max:N1}°", row, 5, bold: bold, alignRight: true, color: color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(string WeightText, (string?, string?, int, int?, int)[] WeightGrid, string GradationText, (string?, string?, double, double, double)[] GradationGrid)> GenerateToolTipData(IQueryable<DeliveryPart> deliveryParts) {
|
private static string? GetGroupName(params string?[] parts) {
|
||||||
var wGrid = new List<(string?, string?, int, int?, int)>();
|
return parts.All(p => p == null) ? null : string.Join(" / ", parts.Where(p => p != null));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<(string WeightText, (string?, string?, string?, int, int?, int?, int, string?)[] WeightGrid, string GradationText, (string?, string?, string?, double, double, double, string?)[] GradationGrid)> GenerateToolTipData(IQueryable<DeliveryPart> deliveryParts) {
|
||||||
|
var wGrid = new List<(string?, string?, string?, int, int?, int?, int, string?)>();
|
||||||
var wText = "-";
|
var wText = "-";
|
||||||
var gGrid = new List<(string?, string?, double, double, double)>();
|
var gGrid = new List<(string?, string?, string?, double, double, double, string?)>();
|
||||||
var gText = "-";
|
var gText = "-";
|
||||||
|
|
||||||
var stat = (await deliveryParts.GroupBy(p => 0)
|
var stat = (await deliveryParts.GroupBy(p => 0)
|
||||||
@@ -968,11 +1025,11 @@ namespace Elwig.Services {
|
|||||||
.Single();
|
.Single();
|
||||||
|
|
||||||
wText = $"{stat.Weight:N0} kg";
|
wText = $"{stat.Weight:N0} kg";
|
||||||
wGrid.Add(("Menge", null, stat.Weight, null, stat.Weight));
|
wGrid.Add(("Menge", null, null, stat.Weight, null, null, stat.Weight, null));
|
||||||
|
|
||||||
if (stat.Min != null && stat.Max != null) {
|
if (stat.Min != null && stat.Max != null) {
|
||||||
gText = $"{stat.Min:N1}° / {stat.Avg:N1}° / {stat.Max:N1}°";
|
gText = $"{stat.Min:N1}° / {stat.Avg:N1}° / {stat.Max:N1}°";
|
||||||
gGrid.Add(("Gradation", null, stat.Min.Value, stat.Avg, stat.Max.Value));
|
gGrid.Add(("Gradation", null, null, stat.Min.Value, stat.Avg, stat.Max.Value, null));
|
||||||
|
|
||||||
var attrGroups = await deliveryParts
|
var attrGroups = await deliveryParts
|
||||||
.GroupBy(p => new { Attr = p.Attribute!.Name, Cult = p.Cultivation!.Name })
|
.GroupBy(p => new { Attr = p.Attribute!.Name, Cult = p.Cultivation!.Name })
|
||||||
@@ -989,9 +1046,10 @@ namespace Elwig.Services {
|
|||||||
.ThenBy(g => g.Cult)
|
.ThenBy(g => g.Cult)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var sortGroups = await deliveryParts
|
var sortGroups = await deliveryParts
|
||||||
.GroupBy(p => p.SortId)
|
.GroupBy(p => new { p.SortId, p.Variety.Type })
|
||||||
.Select(g => new {
|
.Select(g => new {
|
||||||
SortId = g.Key,
|
g.Key.SortId,
|
||||||
|
g.Key.Type,
|
||||||
Weight = g.Sum(p => p.Weight),
|
Weight = g.Sum(p => p.Weight),
|
||||||
Min = g.Min(p => p.Kmw),
|
Min = g.Min(p => p.Kmw),
|
||||||
Avg = g.Sum(p => p.Kmw * p.Weight) / g.Sum(p => p.Weight),
|
Avg = g.Sum(p => p.Kmw * p.Weight) / g.Sum(p => p.Weight),
|
||||||
@@ -1004,11 +1062,13 @@ namespace Elwig.Services {
|
|||||||
.GroupBy(p => new {
|
.GroupBy(p => new {
|
||||||
Attr = p.Attribute!.Name,
|
Attr = p.Attribute!.Name,
|
||||||
Cult = p.Cultivation!.Name,
|
Cult = p.Cultivation!.Name,
|
||||||
|
p.Variety.Type,
|
||||||
p.SortId,
|
p.SortId,
|
||||||
})
|
})
|
||||||
.Select(g => new {
|
.Select(g => new {
|
||||||
g.Key.Attr,
|
g.Key.Attr,
|
||||||
g.Key.Cult,
|
g.Key.Cult,
|
||||||
|
g.Key.Type,
|
||||||
g.Key.SortId,
|
g.Key.SortId,
|
||||||
Weight = g.Sum(p => p.Weight),
|
Weight = g.Sum(p => p.Weight),
|
||||||
Min = g.Min(p => p.Kmw),
|
Min = g.Min(p => p.Kmw),
|
||||||
@@ -1018,27 +1078,62 @@ namespace Elwig.Services {
|
|||||||
.OrderByDescending(g => g.Weight)
|
.OrderByDescending(g => g.Weight)
|
||||||
.ThenBy(g => g.Attr)
|
.ThenBy(g => g.Attr)
|
||||||
.ThenBy(g => g.Cult)
|
.ThenBy(g => g.Cult)
|
||||||
|
.ThenBy(g => g.Type)
|
||||||
.ThenBy(g => g.SortId)
|
.ThenBy(g => g.SortId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
foreach (var attrG in attrGroups) {
|
foreach (var attrG in attrGroups) {
|
||||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
var name = GetGroupName(attrG.Attr, attrG.Cult);
|
||||||
wGrid.Add((name, null, attrG.Weight, attrG.Weight, stat.Weight));
|
var typeGroups = groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult)
|
||||||
|
.GroupBy(g => g.Type)
|
||||||
|
.Select(g => new { Type = g.Key, Weight = g.Sum(p => p.Weight) })
|
||||||
|
.OrderByDescending(g => g.Weight).ThenBy(g => g.Type)
|
||||||
|
.ToList();
|
||||||
|
wGrid.Add((name, null, null, attrG.Weight, null, attrG.Weight, stat.Weight, typeGroups.Count == 1 ? typeGroups.First().Type : null));
|
||||||
|
if (typeGroups.Count == 1) {
|
||||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||||
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, stat.Weight));
|
wGrid.Add((null, null, g.SortId, g.Weight, null, attrG.Weight, stat.Weight, null));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach (var t in typeGroups) {
|
||||||
|
wGrid.Add((null, t.Type == "R" ? "Rot" : "Weiß", null, t.Weight, t.Weight, attrG.Weight, stat.Weight, t.Type));
|
||||||
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult && g.Type == t.Type).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||||
|
wGrid.Add((null, null, g.SortId, g.Weight, t.Weight, attrG.Weight, stat.Weight, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
foreach (var attrG in attrGroups) {
|
foreach (var attrG in attrGroups) {
|
||||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
var name = GetGroupName(attrG.Attr, attrG.Cult);
|
||||||
gGrid.Add((name, null, attrG.Min, attrG.Avg, attrG.Max));
|
var typeGroups = groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult)
|
||||||
|
.GroupBy(g => g.Type)
|
||||||
|
.Select(g => new {
|
||||||
|
Type = g.Key,
|
||||||
|
Weight = g.Sum(p => p.Weight),
|
||||||
|
Min = g.Min(p => p.Min),
|
||||||
|
Avg = g.Sum(p => p.Avg * p.Weight) / g.Sum(p => p.Weight),
|
||||||
|
Max = g.Max(p => p.Max),
|
||||||
|
})
|
||||||
|
.OrderByDescending(g => g.Weight).ThenBy(g => g.Type)
|
||||||
|
.ToList();
|
||||||
|
gGrid.Add((name, null, null, attrG.Min, attrG.Avg, attrG.Max, typeGroups.Count == 1 ? typeGroups.First().Type : null));
|
||||||
|
if (typeGroups.Count == 1) {
|
||||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Avg).ThenBy(g => g.SortId)) {
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Avg).ThenBy(g => g.SortId)) {
|
||||||
gGrid.Add((null, g.SortId, g.Min, g.Avg, g.Max));
|
gGrid.Add((null, null, g.SortId, g.Min, g.Avg, g.Max, null));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
foreach (var t in typeGroups) {
|
||||||
|
gGrid.Add((null, t.Type == "R" ? "Rot" : "Weiß", null, t.Min, t.Avg, t.Max, t.Type));
|
||||||
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult && g.Type == t.Type).OrderByDescending(g => g.Avg).ThenBy(g => g.SortId)) {
|
||||||
|
gGrid.Add((null, null, g.SortId, g.Min, g.Avg, g.Max, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attrGroups.Count == 1) {
|
if (attrGroups.Count == 1) {
|
||||||
var g = attrGroups.First();
|
var g = attrGroups.First();
|
||||||
var name = g.Attr == null && g.Cult == null ? null : g.Attr + (g.Attr != null && g.Cult != null ? " / " : "") + g.Cult;
|
var name = GetGroupName(g.Attr, g.Cult);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
wText += $" [{name}]";
|
wText += $" [{name}]";
|
||||||
gText += $" [{name}]";
|
gText += $" [{name}]";
|
||||||
@@ -1049,40 +1144,43 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} else if (attrGroups.Count <= 4) {
|
} else if (attrGroups.Count <= 4) {
|
||||||
wText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / stat.Weight:0%})" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
wText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Weight:N0} kg ({(double)g.Weight / stat.Weight:0%})" + (GetGroupName(g.Attr, g.Cult) is string s ? $" [{s}]" : "")))}";
|
||||||
gText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (g.Attr == null && g.Cult == null ? "" : $" [{g.Attr}{(g.Attr != null && g.Cult != null ? " / " : "")}{g.Cult}]")))}";
|
gText += $" = {string.Join(" + ", attrGroups.Select(g => $"{g.Min:N1}/{g.Avg:N1}/{g.Max:N1}" + (GetGroupName(g.Attr, g.Cult) is string s ? $" [{s}]" : "")))}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (wText, wGrid.ToArray(), gText, gGrid.ToArray());
|
return (wText, wGrid.ToArray(), gText, gGrid.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static (Grid WeightGrid, Grid GradationGrid) GenerateToolTip((string?, string?, int, int?, int)[] weightData, (string?, string?, double, double, double)[] gradationData) {
|
public static (Grid WeightGrid, Grid GradationGrid) GenerateToolTip((string?, string?, string?, int, int?, int?, int, string?)[] weightData, (string?, string?, string?, double, double, double, string?)[] gradationData) {
|
||||||
var wGrid = new Grid();
|
var wGrid = new Grid();
|
||||||
wGrid.ColumnDefinitions.Add(new() { Width = new(10) });
|
wGrid.ColumnDefinitions.Add(new() { Width = new(10) });
|
||||||
wGrid.ColumnDefinitions.Add(new() { Width = new(60) });
|
wGrid.ColumnDefinitions.Add(new() { Width = new(10) });
|
||||||
wGrid.ColumnDefinitions.Add(new() { Width = new(80) });
|
wGrid.ColumnDefinitions.Add(new() { Width = new(80) });
|
||||||
|
wGrid.ColumnDefinitions.Add(new() { Width = new(80) });
|
||||||
|
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
int rowNum = 0;
|
int rowNum = 0;
|
||||||
foreach (var row in weightData) {
|
foreach (var row in weightData) {
|
||||||
if (rowNum != 0 && row.Item2 == null) rowNum++;
|
if (rowNum != 0 && row.Item2 == null && row.Item3 == null) rowNum++;
|
||||||
AddWeightToolTipRow(wGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
|
AddWeightToolTipRow(wGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5, row.Item6, row.Item7, row.Item8);
|
||||||
}
|
}
|
||||||
|
|
||||||
var gGrid = new Grid();
|
var gGrid = new Grid();
|
||||||
gGrid.ColumnDefinitions.Add(new() { Width = new(10) });
|
gGrid.ColumnDefinitions.Add(new() { Width = new(10) });
|
||||||
gGrid.ColumnDefinitions.Add(new() { Width = new(60) });
|
gGrid.ColumnDefinitions.Add(new() { Width = new(10) });
|
||||||
|
gGrid.ColumnDefinitions.Add(new() { Width = new(80) });
|
||||||
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
|
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
|
||||||
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
|
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
|
||||||
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
|
gGrid.ColumnDefinitions.Add(new() { Width = new(35) });
|
||||||
gGrid.AddToolTipCell("Min.", 0, 2, alignCenter: true);
|
gGrid.AddToolTipCell("Min.", 0, 3, alignCenter: true);
|
||||||
gGrid.AddToolTipCell("⌀", 0, 3, alignCenter: true);
|
gGrid.AddToolTipCell("⌀", 0, 4, alignCenter: true);
|
||||||
gGrid.AddToolTipCell("Max.", 0, 4, alignCenter: true);
|
gGrid.AddToolTipCell("Max.", 0, 5, alignCenter: true);
|
||||||
rowNum = 1;
|
rowNum = 1;
|
||||||
foreach (var row in gradationData) {
|
foreach (var row in gradationData) {
|
||||||
if (rowNum != 1 && row.Item2 == null) rowNum++;
|
if (rowNum != 1 && row.Item2 == null && row.Item3 == null) rowNum++;
|
||||||
AddGradationToolTipRow(gGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
|
AddGradationToolTipRow(gGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5, row.Item6, row.Item7);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (wGrid, gGrid);
|
return (wGrid, gGrid);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using Microsoft.Data.Sqlite;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -117,8 +118,35 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
public static void ShowException(string title, string? text, Exception exc, bool showExcType = false, bool isError = true) {
|
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 = text == null ? "" : text + (text.EndsWith('.') || text.EndsWith('!') || text.EndsWith('?') ? "" : ":") + "\n\n";
|
||||||
|
if ((exc.InnerException ?? exc) is SqliteException sql) {
|
||||||
|
if (sql.SqliteErrorCode == 5 || sql.SqliteErrorCode == 6) {
|
||||||
|
// SQLITE_BUSY / SQLITE_LOCKED
|
||||||
|
text += "Die Datenbank wurde gerade von einem anderen Gerät/Prozess verwendet. Bitte noch einmal versuchen!\n\n" + sql.Message;
|
||||||
|
} else if (sql.SqliteErrorCode == 19) {
|
||||||
|
// SQLITE_CONSTRAINT
|
||||||
|
switch (sql.SqliteExtendedErrorCode) {
|
||||||
|
case 1555: // SQLITE_CONSTRAINT_PRIMARYKEY - indicating that a PRIMARY KEY constraint failed
|
||||||
|
case 2067: // SQLITE_CONSTRAINT_UNIQUE - indicating that a UNIQUE constraint failed
|
||||||
|
case 2579: // SQLITE_CONSTRAINT_ROWID - indicating that a rowid is not unique
|
||||||
|
text += "Dieser Datensatz existiert bereits!\n\n";
|
||||||
|
break;
|
||||||
|
case 787: // SQLITE_CONSTRAINT_FOREIGNKEY - indicating that a foreign key constraint failed
|
||||||
|
case 1299: // SQLITE_CONSTRAINT_NOTNULL - indicating that a NOT NULL constraint failed
|
||||||
|
case 275: // SQLITE_CONSTRAINT_CHECK - indicating that a CHECK constraint failed
|
||||||
|
case 1811: // SQLITE_CONSTRAINT_TRIGGER - indicating that a RAISE function within a trigger fired, causing the SQL statement to abort
|
||||||
|
case 531: // SQLITE_CONSTRAINT_COMMITHOOK - indicating that a commit hook callback returned non-zero that thus caused the SQL statement to be rolled back
|
||||||
|
text += "Der Datensatz ist inkonsistent!\n\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
text += sql.Message;
|
||||||
|
} else {
|
||||||
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
|
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
|
||||||
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
|
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
|
||||||
|
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
|
||||||
|
}
|
||||||
if (isError) {
|
if (isError) {
|
||||||
ShowError(title, text);
|
ShowError(title, text);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,17 +1,24 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Helpers.Export;
|
||||||
using Elwig.Models;
|
using Elwig.Models;
|
||||||
|
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 System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Elwig.Services {
|
namespace Elwig.Services {
|
||||||
public static class MemberBusinessSharesService {
|
public static class MemberBusinessSharesService {
|
||||||
|
|
||||||
|
public enum ExportSubject {
|
||||||
|
Pending,
|
||||||
|
};
|
||||||
|
|
||||||
public static async Task InitInputs(this MemberBusinessSharesViewModel vm) {
|
public static async Task InitInputs(this MemberBusinessSharesViewModel vm) {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
vm.DateNoticeString = $"{Utils.Today:dd.MM.yyyy}";
|
vm.DateNoticeString = $"{DateTime.Today:dd.MM.yyyy}";
|
||||||
vm.ValuePerShare = (await ctx.Seasons.OrderBy(s => s.Year).LastOrDefaultAsync())?.BusinessShareValue;
|
vm.ValuePerShare = (await ctx.Seasons.OrderBy(s => s.Year).LastOrDefaultAsync())?.BusinessShareValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,6 +32,7 @@ namespace Elwig.Services {
|
|||||||
vm.DateEffective = h.DateEffective;
|
vm.DateEffective = h.DateEffective;
|
||||||
vm.Reason = h.Reason + (h.Reason == MemberHistory.REASON_TRANSFER ? $"_{(h.ToMgNr == mgnr ? "from" : "to")}" : "");
|
vm.Reason = h.Reason + (h.Reason == MemberHistory.REASON_TRANSFER ? $"_{(h.ToMgNr == mgnr ? "from" : "to")}" : "");
|
||||||
vm.Shares = h.Shares;
|
vm.Shares = h.Shares;
|
||||||
|
vm.CompanyHasSigned = h.CompanyHasSigned;
|
||||||
vm.MemberHasSigned = h.MemberHasSigned;
|
vm.MemberHasSigned = h.MemberHasSigned;
|
||||||
vm.ValuePerShare = h.ValuePerShare;
|
vm.ValuePerShare = h.ValuePerShare;
|
||||||
vm.OtherMgNr = h.FromMgNr != null && h.FromMgNr != mgnr ? h.FromMgNr : h.ToMgNr != null && h.ToMgNr != mgnr ? h.ToMgNr : null;
|
vm.OtherMgNr = h.FromMgNr != null && h.FromMgNr != mgnr ? h.FromMgNr : h.ToMgNr != null && h.ToMgNr != mgnr ? h.ToMgNr : null;
|
||||||
@@ -62,6 +70,7 @@ namespace Elwig.Services {
|
|||||||
Reason = vm.Reason?.Split("_")[0] ?? MemberHistory.REASON_CONVERT,
|
Reason = vm.Reason?.Split("_")[0] ?? MemberHistory.REASON_CONVERT,
|
||||||
Source = "manual",
|
Source = "manual",
|
||||||
Shares = vm.Shares ?? 0,
|
Shares = vm.Shares ?? 0,
|
||||||
|
CompanyHasSigned = vm.CompanyHasSigned,
|
||||||
MemberHasSigned = vm.MemberHasSigned,
|
MemberHasSigned = vm.MemberHasSigned,
|
||||||
ValuePerShare = vm.ValuePerShare,
|
ValuePerShare = vm.ValuePerShare,
|
||||||
CurrencyCode = vm.ValuePerShare != null ? "EUR" : null,
|
CurrencyCode = vm.ValuePerShare != null ? "EUR" : null,
|
||||||
@@ -94,5 +103,19 @@ namespace Elwig.Services {
|
|||||||
await tx.CommitAsync();
|
await tx.CommitAsync();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task GenerateMemberMovements(ExportSubject subject, ExportMode mode) {
|
||||||
|
var today = DateTime.Today;
|
||||||
|
var filename = InteractionService.SaveFile($"Ausstehende Mitgl.-Bewegungen {today:dd.MM.yyyy}", $"MitglBewegungen_{today:yyyy-MM-dd}", "ods");
|
||||||
|
if (filename == null)
|
||||||
|
return;
|
||||||
|
await Utils.RunForeground(async () => {
|
||||||
|
using var ctx = new AppDbContext();
|
||||||
|
var hist = await ctx.MemberHistory.Where(h => !h.CompanyHasSigned).ToListAsync();
|
||||||
|
var data = MemberMovementData.FromMemberHistory($"Ausstehend ({today:dd.MM.yyyy})", hist, await ctx.GetMemberHistory());
|
||||||
|
using var ods = new OdsFile(filename);
|
||||||
|
await ods.AddTable(data);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+131
-49
@@ -10,6 +10,7 @@ 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.Media;
|
||||||
|
|
||||||
namespace Elwig.Services {
|
namespace Elwig.Services {
|
||||||
public static class MemberService {
|
public static class MemberService {
|
||||||
@@ -19,6 +20,7 @@ namespace Elwig.Services {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public static async Task InitInputs(this MemberAdminViewModel vm) {
|
public static async Task InitInputs(this MemberAdminViewModel vm) {
|
||||||
|
vm.IsMemberSelectedOrCreating = true;
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
vm.MgNr = await ctx.NextMgNr();
|
vm.MgNr = await ctx.NextMgNr();
|
||||||
vm.EntryDate = DateTime.Now.ToString("dd.MM.yyyy");
|
vm.EntryDate = DateTime.Now.ToString("dd.MM.yyyy");
|
||||||
@@ -31,6 +33,7 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
public static void ClearInputs(this MemberAdminViewModel vm) {
|
public static void ClearInputs(this MemberAdminViewModel vm) {
|
||||||
vm.IsMemberSelected = false;
|
vm.IsMemberSelected = false;
|
||||||
|
vm.IsMemberSelectedOrCreating = false;
|
||||||
vm.MemberHasEmail = false;
|
vm.MemberHasEmail = false;
|
||||||
vm.MemberCanSendEmail = false;
|
vm.MemberCanSendEmail = false;
|
||||||
vm.EnableMemberReferenceButton = false;
|
vm.EnableMemberReferenceButton = false;
|
||||||
@@ -49,10 +52,15 @@ namespace Elwig.Services {
|
|||||||
vm.ModifiedAtShort = "-";
|
vm.ModifiedAtShort = "-";
|
||||||
vm.ExportedAt = "-";
|
vm.ExportedAt = "-";
|
||||||
vm.ImportedAt = "-";
|
vm.ImportedAt = "-";
|
||||||
|
vm.OrganicState = null;
|
||||||
|
vm.OrganicColor = Brushes.Black;
|
||||||
|
vm.OrganicDetails = "-";
|
||||||
|
vm.OrganicToolTip = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FillInputs(this MemberAdminViewModel vm, Member m) {
|
public static void FillInputs(this MemberAdminViewModel vm, Member m) {
|
||||||
vm.IsMemberSelected = true;
|
vm.IsMemberSelected = true;
|
||||||
|
vm.IsMemberSelectedOrCreating = true;
|
||||||
vm.MgNr = m.MgNr;
|
vm.MgNr = m.MgNr;
|
||||||
vm.PredecessorMgNr = m.PredecessorMgNr;
|
vm.PredecessorMgNr = m.PredecessorMgNr;
|
||||||
vm.IsJuridicalPerson = m.IsJuridicalPerson;
|
vm.IsJuridicalPerson = m.IsJuridicalPerson;
|
||||||
@@ -106,7 +114,9 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
vm.UstIdNr = m.UstIdNr;
|
vm.UstIdNr = m.UstIdNr;
|
||||||
vm.LfbisNr = m.LfbisNr;
|
vm.LfbisNr = m.LfbisNr;
|
||||||
vm.IsBuchführend = m.IsBuchführend;
|
vm.OrganicOperatorId = m.OrganicOperatorId;
|
||||||
|
vm.OrganicAuthorityCode = m.OrganicAuthorityCode;
|
||||||
|
vm.IsAccounting = m.IsAccounting;
|
||||||
vm.IsOrganic = m.IsOrganic;
|
vm.IsOrganic = m.IsOrganic;
|
||||||
|
|
||||||
var billingAddr = m.BillingAddress;
|
var billingAddr = m.BillingAddress;
|
||||||
@@ -140,8 +150,8 @@ namespace Elwig.Services {
|
|||||||
vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr);
|
vm.DefaultKg = (AT_Kg?)ControlUtils.GetItemFromSourceWithPk(vm.DefaultKgSource, m.DefaultKgNr);
|
||||||
vm.Comment = m.Comment;
|
vm.Comment = m.Comment;
|
||||||
vm.IsActive = m.IsActive;
|
vm.IsActive = m.IsActive;
|
||||||
vm.IsVollLieferant = m.IsVollLieferant;
|
vm.IsFullDelivery = m.IsFullDelivery;
|
||||||
vm.IsFunktionär = m.IsFunktionär;
|
vm.IsOfficer = m.IsOfficer;
|
||||||
vm.ContactViaPost = m.ContactViaPost;
|
vm.ContactViaPost = m.ContactViaPost;
|
||||||
vm.ContactViaEmail = m.ContactViaEmail;
|
vm.ContactViaEmail = m.ContactViaEmail;
|
||||||
|
|
||||||
@@ -180,20 +190,19 @@ namespace Elwig.Services {
|
|||||||
var s = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
var s = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||||
if (s != null) maxKgPerHa = s.MaxKgPerHa;
|
if (s != null) maxKgPerHa = s.MaxKgPerHa;
|
||||||
} catch { }
|
} catch { }
|
||||||
var (text, gridData) = await AreaComService.GenerateToolTipData(c, maxKgPerHa);
|
var (text, gridData) = await AreaCmtService.GenerateToolTipData(c, maxKgPerHa);
|
||||||
|
|
||||||
var deliveries = await ctx.Deliveries
|
var deliveries = await ctx.Deliveries
|
||||||
.Where(d => d.MgNr == m.MgNr)
|
.Where(d => d.MgNr == m.MgNr)
|
||||||
.GroupBy(d => d.Year)
|
.GroupBy(d => d.Year)
|
||||||
.ToDictionaryAsync(g => g.Key, g => g.Any());
|
.ToDictionaryAsync(g => g.Key, g => g.Any());
|
||||||
|
|
||||||
|
await App.MainDispatcher.BeginInvoke(() => {
|
||||||
if (m.MgNr != vm.MgNr)
|
if (m.MgNr != vm.MgNr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
await App.MainDispatcher.BeginInvoke(() => {
|
|
||||||
var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []);
|
var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []);
|
||||||
var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []);
|
var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []);
|
||||||
var grid = AreaComService.GenerateToolTip(gridData);
|
var grid = AreaCmtService.GenerateToolTip(gridData);
|
||||||
vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}";
|
vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}";
|
||||||
vm.StatusDeliveriesLastSeason = textLast;
|
vm.StatusDeliveriesLastSeason = textLast;
|
||||||
vm.StatusDeliveriesLastSeasonToolTip = d1Grid;
|
vm.StatusDeliveriesLastSeasonToolTip = d1Grid;
|
||||||
@@ -203,13 +212,76 @@ namespace Elwig.Services {
|
|||||||
vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}";
|
vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}";
|
||||||
vm.StatusAreaCommitment = text;
|
vm.StatusAreaCommitment = text;
|
||||||
vm.StatusAreaCommitmentToolTip = grid;
|
vm.StatusAreaCommitmentToolTip = grid;
|
||||||
vm.MemberHasDeliveries = Enumerable.Range(0, 9999).Select(i => deliveries.GetValueOrDefault(i, false)).ToList();
|
vm.MemberHasDeliveries = [.. Enumerable.Range(0, 9999).Select(i => deliveries.GetValueOrDefault(i, false))];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
vm.OrganicState = null;
|
||||||
|
vm.OrganicColor = Brushes.Black;
|
||||||
|
vm.OrganicToolTip = null;
|
||||||
|
if (!vm.IsOrganic) {
|
||||||
|
vm.OrganicDetails = "-";
|
||||||
|
} else {
|
||||||
|
vm.OrganicDetails = "...";
|
||||||
|
Utils.RunBackground("Bio-Zertifikatsdaten laden", async () => {
|
||||||
|
if (App.MainDispatcher == null) return;
|
||||||
|
var certs = await OrganicService.GetTracesCertificates(m);
|
||||||
|
await App.MainDispatcher.BeginInvoke(() => {
|
||||||
|
if (m.MgNr != vm.MgNr) return;
|
||||||
|
vm.FillOrganicInputs(certs.FirstOrDefault(c => c.IsValidForWineProduction));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
vm.MemberHasEmail = m.EmailAddresses.Count > 0;
|
vm.MemberHasEmail = m.EmailAddresses.Count > 0;
|
||||||
vm.MemberCanSendEmail = App.Config.Smtp != null && m.EmailAddresses.Count > 0;
|
vm.MemberCanSendEmail = App.Config.Smtp != null && m.EmailAddresses.Count > 0;
|
||||||
vm.MemberHasDeliveries = Enumerable.Range(0, 9999).Select(i => false).ToList();
|
vm.MemberHasDeliveries = [.. Enumerable.Range(0, 9999).Select(i => false)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void FillOrganicInputs(this MemberAdminViewModel vm, OrganicService.TracesCertificate? cert) {
|
||||||
|
vm.OrganicDetails = null;
|
||||||
|
if (cert == null) {
|
||||||
|
vm.OrganicState = "Nicht gefunden";
|
||||||
|
vm.OrganicColor = Brushes.DarkRed;
|
||||||
|
vm.OrganicToolTip = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vm.OrganicToolTip = $"""
|
||||||
|
Zertifikat-Nr.: {cert.Id}
|
||||||
|
Status: {cert.Status}
|
||||||
|
Bio-KSt.: {cert.AuthorityCode}
|
||||||
|
EU Operator-ID: {cert.OperatorId}
|
||||||
|
Operator: {cert.OperatorName}
|
||||||
|
Ausgestellt am: {cert.IssuedOn:dd.MM.yyyy}
|
||||||
|
Aktualisiert am: {cert.LastStatusUpdateOn:dd.MM.yyyy}
|
||||||
|
Erlischt am: {cert.ExpiresOn:dd.MM.yyyy}
|
||||||
|
""";
|
||||||
|
if (cert.IsValidForWineProduction) {
|
||||||
|
vm.OrganicState = "Gültig";
|
||||||
|
vm.OrganicDetails = $" ({cert.ExpiresOn:MMM. yyyy})";
|
||||||
|
vm.OrganicColor = Brushes.DarkGreen;
|
||||||
|
} else if (cert.IsValid) {
|
||||||
|
vm.OrganicState = "Gültig";
|
||||||
|
vm.OrganicDetails = $" ({cert.ExpiresOn:MMM. yyyy})";
|
||||||
|
vm.OrganicColor = Brushes.OrangeRed;
|
||||||
|
} else {
|
||||||
|
vm.OrganicColor = Brushes.DarkRed;
|
||||||
|
switch (cert.Status) {
|
||||||
|
case OrganicService.TracesStatus.ISSUED:
|
||||||
|
vm.OrganicState = "Ausgestellt";
|
||||||
|
vm.OrganicDetails = $" ({cert.LastStatusUpdateOn:MMM. yyyy})"; break;
|
||||||
|
case OrganicService.TracesStatus.SUSPENDED:
|
||||||
|
vm.OrganicState = "Gesperrt";
|
||||||
|
vm.OrganicDetails = $" ({cert.LastStatusUpdateOn:MMM. yyyy})"; break;
|
||||||
|
case OrganicService.TracesStatus.EXPIRED:
|
||||||
|
vm.OrganicState = "Ausgelaufen";
|
||||||
|
vm.OrganicDetails = $" ({cert.LastStatusUpdateOn:MMM. yyyy})"; break;
|
||||||
|
case OrganicService.TracesStatus.WITHDRAWN:
|
||||||
|
vm.OrganicState = "Widerrufen";
|
||||||
|
vm.OrganicDetails = $" ({cert.LastStatusUpdateOn:MMM. yyyy})"; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(List<string>, IQueryable<Member>, List<string>)> GetFilters(this MemberAdminViewModel vm, AppDbContext ctx) {
|
public static async Task<(List<string>, IQueryable<Member>, List<string>)> GetFilters(this MemberAdminViewModel vm, AppDbContext ctx) {
|
||||||
@@ -225,15 +297,15 @@ namespace Elwig.Services {
|
|||||||
var filterKgNr = new List<int>();
|
var filterKgNr = new List<int>();
|
||||||
var filterLfbisNr = new List<string>();
|
var filterLfbisNr = new List<string>();
|
||||||
var filterUstIdNr = new List<string>();
|
var filterUstIdNr = new List<string>();
|
||||||
var filterAreaCom = new List<string>();
|
var filterAreaCmt = new List<string>();
|
||||||
var filterNotAreaCom = new List<string>();
|
var filterNotAreaCmt = new List<string>();
|
||||||
|
|
||||||
var filter = vm.TextFilter;
|
var filter = vm.TextFilter;
|
||||||
if (filter.Count > 0) {
|
if (filter.Count > 0) {
|
||||||
var branches = await ctx.FetchBranches().ToListAsync();
|
var branches = await ctx.FetchBranches().ToListAsync();
|
||||||
var mgnr = await ctx.FetchMembers(includeNotActive: true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
var mgnr = await ctx.FetchMembers(includeNotActive: true).ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||||
var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg);
|
var kgs = await ctx.WbKgs.ToDictionaryAsync(k => k.AtKg.Name.ToLower(), k => k.AtKg);
|
||||||
var areaComs = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
var areaCmts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => $"{t.SortId}{t.AttrId}", t => t);
|
||||||
|
|
||||||
for (int i = 0; i < filter.Count; i++) {
|
for (int i = 0; i < filter.Count; i++) {
|
||||||
var e = filter[i];
|
var e = filter[i];
|
||||||
@@ -247,11 +319,11 @@ namespace Elwig.Services {
|
|||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("inaktive Mitglieder");
|
filterNames.Add("inaktive Mitglieder");
|
||||||
} else if (e.Length >= 5 && e.Length <= 10 && "funktionär".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 5 && e.Length <= 10 && "funktionär".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => m.IsFunktionär);
|
memberQuery = memberQuery.Where(m => m.IsOfficer);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("Funktionäre");
|
filterNames.Add("Funktionäre");
|
||||||
} else if (e.Length >= 6 && e.Length <= 11 && e[0] == '!' && "funktionär".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 6 && e.Length <= 11 && e[0] == '!' && "funktionär".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => !m.IsFunktionär);
|
memberQuery = memberQuery.Where(m => !m.IsOfficer);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("Nicht-Funktionäre");
|
filterNames.Add("Nicht-Funktionäre");
|
||||||
} else if (e.Equals("bio", StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Equals("bio", StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
@@ -262,28 +334,36 @@ namespace Elwig.Services {
|
|||||||
memberQuery = memberQuery.Where(m => !m.IsOrganic);
|
memberQuery = memberQuery.Where(m => !m.IsOrganic);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("Nicht-Bio-Betriebe");
|
filterNames.Add("Nicht-Bio-Betriebe");
|
||||||
|
} else if (e.Length >= 4 && e.Length <= 14 && "vollablieferer".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
|
memberQuery = memberQuery.Where(m => m.IsFullDelivery);
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("Vollablieferer");
|
||||||
} else if (e.Length >= 4 && e.Length <= 13 && "volllieferant".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 4 && e.Length <= 13 && "volllieferant".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => m.IsVollLieferant);
|
memberQuery = memberQuery.Where(m => m.IsFullDelivery);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("Volllieferanten");
|
filterNames.Add("Vollablieferer");
|
||||||
|
} else if (e.Length >= 5 && e.Length <= 15 && e[0] == '!' && "vollablieferer".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
|
memberQuery = memberQuery.Where(m => !m.IsFullDelivery);
|
||||||
|
filter.RemoveAt(i--);
|
||||||
|
filterNames.Add("Nicht-Vollablieferer");
|
||||||
} else if (e.Length >= 5 && e.Length <= 14 && e[0] == '!' && "volllieferant".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 5 && e.Length <= 14 && e[0] == '!' && "volllieferant".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => !m.IsVollLieferant);
|
memberQuery = memberQuery.Where(m => !m.IsFullDelivery);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("Nicht-Vollieferanten");
|
filterNames.Add("Nicht-Vollablieferer");
|
||||||
} else if (e.Length >= 5 && e.Length <= 11 && "buchführend".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 5 && e.Length <= 11 && "buchführend".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => m.IsBuchführend);
|
memberQuery = memberQuery.Where(m => m.IsAccounting);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("buchführend");
|
filterNames.Add("buchführend");
|
||||||
} else if (e.Length >= 6 && e.Length <= 12 && e[0] == '!' && "buchführend".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 6 && e.Length <= 12 && e[0] == '!' && "buchführend".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => !m.IsBuchführend);
|
memberQuery = memberQuery.Where(m => !m.IsAccounting);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("pauschaliert");
|
filterNames.Add("pauschaliert");
|
||||||
} else if (e.Length >= 8 && e.Length <= 12 && "pauschaliert".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 8 && e.Length <= 12 && "pauschaliert".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => !m.IsBuchführend);
|
memberQuery = memberQuery.Where(m => !m.IsAccounting);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("pauschaliert");
|
filterNames.Add("pauschaliert");
|
||||||
} else if (e.Length >= 9 && e.Length <= 13 && e[0] == '!' && "pauschaliert".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 9 && e.Length <= 13 && e[0] == '!' && "pauschaliert".StartsWith(e[1..], StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
memberQuery = memberQuery.Where(m => m.IsBuchführend);
|
memberQuery = memberQuery.Where(m => m.IsAccounting);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add("buchführend");
|
filterNames.Add("buchführend");
|
||||||
} else if (e.Equals("email", StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Equals("email", StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
@@ -354,19 +434,19 @@ namespace Elwig.Services {
|
|||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add($"Tel.-Nr. {e}");
|
filterNames.Add($"Tel.-Nr. {e}");
|
||||||
} else if (e.Length >= 5 && e.Length <= 14 && "flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 5 && e.Length <= 14 && "flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
filterAreaCom.AddRange(areaComs.Keys);
|
filterAreaCmt.AddRange(areaCmts.Keys);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add($"Flächenbindung");
|
filterNames.Add($"Flächenbindung");
|
||||||
} else if (e.Length >= 6 && e.Length <= 15 && "!flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
} else if (e.Length >= 6 && e.Length <= 15 && "!flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) {
|
||||||
filterNotAreaCom.AddRange(areaComs.Keys);
|
filterNotAreaCmt.AddRange(areaCmts.Keys);
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add($"keine Flächenbindung");
|
filterNames.Add($"keine Flächenbindung");
|
||||||
} else if (areaComs.ContainsKey(e.ToUpper())) {
|
} else if (areaCmts.ContainsKey(e.ToUpper())) {
|
||||||
filterAreaCom.Add(e.ToUpper());
|
filterAreaCmt.Add(e.ToUpper());
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add($"Flächenbindung {e.ToUpper()}");
|
filterNames.Add($"Flächenbindung {e.ToUpper()}");
|
||||||
} else if (e.Length >= 3 && e[0] == '!' && areaComs.ContainsKey(e[1..].ToUpper())) {
|
} else if (e.Length >= 3 && e[0] == '!' && areaCmts.ContainsKey(e[1..].ToUpper())) {
|
||||||
filterNotAreaCom.Add(e[1..].ToUpper());
|
filterNotAreaCmt.Add(e[1..].ToUpper());
|
||||||
filter.RemoveAt(i--);
|
filter.RemoveAt(i--);
|
||||||
filterNames.Add($"ohne Flächenbindung {e[1..].ToUpper()}");
|
filterNames.Add($"ohne Flächenbindung {e[1..].ToUpper()}");
|
||||||
} else if (Validator.CheckLfbisNr(e)) {
|
} else if (Validator.CheckLfbisNr(e)) {
|
||||||
@@ -387,8 +467,8 @@ namespace Elwig.Services {
|
|||||||
if (filterMgNr.Count > 0) memberQuery = memberQuery.Where(m => filterMgNr.Contains(m.MgNr));
|
if (filterMgNr.Count > 0) memberQuery = memberQuery.Where(m => filterMgNr.Contains(m.MgNr));
|
||||||
if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr));
|
if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr));
|
||||||
if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId));
|
if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId));
|
||||||
if (filterAreaCom.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).Any(c => filterAreaCom.Contains(c.VtrgId)));
|
if (filterAreaCmt.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).Any(c => filterAreaCmt.Contains(c.VtrgId)));
|
||||||
if (filterNotAreaCom.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).All(c => filterNotAreaCom.Contains(c.VtrgId)));
|
if (filterNotAreaCmt.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).All(c => filterNotAreaCmt.Contains(c.VtrgId)));
|
||||||
if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr));
|
if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr));
|
||||||
if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr));
|
if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr));
|
||||||
}
|
}
|
||||||
@@ -505,7 +585,7 @@ namespace Elwig.Services {
|
|||||||
.DistinctBy(h => h.HistNr)
|
.DistinctBy(h => h.HistNr)
|
||||||
.OrderBy(h => h.DateNotice).ThenBy(h => h.HistNr)
|
.OrderBy(h => h.DateNotice).ThenBy(h => h.HistNr)
|
||||||
.ToList();
|
.ToList();
|
||||||
var areaComs = await query
|
var areaCmts = 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)
|
||||||
@@ -513,11 +593,11 @@ namespace Elwig.Services {
|
|||||||
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(areaCmts.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(filename, members, history, areaCmts, wbKgs, filterNames);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
|
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
|
||||||
@@ -555,7 +635,9 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
UstIdNr = string.IsNullOrWhiteSpace(vm.UstIdNr) ? null : vm.UstIdNr,
|
UstIdNr = string.IsNullOrWhiteSpace(vm.UstIdNr) ? null : vm.UstIdNr,
|
||||||
LfbisNr = string.IsNullOrWhiteSpace(vm.LfbisNr) ? null : vm.LfbisNr,
|
LfbisNr = string.IsNullOrWhiteSpace(vm.LfbisNr) ? null : vm.LfbisNr,
|
||||||
IsBuchführend = vm.IsBuchführend,
|
OrganicOperatorId = string.IsNullOrWhiteSpace(vm.OrganicOperatorId) ? null : vm.OrganicOperatorId,
|
||||||
|
OrganicAuthorityCode = string.IsNullOrWhiteSpace(vm.OrganicAuthorityCode) ? null : vm.OrganicAuthorityCode,
|
||||||
|
IsAccounting = vm.IsAccounting,
|
||||||
IsOrganic = vm.IsOrganic,
|
IsOrganic = vm.IsOrganic,
|
||||||
|
|
||||||
EntryDateString = string.IsNullOrWhiteSpace(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()),
|
EntryDateString = string.IsNullOrWhiteSpace(vm.EntryDate) ? null : string.Join("-", vm.EntryDate.Split(".").Reverse()),
|
||||||
@@ -566,8 +648,8 @@ namespace Elwig.Services {
|
|||||||
SharesDormant = App.Client.HasRedWhite ? vm.BusinessShares3 ?? 0 : vm.BusinessShares2 ?? 0,
|
SharesDormant = App.Client.HasRedWhite ? vm.BusinessShares3 ?? 0 : vm.BusinessShares2 ?? 0,
|
||||||
AccountingNr = string.IsNullOrWhiteSpace(vm.AccountingNr) ? null : vm.AccountingNr,
|
AccountingNr = string.IsNullOrWhiteSpace(vm.AccountingNr) ? null : vm.AccountingNr,
|
||||||
IsActive = vm.IsActive,
|
IsActive = vm.IsActive,
|
||||||
IsVollLieferant = vm.IsVollLieferant,
|
IsFullDelivery = vm.IsFullDelivery,
|
||||||
IsFunktionär = vm.IsFunktionär,
|
IsOfficer = vm.IsOfficer,
|
||||||
ZwstId = vm.Branch?.ZwstId,
|
ZwstId = vm.Branch?.ZwstId,
|
||||||
DefaultKgNr = vm.DefaultKg?.KgNr,
|
DefaultKgNr = vm.DefaultKg?.KgNr,
|
||||||
Comment = string.IsNullOrWhiteSpace(vm.Comment) ? null : vm.Comment,
|
Comment = string.IsNullOrWhiteSpace(vm.Comment) ? null : vm.Comment,
|
||||||
@@ -618,12 +700,12 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
|
|
||||||
if (vm.TransferPredecessorAreaComs is int year && m.PredecessorMgNr is int predecessor) {
|
if (vm.TransferPredecessorAreaCmts is int year && m.PredecessorMgNr is int predecessor) {
|
||||||
var areaComs = await ctx.AreaCommitments
|
var areaCmts = await ctx.AreaCommitments
|
||||||
.Where(c => c.MgNr == predecessor && (c.YearTo == null || c.YearTo >= year))
|
.Where(c => c.MgNr == predecessor && (c.YearTo == null || c.YearTo >= year))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
ctx.AddRange(await Task.WhenAll(areaComs.Select(async (c, i) => new AreaCom {
|
ctx.AddRange(await Task.WhenAll(areaCmts.Select(async (c, i) => new AreaCmt {
|
||||||
FbNr = c.FbNr,
|
FbNr = c.FbNr,
|
||||||
RevNr = await ctx.NextRevNr(c.FbNr),
|
RevNr = await ctx.NextRevNr(c.FbNr),
|
||||||
MgNr = m.MgNr,
|
MgNr = m.MgNr,
|
||||||
@@ -635,24 +717,24 @@ namespace Elwig.Services {
|
|||||||
YearTo = c.YearTo,
|
YearTo = c.YearTo,
|
||||||
})));
|
})));
|
||||||
|
|
||||||
foreach (var ac in areaComs)
|
foreach (var ac in areaCmts)
|
||||||
ac.YearTo = year - 1;
|
ac.YearTo = year - 1;
|
||||||
ctx.UpdateRange(areaComs);
|
ctx.UpdateRange(areaCmts);
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
vm.TransferPredecessorAreaComs = null;
|
vm.TransferPredecessorAreaCmts = null;
|
||||||
|
|
||||||
if (vm.CancelAreaComs is int yearTo) {
|
if (vm.CancelAreaCmts is int yearTo) {
|
||||||
var areaComs = await ctx.AreaCommitments
|
var areaCmts = await ctx.AreaCommitments
|
||||||
.Where(c => c.MgNr == m.MgNr && (c.YearTo == null || c.YearTo > yearTo))
|
.Where(c => c.MgNr == m.MgNr && (c.YearTo == null || c.YearTo > yearTo))
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
foreach (var ac in areaComs)
|
foreach (var ac in areaCmts)
|
||||||
ac.YearTo = yearTo;
|
ac.YearTo = yearTo;
|
||||||
ctx.UpdateRange(areaComs);
|
ctx.UpdateRange(areaCmts);
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
vm.CancelAreaComs = null;
|
vm.CancelAreaCmts = null;
|
||||||
|
|
||||||
if (newMgNr != m.MgNr) {
|
if (newMgNr != m.MgNr) {
|
||||||
await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}");
|
await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}");
|
||||||
@@ -662,7 +744,7 @@ namespace Elwig.Services {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
|
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaCmts) {
|
||||||
await Task.Run(async () => {
|
await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
using var tx = await ctx.Database.BeginTransactionAsync();
|
using var tx = await ctx.Database.BeginTransactionAsync();
|
||||||
@@ -673,7 +755,7 @@ namespace Elwig.Services {
|
|||||||
if (deleteDeliveries) {
|
if (deleteDeliveries) {
|
||||||
await ctx.Deliveries.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
await ctx.Deliveries.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
if (deleteAreaComs) {
|
if (deleteAreaCmts) {
|
||||||
await ctx.AreaCommitments.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
await ctx.AreaCommitments.Where(c => c.MgNr == mgnr).ExecuteDeleteAsync();
|
||||||
}
|
}
|
||||||
ctx.Remove(l);
|
ctx.Remove(l);
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
using Elwig.Helpers;
|
||||||
|
using Elwig.Models.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace Elwig.Services {
|
||||||
|
public static class OrganicService {
|
||||||
|
|
||||||
|
public const string TRACES_API_URL = "https://webgate.ec.europa.eu/tracesnt/directory/publication/organic-operator/for/query";
|
||||||
|
public const string TRACES_PDF_URL_PREFIX = "https://webgate.ec.europa.eu/tracesnt/directory/publication/organic-operator/digitally-signed/";
|
||||||
|
|
||||||
|
public enum TracesStatus {
|
||||||
|
ISSUED, SUSPENDED, WITHDRAWN, EXPIRED
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TracesActivity {
|
||||||
|
PREPARATION, EXPORT, IMPORT, STORING, PRODUCTION, DISTRIBUTION, DISTRIBUTION_PLACING_ON_THE_MARKET
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum TracesCategoryOfProduct {
|
||||||
|
UNPROCESSED_PLANT_PRODUCTS_INCLUDING_SEEDS, LIVESTOCK_AND_UNPROCESSED_LIVESTOCK_PRODUCTS, ALGAE_AND_UNPROCESSED_AQUACULTURE_PRODUCTS,
|
||||||
|
PROCESSED_AGRICULTURAL_PRODUCTS_INCLUDING_AQUACULTURE_FOR_USE_AS_FOOD, FEED, WINE, OTHER_PRODUCTS_NOT_COVERED_BY_PREVIOUS_CATEGORIES
|
||||||
|
}
|
||||||
|
|
||||||
|
public record TracesCertificate {
|
||||||
|
public required string Id { get; init; }
|
||||||
|
public required string AuthorityCode { get; init; }
|
||||||
|
public required string OperatorId { get; init; }
|
||||||
|
public required string OperatorName { get; init; }
|
||||||
|
public required TracesActivity[] Activities { get; init; }
|
||||||
|
public required TracesCategoryOfProduct[] CategoriesOfProduct { get; init; }
|
||||||
|
public required DateOnly IssuedOn { get; init; }
|
||||||
|
public required DateOnly ExpiresOn { get; init; }
|
||||||
|
public required DateOnly LastStatusUpdateOn { get; init; }
|
||||||
|
public required TracesStatus Status { get; init; }
|
||||||
|
|
||||||
|
public string PdfUrl => TRACES_PDF_URL_PREFIX + Id + ".pdf";
|
||||||
|
public bool IsValid => Status == TracesStatus.ISSUED && IssuedOn.ToDateTime(new()) <= DateTime.Today && ExpiresOn.ToDateTime(new()) >= DateTime.Today;
|
||||||
|
public bool IsValidForWineProduction => IsValid && Activities.Contains(TracesActivity.PRODUCTION) &&
|
||||||
|
(CategoriesOfProduct.Contains(TracesCategoryOfProduct.UNPROCESSED_PLANT_PRODUCTS_INCLUDING_SEEDS) || CategoriesOfProduct.Contains(TracesCategoryOfProduct.WINE));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly ConcurrentDictionary<int, (DateTime Timestamp, TracesCertificate[] Certificates)> _memberCerts = [];
|
||||||
|
|
||||||
|
public async static Task<TracesCertificate[]> GetTracesCertificates(Member m, bool? tryNameAndAddress = null) {
|
||||||
|
if (_memberCerts.TryGetValue(m.MgNr, out var entry) && entry.Timestamp >= DateTime.Now.AddDays(-1))
|
||||||
|
return entry.Certificates;
|
||||||
|
var certs = await FetchTracesCertificates(m, tryNameAndAddress);
|
||||||
|
_memberCerts[m.MgNr] = (DateTime.Now, certs);
|
||||||
|
return certs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async static Task<JsonArray> TryFetchTracesCertificates(Dictionary<string, string> query) {
|
||||||
|
var q = HttpUtility.ParseQueryString("");
|
||||||
|
q.Add("sort", "-issuedOn");
|
||||||
|
q.Add("countryCode", "AT");
|
||||||
|
foreach (var (k, v) in query) {
|
||||||
|
q.Add(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
using var client = Utils.GetHttpClient();
|
||||||
|
using var res = await client.GetAsync($"{TRACES_API_URL}?{q}");
|
||||||
|
res.EnsureSuccessStatusCode();
|
||||||
|
var resJson = JsonNode.Parse(await res.Content.ReadAsStringAsync());
|
||||||
|
return resJson?.AsArray() ?? throw new JsonException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Task<TracesCertificate[]> FetchTracesCertificates(Member m, bool? tryNameAndAddress = null) {
|
||||||
|
return FetchTracesCertificates(m.OrganicOperatorId, m.LfbisNr,
|
||||||
|
(tryNameAndAddress ?? m.IsOrganic) ? m.BillingAddress is BillingAddr a ?
|
||||||
|
(a.FullName, a.Address, $"{a.PostalDest.AtPlz?.Plz}") :
|
||||||
|
(m.FullName, m.Address, $"{m.PostalDest.AtPlz?.Plz}") :
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async static Task<TracesCertificate[]> FetchTracesCertificates(string? oocId = null, string? lfbisNr = null, (string Name, string Address, string PostalCode)? address = null) {
|
||||||
|
bool searchedByName = false;
|
||||||
|
JsonArray jsonCerts = [];
|
||||||
|
|
||||||
|
if (jsonCerts.Count == 0 && oocId != null) {
|
||||||
|
jsonCerts = await TryFetchTracesCertificates(new Dictionary<string, string> {
|
||||||
|
{ "operatorIdentifierType", "ooc_identifier" },
|
||||||
|
{ "operatorIdentifierSearchOperator", "STRICT" },
|
||||||
|
{ "operatorIdentifier", oocId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonCerts.Count == 0 && lfbisNr != null) {
|
||||||
|
jsonCerts = await TryFetchTracesCertificates(new Dictionary<string, string> {
|
||||||
|
{ "operatorIdentifierType", "comp_reg" },
|
||||||
|
{ "operatorIdentifierSearchOperator", "STRICT" },
|
||||||
|
{ "operatorIdentifier", lfbisNr.TrimStart('0') },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonCerts.Count == 0 && address != null) {
|
||||||
|
var query = $"{Regex.Replace(address.Value.Name, @"\(.*?\)", "")} {address.Value.Address}";
|
||||||
|
jsonCerts = await TryFetchTracesCertificates(new Dictionary<string, string> {
|
||||||
|
{ "operatorPostalCode", address.Value.PostalCode },
|
||||||
|
{ "query", query.Length > 40 ? query[..query.LastIndexOf(' ', 40)] : query },
|
||||||
|
});
|
||||||
|
searchedByName = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jsonCerts.Count == 0)
|
||||||
|
return [];
|
||||||
|
|
||||||
|
TracesCertificate[] certs = [.. jsonCerts.Select(j => new TracesCertificate {
|
||||||
|
Id = j!["reference"]?.GetValue<string>() ?? throw new Exception(),
|
||||||
|
AuthorityCode = j["issuingBody"]?["code"]?.GetValue<string>() ?? throw new Exception(),
|
||||||
|
OperatorId = j["operatorIdentifier"]?.GetValue<string>() ?? throw new Exception(),
|
||||||
|
OperatorName = j["operator"]?["name"]?.GetValue<string>() ?? throw new Exception(),
|
||||||
|
Activities = [.. j["activities"]?.AsArray().Select(a => Enum.Parse<TracesActivity>(a?["id"]?.GetValue<string>().ToUpper().Replace("_IMPORT", "IMPORT") ?? throw new Exception())) ?? []],
|
||||||
|
CategoriesOfProduct = [.. j["categoriesOfProduct"]?.AsArray().Select(c => Enum.Parse<TracesCategoryOfProduct>(c?["id"]?.GetValue<string>() ?? throw new Exception())) ?? []],
|
||||||
|
IssuedOn = DateOnly.FromDateTime(DateTime.ParseExact(j["issuedOn"]?.GetValue<string>() ?? throw new Exception(), "yyyy-MM-ddTHH:mm:ss.fffK", CultureInfo.InvariantCulture, DateTimeStyles.None)),
|
||||||
|
ExpiresOn = DateOnly.ParseExact(j["expiresOn"]?.GetValue<string>() ?? throw new Exception(), "yyyy-MM-dd"),
|
||||||
|
LastStatusUpdateOn = DateOnly.FromDateTime(DateTime.ParseExact(j["lastStatusUpdateDateTime"]?.GetValue<string>() ?? throw new Exception(), "yyyy-MM-ddTHH:mm:ss.fffK", CultureInfo.InvariantCulture, DateTimeStyles.None)),
|
||||||
|
Status = Enum.Parse<TracesStatus>(j["status"]?["id"]?.GetValue<string>() ?? throw new Exception()),
|
||||||
|
})];
|
||||||
|
|
||||||
|
return (!searchedByName || certs.Where(c => c.Status == TracesStatus.ISSUED).Select(c => c.OperatorId).ToHashSet().Count == 1) ? certs : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? GetTracesSearchUrl(Member m, bool? tryNameAndAddress = null) {
|
||||||
|
return GetTracesSearchUrl(m.OrganicOperatorId, m.LfbisNr,
|
||||||
|
(tryNameAndAddress ?? m.IsOrganic) ? m.BillingAddress is BillingAddr a ?
|
||||||
|
(a.FullName, a.Address, $"{a.PostalDest.AtPlz?.Plz}") :
|
||||||
|
(m.FullName, m.Address, $"{m.PostalDest.AtPlz?.Plz}") :
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? GetTracesSearchUrl(string? oocId = null, string? lfbisNr = null, (string Name, string Address, string PostalCode)? address = null) {
|
||||||
|
var baseUrl = "https://webgate.ec.europa.eu/tracesnt/directory/publication/organic-operator/index";
|
||||||
|
if (oocId != null) {
|
||||||
|
return $"{baseUrl}#!?countryCode=AT&operatorIdentifierType=ooc_identifier&operatorIdentifierSearchOperator=STRICT&operatorIdentifier={oocId}&states=ISSUED";
|
||||||
|
} else if (lfbisNr != null) {
|
||||||
|
return $"{baseUrl}#!?countryCode=AT&operatorIdentifierType=comp_reg&operatorIdentifierSearchOperator=STRICT&operatorIdentifier={lfbisNr.TrimStart('0')}&states=ISSUED";
|
||||||
|
} else if (address != null) {
|
||||||
|
return $"{baseUrl}#!?countryCode=AT&operatorPostalCode={address?.PostalCode}&query={address?.Name.Replace(' ', '+')}+{address?.Address.Replace(' ', '+')}&states=ISSUED";
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? GetEasyCertSearchUrl(string lfbisNr) {
|
||||||
|
var baseUrl = "https://www.easy-cert.com/htm/suchergebnis.htm";
|
||||||
|
return $"{baseUrl}?CountryCode=AT&CustomerNumber={lfbisNr.TrimStart('0')}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string? GetBiocSearchUrl(string lfbisNr) {
|
||||||
|
var baseUrl = "https://www.bioc.info/search/producersearchresult";
|
||||||
|
return $"{baseUrl}?producerSearch[country]=a1e51f85-27b5-a1e3-65f7-561569884d38&producerSearch[operatorId]={lfbisNr.TrimStart('0')}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -159,10 +159,10 @@ namespace Elwig.Services {
|
|||||||
foreach (int mgnr in currentPayments.Keys) {
|
foreach (int mgnr in currentPayments.Keys) {
|
||||||
var c = currentPayments[mgnr];
|
var c = currentPayments[mgnr];
|
||||||
var l = lastPayments.GetValueOrDefault(mgnr);
|
var l = lastPayments.GetValueOrDefault(mgnr);
|
||||||
vatSum += (c.Amount - (l?.Amount ?? 0)) * (decimal)(c.Member.IsBuchführend ? v.Season.VatNormal : v.Season.VatFlatrate);
|
vatSum += (c.Amount - (l?.Amount ?? 0)) * (decimal)(c.Member.IsAccounting ? v.Season.VatNormal : v.Season.VatFlatrate);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vatSum = currentPayments.Sum(e => e.Value.Amount * (decimal)(e.Value.Member.IsBuchführend ? v.Season.VatNormal : v.Season.VatFlatrate));
|
vatSum = currentPayments.Sum(e => e.Value.Amount * (decimal)(e.Value.Member.IsAccounting ? v.Season.VatNormal : v.Season.VatFlatrate));
|
||||||
}
|
}
|
||||||
vatText = $"~{vatSum:N2} {sym}";
|
vatText = $"~{vatSum:N2} {sym}";
|
||||||
deductionText = $"- {sym}";
|
deductionText = $"- {sym}";
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Elwig.Services {
|
|||||||
public static class SyncService {
|
public static class SyncService {
|
||||||
|
|
||||||
public static readonly Expression<Func<Member, bool>> ChangedMembers = (m) => ((m.XTime == null && m.MTime > 1751328000) || m.MTime > m.XTime) && (m.ITime == null || m.MTime > m.ITime);
|
public static readonly Expression<Func<Member, bool>> ChangedMembers = (m) => ((m.XTime == null && m.MTime > 1751328000) || m.MTime > m.XTime) && (m.ITime == null || m.MTime > m.ITime);
|
||||||
public static readonly Expression<Func<AreaComContract, bool>> ChangedAreaComContracts = (c) => ((c.XTime == null && c.MTime > 1751328000) || c.MTime > c.XTime) && (c.ITime == null || c.MTime > c.ITime);
|
public static readonly Expression<Func<AreaCmtContract, bool>> ChangedAreaCmtContracts = (c) => ((c.XTime == null && c.MTime > 1751328000) || c.MTime > c.XTime) && (c.ITime == null || c.MTime > c.ITime);
|
||||||
public static readonly Expression<Func<Delivery, bool>> ChangedDeliveries = (d) => ((d.XTime == null && d.MTime > 1751328000) || d.MTime > d.XTime) && (d.ITime == null || d.MTime > d.ITime);
|
public static readonly Expression<Func<Delivery, bool>> ChangedDeliveries = (d) => ((d.XTime == null && d.MTime > 1751328000) || d.MTime > d.XTime) && (d.ITime == null || d.MTime > d.ITime);
|
||||||
|
|
||||||
public static async Task Upload(string url, string username, string password, IQueryable<Member> query, IEnumerable<string> filterNames) {
|
public static async Task Upload(string url, string username, string password, IQueryable<Member> query, IEnumerable<string> filterNames) {
|
||||||
@@ -37,7 +37,7 @@ namespace Elwig.Services {
|
|||||||
.DistinctBy(h => h.HistNr)
|
.DistinctBy(h => h.HistNr)
|
||||||
.OrderBy(h => h.DateNotice).ThenBy(h => h.HistNr)
|
.OrderBy(h => h.DateNotice).ThenBy(h => h.HistNr)
|
||||||
.ToList();
|
.ToList();
|
||||||
var areaComs = await query
|
var areaCmts = await query
|
||||||
.SelectMany(m => m.AreaCommitments)
|
.SelectMany(m => m.AreaCommitments)
|
||||||
.Select(c => c.Contract).Distinct()
|
.Select(c => c.Contract).Distinct()
|
||||||
.OrderBy(c => c.FbNr)
|
.OrderBy(c => c.FbNr)
|
||||||
@@ -46,7 +46,7 @@ namespace Elwig.Services {
|
|||||||
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(areaCmts.Select(c => c.Kg))
|
||||||
.Distinct()
|
.Distinct()
|
||||||
.OrderBy(k => k.KgNr)
|
.OrderBy(k => k.KgNr)
|
||||||
.ToList();
|
.ToList();
|
||||||
@@ -54,9 +54,9 @@ namespace Elwig.Services {
|
|||||||
InteractionService.ShowError("Mitglieder hochladen", "Es wurden keine Mitglieder zum Hochladen ausgewählt!");
|
InteractionService.ShowError("Mitglieder hochladen", "Es wurden keine Mitglieder zum Hochladen ausgewählt!");
|
||||||
} else {
|
} else {
|
||||||
var exportedAt = DateTime.Now;
|
var exportedAt = DateTime.Now;
|
||||||
await ElwigData.Export(path, members, history, areaComs, wbKgs, filterNames);
|
await ElwigData.Export(path, members, history, areaCmts, wbKgs, filterNames);
|
||||||
await Utils.UploadExportData(path, url, username, password);
|
await Utils.UploadExportData(path, url, username, password);
|
||||||
await UpdateExportedAt(members, areaComs, [], exportedAt);
|
await UpdateExportedAt(members, areaCmts, [], exportedAt);
|
||||||
InteractionService.ShowInformation("Mitglieder hochgeladen", $"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!");
|
InteractionService.ShowInformation("Mitglieder hochgeladen", $"Hochladen von {members.Count:N0} Mitgliedern erfolgreich!");
|
||||||
}
|
}
|
||||||
} catch (HttpRequestException exc) {
|
} catch (HttpRequestException exc) {
|
||||||
@@ -106,7 +106,7 @@ namespace Elwig.Services {
|
|||||||
try {
|
try {
|
||||||
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
|
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
|
||||||
List<Member> members;
|
List<Member> members;
|
||||||
List<AreaComContract> areaComs;
|
List<AreaCmtContract> areaCmts;
|
||||||
List<Delivery> deliveries;
|
List<Delivery> deliveries;
|
||||||
using (var ctx = new AppDbContext()) {
|
using (var ctx = new AppDbContext()) {
|
||||||
members = await ctx.Members
|
members = await ctx.Members
|
||||||
@@ -115,8 +115,8 @@ namespace Elwig.Services {
|
|||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.EmailAddresses)
|
||||||
.OrderBy(m => m.MgNr)
|
.OrderBy(m => m.MgNr)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
areaComs = await ctx.AreaCommitmentContracts
|
areaCmts = await ctx.AreaCommitmentContracts
|
||||||
.Where(ChangedAreaComContracts)
|
.Where(ChangedAreaCmtContracts)
|
||||||
.Include(c => c.Revisions)
|
.Include(c => c.Revisions)
|
||||||
.OrderBy(c => c.FbNr)
|
.OrderBy(c => c.FbNr)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
@@ -129,7 +129,7 @@ namespace Elwig.Services {
|
|||||||
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(areaCmts.Select(c => c.Kg))
|
||||||
.Union(deliveries.SelectMany(d => d.Parts)
|
.Union(deliveries.SelectMany(d => d.Parts)
|
||||||
.Where(p => p.Kg != null)
|
.Where(p => p.Kg != null)
|
||||||
.Select(p => p.Kg!))
|
.Select(p => p.Kg!))
|
||||||
@@ -142,13 +142,13 @@ namespace Elwig.Services {
|
|||||||
var exportedAt = DateTime.Now;
|
var exportedAt = DateTime.Now;
|
||||||
await (new ElwigData.ElwigExport {
|
await (new ElwigData.ElwigExport {
|
||||||
Members = (members, ["geändert seit letztem Export"]),
|
Members = (members, ["geändert seit letztem Export"]),
|
||||||
AreaComs = (areaComs, ["geändert seit letztem Export"]),
|
AreaCmts = (areaCmts, ["geändert seit letztem Export"]),
|
||||||
Deliveries = (deliveries, ["geändert seit letzem Export"]),
|
Deliveries = (deliveries, ["geändert seit letzem Export"]),
|
||||||
WbKgs = (wbKgs, ["von exportierten Mitgliedern, Flächenbindungen und Lieferungen"]),
|
WbKgs = (wbKgs, ["von exportierten Mitgliedern, Flächenbindungen und Lieferungen"]),
|
||||||
}).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, areaCmts, deliveries, exportedAt);
|
||||||
InteractionService.ShowInformation("Mitglieder und Lieferungen hochladen", $"Hochladen von {members.Count:N0} Mitgliedern, {areaComs.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!");
|
InteractionService.ShowInformation("Mitglieder und Lieferungen hochladen", $"Hochladen von {members.Count:N0} Mitgliedern, {areaCmts.Count:N0} Flächenbindungsverträgen, und {deliveries.Count:N0} Lieferungen erfolgreich!");
|
||||||
}
|
}
|
||||||
} catch (HttpRequestException exc) {
|
} catch (HttpRequestException exc) {
|
||||||
InteractionService.ShowException("Mitglieder und Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
|
InteractionService.ShowException("Mitglieder und Lieferungen hochladen", "Eventuell Internetverbindung prüfen!", exc);
|
||||||
@@ -236,7 +236,7 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task UpdateExportedAt(IEnumerable<Member> member, IEnumerable<AreaComContract> contracts, IEnumerable<Delivery> deliveries, DateTime dateTime) {
|
private static async Task UpdateExportedAt(IEnumerable<Member> member, IEnumerable<AreaCmtContract> contracts, IEnumerable<Delivery> deliveries, DateTime dateTime) {
|
||||||
var timestamp = ((DateTimeOffset)dateTime.ToUniversalTime()).ToUnixTimeSeconds();
|
var timestamp = ((DateTimeOffset)dateTime.ToUniversalTime()).ToUnixTimeSeconds();
|
||||||
var mgnrs = string.Join(",", member.Select(m => $"{m.MgNr}").Append("0"));
|
var mgnrs = string.Join(",", member.Select(m => $"{m.MgNr}").Append("0"));
|
||||||
var fbnrs = string.Join(",", contracts.Select(c => $"{c.FbNr}").Append("0"));
|
var fbnrs = string.Join(",", contracts.Select(c => $"{c.FbNr}").Append("0"));
|
||||||
@@ -259,7 +259,7 @@ namespace Elwig.Services {
|
|||||||
|
|
||||||
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
public static async Task<bool> ChangesAvailable(AppDbContext ctx, string url, string username, string password) {
|
||||||
try {
|
try {
|
||||||
return await ctx.Members.Where(ChangedMembers).AnyAsync() || await ctx.AreaCommitmentContracts.Where(ChangedAreaComContracts).AnyAsync() || await ctx.Deliveries.Where(ChangedDeliveries).AnyAsync() || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
return await ctx.Members.Where(ChangedMembers).AnyAsync() || await ctx.AreaCommitmentContracts.Where(ChangedAreaCmtContracts).AnyAsync() || await ctx.Deliveries.Where(ChangedDeliveries).AnyAsync() || (Utils.HasInternetConnectivity() && (await GetFilesToImport(url, username, password)).Count > 0);
|
||||||
} catch {
|
} catch {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-24
@@ -5,97 +5,97 @@ using System.Linq;
|
|||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace Elwig.ViewModels {
|
namespace Elwig.ViewModels {
|
||||||
public partial class AreaComAdminViewModel : ObservableObject {
|
public partial class AreaCmtAdminViewModel : ObservableObject {
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _title = "Flächenbindungen - Elwig";
|
public partial string Title { get; set; } = "Flächenbindungen - Elwig";
|
||||||
|
|
||||||
public required Member FilterMember { get; set; }
|
public required Member FilterMember { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _searchQuery = "";
|
public partial string? SearchQuery { get; set; } = "";
|
||||||
public List<string> TextFilter {
|
public List<string> TextFilter {
|
||||||
get => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
get => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||||
set => SearchQuery = string.Join(' ', value.Where(e => e.Length > 0));
|
set => SearchQuery = string.Join(' ', value.Where(e => e.Length > 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _filterSeasonString;
|
public partial string? FilterSeasonString { get; set; }
|
||||||
public int? FilterSeason {
|
public int? FilterSeason {
|
||||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||||
set => FilterSeasonString = $"{value}";
|
set => FilterSeasonString = $"{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _fbNrString;
|
public partial string? FbNrString { get; set; }
|
||||||
public int? FbNr {
|
public int? FbNr {
|
||||||
get => int.TryParse(FbNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(FbNrString, out var mgnr) ? mgnr : null;
|
||||||
set => FbNrString = $"{value}";
|
set => FbNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _mgNrString;
|
public partial string? MgNrString { get; set; }
|
||||||
public int? MgNr {
|
public int? MgNr {
|
||||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||||
set => MgNrString = $"{value}";
|
set => MgNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _yearFromString;
|
public partial string? YearFromString { get; set; }
|
||||||
public int? YearFrom {
|
public int? YearFrom {
|
||||||
get => int.TryParse(YearFromString, out var year) ? year : null;
|
get => int.TryParse(YearFromString, out var year) ? year : null;
|
||||||
set => YearFromString = $"{value}";
|
set => YearFromString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _yearToString;
|
public partial string? YearToString { get; set; }
|
||||||
public int? YearTo {
|
public int? YearTo {
|
||||||
get => int.TryParse(YearToString, out var year) ? year : null;
|
get => int.TryParse(YearToString, out var year) ? year : null;
|
||||||
set => YearToString = $"{value}";
|
set => YearToString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _period;
|
public partial string? Period { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AreaComType? _areaComType;
|
public partial AreaCmtType? AreaCmtType { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<AreaComType> _areaComTypeSource = [];
|
public partial IEnumerable<AreaCmtType> AreaCmtTypeSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _wineCultObj;
|
public partial object? WineCultObj { get; set; }
|
||||||
public WineCult? WineCult {
|
public WineCult? WineCult {
|
||||||
get => WineCultObj as WineCult;
|
get => WineCultObj as WineCult;
|
||||||
set => WineCultObj = value ?? WineCultSource.FirstOrDefault();
|
set => WineCultObj = value ?? WineCultSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _wineCultSource = [];
|
public partial IEnumerable<object> WineCultSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _comment;
|
public partial string? Comment { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AT_Kg? _kg;
|
public partial AT_Kg? Kg { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<AT_Kg> _kgSource = [];
|
public partial IEnumerable<AT_Kg> KgSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _rdObj;
|
public partial object? RdObj { get; set; }
|
||||||
public WbRd? Rd {
|
public WbRd? Rd {
|
||||||
get => RdObj as WbRd;
|
get => RdObj as WbRd;
|
||||||
set => RdObj = value ?? RdSource.FirstOrDefault();
|
set => RdObj = value ?? RdSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _rdSource = [];
|
public partial IEnumerable<object> RdSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _gstNr;
|
public partial string? GstNr { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _areaString;
|
public partial string? AreaString { get; set; }
|
||||||
public int? Area {
|
public int? Area {
|
||||||
get => int.TryParse(AreaString, out var area) ? area : null;
|
get => int.TryParse(AreaString, out var area) ? area : null;
|
||||||
set => AreaString = $"{value}";
|
set => AreaString = $"{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusAreaCommitments = "-";
|
public partial string StatusAreaCommitments { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusContracts = "-";
|
public partial string StatusContracts { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusArea = "-";
|
public partial string StatusArea { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusAreaToolTip;
|
public partial Grid? StatusAreaToolTip { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,167 +9,175 @@ using System.Windows.Controls;
|
|||||||
namespace Elwig.ViewModels {
|
namespace Elwig.ViewModels {
|
||||||
public partial class DeliveryAdminViewModel : ObservableObject {
|
public partial class DeliveryAdminViewModel : ObservableObject {
|
||||||
|
|
||||||
public bool IsReceipt = false;
|
public bool IsReceipt { get; set; } = false;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _title = "Lieferungen - Elwig";
|
public partial string Title { get; set; } = "Lieferungen - Elwig";
|
||||||
|
|
||||||
public Member? FilterMember { get; set; }
|
public Member? FilterMember { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _searchQuery = "";
|
public partial string? SearchQuery { get; set; } = "";
|
||||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _lastScaleError;
|
public partial string? LastScaleError { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _manualWeighingReason;
|
public partial string? ManualWeighingReason { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _scaleTerminalId;
|
public partial string? ScaleTerminalId { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _weighingData;
|
public partial string? WeighingData { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _filterTodayOnly;
|
public partial bool FilterTodayOnly { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _filterAllSeasons;
|
public partial bool FilterAllSeasons { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _enableAllSeasons;
|
public partial bool EnableAllSeasons { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _filterSeasonString;
|
public partial string? FilterSeasonString { get; set; }
|
||||||
public int? FilterSeason {
|
public int? FilterSeason {
|
||||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||||
set => FilterSeasonString = $"{value}";
|
set => FilterSeasonString = $"{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Delivery? _selectedDelivery;
|
public partial Delivery? SelectedDelivery { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Delivery> _deliveries = [];
|
public partial IEnumerable<Delivery> Deliveries { get; set; } = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _mgNrString;
|
public partial string? MgNrString { get; set; }
|
||||||
public int? MgNr {
|
public int? MgNr {
|
||||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||||
set => MgNrString = $"{value}";
|
set => MgNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Member? _member;
|
public partial Member? Member { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Member> _memberSource = [];
|
public partial IEnumerable<Member> MemberSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _memberAddress;
|
public partial string? MemberAddress { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _lsNr;
|
public partial string? LsNr { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _date;
|
public partial string? Date { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _time;
|
public partial string? Time { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Branch? _branch;
|
public partial Branch? Branch { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Branch> _branchSource = [];
|
public partial IEnumerable<Branch> BranchSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _comment;
|
public partial string? Comment { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _sortId;
|
public partial string? SortId { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private WineVar? _wineVar;
|
public partial WineVar? WineVar { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<WineVar> _wineVarSource = [];
|
public partial IEnumerable<WineVar> WineVarSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _wineAttrObj;
|
public partial object? WineAttrObj { get; set; }
|
||||||
public WineAttr? WineAttr {
|
public WineAttr? WineAttr {
|
||||||
get => WineAttrObj as WineAttr;
|
get => WineAttrObj as WineAttr;
|
||||||
set => WineAttrObj = value ?? WineAttrSource.FirstOrDefault();
|
set => WineAttrObj = value ?? WineAttrSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _wineAttrSource = [];
|
public partial IEnumerable<object> WineAttrSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _wineCultObj;
|
public partial object? WineCultObj { get; set; }
|
||||||
public WineCult? WineCult {
|
public WineCult? WineCult {
|
||||||
get => WineCultObj as WineCult;
|
get => WineCultObj as WineCult;
|
||||||
set => WineCultObj = value ?? WineCultSource.FirstOrDefault();
|
set => WineCultObj = value ?? WineCultSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _wineCultSource = [];
|
public partial IEnumerable<object> WineCultSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _gradationOeString;
|
public partial string? GradationOeString { get; set; }
|
||||||
public double? GradationOe {
|
public double? GradationOe {
|
||||||
get => double.TryParse(GradationOeString, out var oe) ? oe : null;
|
get => double.TryParse(GradationOeString, out var oe) ? oe : null;
|
||||||
set => GradationOeString = $"{value:0}";
|
set => GradationOeString = $"{value:0}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _gradationKmwString;
|
public partial string? GradationKmwString { get; set; }
|
||||||
public double? GradationKmw {
|
public double? GradationKmw {
|
||||||
get => double.TryParse(GradationKmwString, out var kmw) ? kmw : null;
|
get => double.TryParse(GradationKmwString, out var kmw) ? kmw : null;
|
||||||
set => GradationKmwString = $"{value:0.0}";
|
set => GradationKmwString = $"{value:0.0}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private WineQualLevel? _wineQualityLevel;
|
public partial WineQualLevel? WineQualityLevel { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<WineQualLevel> _wineQualityLevelSource = [];
|
public partial IEnumerable<WineQualLevel> WineQualityLevelSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _abgewertet;
|
public partial bool Abgewertet { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _weightString;
|
public partial string? WeightString { get; set; }
|
||||||
public int? Weight {
|
public int? Weight {
|
||||||
get => int.TryParse(WeightString?.Replace(Utils.GroupSeparator, ""), out var w) ? w : null;
|
get => int.TryParse(WeightString?.Replace(Utils.GroupSeparator, ""), out var w) ? w : null;
|
||||||
set => WeightString = $"{value:N0}";
|
set => WeightString = value > 0 ? $"{value:N0}" : null;
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isManualWeighing;
|
public partial string? TareString { get; set; } = "-";
|
||||||
|
public int? Tare {
|
||||||
|
get => int.TryParse(TareString?.Replace(Utils.GroupSeparator, "").Replace(" kg", ""), out var w) ? w : null;
|
||||||
|
set => TareString = value == null ? "-" : $"{value:N0} kg{(TargetTare != null ? "*" : "")}";
|
||||||
|
}
|
||||||
|
public int? ActualTare { get; set; }
|
||||||
|
public int? TargetTare { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool? _isNetWeightValue = false;
|
public partial bool IsManualWeighing { get; set; }
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial bool? IsNetWeightValue { get; set; } = false;
|
||||||
public bool IsNetWeight {
|
public bool IsNetWeight {
|
||||||
get => IsNetWeightValue ?? false;
|
get => IsNetWeightValue ?? false;
|
||||||
set => IsNetWeightValue = value;
|
set => IsNetWeightValue = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private WineOrigin? _wineOrigin;
|
public partial WineOrigin? WineOrigin { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<WineOrigin> _wineOriginSource = [];
|
public partial IEnumerable<WineOrigin> WineOriginSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _wineKgObj;
|
public partial object? WineKgObj { get; set; }
|
||||||
public AT_Kg? WineKg {
|
public AT_Kg? WineKg {
|
||||||
get => WineKgObj as AT_Kg;
|
get => WineKgObj as AT_Kg;
|
||||||
set => WineKgObj = value ?? WineKgSource.FirstOrDefault();
|
set => WineKgObj = value ?? WineKgSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _wineKgSource = [];
|
public partial IEnumerable<object> WineKgSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _wineRdObj;
|
public partial object? WineRdObj { get; set; }
|
||||||
public WbRd? WineRd {
|
public WbRd? WineRd {
|
||||||
get => WineRdObj as WbRd;
|
get => WineRdObj as WbRd;
|
||||||
set => WineRdObj = value ?? WineRdSource.FirstOrDefault();
|
set => WineRdObj = value ?? WineRdSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _wineRdSource = [];
|
public partial IEnumerable<object> WineRdSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool? _isGebunden;
|
public partial bool? IsContracted { get; set; }
|
||||||
|
|
||||||
public ObservableCollection<Modifier> Modifiers { get; set; } = [];
|
public ObservableCollection<Modifier> Modifiers { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Modifier> _modifiersSource = [];
|
public partial IEnumerable<Modifier> ModifiersSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _partComment;
|
public partial string? PartComment { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _temperatureString;
|
public partial string? TemperatureString { get; set; }
|
||||||
public double? Temperature {
|
public double? Temperature {
|
||||||
get => double.TryParse(TemperatureString, out var t) ? t : null;
|
get => double.TryParse(TemperatureString, out var t) ? t : null;
|
||||||
set => TemperatureString = $"{value:0.0}";
|
set => TemperatureString = $"{value:0.0}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _acidString;
|
public partial string? AcidString { get; set; }
|
||||||
public double? Acid {
|
public double? Acid {
|
||||||
get => double.TryParse(AcidString, out var a) ? a : null;
|
get => double.TryParse(AcidString, out var a) ? a : null;
|
||||||
set => AcidString = $"{value:0.0}";
|
set => AcidString = $"{value:0.0}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool? _isHandPicked;
|
public partial bool? IsHandPicked { get; set; }
|
||||||
|
|
||||||
public string? Unloading {
|
public string? Unloading {
|
||||||
get => IsUnloadingDumper ? DeliveryPart.Dumper : IsUnloadingPumped ? DeliveryPart.Pumped : IsUnloadingBox ? DeliveryPart.Box : null;
|
get => IsUnloadingDumper ? DeliveryPart.Dumper : IsUnloadingPumped ? DeliveryPart.Pumped : IsUnloadingBox ? DeliveryPart.Box : null;
|
||||||
@@ -183,28 +191,28 @@ namespace Elwig.ViewModels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isUnloadingDumper;
|
public partial bool IsUnloadingDumper { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isUnloadingPumped;
|
public partial bool IsUnloadingPumped { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isUnloadingBox;
|
public partial bool IsUnloadingBox { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isUnloadingOther;
|
public partial bool IsUnloadingOther { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusMembers = "-";
|
public partial string StatusMembers { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusDeliveries = "-";
|
public partial string StatusDeliveries { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusVarieties = "-";
|
public partial string StatusVarieties { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusWeight = "-";
|
public partial string StatusWeight { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusGradation = "-";
|
public partial string StatusGradation { get; set; } = "-";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusWeightToolTip;
|
public partial Grid? StatusWeightToolTip { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusGradationToolTip;
|
public partial Grid? StatusGradationToolTip { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,77 +9,80 @@ namespace Elwig.ViewModels {
|
|||||||
public partial class DeliveryAncmtAdminViewModel : ObservableObject {
|
public partial class DeliveryAncmtAdminViewModel : ObservableObject {
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _searchQuery = "";
|
public partial string Title { get; set; } = "Anmeldungen - Elwig";
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? SearchQuery { get; set; } = "";
|
||||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _filterOnlyUpcoming;
|
public partial bool FilterOnlyUpcoming { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _filterFromAllSchedules;
|
public partial bool FilterFromAllSchedules { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _filterSeasonString;
|
public partial string? FilterSeasonString { get; set; }
|
||||||
public int? FilterSeason {
|
public int? FilterSeason {
|
||||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||||
set => FilterSeasonString = $"{value}";
|
set => FilterSeasonString = $"{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private DeliveryAncmt? _selectedDeliveryAncmt;
|
public partial DeliveryAncmt? SelectedDeliveryAncmt { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<DeliveryAncmt> _deliveryAncmts = [];
|
public partial IEnumerable<DeliveryAncmt> DeliveryAncmts { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private DeliverySchedule? _selectedDeliverySchedule;
|
public partial DeliverySchedule? SelectedDeliverySchedule { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<DeliverySchedule> _deliverySchedules = [];
|
public partial IEnumerable<DeliverySchedule> DeliverySchedules { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _enableSearchInputs = true;
|
public partial bool EnableSearchInputs { get; set; } = true;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _mgNrString;
|
public partial string? MgNrString { get; set; }
|
||||||
public int? MgNr {
|
public int? MgNr {
|
||||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||||
set => MgNrString = $"{value}";
|
set => MgNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Member? _member;
|
public partial Member? Member { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Member> _memberSource = [];
|
public partial IEnumerable<Member> MemberSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _memberAddress;
|
public partial string? MemberAddress { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private DeliverySchedule? _deliverySchedule;
|
public partial DeliverySchedule? DeliverySchedule { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<DeliverySchedule> _deliveryScheduleSource = [];
|
public partial IEnumerable<DeliverySchedule> DeliveryScheduleSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _sortId;
|
public partial string? SortId { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private WineVar? _wineVariety;
|
public partial WineVar? WineVariety { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<WineVar> _wineVarietySource = [];
|
public partial IEnumerable<WineVar> WineVarietySource { get; set; } = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _weightString;
|
public partial string? WeightString { get; set; }
|
||||||
public int? Weight {
|
public int? Weight {
|
||||||
get => int.TryParse(WeightString, out var w) ? w : null;
|
get => int.TryParse(WeightString, out var w) ? w : null;
|
||||||
set => WeightString = $"{value}";
|
set => WeightString = $"{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusAncmts = "-";
|
public partial string StatusAncmts { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusWeight = "-";
|
public partial string StatusWeight { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusAncmtCreated = "-";
|
public partial string StatusAncmtCreated { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusAncmtModified = "-";
|
public partial string StatusAncmtModified { get; set; } = "-";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusWeightToolTip;
|
public partial Grid? StatusWeightToolTip { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,76 +10,76 @@ namespace Elwig.ViewModels {
|
|||||||
public partial class DeliveryScheduleAdminViewModel : ObservableObject {
|
public partial class DeliveryScheduleAdminViewModel : ObservableObject {
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _searchQuery = "";
|
public partial string? SearchQuery { get; set; } = "";
|
||||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _filterOnlyUpcoming;
|
public partial bool FilterOnlyUpcoming { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _filterSeasonString;
|
public partial string? FilterSeasonString { get; set; }
|
||||||
public int? FilterSeason {
|
public int? FilterSeason {
|
||||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||||
set => FilterSeasonString = $"{value}";
|
set => FilterSeasonString = $"{value}";
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private DeliverySchedule? _selectedDeliverySchedule;
|
public partial DeliverySchedule? SelectedDeliverySchedule { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<DeliverySchedule> _deliverySchedules = [];
|
public partial IEnumerable<DeliverySchedule> DeliverySchedules { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _enableSearchInputs = true;
|
public partial bool EnableSearchInputs { get; set; } = true;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _dateString = "";
|
public partial string DateString { get; set; } = "";
|
||||||
public DateOnly? Date {
|
public DateOnly? Date {
|
||||||
get => DateOnly.TryParseExact(DateString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(DateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => DateString = $"{value:dd.MM.yyyy}";
|
set => DateString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Branch? _branch;
|
public partial Branch? Branch { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Branch> _branchSource = [];
|
public partial IEnumerable<Branch> BranchSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _description = "";
|
public partial string Description { get; set; } = "";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _maxWeightString = "";
|
public partial string? MaxWeightString { get; set; } = "";
|
||||||
public int? MaxWeight {
|
public int? MaxWeight {
|
||||||
get => int.TryParse(MaxWeightString, out var w) ? w : null;
|
get => int.TryParse(MaxWeightString, out var w) ? w : null;
|
||||||
set => MaxWeightString = $"{value}";
|
set => MaxWeightString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isCancelled;
|
public partial bool IsCancelled { get; set; }
|
||||||
public ObservableCollection<WineVar> MainVarieties { get; set; } = [];
|
public ObservableCollection<WineVar> MainVarieties { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<WineVar> _mainVarietiesSource = [];
|
public partial IEnumerable<WineVar> MainVarietiesSource { get; set; } = [];
|
||||||
public ObservableCollection<WineVar> OtherVarieties { get; set; } = [];
|
public ObservableCollection<WineVar> OtherVarieties { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<WineVar> _otherVarietiesSource = [];
|
public partial IEnumerable<WineVar> OtherVarietiesSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _attributeSource = [];
|
public partial IEnumerable<object> AttributeSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _attributeObj;
|
public partial object? AttributeObj { get; set; }
|
||||||
public WineAttr? Attribute {
|
public WineAttr? Attribute {
|
||||||
get => AttributeObj as WineAttr;
|
get => AttributeObj as WineAttr;
|
||||||
set => AttributeObj = value ?? AttributeSource.FirstOrDefault();
|
set => AttributeObj = value ?? AttributeSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<object> _cultivationSource = [];
|
public partial IEnumerable<object> CultivationSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private object? _cultivationObj;
|
public partial object? CultivationObj { get; set; }
|
||||||
public WineCult? Cultivation {
|
public WineCult? Cultivation {
|
||||||
get => CultivationObj as WineCult;
|
get => CultivationObj as WineCult;
|
||||||
set => CultivationObj = value ?? CultivationSource.FirstOrDefault();
|
set => CultivationObj = value ?? CultivationSource.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _ancmtFromDateString = "";
|
public partial string AncmtFromDateString { get; set; } = "";
|
||||||
public DateOnly? AncmtFromDate {
|
public DateOnly? AncmtFromDate {
|
||||||
get => DateOnly.TryParseExact(AncmtFromDateString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(AncmtFromDateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => AncmtFromDateString = $"{value:dd.MM.yyyy}";
|
set => AncmtFromDateString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _ancmtFromTimeString = "";
|
public partial string AncmtFromTimeString { get; set; } = "";
|
||||||
public TimeOnly? AncmtFromTime {
|
public TimeOnly? AncmtFromTime {
|
||||||
get => TimeOnly.TryParseExact(AncmtFromTimeString, "HH:mm", out var t) ? t : null;
|
get => TimeOnly.TryParseExact(AncmtFromTimeString, "HH:mm", out var t) ? t : null;
|
||||||
set => AncmtFromTimeString = $"{value:HH:mm}";
|
set => AncmtFromTimeString = $"{value:HH:mm}";
|
||||||
@@ -92,13 +92,13 @@ namespace Elwig.ViewModels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _ancmtToDateString = "";
|
public partial string AncmtToDateString { get; set; } = "";
|
||||||
public DateOnly? AncmtToDate {
|
public DateOnly? AncmtToDate {
|
||||||
get => DateOnly.TryParseExact(AncmtToDateString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(AncmtToDateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => AncmtToDateString = $"{value:dd.MM.yyyy}";
|
set => AncmtToDateString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _ancmtToTimeString = "";
|
public partial string AncmtToTimeString { get; set; } = "";
|
||||||
public TimeOnly? AncmtToTime {
|
public TimeOnly? AncmtToTime {
|
||||||
get => TimeOnly.TryParseExact(AncmtToTimeString, "HH:mm", out var t) ? t : null;
|
get => TimeOnly.TryParseExact(AncmtToTimeString, "HH:mm", out var t) ? t : null;
|
||||||
set => AncmtToTimeString = $"{value:HH:mm}";
|
set => AncmtToTimeString = $"{value:HH:mm}";
|
||||||
@@ -112,8 +112,8 @@ namespace Elwig.ViewModels {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,185 +6,203 @@ using System.Collections.ObjectModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Documents;
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace Elwig.ViewModels {
|
namespace Elwig.ViewModels {
|
||||||
public partial class MemberAdminViewModel : ObservableObject {
|
public partial class MemberAdminViewModel : ObservableObject {
|
||||||
|
|
||||||
public int? TransferPredecessorAreaComs = null;
|
[ObservableProperty]
|
||||||
public int? CancelAreaComs = null;
|
public partial string Title { get; set; } = "Mitglieder - Elwig";
|
||||||
|
|
||||||
|
public int? TransferPredecessorAreaCmts { get; set; } = null;
|
||||||
|
public int? CancelAreaCmts { get; set; } = null;
|
||||||
|
|
||||||
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
|
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _searchQuery = "";
|
public partial string? SearchQuery { get; set; } = "";
|
||||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _showOnlyActiveMembers = true;
|
public partial bool ShowOnlyActiveMembers { get; set; } = true;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Member? _selectedMember;
|
public partial Member? SelectedMember { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Member> _members = [];
|
public partial IEnumerable<Member> Members { get; set; } = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isMemberSelected;
|
public partial bool IsMemberSelected { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _memberHasEmail;
|
public partial bool IsMemberSelectedOrCreating { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _memberCanSendEmail;
|
public partial bool MemberHasEmail { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _enableMemberReferenceButton;
|
public partial bool MemberCanSendEmail { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _enableSearchInputs = true;
|
public partial bool EnableMemberReferenceButton { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<bool> _memberHasDeliveries = [.. Enumerable.Range(0, 9999).Select(i => false)];
|
public partial bool EnableSearchInputs { get; set; } = true;
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial IEnumerable<bool> MemberHasDeliveries { get; set; } = [.. Enumerable.Range(0, 9999).Select(i => false)];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _memberListOrderByMgNr;
|
public partial bool MemberListOrderByMgNr { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _memberListOrderByName;
|
public partial bool MemberListOrderByName { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _memberListOrderByOrt;
|
public partial bool MemberListOrderByOrt { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _mgNrString;
|
public partial string? MgNrString { get; set; }
|
||||||
public int? MgNr {
|
public int? MgNr {
|
||||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||||
set => MgNrString = $"{value}";
|
set => MgNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _predecessorMgNrString;
|
public partial string? PredecessorMgNrString { get; set; }
|
||||||
public int? PredecessorMgNr {
|
public int? PredecessorMgNr {
|
||||||
get => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null;
|
||||||
set => PredecessorMgNrString = $"{value}";
|
set => PredecessorMgNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isJuridicalPerson;
|
public partial bool IsJuridicalPerson { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _prefix;
|
public partial string? Prefix { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _givenName;
|
public partial string? GivenName { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _name;
|
public partial string? Name { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _suffix;
|
public partial string? Suffix { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _forTheAttentionOf;
|
public partial string? ForTheAttentionOf { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _birthday;
|
public partial string? Birthday { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _age;
|
public partial string? Age { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isDeceased;
|
public partial bool IsDeceased { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _address;
|
public partial string? Address { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _plzString;
|
public partial string? PlzString { get; set; }
|
||||||
public int? Plz {
|
public int? Plz {
|
||||||
get => int.TryParse(PlzString, out var plz) ? plz : null;
|
get => int.TryParse(PlzString, out var plz) ? plz : null;
|
||||||
set => PlzString = $"{value}";
|
set => PlzString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AT_PlzDest? _ort;
|
public partial AT_PlzDest? Ort { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<AT_PlzDest> _ortSource = [];
|
public partial IEnumerable<AT_PlzDest> OrtSource { get; set; } = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _billingName;
|
public partial string? BillingName { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _billingAddress;
|
public partial string? BillingAddress { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _billingPlzString;
|
public partial string? BillingPlzString { get; set; }
|
||||||
public int? BillingPlz {
|
public int? BillingPlz {
|
||||||
get => int.TryParse(BillingPlzString, out var plz) ? plz : null;
|
get => int.TryParse(BillingPlzString, out var plz) ? plz : null;
|
||||||
set => BillingPlzString = $"{value}";
|
set => BillingPlzString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AT_PlzDest? _billingOrt;
|
public partial AT_PlzDest? BillingOrt { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<AT_PlzDest> _billingOrtSource = [];
|
public partial IEnumerable<AT_PlzDest> BillingOrtSource { get; set; } = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _iban;
|
public partial string? Iban { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _bic;
|
public partial string? Bic { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _ustIdNr;
|
public partial string? UstIdNr { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _lfbisNr;
|
public partial string? LfbisNr { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isBuchführend;
|
public partial string? OrganicOperatorId { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isOrganic;
|
public partial string? OrganicAuthorityCode { get; set; }
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial bool IsAccounting { get; set; }
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial bool IsOrganic { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _entryDate;
|
public partial string? OrganicState { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _exitDate;
|
public partial string? OrganicDetails { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _businessShares1String;
|
public partial Brush? OrganicColor { get; set; } = Brushes.Black;
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? OrganicToolTip { get; set; }
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? EntryDate { get; set; }
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? ExitDate { get; set; }
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? BusinessShares1String { get; set; }
|
||||||
public int? BusinessShares1 {
|
public int? BusinessShares1 {
|
||||||
get => int.TryParse(BusinessShares1String, out var shares) ? shares : null;
|
get => int.TryParse(BusinessShares1String, out var shares) ? shares : null;
|
||||||
set => BusinessShares1String = $"{value}";
|
set => BusinessShares1String = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _businessShares2String;
|
public partial string? BusinessShares2String { get; set; }
|
||||||
public int? BusinessShares2 {
|
public int? BusinessShares2 {
|
||||||
get => int.TryParse(BusinessShares2String, out var shares) ? shares : null;
|
get => int.TryParse(BusinessShares2String, out var shares) ? shares : null;
|
||||||
set => BusinessShares2String = $"{value}";
|
set => BusinessShares2String = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _businessShares3String;
|
public partial string? BusinessShares3String { get; set; }
|
||||||
public int? BusinessShares3 {
|
public int? BusinessShares3 {
|
||||||
get => int.TryParse(BusinessShares3String, out var shares) ? shares : null;
|
get => int.TryParse(BusinessShares3String, out var shares) ? shares : null;
|
||||||
set => BusinessShares3String = $"{value}";
|
set => BusinessShares3String = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _accountingNr;
|
public partial string? AccountingNr { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isActive;
|
public partial bool IsActive { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isVollLieferant;
|
public partial bool IsFullDelivery { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isFunktionär;
|
public partial bool IsOfficer { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Branch? _branch;
|
public partial Branch? Branch { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<Branch> _branchSource = [];
|
public partial IEnumerable<Branch> BranchSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private AT_Kg? _defaultKg;
|
public partial AT_Kg? DefaultKg { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<AT_Kg> _defaultKgSource = [];
|
public partial IEnumerable<AT_Kg> DefaultKgSource { get; set; } = [];
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _comment;
|
public partial string? Comment { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _contactViaPost;
|
public partial bool ContactViaPost { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _contactViaEmail;
|
public partial bool ContactViaEmail { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _createdAt = "-";
|
public partial string CreatedAt { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _modifiedAt = "-";
|
public partial string ModifiedAt { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _modifiedAtShort = "-";
|
public partial string ModifiedAtShort { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _exportedAt = "-";
|
public partial string ExportedAt { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _importedAt = "-";
|
public partial string ImportedAt { get; set; } = "-";
|
||||||
|
|
||||||
public ObservableCollection<string?> EmailAddresses { get; private set; } = [null, null, null, null, null, null, null, null, null];
|
public ObservableCollection<string?> EmailAddresses { get; private set; } = [null, null, null, null, null, null, null, null, null];
|
||||||
|
|
||||||
public partial class PhoneNr(int? type = null, string? number = null, string? comment = null) : ObservableObject {
|
public partial class PhoneNr(int? type = null, string? number = null, string? comment = null) : ObservableObject {
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public int _type = type ?? -1;
|
public partial int Type { get; set; } = type ?? -1;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public string? _number = number;
|
public partial string? Number { get; set; } = number;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public string? _comment = comment;
|
public partial string? Comment { get; set; } = comment;
|
||||||
|
|
||||||
public override bool Equals(object? obj) {
|
public override bool Equals(object? obj) {
|
||||||
return obj is PhoneNr nr && Type == nr.Type && Number == nr.Number && Comment == nr.Comment;
|
return obj is PhoneNr nr && Type == nr.Type && Number == nr.Number && Comment == nr.Comment;
|
||||||
@@ -197,37 +215,37 @@ namespace Elwig.ViewModels {
|
|||||||
public ObservableCollection<PhoneNr> PhoneNrs { get; private set; } = [new(), new(), new(), new(), new(), new(), new(), new(), new()];
|
public ObservableCollection<PhoneNr> PhoneNrs { get; private set; } = [new(), new(), new(), new(), new(), new(), new(), new(), new()];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusMembers = "-";
|
public partial string StatusMembers { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _statusMembersToolTip;
|
public partial string? StatusMembersToolTip { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private TextBlock? _statusBusinessShares;
|
public partial TextBlock? StatusBusinessShares { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusDeliveriesLastSeason = "-";
|
public partial string StatusDeliveriesLastSeason { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusDeliveriesLastSeasonInfo = "letzte Saison";
|
public partial string StatusDeliveriesLastSeasonInfo { get; set; } = "letzte Saison";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusDeliveriesLastSeasonToolTip;
|
public partial Grid? StatusDeliveriesLastSeasonToolTip { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusDeliveriesThisSeason = "-";
|
public partial string StatusDeliveriesThisSeason { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusDeliveriesThisSeasonInfo = "aktuelle Saison";
|
public partial string StatusDeliveriesThisSeasonInfo { get; set; } = "aktuelle Saison";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusDeliveriesThisSeasonToolTip;
|
public partial Grid? StatusDeliveriesThisSeasonToolTip { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusAreaCommitment = "-";
|
public partial string StatusAreaCommitment { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Grid? _statusAreaCommitmentToolTip;
|
public partial Grid? StatusAreaCommitmentToolTip { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusAreaCommitmentInfo = "aktuelle Saison";
|
public partial string StatusAreaCommitmentInfo { get; set; } = "aktuelle Saison";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _personalNameVisibility = Visibility.Visible;
|
public partial Visibility PersonalNameVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _juridicalNameVisibility = Visibility.Hidden;
|
public partial Visibility JuridicalNameVisibility { get; set; } = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,69 +8,71 @@ namespace Elwig.ViewModels {
|
|||||||
public partial class MemberBusinessSharesViewModel : ObservableObject {
|
public partial class MemberBusinessSharesViewModel : ObservableObject {
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _title = "Geschäftsanteilbewegungen - Elwig";
|
public partial string Title { get; set; } = "Geschäftsanteilbewegungen - Elwig";
|
||||||
|
|
||||||
public required Member FilterMember { get; set; }
|
public required Member FilterMember { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private MemberHistory? _selectedHistoryEntry;
|
public partial MemberHistory? SelectedHistoryEntry { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<MemberHistory> _history = [];
|
public partial IEnumerable<MemberHistory> History { get; set; } = [];
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _dateNoticeString;
|
public partial string? DateNoticeString { get; set; }
|
||||||
public DateOnly? DateNotice {
|
public DateOnly? DateNotice {
|
||||||
get => DateOnly.TryParseExact(DateNoticeString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(DateNoticeString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => DateNoticeString = $"{value:dd.MM.yyyy}";
|
set => DateNoticeString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _dateEffectiveString;
|
public partial string? DateEffectiveString { get; set; }
|
||||||
public DateOnly? DateEffective {
|
public DateOnly? DateEffective {
|
||||||
get => DateOnly.TryParseExact(DateEffectiveString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(DateEffectiveString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => DateEffectiveString = $"{value:dd.MM.yyyy}";
|
set => DateEffectiveString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _reason;
|
public partial string? Reason { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _sharesString;
|
public partial string? SharesString { get; set; }
|
||||||
public int? Shares {
|
public int? Shares {
|
||||||
get => int.TryParse(SharesString, out var shares) ? shares : null;
|
get => int.TryParse(SharesString, out var shares) ? shares : null;
|
||||||
set => SharesString = $"{value}";
|
set => SharesString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _otherMgNrString;
|
public partial string? OtherMgNrString { get; set; }
|
||||||
public int? OtherMgNr {
|
public int? OtherMgNr {
|
||||||
get => int.TryParse(OtherMgNrString, out var mgnr) ? mgnr : null;
|
get => int.TryParse(OtherMgNrString, out var mgnr) ? mgnr : null;
|
||||||
set => OtherMgNrString = $"{value}";
|
set => OtherMgNrString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _deductYearString;
|
public partial string? DeductYearString { get; set; }
|
||||||
public int? DeductYear {
|
public int? DeductYear {
|
||||||
get => int.TryParse(DeductYearString, out var year) ? year : null;
|
get => int.TryParse(DeductYearString, out var year) ? year : null;
|
||||||
set => DeductYearString = $"{value}";
|
set => DeductYearString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _deduct;
|
public partial bool Deduct { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _memberHasSigned;
|
public partial bool CompanyHasSigned { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _valuePerShareString;
|
public partial bool MemberHasSigned { get; set; }
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? ValuePerShareString { get; set; }
|
||||||
public decimal? ValuePerShare {
|
public decimal? ValuePerShare {
|
||||||
get => decimal.TryParse(ValuePerShareString, out var v) ? v : null;
|
get => decimal.TryParse(ValuePerShareString, out var v) ? v : null;
|
||||||
set => ValuePerShareString = $"{value:0.00}";
|
set => ValuePerShareString = $"{value:0.00}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _totalAmount;
|
public partial string? TotalAmount { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string? _comment;
|
public partial string? Comment { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _personalNameVisibility = Visibility.Visible;
|
public partial Visibility PersonalNameVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _juridicalNameVisibility = Visibility.Hidden;
|
public partial Visibility JuridicalNameVisibility { get; set; } = Visibility.Hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,87 +9,87 @@ namespace Elwig.ViewModels {
|
|||||||
public partial class PaymentVariantsViewModel : ObservableObject {
|
public partial class PaymentVariantsViewModel : ObservableObject {
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private PaymentVar? _selectedPaymentVariant;
|
public partial PaymentVar? SelectedPaymentVariant { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private IEnumerable<PaymentVar> _paymentVariants = [];
|
public partial IEnumerable<PaymentVar> PaymentVariants { get; set; } = [];
|
||||||
|
|
||||||
public BillingData? BillingData;
|
public BillingData? BillingData { get; set; }
|
||||||
public bool SeasonLocked = false; // never locked
|
public bool SeasonLocked { get; set; } = false; // never locked
|
||||||
public bool WeightModifierChanged;
|
public bool WeightModifierChanged { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _name = "";
|
public partial string Name { get; set; } = "";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _comment = "";
|
public partial string Comment { get; set; } = "";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _dateString = "";
|
public partial string DateString { get; set; } = "";
|
||||||
public DateOnly? Date {
|
public DateOnly? Date {
|
||||||
get => DateOnly.TryParseExact(DateString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(DateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => DateString = $"{value:dd.MM.yyyy}";
|
set => DateString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _transferDateString = "";
|
public partial string TransferDateString { get; set; } = "";
|
||||||
public DateOnly? TransferDate {
|
public DateOnly? TransferDate {
|
||||||
get => DateOnly.TryParseExact(TransferDateString, "dd.MM.yyyy", out var d) ? d : null;
|
get => DateOnly.TryParseExact(TransferDateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||||
set => TransferDateString = $"{value:dd.MM.yyyy}";
|
set => TransferDateString = $"{value:dd.MM.yyyy}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _weightModifierString = "";
|
public partial string WeightModifierString { get; set; } = "";
|
||||||
public double? WeightModifier {
|
public double? WeightModifier {
|
||||||
get => double.TryParse(WeightModifierString, out var d) ? d : null;
|
get => double.TryParse(WeightModifierString, out var d) ? d : null;
|
||||||
set => WeightModifierString = $"{value}";
|
set => WeightModifierString = $"{value}";
|
||||||
}
|
}
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _data = "";
|
public partial string Data { get; set; } = "";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _considerModifiers;
|
public partial bool ConsiderModifiers { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _considerPenalties;
|
public partial bool ConsiderPenalties { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _considerPenalty;
|
public partial bool ConsiderPenalty { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _considerAuto;
|
public partial bool ConsiderAuto { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _considerCustom;
|
public partial bool ConsiderCustom { get; set; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isPaymentVariantSelected;
|
public partial bool IsPaymentVariantSelected { get; set; }
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isReadOnly = true;
|
public partial bool IsReadOnly { get; set; } = true;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _dataIsReadOnly = true;
|
public partial bool DataIsReadOnly { get; set; } = true;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _isEnabled = false;
|
public partial bool IsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _saveIsEnabled = false;
|
public partial bool SaveIsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _deleteIsEnabled = false;
|
public partial bool DeleteIsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _calculateIsEnabled = false;
|
public partial bool CalculateIsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _exportIsEnabled = false;
|
public partial bool ExportIsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _commitIsEnabled = false;
|
public partial bool CommitIsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _commitVisibility = Visibility.Visible;
|
public partial Visibility CommitVisibility { get; set; } = Visibility.Visible;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool _revertIsEnabled = false;
|
public partial bool RevertIsEnabled { get; set; } = false;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private Visibility _revertVisibility = Visibility.Hidden;
|
public partial Visibility RevertVisibility { get; set; } = Visibility.Hidden;
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _arrow = "\xF0AF";
|
public partial string Arrow { get; set; } = "\xF0AF";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _editText = "Bearbeiten";
|
public partial string EditText { get; set; } = "Bearbeiten";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusModifierSum = "-";
|
public partial string StatusModifierSum { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusTotalSum = "-";
|
public partial string StatusTotalSum { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusVatSum = "-";
|
public partial string StatusVatSum { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusDeductionSum = "-";
|
public partial string StatusDeductionSum { get; set; } = "-";
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string _statusPaymentSum = "-";
|
public partial string StatusPaymentSum { get; set; } = "-";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,12 +108,20 @@ namespace Elwig.Windows {
|
|||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TryClose() {
|
||||||
|
var evt = new CancelEventArgs();
|
||||||
|
OnClosing(this, evt);
|
||||||
|
if (!evt.Cancel) Close();
|
||||||
|
}
|
||||||
|
|
||||||
private void OnClosing(object? sender, CancelEventArgs evt) {
|
private void OnClosing(object? sender, CancelEventArgs evt) {
|
||||||
if ((IsCreating || IsEditing) && HasChanged) {
|
if (!IsClosing && (IsCreating || IsEditing) && HasChanged) {
|
||||||
|
try {
|
||||||
if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) {
|
if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) {
|
||||||
evt.Cancel = true;
|
evt.Cancel = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} catch { }
|
||||||
}
|
}
|
||||||
IsClosing = true;
|
IsClosing = true;
|
||||||
}
|
}
|
||||||
@@ -434,7 +442,7 @@ namespace Elwig.Windows {
|
|||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void TextBox_TextChanged(object sender, RoutedEventArgs? evt) {
|
protected void TextBox_TextChanged(object sender, TextChangedEventArgs? evt) {
|
||||||
var input = (Control)sender;
|
var input = (Control)sender;
|
||||||
var tb = input as TextBox;
|
var tb = input as TextBox;
|
||||||
if (SenderIsRequired(input) && tb?.Text.Length == 0) {
|
if (SenderIsRequired(input) && tb?.Text.Length == 0) {
|
||||||
@@ -576,6 +584,14 @@ namespace Elwig.Windows {
|
|||||||
InputLostFocus((TextBox)sender, Validator.CheckLfbisNr);
|
InputLostFocus((TextBox)sender, Validator.CheckLfbisNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void OrganicOperatorIdInput_TextChanged(object sender, TextChangedEventArgs? evt) {
|
||||||
|
InputTextChanged((TextBox)sender, Validator.CheckOrganicOperatorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void OrganicOperatorIdInput_LostFocus(object sender, RoutedEventArgs? evt) {
|
||||||
|
InputLostFocus((TextBox)sender, Validator.CheckOrganicOperatorId);
|
||||||
|
}
|
||||||
|
|
||||||
protected void OrganicAuthorityCodeInput_TextChanged(object sender, TextChangedEventArgs? evt) {
|
protected void OrganicAuthorityCodeInput_TextChanged(object sender, TextChangedEventArgs? evt) {
|
||||||
InputTextChanged((TextBox)sender, Validator.CheckOrganicAuthorityCode);
|
InputTextChanged((TextBox)sender, Validator.CheckOrganicAuthorityCode);
|
||||||
}
|
}
|
||||||
@@ -592,8 +608,16 @@ namespace Elwig.Windows {
|
|||||||
InputLostFocus((TextBox)sender, Validator.CheckUpperCase);
|
InputLostFocus((TextBox)sender, Validator.CheckUpperCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void AreaComTypeDetailsButton_Click(object sender, RoutedEventArgs? evt) {
|
protected void AreaCmtTypeDetailsButton_Click(object sender, RoutedEventArgs? evt) {
|
||||||
App.FocusBaseDataAreaComType();
|
App.FocusBaseDataAreaCmtType();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void AddressInput_TextChanged(object sender, TextChangedEventArgs? evt) {
|
||||||
|
if ((IsCreating || IsEditing) && sender is TextBox b) {
|
||||||
|
InputTextChanged(b, (i, r) => Validator.CheckAddress(i, r));
|
||||||
|
} else {
|
||||||
|
TextBox_TextChanged(sender, evt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<local:AdministrationWindow
|
<local:AdministrationWindow
|
||||||
x:Class="Elwig.Windows.AreaComAdminWindow"
|
x:Class="Elwig.Windows.AreaCmtAdminWindow"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
Title="{Binding Title}" Height="600" MinHeight="550" Width="1000" MinWidth="860">
|
Title="{Binding Title}" Height="600" MinHeight="550" Width="1000" MinWidth="860">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:AreaComAdminViewModel/>
|
<vm:AreaCmtAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Label">
|
<Style TargetType="Label">
|
||||||
@@ -110,10 +110,10 @@
|
|||||||
</DataGridTextColumn.CellStyle>
|
</DataGridTextColumn.CellStyle>
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="130"/>
|
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="130"/>
|
||||||
<DataGridTextColumn Header="Sorte" Binding="{Binding Latest.AreaComType.VtrgId}" Width="50">
|
<DataGridTextColumn Header="Sorte" Binding="{Binding Latest.AreaCmtType.VtrgId}" Width="50">
|
||||||
<DataGridTextColumn.CellStyle>
|
<DataGridTextColumn.CellStyle>
|
||||||
<Style>
|
<Style>
|
||||||
<Setter Property="TextBlock.Foreground" Value="{Binding Latest.AreaComType.WineVar.Color}"/>
|
<Setter Property="TextBlock.Foreground" Value="{Binding Latest.AreaCmtType.WineVar.Color}"/>
|
||||||
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.CellStyle>
|
</DataGridTextColumn.CellStyle>
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
<TextBlock Text="{Binding YearFrom}" Width="28" TextAlignment="Right" Margin="0,0,0,0"/>
|
<TextBlock Text="{Binding YearFrom}" Width="28" TextAlignment="Right" Margin="0,0,0,0"/>
|
||||||
<TextBlock Text="–" TextAlignment="Center" Margin="0,0,0,0"/>
|
<TextBlock Text="–" TextAlignment="Center" Margin="0,0,0,0"/>
|
||||||
<TextBlock Text="{Binding YearTo}" Width="28" TextAlignment="Left" Margin="0,0,0,0"/>
|
<TextBlock Text="{Binding YearTo}" Width="28" TextAlignment="Left" Margin="0,0,0,0"/>
|
||||||
<TextBlock Text="{Binding VtrgId}" Width="40" TextAlignment="Center" Foreground="{Binding AreaComType.WineVar.Color}"/>
|
<TextBlock Text="{Binding VtrgId}" Width="40" TextAlignment="Center" Foreground="{Binding AreaCmtType.WineVar.Color}"/>
|
||||||
<TextBlock Text="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/>
|
<TextBlock Text="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/>
|
||||||
<TextBlock Text="{Binding Member.AdministrativeName}"/>
|
<TextBlock Text="{Binding Member.AdministrativeName}"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
@@ -268,11 +268,11 @@
|
|||||||
TextChanged="IntegerInput_TextChanged"/>
|
TextChanged="IntegerInput_TextChanged"/>
|
||||||
|
|
||||||
<Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0"/>
|
<Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0"/>
|
||||||
<ComboBox x:Name="AreaComTypeInput" SelectedItem="{Binding AreaComType, Mode=TwoWay}" ItemsSource="{Binding AreaComTypeSource, Mode=TwoWay}"
|
<ComboBox x:Name="AreaCmtTypeInput" SelectedItem="{Binding AreaCmtType, Mode=TwoWay}" ItemsSource="{Binding AreaCmtTypeSource, Mode=TwoWay}"
|
||||||
ItemTemplate="{StaticResource AreaCommitmentTypeTemplate}" TextSearch.TextPath="DisplayName"
|
ItemTemplate="{StaticResource AreaCommitmentTypeTemplate}" TextSearch.TextPath="DisplayName"
|
||||||
HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1"/>
|
HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1"/>
|
||||||
<Button x:Name="AreaComTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
<Button x:Name="AreaCmtTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
||||||
Click="AreaComTypeDetailsButton_Click"
|
Click="AreaCmtTypeDetailsButton_Click"
|
||||||
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
|
Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
|
||||||
|
|
||||||
<Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0"/>
|
<Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0"/>
|
||||||
+39
-40
@@ -12,18 +12,17 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
|
||||||
namespace Elwig.Windows {
|
namespace Elwig.Windows {
|
||||||
public partial class AreaComAdminWindow : AdministrationWindow {
|
public partial class AreaCmtAdminWindow : AdministrationWindow {
|
||||||
|
|
||||||
public AreaComAdminViewModel ViewModel => (AreaComAdminViewModel)DataContext;
|
public AreaCmtAdminViewModel ViewModel => (AreaCmtAdminViewModel)DataContext;
|
||||||
|
|
||||||
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(AreaComAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(AreaCmtAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
||||||
|
|
||||||
public AreaComAdminWindow(int mgnr) {
|
public AreaCmtAdminWindow(int mgnr) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
|
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||||
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
|
||||||
ExemptInputs = [
|
ExemptInputs = [
|
||||||
AreaCommitmentList, RevisionList,
|
AreaCommitmentList, RevisionList,
|
||||||
NewAreaCommitmentButton, EditAreaCommitmentButton, DeleteAreaCommitmentButton, SaveButton,
|
NewAreaCommitmentButton, EditAreaCommitmentButton, DeleteAreaCommitmentButton, SaveButton,
|
||||||
@@ -31,7 +30,7 @@ namespace Elwig.Windows {
|
|||||||
];
|
];
|
||||||
RequiredInputs = [
|
RequiredInputs = [
|
||||||
FbNrInput, MgNrInput, MemberInput, YearFromInput, KgInput, RdInput,
|
FbNrInput, MgNrInput, MemberInput, YearFromInput, KgInput, RdInput,
|
||||||
GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput
|
GstNrInput, AreaInput, AreaCmtTypeInput, WineCultivationInput
|
||||||
];
|
];
|
||||||
|
|
||||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||||
@@ -51,13 +50,13 @@ namespace Elwig.Windows {
|
|||||||
var cursor = Mouse.OverrideCursor != null;
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
var query = (vm.SearchQuery, vm.FilterSeason);
|
var query = (vm.SearchQuery, vm.FilterSeason);
|
||||||
var (filter, contracts, areaComs, areaComCount, stat) = await Task.Run(async () => {
|
var (filterNames, filter, contracts, areaCmts, areaCmtCount, stat) = await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var (_, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
var (filterNames, contractQuery, areaCmtQuery, filter) = await vm.GetFilters(ctx);
|
||||||
var contracts = await contractQuery
|
var contracts = await contractQuery
|
||||||
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
var areaComs = await areaComQuery.ToListAsync();
|
var areaCmts = await areaCmtQuery.ToListAsync();
|
||||||
|
|
||||||
if (filter.Count > 0 && contracts.Count > 0) {
|
if (filter.Count > 0 && contracts.Count > 0) {
|
||||||
var dict = contracts.AsParallel()
|
var dict = contracts.AsParallel()
|
||||||
@@ -69,30 +68,31 @@ namespace Elwig.Windows {
|
|||||||
.Select(a => a.Key)];
|
.Select(a => a.Key)];
|
||||||
}
|
}
|
||||||
|
|
||||||
var areaComCount = await areaComQuery.CountAsync();
|
var areaCmtCount = await areaCmtQuery.CountAsync();
|
||||||
var season = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
var season = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||||
var stat = await AreaComService.GenerateToolTipData(areaComQuery, season?.MaxKgPerHa ?? 10_000);
|
var stat = await AreaCmtService.GenerateToolTipData(areaCmtQuery, season?.MaxKgPerHa ?? 10_000);
|
||||||
|
|
||||||
return (filter, contracts, areaComs, areaComCount, stat);
|
return (filterNames, filter, contracts, areaCmts, areaCmtCount, stat);
|
||||||
});
|
});
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason)) return;
|
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason)) return;
|
||||||
|
|
||||||
|
ViewModel.Title = Utils.GetTitle("Flächenbindungen", filterNames, filter);
|
||||||
ControlUtils.RenewItemsSource(AreaCommitmentList, contracts,
|
ControlUtils.RenewItemsSource(AreaCommitmentList, contracts,
|
||||||
AreaCommitmentList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
AreaCommitmentList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
|
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
ViewModel.StatusAreaCommitments = $"{areaComCount:N0}";
|
ViewModel.StatusAreaCommitments = $"{areaCmtCount:N0}";
|
||||||
var (text, gridData) = stat;
|
var (text, gridData) = stat;
|
||||||
ViewModel.StatusArea = text;
|
ViewModel.StatusArea = text;
|
||||||
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
|
ViewModel.StatusAreaToolTip = AreaCmtService.GenerateToolTip(gridData);
|
||||||
} else {
|
} else {
|
||||||
ViewModel.StatusAreaCommitments = $"{contracts.Count:N0}";
|
ViewModel.StatusAreaCommitments = $"{contracts.Count:N0}";
|
||||||
ViewModel.StatusArea = $"{areaComs.Sum(a => a.Area):N0} m²";
|
ViewModel.StatusArea = $"{areaCmts.Sum(a => a.Area):N0} m²";
|
||||||
ViewModel.StatusAreaToolTip = null;
|
ViewModel.StatusAreaToolTip = null;
|
||||||
}
|
}
|
||||||
var groups = areaComs.GroupBy(a => $"{a.AreaComType.SortId}{a.AreaComType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
var groups = areaCmts.GroupBy(a => $"{a.AreaCmtType.SortId}{a.AreaCmtType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
||||||
ViewModel.StatusContracts = $"{groups.Count:N0}";
|
ViewModel.StatusContracts = $"{groups.Count:N0}";
|
||||||
if (groups.Count > 0)
|
if (groups.Count > 0)
|
||||||
ViewModel.StatusContracts += $" ({string.Join(", ", groups.Select(g => g.Key))})";
|
ViewModel.StatusContracts += $" ({string.Join(", ", groups.Select(g => g.Key))})";
|
||||||
@@ -100,7 +100,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private async Task RefreshRevisions() {
|
private async Task RefreshRevisions() {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
if (AreaCommitmentList.SelectedItem is AreaComContract c) {
|
if (AreaCommitmentList.SelectedItem is AreaCmtContract c) {
|
||||||
ControlUtils.RenewItemsSource(RevisionList, c.Revisions.OrderByDescending(p => p.RevNr).ToList(), RevisionList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
ControlUtils.RenewItemsSource(RevisionList, c.Revisions.OrderByDescending(p => p.RevNr).ToList(), RevisionList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||||
} else {
|
} else {
|
||||||
RevisionList.ItemsSource = null;
|
RevisionList.ItemsSource = null;
|
||||||
@@ -109,11 +109,11 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private void RefreshInputs(bool validate = false) {
|
private void RefreshInputs(bool validate = false) {
|
||||||
ClearInputStates();
|
ClearInputStates();
|
||||||
if (RevisionList.SelectedItem is AreaCom a) {
|
if (RevisionList.SelectedItem is AreaCmt a) {
|
||||||
EditAreaCommitmentButton.IsEnabled = true;
|
EditAreaCommitmentButton.IsEnabled = true;
|
||||||
DeleteAreaCommitmentButton.IsEnabled = true;
|
DeleteAreaCommitmentButton.IsEnabled = true;
|
||||||
FillInputs(a);
|
FillInputs(a);
|
||||||
} else if (AreaCommitmentList.SelectedItem is AreaComContract c) {
|
} else if (AreaCommitmentList.SelectedItem is AreaCmtContract c) {
|
||||||
EditAreaCommitmentButton.IsEnabled = true;
|
EditAreaCommitmentButton.IsEnabled = true;
|
||||||
DeleteAreaCommitmentButton.IsEnabled = true;
|
DeleteAreaCommitmentButton.IsEnabled = true;
|
||||||
FillInputs(c);
|
FillInputs(c);
|
||||||
@@ -128,14 +128,14 @@ namespace Elwig.Windows {
|
|||||||
GC.Collect();
|
GC.Collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillInputs(AreaComContract c) {
|
private void FillInputs(AreaCmtContract c) {
|
||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
ViewModel.FillInputs(c);
|
ViewModel.FillInputs(c);
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FillInputs(AreaCom a) {
|
private void FillInputs(AreaCmt a) {
|
||||||
FillInputs(a.Contract);
|
FillInputs(a.Contract);
|
||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
@@ -164,14 +164,13 @@ namespace Elwig.Windows {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ViewModel.FilterMember = m;
|
ViewModel.FilterMember = m;
|
||||||
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(KgInput, await ctx.WbKgs
|
ControlUtils.RenewItemsSource(KgInput, await ctx.WbKgs
|
||||||
.Include(k => k.AtKg.WbKg!.Rds)
|
.Include(k => k.AtKg.WbKg!.Rds)
|
||||||
.Select(k => k.AtKg)
|
.Select(k => k.AtKg)
|
||||||
.OrderBy(k => k.Name)
|
.OrderBy(k => k.Name)
|
||||||
.ToListAsync());
|
.ToListAsync());
|
||||||
ControlUtils.RenewItemsSource(AreaComTypeInput, await ctx.AreaCommitmentTypes
|
ControlUtils.RenewItemsSource(AreaCmtTypeInput, await ctx.AreaCommitmentTypes
|
||||||
.Include(c => c.WineVar)
|
.Include(c => c.WineVar)
|
||||||
.Include(c => c.WineAttr)
|
.Include(c => c.WineAttr)
|
||||||
.OrderBy(v => v.VtrgId)
|
.OrderBy(v => v.VtrgId)
|
||||||
@@ -229,10 +228,10 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) {
|
private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||||
if (RevisionList.SelectedItem is not AreaCom a)
|
if (RevisionList.SelectedItem is not AreaCmt a)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, true, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
var d = new AreaCmtModifyDialog(a.YearFrom, a.YearTo, a.Area, true, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||||
if (d.ShowDialog() != true)
|
if (d.ShowDialog() != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -242,7 +241,7 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.YearTo = yearTo;
|
ViewModel.YearTo = yearTo;
|
||||||
await ViewModel.UpdateAreaCommitment(a.FbNr, a.RevNr);
|
await ViewModel.UpdateAreaCommitment(a.FbNr, a.RevNr);
|
||||||
} else {
|
} else {
|
||||||
await AreaComService.DeleteAreaCom(a.FbNr);
|
await AreaCmtService.DeleteAreaCmt(a.FbNr);
|
||||||
}
|
}
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
@@ -261,9 +260,9 @@ namespace Elwig.Windows {
|
|||||||
SaveButton.IsEnabled = false;
|
SaveButton.IsEnabled = false;
|
||||||
|
|
||||||
int? yearTo = null;
|
int? yearTo = null;
|
||||||
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput) || InputHasChanged(MgNrInput)) {
|
if (InputHasChanged(AreaInput) || InputHasChanged(AreaCmtTypeInput) || InputHasChanged(MgNrInput)) {
|
||||||
var a = (RevisionList.SelectedItem as AreaCom)!;
|
var a = (RevisionList.SelectedItem as AreaCmt)!;
|
||||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
var d = new AreaCmtModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||||
if (d.ShowDialog() != true) {
|
if (d.ShowDialog() != true) {
|
||||||
SaveButton.IsEnabled = true;
|
SaveButton.IsEnabled = true;
|
||||||
return;
|
return;
|
||||||
@@ -274,13 +273,13 @@ namespace Elwig.Windows {
|
|||||||
int fbnr, revnr;
|
int fbnr, revnr;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
try {
|
try {
|
||||||
AreaCom? temp = null;
|
AreaCmt? temp = null;
|
||||||
if (yearTo != null && (!ViewModel.YearTo.HasValue || yearTo < ViewModel.YearTo)) {
|
if (yearTo != null && (!ViewModel.YearTo.HasValue || yearTo < ViewModel.YearTo)) {
|
||||||
temp = new AreaCom {
|
temp = new AreaCmt {
|
||||||
MgNr = ViewModel.MgNr!.Value,
|
MgNr = ViewModel.MgNr!.Value,
|
||||||
YearFrom = ViewModel.YearFrom,
|
YearFrom = ViewModel.YearFrom,
|
||||||
YearTo = ViewModel.YearTo,
|
YearTo = ViewModel.YearTo,
|
||||||
VtrgId = ViewModel.AreaComType!.VtrgId,
|
VtrgId = ViewModel.AreaCmtType!.VtrgId,
|
||||||
CultId = ViewModel.WineCult?.CultId,
|
CultId = ViewModel.WineCult?.CultId,
|
||||||
GstNr = ViewModel.GstNr?.Trim() ?? "-",
|
GstNr = ViewModel.GstNr?.Trim() ?? "-",
|
||||||
Area = ViewModel.Area!.Value,
|
Area = ViewModel.Area!.Value,
|
||||||
@@ -288,11 +287,11 @@ namespace Elwig.Windows {
|
|||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
ViewModel.YearTo = yearTo;
|
ViewModel.YearTo = yearTo;
|
||||||
}
|
}
|
||||||
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaComContract)?.FbNr, (RevisionList.SelectedItem as AreaCom)?.RevNr);
|
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCmtContract)?.FbNr, (RevisionList.SelectedItem as AreaCmt)?.RevNr);
|
||||||
if (temp is AreaCom t) {
|
if (temp is AreaCmt t) {
|
||||||
t.YearFrom = yearTo + 1;
|
t.YearFrom = yearTo + 1;
|
||||||
ViewModel.FillInputs(t);
|
ViewModel.FillInputs(t);
|
||||||
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaComContract)?.FbNr, null);
|
(fbnr, revnr) = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCmtContract)?.FbNr, null);
|
||||||
}
|
}
|
||||||
App.HintContextChange();
|
App.HintContextChange();
|
||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
@@ -416,7 +415,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private void RevisionList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
private void RevisionList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
if (RevisionList.SelectedItem is AreaCom c) {
|
if (RevisionList.SelectedItem is AreaCmt c) {
|
||||||
EditAreaCommitmentButton.IsEnabled = true;
|
EditAreaCommitmentButton.IsEnabled = true;
|
||||||
} else {
|
} else {
|
||||||
EditAreaCommitmentButton.IsEnabled = false;
|
EditAreaCommitmentButton.IsEnabled = false;
|
||||||
@@ -496,12 +495,12 @@ namespace Elwig.Windows {
|
|||||||
RdInput.SelectedIndex = s.Count();
|
RdInput.SelectedIndex = s.Count();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaComContract?, ValidationResult> checker) {
|
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaCmtContract?, ValidationResult> checker) {
|
||||||
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaComContract)AreaCommitmentList.SelectedItem));
|
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaCmtContract)AreaCommitmentList.SelectedItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaComContract?, ValidationResult> checker, string? msg = null) {
|
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaCmtContract?, ValidationResult> checker, string? msg = null) {
|
||||||
InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaComContract)AreaCommitmentList.SelectedItem), msg);
|
InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaCmtContract)AreaCommitmentList.SelectedItem), msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FbNrInput_TextChanged(object sender, RoutedEventArgs evt) {
|
private void FbNrInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
<Label Content="Adresse:"
|
<Label Content="Adresse:"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,160,0,10"/>
|
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,160,0,10"/>
|
||||||
<TextBox x:Name="ClientAddressInput"
|
<TextBox x:Name="ClientAddressInput"
|
||||||
TextChanged="TextBox_TextChanged"
|
TextChanged="AddressInput_TextChanged"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Margin="0,160,10,10"/>
|
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Margin="0,160,10,10"/>
|
||||||
|
|
||||||
<Label Content="PLZ/Ort:"
|
<Label Content="PLZ/Ort:"
|
||||||
@@ -109,24 +109,30 @@
|
|||||||
<TextBox x:Name="ClientBicInput" Margin="0,250,10,0" Grid.Column="1"
|
<TextBox x:Name="ClientBicInput" Margin="0,250,10,0" Grid.Column="1"
|
||||||
TextChanged="BicInput_TextChanged" LostFocus="BicInput_LostFocus"/>
|
TextChanged="BicInput_TextChanged" LostFocus="BicInput_LostFocus"/>
|
||||||
|
|
||||||
<Label Content="UID:"
|
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,100,0,10"/>
|
|
||||||
<TextBox x:Name="ClientUstIdNrInput"
|
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="3" Margin="0,100,10,10" Width="96"
|
|
||||||
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
|
|
||||||
|
|
||||||
<Label Content="Betriebs-Nr.:"
|
<Label Content="Betriebs-Nr.:"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,130,0,10"/>
|
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,100,0,10"/>
|
||||||
<TextBox x:Name="ClientLfbisNrInput"
|
<TextBox x:Name="ClientLfbisNrInput"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="3" Margin="0,130,10,10" Width="64"
|
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="3" Margin="0,100,10,10" Width="64"
|
||||||
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
|
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
|
||||||
|
|
||||||
<Label Content="Bio-Kontrollstelle:"
|
<Label Content="UID:"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,130,110,10"/>
|
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,130,0,10"/>
|
||||||
<TextBox x:Name="ClientOrganicAuthorityInput"
|
<TextBox x:Name="ClientUstIdNrInput"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,130,10,10" Width="90"
|
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="3" Margin="0,130,10,10" Width="96"
|
||||||
|
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label Content="Bio-KSt.:" ToolTip="Bio-Konstrollstelle"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,100,110,10"/>
|
||||||
|
<TextBox x:Name="ClientOrganicAuthorityCodeInput"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,100,10,10" Width="91"
|
||||||
TextChanged="OrganicAuthorityCodeInput_TextChanged" LostFocus="OrganicAuthorityCodeInput_LostFocus"/>
|
TextChanged="OrganicAuthorityCodeInput_TextChanged" LostFocus="OrganicAuthorityCodeInput_LostFocus"/>
|
||||||
|
|
||||||
|
<Label Content="OOC-ID:" ToolTip="Bio-EU-Operator-ID / Organic Operator Certificate ID"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,130,110,10"/>
|
||||||
|
<TextBox x:Name="ClientOrganicOperatorIdInput"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,130,10,10" Width="91"
|
||||||
|
TextChanged="OrganicOperatorIdInput_TextChanged" LostFocus="OrganicOperatorIdInput_LostFocus"/>
|
||||||
|
|
||||||
<Label Content="Telefon-Nr.:"
|
<Label Content="Telefon-Nr.:"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,160,0,10"/>
|
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,160,0,10"/>
|
||||||
<TextBox x:Name="ClientPhoneNrInput" Margin="0,160,10,10" Grid.Column="3"
|
<TextBox x:Name="ClientPhoneNrInput" Margin="0,160,10,10" Grid.Column="3"
|
||||||
@@ -189,7 +195,7 @@
|
|||||||
<Label Content="PLZ/Ort:" Margin="10,70,0,10"/>
|
<Label Content="PLZ/Ort:" Margin="10,70,0,10"/>
|
||||||
<TextBox x:Name="BranchPlzInput" Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
<TextBox x:Name="BranchPlzInput" Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
|
||||||
TextChanged="BranchPlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
TextChanged="BranchPlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||||
<ComboBox x:Name="BranchOrtInput" ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
<ComboBox x:Name="BranchOrtInput" DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
|
||||||
Margin="47,70,10,0" Grid.Column="1" Grid.ColumnSpan="3" Width="253" HorizontalAlignment="Left"
|
Margin="47,70,10,0" Grid.Column="1" Grid.ColumnSpan="3" Width="253" HorizontalAlignment="Left"
|
||||||
SelectionChanged="Branch_Changed"/>
|
SelectionChanged="Branch_Changed"/>
|
||||||
|
|
||||||
@@ -320,6 +326,10 @@
|
|||||||
<Label Content="Beschreibung:" Margin="10,70,0,10"/>
|
<Label Content="Beschreibung:" Margin="10,70,0,10"/>
|
||||||
<TextBox x:Name="WineCultivationDescriptionInput" Grid.Column="1" Margin="0,70,10,10"
|
<TextBox x:Name="WineCultivationDescriptionInput" Grid.Column="1" Margin="0,70,10,10"
|
||||||
TextChanged="WineCultivation_Changed"/>
|
TextChanged="WineCultivation_Changed"/>
|
||||||
|
|
||||||
|
<CheckBox x:Name="WineCultivationOrganicInput" Content="Bio" Grid.Column="1" Margin="0,105,10,10"
|
||||||
|
Checked="WineCultivation_Changed" Unchecked="WineCultivation_Changed"
|
||||||
|
HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
</TabItem>
|
</TabItem>
|
||||||
@@ -556,7 +566,7 @@
|
|||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
<GroupBox x:Name="ParameterAreaComGroup" Header="Berechnung Flächenbindungen (aktuelle Saison)" Margin="10,10,10,0" VerticalAlignment="Top">
|
<GroupBox x:Name="ParameterAreaCmtGroup" 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) "schlechtere" Flächenbindungen aufzuteilen"
|
<CheckBox x:Name="ParameterAllowAttrIntoLowerInput" Content="Erlauben Lieferungen auch auf (konfigurierte) "schlechtere" Flächenbindungen aufzuteilen"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,10,10,10"
|
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,10,10,10"
|
||||||
@@ -564,7 +574,7 @@
|
|||||||
<CheckBox x:Name="ParameterAvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei "besseren" Flächenbindungen vermeiden"
|
<CheckBox x:Name="ParameterAvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei "besseren" Flächenbindungen vermeiden"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,30,10,10"
|
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,30,10,10"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||||
<CheckBox x:Name="ParameterHonorGebundenInput" Margin="10,50,10,10" VerticalAlignment="Top"
|
<CheckBox x:Name="ParameterHonorContractedInput" Margin="10,50,10,10" VerticalAlignment="Top"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed">
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed">
|
||||||
<TextBlock>Bei Lieferungen das Feld <Italic>Gebunden</Italic> berücksichtigen</TextBlock>
|
<TextBlock>Bei Lieferungen das Feld <Italic>Gebunden</Italic> berücksichtigen</TextBlock>
|
||||||
</CheckBox>
|
</CheckBox>
|
||||||
@@ -601,6 +611,13 @@
|
|||||||
<TabItem Header="Textelemente">
|
<TabItem Header="Textelemente">
|
||||||
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
<ScrollViewer VerticalScrollBarVisibility="Visible">
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
<GroupBox Header="Stammdatenblatt" Margin="10,10,10,10" Height="70">
|
||||||
|
<Grid>
|
||||||
|
<CheckBox x:Name="ModeMemberDataSheetShares" Content="Verlauf der Geschäftsanteile anzeigen" Margin="15,15,10,15"
|
||||||
|
HorizontalAlignment="Left" VerticalAlignment="Top"
|
||||||
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||||
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
<GroupBox Header="Lieferschein" Margin="10,10,10,10" Height="180">
|
<GroupBox Header="Lieferschein" Margin="10,10,10,10" Height="180">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ namespace Elwig.Windows {
|
|||||||
public partial class BaseDataWindow {
|
public partial class BaseDataWindow {
|
||||||
|
|
||||||
private Dictionary<string, string?>? _acts = null;
|
private Dictionary<string, string?>? _acts = null;
|
||||||
private Dictionary<AreaComType, string>? _actIds = null;
|
private Dictionary<AreaCmtType, string>? _actIds = null;
|
||||||
private ObservableCollection<AreaComType>? _actList = null;
|
private ObservableCollection<AreaCmtType>? _actList = null;
|
||||||
private bool _actChanged = false;
|
private bool _actChanged = false;
|
||||||
private bool _actUpdate = false;
|
private bool _actUpdate = false;
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ namespace Elwig.Windows {
|
|||||||
private void AreaCommitmentTypeList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
private void AreaCommitmentTypeList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
_actUpdate = true;
|
_actUpdate = true;
|
||||||
if (AreaCommitmentTypeList.SelectedItem is AreaComType type) {
|
if (AreaCommitmentTypeList.SelectedItem is AreaCmtType type) {
|
||||||
AreaCommitmentTypeIdInput.Text = $"{type.SortId}{type.AttrId}";
|
AreaCommitmentTypeIdInput.Text = $"{type.SortId}{type.AttrId}";
|
||||||
ControlUtils.SelectItemWithPk(AreaCommitmentTypeWineVariantInput, type.SortId);
|
ControlUtils.SelectItemWithPk(AreaCommitmentTypeWineVariantInput, type.SortId);
|
||||||
ControlUtils.SelectItemWithPk(AreaCommitmentTypeWineAttributeInput, type.AttrId);
|
ControlUtils.SelectItemWithPk(AreaCommitmentTypeWineAttributeInput, type.AttrId);
|
||||||
@@ -96,7 +96,7 @@ namespace Elwig.Windows {
|
|||||||
private void AreaCommitmentTypeAddButton_Click(object sender, RoutedEventArgs evt) {
|
private void AreaCommitmentTypeAddButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
if (_actList == null) return;
|
if (_actList == null) return;
|
||||||
_actChanged = true;
|
_actChanged = true;
|
||||||
var item = new AreaComType { VtrgId = "", SortId = "" };
|
var item = new AreaCmtType { VtrgId = "", SortId = "" };
|
||||||
_actList.Add(item);
|
_actList.Add(item);
|
||||||
AreaCommitmentTypeList.SelectedItem = item;
|
AreaCommitmentTypeList.SelectedItem = item;
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
@@ -114,7 +114,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void AreaCommitmentType_Changed(object? sender, RoutedEventArgs? evt) {
|
private void AreaCommitmentType_Changed(object? sender, RoutedEventArgs? evt) {
|
||||||
if (_actUpdate || (!IsEditing && !IsCreating) || AreaCommitmentTypeList.SelectedItem is not AreaComType attr || _acts == null || _actIds == null) return;
|
if (_actUpdate || (!IsEditing && !IsCreating) || AreaCommitmentTypeList.SelectedItem is not AreaCmtType attr || _acts == null || _actIds == null) return;
|
||||||
_actChanged = true;
|
_actChanged = true;
|
||||||
|
|
||||||
var v = AreaCommitmentTypeWineVariantInput.SelectedItem as WineVar;
|
var v = AreaCommitmentTypeWineVariantInput.SelectedItem as WineVar;
|
||||||
|
|||||||
@@ -72,10 +72,12 @@ namespace Elwig.Windows {
|
|||||||
WineCultivationIdInput.Text = "";
|
WineCultivationIdInput.Text = "";
|
||||||
WineCultivationNameInput.Text = "";
|
WineCultivationNameInput.Text = "";
|
||||||
WineCultivationDescriptionInput.Text = "";
|
WineCultivationDescriptionInput.Text = "";
|
||||||
|
WineCultivationOrganicInput.IsChecked = false;
|
||||||
} else {
|
} else {
|
||||||
WineCultivationIdInput.Text = cult.CultId;
|
WineCultivationIdInput.Text = cult.CultId;
|
||||||
WineCultivationNameInput.Text = cult.Name;
|
WineCultivationNameInput.Text = cult.Name;
|
||||||
WineCultivationDescriptionInput.Text = cult.Description;
|
WineCultivationDescriptionInput.Text = cult.Description;
|
||||||
|
WineCultivationOrganicInput.IsChecked = cult.IsOrganic;
|
||||||
}
|
}
|
||||||
_cultUpdate = false;
|
_cultUpdate = false;
|
||||||
}
|
}
|
||||||
@@ -105,7 +107,8 @@ namespace Elwig.Windows {
|
|||||||
_cultChanged = _cultChanged ||
|
_cultChanged = _cultChanged ||
|
||||||
WineCultivationIdInput.Text != cult.CultId ||
|
WineCultivationIdInput.Text != cult.CultId ||
|
||||||
WineCultivationNameInput.Text != cult.Name ||
|
WineCultivationNameInput.Text != cult.Name ||
|
||||||
WineCultivationDescriptionInput.Text != (cult.Description ?? "");
|
WineCultivationDescriptionInput.Text != (cult.Description ?? "") ||
|
||||||
|
WineCultivationOrganicInput.IsChecked != cult.IsOrganic;
|
||||||
|
|
||||||
var old = _cultIds.GetValueOrDefault(cult);
|
var old = _cultIds.GetValueOrDefault(cult);
|
||||||
var id = WineCultivationIdInput.Text ?? "";
|
var id = WineCultivationIdInput.Text ?? "";
|
||||||
@@ -113,7 +116,8 @@ namespace Elwig.Windows {
|
|||||||
cult.CultId = id;
|
cult.CultId = id;
|
||||||
cult.Name = WineCultivationNameInput.Text ?? "";
|
cult.Name = WineCultivationNameInput.Text ?? "";
|
||||||
cult.Description = WineCultivationDescriptionInput.Text ?? "";
|
cult.Description = WineCultivationDescriptionInput.Text ?? "";
|
||||||
if (cult.Description.Length == 0) cult.Description = null;
|
cult.IsOrganic = WineCultivationOrganicInput.IsChecked ?? false;
|
||||||
|
if (string.IsNullOrWhiteSpace(cult.Description)) cult.Description = null;
|
||||||
|
|
||||||
CollectionViewSource.GetDefaultView(_cultList).Refresh();
|
CollectionViewSource.GetDefaultView(_cultList).Refresh();
|
||||||
UpdateButtons();
|
UpdateButtons();
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ namespace Elwig.Windows {
|
|||||||
BranchAddressInput, BranchPhoneNrInput, BranchFaxNrInput, BranchMobileNrInput,
|
BranchAddressInput, BranchPhoneNrInput, BranchFaxNrInput, BranchMobileNrInput,
|
||||||
WineAttributeIdInput, WineAttributeNameInput, WineAttributeActiveInput,
|
WineAttributeIdInput, WineAttributeNameInput, WineAttributeActiveInput,
|
||||||
WineAttributeMaxKgPerHaInput, WineAttributeStrictInput, WineAttributeFillLowerInput,
|
WineAttributeMaxKgPerHaInput, WineAttributeStrictInput, WineAttributeFillLowerInput,
|
||||||
WineCultivationIdInput, WineCultivationNameInput, WineCultivationDescriptionInput,
|
WineCultivationIdInput, WineCultivationNameInput, WineCultivationDescriptionInput, WineCultivationOrganicInput,
|
||||||
AreaCommitmentTypeIdInput, AreaCommitmentTypeWineVariantInput, AreaCommitmentTypeWineAttributeInput,
|
AreaCommitmentTypeIdInput, AreaCommitmentTypeWineVariantInput, AreaCommitmentTypeWineAttributeInput,
|
||||||
AreaCommitmentTypeMinKgPerHaInput, AreaCommitmentTypePenaltyPerKgInput,
|
AreaCommitmentTypeMinKgPerHaInput, AreaCommitmentTypePenaltyPerKgInput,
|
||||||
AreaCommitmentTypePenaltyInput, AreaCommitmentTypePenaltyNoneInput,
|
AreaCommitmentTypePenaltyInput, AreaCommitmentTypePenaltyNoneInput,
|
||||||
@@ -37,7 +37,7 @@ namespace Elwig.Windows {
|
|||||||
];
|
];
|
||||||
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})";
|
ParameterAreaCmtGroup.Header = ParameterAreaCmtGroup.Header.ToString()!.Split('(')[0] + $"({Utils.CurrentLastSeason})";
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,6 +67,7 @@ namespace Elwig.Windows {
|
|||||||
WineCultivationIdInput.IsReadOnly = true;
|
WineCultivationIdInput.IsReadOnly = true;
|
||||||
WineCultivationNameInput.IsReadOnly = true;
|
WineCultivationNameInput.IsReadOnly = true;
|
||||||
WineCultivationDescriptionInput.IsReadOnly = true;
|
WineCultivationDescriptionInput.IsReadOnly = true;
|
||||||
|
WineCultivationOrganicInput.IsEnabled = false;
|
||||||
|
|
||||||
AreaCommitmentTypeWineVariantInput.IsEnabled = false;
|
AreaCommitmentTypeWineVariantInput.IsEnabled = false;
|
||||||
AreaCommitmentTypeWineAttributeInput.IsEnabled = false;
|
AreaCommitmentTypeWineAttributeInput.IsEnabled = false;
|
||||||
@@ -115,6 +116,7 @@ namespace Elwig.Windows {
|
|||||||
WineCultivationIdInput.IsReadOnly = false;
|
WineCultivationIdInput.IsReadOnly = false;
|
||||||
WineCultivationNameInput.IsReadOnly = false;
|
WineCultivationNameInput.IsReadOnly = false;
|
||||||
WineCultivationDescriptionInput.IsReadOnly = false;
|
WineCultivationDescriptionInput.IsReadOnly = false;
|
||||||
|
WineCultivationOrganicInput.IsEnabled = true;
|
||||||
|
|
||||||
AreaCommitmentTypeWineVariantInput.IsEnabled = true;
|
AreaCommitmentTypeWineVariantInput.IsEnabled = true;
|
||||||
AreaCommitmentTypeWineAttributeInput.IsEnabled = true;
|
AreaCommitmentTypeWineAttributeInput.IsEnabled = true;
|
||||||
@@ -329,12 +331,14 @@ namespace Elwig.Windows {
|
|||||||
ClientBicInput.Text = p.Bic;
|
ClientBicInput.Text = p.Bic;
|
||||||
ClientUstIdNrInput.Text = p.UstIdNr;
|
ClientUstIdNrInput.Text = p.UstIdNr;
|
||||||
ClientLfbisNrInput.Text = p.LfbisNr;
|
ClientLfbisNrInput.Text = p.LfbisNr;
|
||||||
ClientOrganicAuthorityInput.Text = p.OrganicAuthority;
|
ClientOrganicOperatorIdInput.Text = p.OrganicOperatorId;
|
||||||
|
ClientOrganicAuthorityCodeInput.Text = p.OrganicAuthorityCode;
|
||||||
ClientPhoneNrInput.Text = p.PhoneNr;
|
ClientPhoneNrInput.Text = p.PhoneNr;
|
||||||
ClientFaxNrInput.Text = p.FaxNr;
|
ClientFaxNrInput.Text = p.FaxNr;
|
||||||
ClientEmailAddressInput.Text = p.EmailAddress;
|
ClientEmailAddressInput.Text = p.EmailAddress;
|
||||||
ClientWebsiteInput.Text = p.Website;
|
ClientWebsiteInput.Text = p.Website;
|
||||||
|
|
||||||
|
ModeMemberDataSheetShares.IsChecked = p.ModeMemberDataSheetShares > 0;
|
||||||
TextElementDeliveryNote.Text = p.TextDeliveryNote;
|
TextElementDeliveryNote.Text = p.TextDeliveryNote;
|
||||||
switch (p.ModeDeliveryNoteStats) {
|
switch (p.ModeDeliveryNoteStats) {
|
||||||
case 0: ModeDeliveryNoteNone.IsChecked = true; break;
|
case 0: ModeDeliveryNoteNone.IsChecked = true; break;
|
||||||
@@ -349,7 +353,7 @@ namespace Elwig.Windows {
|
|||||||
ParameterBusinessShareHistoryInput.IsChecked = p.EnableMemberHistory;
|
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;
|
ParameterHonorContractedInput.IsChecked = s?.Billing_HonorContracted ?? false;
|
||||||
ParameterExportEbicsVersion.SelectedIndex = p.ExportEbicsVersion - 3;
|
ParameterExportEbicsVersion.SelectedIndex = p.ExportEbicsVersion - 3;
|
||||||
ParameterExportEbicsAddress.SelectedIndex = p.ExportEbicsAddress;
|
ParameterExportEbicsAddress.SelectedIndex = p.ExportEbicsAddress;
|
||||||
|
|
||||||
@@ -369,7 +373,8 @@ namespace Elwig.Windows {
|
|||||||
p.Bic = string.IsNullOrWhiteSpace(ClientBicInput.Text) ? null : ClientBicInput.Text;
|
p.Bic = string.IsNullOrWhiteSpace(ClientBicInput.Text) ? null : ClientBicInput.Text;
|
||||||
p.UstIdNr = string.IsNullOrWhiteSpace(ClientUstIdNrInput.Text) ? null : ClientUstIdNrInput.Text;
|
p.UstIdNr = string.IsNullOrWhiteSpace(ClientUstIdNrInput.Text) ? null : ClientUstIdNrInput.Text;
|
||||||
p.LfbisNr = string.IsNullOrWhiteSpace(ClientLfbisNrInput.Text) ? null : ClientLfbisNrInput.Text;
|
p.LfbisNr = string.IsNullOrWhiteSpace(ClientLfbisNrInput.Text) ? null : ClientLfbisNrInput.Text;
|
||||||
p.OrganicAuthority = string.IsNullOrWhiteSpace(ClientOrganicAuthorityInput.Text) ? null : ClientOrganicAuthorityInput.Text;
|
p.OrganicOperatorId = string.IsNullOrWhiteSpace(ClientOrganicOperatorIdInput.Text) ? null : ClientOrganicOperatorIdInput.Text;
|
||||||
|
p.OrganicAuthorityCode = string.IsNullOrWhiteSpace(ClientOrganicAuthorityCodeInput.Text) ? null : ClientOrganicAuthorityCodeInput.Text;
|
||||||
p.PhoneNr = string.IsNullOrWhiteSpace(ClientPhoneNrInput.Text) ? null : ClientPhoneNrInput.Text;
|
p.PhoneNr = string.IsNullOrWhiteSpace(ClientPhoneNrInput.Text) ? null : ClientPhoneNrInput.Text;
|
||||||
p.FaxNr = string.IsNullOrWhiteSpace(ClientFaxNrInput.Text) ? null : ClientFaxNrInput.Text;
|
p.FaxNr = string.IsNullOrWhiteSpace(ClientFaxNrInput.Text) ? null : ClientFaxNrInput.Text;
|
||||||
p.EmailAddress = string.IsNullOrWhiteSpace(ClientEmailAddressInput.Text) ? null : ClientEmailAddressInput.Text;
|
p.EmailAddress = string.IsNullOrWhiteSpace(ClientEmailAddressInput.Text) ? null : ClientEmailAddressInput.Text;
|
||||||
@@ -377,6 +382,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
p.ModeBusinessShares = ParameterBusinessShareModeInput.SelectedIndex;
|
p.ModeBusinessShares = ParameterBusinessShareModeInput.SelectedIndex;
|
||||||
p.EnableMemberHistory = ParameterBusinessShareHistoryInput.IsChecked ?? false;
|
p.EnableMemberHistory = ParameterBusinessShareHistoryInput.IsChecked ?? false;
|
||||||
|
p.ModeMemberDataSheetShares = ModeMemberDataSheetShares.IsChecked == true ? 1 : 0;
|
||||||
p.TextDeliveryNote = string.IsNullOrWhiteSpace(TextElementDeliveryNote.Text) ? null : TextElementDeliveryNote.Text;
|
p.TextDeliveryNote = string.IsNullOrWhiteSpace(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.IsNullOrWhiteSpace(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text;
|
p.TextDeliveryConfirmation = string.IsNullOrWhiteSpace(TextElementDeliveryConfirmation.Text) ? null : TextElementDeliveryConfirmation.Text;
|
||||||
@@ -402,7 +408,7 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
s.Billing_AllowAttrsIntoLower = ParameterAllowAttrIntoLowerInput.IsChecked ?? false;
|
s.Billing_AllowAttrsIntoLower = ParameterAllowAttrIntoLowerInput.IsChecked ?? false;
|
||||||
s.Billing_AvoidUnderDeliveries = ParameterAvoidUnderDeliveriesInput.IsChecked ?? false;
|
s.Billing_AvoidUnderDeliveries = ParameterAvoidUnderDeliveriesInput.IsChecked ?? false;
|
||||||
s.Billing_HonorGebunden = ParameterHonorGebundenInput.IsChecked ?? false;
|
s.Billing_HonorContracted = ParameterHonorContractedInput.IsChecked ?? false;
|
||||||
ctx.Update(s);
|
ctx.Update(s);
|
||||||
await ctx.SaveChangesAsync();
|
await ctx.SaveChangesAsync();
|
||||||
} catch { }
|
} catch { }
|
||||||
|
|||||||
@@ -138,9 +138,9 @@
|
|||||||
<Label Content="Oechsle:" Margin="10,10,0,0" Grid.Column="0"/>
|
<Label Content="Oechsle:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||||
<ctrl:UnitTextBox x:Name="OechsleInput" Unit="°Oe" TextChanged="OechsleInput_TextChanged" IsEnabled="False"
|
<ctrl:UnitTextBox x:Name="OechsleInput" Unit="°Oe" TextChanged="OechsleInput_TextChanged" IsEnabled="False"
|
||||||
Grid.Column="1" Width="52" Margin="0,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
Grid.Column="1" Width="52" Margin="0,10,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||||
<CheckBox x:Name="GebInput" Content="Geb." IsEnabled="False"
|
<CheckBox x:Name="ContractedInput" Content="Geb." IsEnabled="False"
|
||||||
Grid.Column="1" Margin="0,15,10,0" HorizontalAlignment="Right" VerticalAlignment="Top"
|
Grid.Column="1" Margin="0,15,10,0" HorizontalAlignment="Right" VerticalAlignment="Top"
|
||||||
Checked="GebInput_Changed" Unchecked="GebInput_Changed"/>
|
Checked="ContractedInput_Changed" Unchecked="ContractedInput_Changed"/>
|
||||||
|
|
||||||
<Label Content="Preis:" Margin="10,40,0,0" Grid.Column="0"/>
|
<Label Content="Preis:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||||
<ctrl:UnitTextBox x:Name="PriceInput" Unit="€/kg" TextChanged="PriceInput_TextChanged" IsEnabled="False"
|
<ctrl:UnitTextBox x:Name="PriceInput" Unit="€/kg" TextChanged="PriceInput_TextChanged" IsEnabled="False"
|
||||||
@@ -148,16 +148,16 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Gebunden Aufschlag" Grid.Row="1" Margin="0,5,5,5">
|
<GroupBox Header="Gebunden-Aufschlag" Grid.Row="1" Margin="0,5,5,5">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
|
||||||
<StackPanel Margin="10,10,0,0">
|
<StackPanel Margin="10,10,0,0">
|
||||||
<RadioButton x:Name="GebundenTypeFixed" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Fix</RadioButton>
|
<RadioButton x:Name="ContractedTypeFixed" GroupName="ContractedType" Checked="ContractedType_Checked" IsEnabled="False">Fix</RadioButton>
|
||||||
<RadioButton x:Name="GebundenTypeGraph" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Frei</RadioButton>
|
<RadioButton x:Name="ContractedTypeGraph" GroupName="ContractedType" Checked="ContractedType_Checked" IsEnabled="False">Frei</RadioButton>
|
||||||
<RadioButton x:Name="GebundenTypeNone" GroupName="GebundenType" Checked="GebundenType_Checked" IsEnabled="False">Nein</RadioButton>
|
<RadioButton x:Name="ContractedTypeNone" GroupName="ContractedType" Checked="ContractedType_Checked" IsEnabled="False">Nein</RadioButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<ctrl:UnitTextBox x:Name="GebundenFlatBonus" Unit="€/kg" TextChanged="GebundenFlatBonus_TextChanged" IsEnabled="False"
|
<ctrl:UnitTextBox x:Name="ContractedFlatBonus" Unit="€/kg" TextChanged="ContractedFlatBonus_TextChanged" IsEnabled="False"
|
||||||
Width="90" Margin="5,5,5,5" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Column="1"/>
|
Width="90" Margin="5,5,5,5" HorizontalAlignment="Right" VerticalAlignment="Top" Grid.Column="1"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ using Elwig.Services;
|
|||||||
namespace Elwig.Windows {
|
namespace Elwig.Windows {
|
||||||
public partial class ChartWindow : ContextWindow {
|
public partial class ChartWindow : ContextWindow {
|
||||||
|
|
||||||
public static readonly Color ColorUngebunden = Colors.Blue;
|
public static readonly Color ColorUnContracted = Colors.Blue;
|
||||||
public static readonly Color ColorGebunden = Colors.Gold;
|
public static readonly Color ColorContracted = Colors.Gold;
|
||||||
|
|
||||||
public readonly int Year;
|
public readonly int Year;
|
||||||
public readonly int AvNr;
|
public readonly int AvNr;
|
||||||
@@ -27,20 +27,20 @@ namespace Elwig.Windows {
|
|||||||
private bool Updating = false;
|
private bool Updating = false;
|
||||||
|
|
||||||
private Scatter? DataPlot;
|
private Scatter? DataPlot;
|
||||||
private Scatter? GebundenPlot;
|
private Scatter? ContractedPlot;
|
||||||
private Marker? HighlightedPointPlot;
|
private Marker? HighlightedPointPlot;
|
||||||
private Marker? PrimaryMarkedPointPlot;
|
private Marker? PrimaryMarkedPointPlot;
|
||||||
private Marker? SecondaryMarkedPointPlot;
|
private Marker? SecondaryMarkedPointPlot;
|
||||||
private Text? TooltipPlot;
|
private Text? TooltipPlot;
|
||||||
|
|
||||||
private static readonly LegendItem
|
private static readonly LegendItem
|
||||||
UngebundenLegend = new() {
|
UnContractedLegend = new() {
|
||||||
LabelText = "Ungebunden", LineWidth = 1, LineColor = ColorUngebunden,
|
LabelText = "Ungebunden", LineWidth = 1, LineColor = ColorUnContracted,
|
||||||
MarkerStyle = new(MarkerShape.FilledCircle, 5, ColorUngebunden)
|
MarkerStyle = new(MarkerShape.FilledCircle, 5, ColorUnContracted)
|
||||||
},
|
},
|
||||||
GebundenLegend = new() {
|
ContractedLegend = new() {
|
||||||
LabelText = "Gebunden", LineWidth = 1, LineColor = ColorGebunden,
|
LabelText = "Gebunden", LineWidth = 1, LineColor = ColorContracted,
|
||||||
MarkerStyle = new(MarkerShape.FilledCircle, 5, ColorGebunden)
|
MarkerStyle = new(MarkerShape.FilledCircle, 5, ColorContracted)
|
||||||
},
|
},
|
||||||
LdwLegend = new() {
|
LdwLegend = new() {
|
||||||
LabelText = "68 °Oe (LDW)", LineWidth = 2, LineColor = Colors.Red, MarkerStyle = MarkerStyle.None
|
LabelText = "68 °Oe (LDW)", LineWidth = 2, LineColor = Colors.Red, MarkerStyle = MarkerStyle.None
|
||||||
@@ -75,7 +75,7 @@ namespace Elwig.Windows {
|
|||||||
Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("Season not found");
|
Season = ctx.Seasons.Find(year) ?? throw new ArgumentException("Season not found");
|
||||||
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
||||||
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
||||||
GebundenFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
ContractedFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
||||||
PaymentVar = ctx.PaymentVariants.Find(year, avnr) ?? throw new ArgumentException("PaymentVar not found");
|
PaymentVar = ctx.PaymentVariants.Find(year, avnr) ?? throw new ArgumentException("PaymentVar not found");
|
||||||
Title = $"{PaymentVar.Name} - Lese {year} - Elwig";
|
Title = $"{PaymentVar.Name} - Lese {year} - Elwig";
|
||||||
LockContext = true;
|
LockContext = true;
|
||||||
@@ -100,7 +100,7 @@ namespace Elwig.Windows {
|
|||||||
Season = await ctx.FetchSeasons(Year).SingleOrDefaultAsync() ?? throw new ArgumentException("Season not found");
|
Season = await ctx.FetchSeasons(Year).SingleOrDefaultAsync() ?? throw new ArgumentException("Season not found");
|
||||||
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
CurrencySymbol = Season.Currency.Symbol ?? Season.Currency.Code;
|
||||||
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
PriceInput.Unit = $"{CurrencySymbol}/kg";
|
||||||
GebundenFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
ContractedFlatBonus.Unit = $"{CurrencySymbol}/kg";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var data = EditBillingData.FromJson(PaymentVar.Data, await Utils.GetVaributes(ctx, Year));
|
var data = EditBillingData.FromJson(PaymentVar.Data, await Utils.GetVaributes(ctx, Year));
|
||||||
@@ -148,10 +148,10 @@ namespace Elwig.Windows {
|
|||||||
CopyButton.IsEnabled = true;
|
CopyButton.IsEnabled = true;
|
||||||
DeleteButton.IsEnabled = true;
|
DeleteButton.IsEnabled = true;
|
||||||
EnableTextBox(OechsleInput);
|
EnableTextBox(OechsleInput);
|
||||||
GebInput.IsEnabled = SelectedGraphEntry?.GebundenGraph != null;
|
ContractedInput.IsEnabled = SelectedGraphEntry?.ContractedGraph != null;
|
||||||
GebundenTypeFixed.IsEnabled = true;
|
ContractedTypeFixed.IsEnabled = true;
|
||||||
GebundenTypeGraph.IsEnabled = true;
|
ContractedTypeGraph.IsEnabled = true;
|
||||||
GebundenTypeNone.IsEnabled = true;
|
ContractedTypeNone.IsEnabled = true;
|
||||||
VaributeInput.IsEnabled = true;
|
VaributeInput.IsEnabled = true;
|
||||||
AbgewertetInput.IsEnabled = true;
|
AbgewertetInput.IsEnabled = true;
|
||||||
EnableOptionButtons();
|
EnableOptionButtons();
|
||||||
@@ -160,7 +160,7 @@ namespace Elwig.Windows {
|
|||||||
CopyButton.IsEnabled = false;
|
CopyButton.IsEnabled = false;
|
||||||
DeleteButton.IsEnabled = false;
|
DeleteButton.IsEnabled = false;
|
||||||
DisableTextBox(OechsleInput);
|
DisableTextBox(OechsleInput);
|
||||||
GebInput.IsEnabled = false;
|
ContractedInput.IsEnabled = false;
|
||||||
DisableOptionButtons();
|
DisableOptionButtons();
|
||||||
}
|
}
|
||||||
if (!PaymentVar.TestVariant) {
|
if (!PaymentVar.TestVariant) {
|
||||||
@@ -168,9 +168,9 @@ namespace Elwig.Windows {
|
|||||||
CopyButton.IsEnabled = false;
|
CopyButton.IsEnabled = false;
|
||||||
DeleteButton.IsEnabled = false;
|
DeleteButton.IsEnabled = false;
|
||||||
DisableTextBox(PriceInput);
|
DisableTextBox(PriceInput);
|
||||||
GebundenTypeFixed.IsEnabled = false;
|
ContractedTypeFixed.IsEnabled = false;
|
||||||
GebundenTypeGraph.IsEnabled = false;
|
ContractedTypeGraph.IsEnabled = false;
|
||||||
GebundenTypeNone.IsEnabled = false;
|
ContractedTypeNone.IsEnabled = false;
|
||||||
VaributeInput.IsEnabled = false;
|
VaributeInput.IsEnabled = false;
|
||||||
AbgewertetInput.IsEnabled = false;
|
AbgewertetInput.IsEnabled = false;
|
||||||
}
|
}
|
||||||
@@ -181,15 +181,15 @@ namespace Elwig.Windows {
|
|||||||
FillingInputs = true;
|
FillingInputs = true;
|
||||||
|
|
||||||
AbgewertetInput.IsChecked = SelectedGraphEntry?.Abgewertet;
|
AbgewertetInput.IsChecked = SelectedGraphEntry?.Abgewertet;
|
||||||
if (SelectedGraphEntry?.GebundenFlatBonus is double bonus) {
|
if (SelectedGraphEntry?.ContractedFlatBonus is double bonus) {
|
||||||
GebundenTypeFixed.IsChecked = true;
|
ContractedTypeFixed.IsChecked = true;
|
||||||
GebundenFlatBonus.Text = $"{bonus}";
|
ContractedFlatBonus.Text = $"{bonus}";
|
||||||
} else if (SelectedGraphEntry?.GebundenGraph != null) {
|
} else if (SelectedGraphEntry?.ContractedGraph != null) {
|
||||||
GebundenTypeGraph.IsChecked = true;
|
ContractedTypeGraph.IsChecked = true;
|
||||||
GebundenFlatBonus.Text = "";
|
ContractedFlatBonus.Text = "";
|
||||||
} else {
|
} else {
|
||||||
GebundenTypeNone.IsChecked = true;
|
ContractedTypeNone.IsChecked = true;
|
||||||
GebundenFlatBonus.Text = "";
|
ContractedFlatBonus.Text = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlUtils.SelectItems(VaributeInput, SelectedGraphEntry?.Vaributes ?? []);
|
ControlUtils.SelectItems(VaributeInput, SelectedGraphEntry?.Vaributes ?? []);
|
||||||
@@ -208,21 +208,21 @@ namespace Elwig.Windows {
|
|||||||
private void InitPlot() {
|
private void InitPlot() {
|
||||||
RefreshGradationLines();
|
RefreshGradationLines();
|
||||||
|
|
||||||
if (SelectedGraphEntry?.GebundenGraph != null) {
|
if (SelectedGraphEntry?.ContractedGraph != null) {
|
||||||
GebundenPlot = OechslePricePlot.Plot.Add.Scatter(SelectedGraphEntry.GebundenGraph.DataX, SelectedGraphEntry.GebundenGraph.DataY);
|
ContractedPlot = OechslePricePlot.Plot.Add.Scatter(SelectedGraphEntry.ContractedGraph.DataX, SelectedGraphEntry.ContractedGraph.DataY);
|
||||||
GebundenPlot.LineStyle.Color = ColorGebunden;
|
ContractedPlot.LineStyle.Color = ColorContracted;
|
||||||
GebundenPlot.Color = ColorGebunden;
|
ContractedPlot.Color = ColorContracted;
|
||||||
GebundenPlot.MarkerStyle = new MarkerStyle(MarkerShape.FilledCircle, 9, ColorGebunden);
|
ContractedPlot.MarkerStyle = new MarkerStyle(MarkerShape.FilledCircle, 9, ColorContracted);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SelectedGraphEntry != null) {
|
if (SelectedGraphEntry != null) {
|
||||||
DataPlot = OechslePricePlot.Plot.Add.Scatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY);
|
DataPlot = OechslePricePlot.Plot.Add.Scatter(SelectedGraphEntry.DataGraph.DataX, SelectedGraphEntry.DataGraph.DataY);
|
||||||
DataPlot.LineStyle.Color = ColorUngebunden;
|
DataPlot.LineStyle.Color = ColorUnContracted;
|
||||||
DataPlot.Color = ColorUngebunden;
|
DataPlot.Color = ColorUnContracted;
|
||||||
DataPlot.MarkerStyle = new MarkerStyle(MarkerShape.FilledCircle, 9, ColorUngebunden);
|
DataPlot.MarkerStyle = new MarkerStyle(MarkerShape.FilledCircle, 9, ColorUnContracted);
|
||||||
}
|
}
|
||||||
|
|
||||||
OechslePricePlot.Plot.Axes.SetLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXGeb) - 1, GraphEntry.MaxX + 1, -0.1, 1.5);
|
OechslePricePlot.Plot.Axes.SetLimits(Math.Min(GraphEntry.MinX, GraphEntry.MinXCtrd) - 1, GraphEntry.MaxX + 1, -0.1, 1.5);
|
||||||
|
|
||||||
HighlightedPointPlot = OechslePricePlot.Plot.Add.Marker(0, 0, MarkerShape.OpenCircle, 10, Colors.Red);
|
HighlightedPointPlot = OechslePricePlot.Plot.Add.Marker(0, 0, MarkerShape.OpenCircle, 10, Colors.Red);
|
||||||
HighlightedPointPlot.IsVisible = false;
|
HighlightedPointPlot.IsVisible = false;
|
||||||
@@ -250,9 +250,9 @@ namespace Elwig.Windows {
|
|||||||
OechslePricePlot.Plot.Remove(DataPlot);
|
OechslePricePlot.Plot.Remove(DataPlot);
|
||||||
DataPlot = null;
|
DataPlot = null;
|
||||||
}
|
}
|
||||||
if (GebundenPlot != null) {
|
if (ContractedPlot != null) {
|
||||||
OechslePricePlot.Plot.Remove(GebundenPlot);
|
OechslePricePlot.Plot.Remove(ContractedPlot);
|
||||||
GebundenPlot = null;
|
ContractedPlot = null;
|
||||||
}
|
}
|
||||||
OechslePricePlot.Plot.Clear();
|
OechslePricePlot.Plot.Clear();
|
||||||
OechslePricePlot.Reset();
|
OechslePricePlot.Reset();
|
||||||
@@ -365,8 +365,8 @@ namespace Elwig.Windows {
|
|||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(LdwLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(LdwLegend);
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(QuwLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(QuwLegend);
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(KabLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(KabLegend);
|
||||||
OechslePricePlot.Plot.Legend.ManualItems.Add(UngebundenLegend);
|
OechslePricePlot.Plot.Legend.ManualItems.Add(UnContractedLegend);
|
||||||
if (SelectedGraphEntry?.GebundenGraph != null) OechslePricePlot.Plot.Legend.ManualItems.Add(GebundenLegend);
|
if (SelectedGraphEntry?.ContractedGraph != null) OechslePricePlot.Plot.Legend.ManualItems.Add(ContractedLegend);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HideLegend() {
|
private void HideLegend() {
|
||||||
@@ -408,10 +408,10 @@ namespace Elwig.Windows {
|
|||||||
UpdateSelectedPoint();
|
UpdateSelectedPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GebInput_Changed(object sender, RoutedEventArgs evt) {
|
private void ContractedInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
if (Updating)
|
if (Updating)
|
||||||
return;
|
return;
|
||||||
var sel = GebInput.IsChecked == true ? SelectedGraphEntry?.GebundenGraph : SelectedGraphEntry?.DataGraph;
|
var sel = ContractedInput.IsChecked == true ? SelectedGraphEntry?.ContractedGraph : SelectedGraphEntry?.DataGraph;
|
||||||
if (sel != ActiveGraph) ChangeActiveGraph(sel);
|
if (sel != ActiveGraph) ChangeActiveGraph(sel);
|
||||||
UpdateSelectedPoint();
|
UpdateSelectedPoint();
|
||||||
}
|
}
|
||||||
@@ -424,7 +424,7 @@ namespace Elwig.Windows {
|
|||||||
PrimaryMarkedPointPlot?.Location = new Coordinates(PrimaryMarkedPointPlot.Location.X, price);
|
PrimaryMarkedPointPlot?.Location = new Coordinates(PrimaryMarkedPointPlot.Location.X, price);
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
OechslePricePlot.Refresh();
|
OechslePricePlot.Refresh();
|
||||||
CheckGebundenTypeFixed();
|
CheckContractedTypeFixed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -436,7 +436,7 @@ namespace Elwig.Windows {
|
|||||||
ActiveGraph.FlattenGraphLeft(PrimaryMarkedPoint);
|
ActiveGraph.FlattenGraphLeft(PrimaryMarkedPoint);
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
OechslePricePlot.Refresh();
|
OechslePricePlot.Refresh();
|
||||||
CheckGebundenTypeFixed();
|
CheckContractedTypeFixed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
|
private void RightFlatButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
@@ -446,7 +446,7 @@ namespace Elwig.Windows {
|
|||||||
ActiveGraph.FlattenGraphRight(PrimaryMarkedPoint);
|
ActiveGraph.FlattenGraphRight(PrimaryMarkedPoint);
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
OechslePricePlot.Refresh();
|
OechslePricePlot.Refresh();
|
||||||
CheckGebundenTypeFixed();
|
CheckContractedTypeFixed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
|
private void InterpolateButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
@@ -456,7 +456,7 @@ namespace Elwig.Windows {
|
|||||||
ActiveGraph.InterpolateGraph(PrimaryMarkedPoint, SecondaryMarkedPoint);
|
ActiveGraph.InterpolateGraph(PrimaryMarkedPoint, SecondaryMarkedPoint);
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
OechslePricePlot.Refresh();
|
OechslePricePlot.Refresh();
|
||||||
CheckGebundenTypeFixed();
|
CheckContractedTypeFixed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
|
private void LinearIncreaseButton_Click(object sender, RoutedEventArgs e) {
|
||||||
@@ -470,7 +470,7 @@ namespace Elwig.Windows {
|
|||||||
ActiveGraph.LinearIncreaseGraphToEnd(PrimaryMarkedPoint, priceIncrease.Value);
|
ActiveGraph.LinearIncreaseGraphToEnd(PrimaryMarkedPoint, priceIncrease.Value);
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
OechslePricePlot.Refresh();
|
OechslePricePlot.Refresh();
|
||||||
CheckGebundenTypeFixed();
|
CheckContractedTypeFixed();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
|
private void OechslePricePlot_MouseDown(object sender, MouseEventArgs e) {
|
||||||
@@ -500,7 +500,7 @@ namespace Elwig.Windows {
|
|||||||
if (Highlighted.Graph != null) {
|
if (Highlighted.Graph != null) {
|
||||||
Updating = true;
|
Updating = true;
|
||||||
OechsleInput.Text = Highlighted.Graph.GetOechsleAt(Highlighted.Index).ToString();
|
OechsleInput.Text = Highlighted.Graph.GetOechsleAt(Highlighted.Index).ToString();
|
||||||
GebInput.IsChecked = Highlighted.Graph == SelectedGraphEntry?.GebundenGraph;
|
ContractedInput.IsChecked = Highlighted.Graph == SelectedGraphEntry?.ContractedGraph;
|
||||||
PriceInput.Text = Math.Round(Highlighted.Graph.GetPriceAt(Highlighted.Index), Season.Precision).ToString();
|
PriceInput.Text = Math.Round(Highlighted.Graph.GetPriceAt(Highlighted.Index), Season.Precision).ToString();
|
||||||
Updating = false;
|
Updating = false;
|
||||||
}
|
}
|
||||||
@@ -509,14 +509,14 @@ namespace Elwig.Windows {
|
|||||||
} else {
|
} else {
|
||||||
PrimaryMarkedPoint = -1;
|
PrimaryMarkedPoint = -1;
|
||||||
SecondaryMarkedPoint = -1;
|
SecondaryMarkedPoint = -1;
|
||||||
if (SelectedGraphEntry?.GebundenGraph != null) {
|
if (SelectedGraphEntry?.ContractedGraph != null) {
|
||||||
ChangeActiveGraph(null);
|
ChangeActiveGraph(null);
|
||||||
}
|
}
|
||||||
ChangeMarker(PrimaryMarkedPointPlot, false);
|
ChangeMarker(PrimaryMarkedPointPlot, false);
|
||||||
ChangeMarker(SecondaryMarkedPointPlot, false);
|
ChangeMarker(SecondaryMarkedPointPlot, false);
|
||||||
|
|
||||||
OechsleInput.Text = "";
|
OechsleInput.Text = "";
|
||||||
GebInput.IsChecked = false;
|
ContractedInput.IsChecked = false;
|
||||||
PriceInput.Text = "";
|
PriceInput.Text = "";
|
||||||
DisableTextBox(PriceInput);
|
DisableTextBox(PriceInput);
|
||||||
|
|
||||||
@@ -549,7 +549,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var mouseOnData = MouseOnPlot(DataPlot, GetMouseCoordinates(e.GetPosition(OechslePricePlot)));
|
var mouseOnData = MouseOnPlot(DataPlot, GetMouseCoordinates(e.GetPosition(OechslePricePlot)));
|
||||||
var mouseOnGebunden = MouseOnPlot(GebundenPlot, GetMouseCoordinates(e.GetPosition(OechslePricePlot)));
|
var mouseOnContracted = MouseOnPlot(ContractedPlot, GetMouseCoordinates(e.GetPosition(OechslePricePlot)));
|
||||||
|
|
||||||
Highlighted = LastHighlighted;
|
Highlighted = LastHighlighted;
|
||||||
|
|
||||||
@@ -560,13 +560,13 @@ namespace Elwig.Windows {
|
|||||||
HoverActive = true;
|
HoverActive = true;
|
||||||
if (SelectedGraphEntry?.DataGraph is Graph g)
|
if (SelectedGraphEntry?.DataGraph is Graph g)
|
||||||
HandleTooltip(mouseOnData.Value.X, mouseOnData.Value.Y, mouseOnData.Value.Index, g, e.GetPosition(OechslePricePlot), e is MouseWheelEventArgs);
|
HandleTooltip(mouseOnData.Value.X, mouseOnData.Value.Y, mouseOnData.Value.Index, g, e.GetPosition(OechslePricePlot), e is MouseWheelEventArgs);
|
||||||
} else if (mouseOnGebunden != null) {
|
} else if (mouseOnContracted != null) {
|
||||||
ChangeMarker(HighlightedPointPlot, true, mouseOnGebunden.Value.X, mouseOnGebunden.Value.Y);
|
ChangeMarker(HighlightedPointPlot, true, mouseOnContracted.Value.X, mouseOnContracted.Value.Y);
|
||||||
HighlightedPointPlot?.IsVisible = true;
|
HighlightedPointPlot?.IsVisible = true;
|
||||||
HoverChanged = true ^ HoverActive;
|
HoverChanged = true ^ HoverActive;
|
||||||
HoverActive = true;
|
HoverActive = true;
|
||||||
if (SelectedGraphEntry?.GebundenGraph is Graph g)
|
if (SelectedGraphEntry?.ContractedGraph is Graph g)
|
||||||
HandleTooltip(mouseOnGebunden.Value.X, mouseOnGebunden.Value.Y, mouseOnGebunden.Value.Index, g, e.GetPosition(OechslePricePlot), e is MouseWheelEventArgs);
|
HandleTooltip(mouseOnContracted.Value.X, mouseOnContracted.Value.Y, mouseOnContracted.Value.Index, g, e.GetPosition(OechslePricePlot), e is MouseWheelEventArgs);
|
||||||
} else {
|
} else {
|
||||||
ChangeMarker(HighlightedPointPlot, false);
|
ChangeMarker(HighlightedPointPlot, false);
|
||||||
HoverChanged = false ^ HoverActive;
|
HoverChanged = false ^ HoverActive;
|
||||||
@@ -699,25 +699,25 @@ namespace Elwig.Windows {
|
|||||||
private void ChangeActiveGraph(Graph? g) {
|
private void ChangeActiveGraph(Graph? g) {
|
||||||
if (g != null && g == SelectedGraphEntry?.DataGraph) {
|
if (g != null && g == SelectedGraphEntry?.DataGraph) {
|
||||||
EnableTextBox(OechsleInput);
|
EnableTextBox(OechsleInput);
|
||||||
if (SelectedGraphEntry?.GebundenGraph != null) ChangeLineWidth(DataPlot, 4);
|
if (SelectedGraphEntry?.ContractedGraph != null) ChangeLineWidth(DataPlot, 4);
|
||||||
ChangeLineWidth(GebundenPlot, 1);
|
ChangeLineWidth(ContractedPlot, 1);
|
||||||
GebInput.IsEnabled = SelectedGraphEntry?.GebundenGraph != null;
|
ContractedInput.IsEnabled = SelectedGraphEntry?.ContractedGraph != null;
|
||||||
GebInput.IsChecked = false;
|
ContractedInput.IsChecked = false;
|
||||||
} else if (g != null && g == SelectedGraphEntry?.GebundenGraph) {
|
} else if (g != null && g == SelectedGraphEntry?.ContractedGraph) {
|
||||||
EnableTextBox(OechsleInput);
|
EnableTextBox(OechsleInput);
|
||||||
ChangeLineWidth(GebundenPlot, 4);
|
ChangeLineWidth(ContractedPlot, 4);
|
||||||
ChangeLineWidth(DataPlot, 1);
|
ChangeLineWidth(DataPlot, 1);
|
||||||
GebInput.IsEnabled = SelectedGraphEntry?.GebundenGraph != null;
|
ContractedInput.IsEnabled = SelectedGraphEntry?.ContractedGraph != null;
|
||||||
GebInput.IsChecked = true;
|
ContractedInput.IsChecked = true;
|
||||||
} else {
|
} else {
|
||||||
DisableTextBox(OechsleInput);
|
DisableTextBox(OechsleInput);
|
||||||
DisableTextBox(PriceInput);
|
DisableTextBox(PriceInput);
|
||||||
OechsleInput.Text = "";
|
OechsleInput.Text = "";
|
||||||
GebInput.IsEnabled = false;
|
ContractedInput.IsEnabled = false;
|
||||||
GebInput.IsChecked = false;
|
ContractedInput.IsChecked = false;
|
||||||
PriceInput.Text = "";
|
PriceInput.Text = "";
|
||||||
ChangeLineWidth(DataPlot, 1);
|
ChangeLineWidth(DataPlot, 1);
|
||||||
ChangeLineWidth(GebundenPlot, 1);
|
ChangeLineWidth(ContractedPlot, 1);
|
||||||
}
|
}
|
||||||
ActiveGraph = g;
|
ActiveGraph = g;
|
||||||
}
|
}
|
||||||
@@ -730,11 +730,11 @@ namespace Elwig.Windows {
|
|||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GebundenFlatBonus_TextChanged(object sender, TextChangedEventArgs e) {
|
private void ContractedFlatBonus_TextChanged(object sender, TextChangedEventArgs e) {
|
||||||
if (FillingInputs) return;
|
if (FillingInputs) return;
|
||||||
var r = Validator.CheckDecimal(GebundenFlatBonus, true, 2, Season.Precision);
|
var r = Validator.CheckDecimal(ContractedFlatBonus, true, 2, Season.Precision);
|
||||||
if (r.IsValid && SelectedGraphEntry != null) {
|
if (r.IsValid && SelectedGraphEntry != null) {
|
||||||
SelectedGraphEntry.GebundenFlatBonus = double.Parse(GebundenFlatBonus.Text);
|
SelectedGraphEntry.ContractedFlatBonus = double.Parse(ContractedFlatBonus.Text);
|
||||||
ResetPlot();
|
ResetPlot();
|
||||||
InitPlot();
|
InitPlot();
|
||||||
}
|
}
|
||||||
@@ -795,37 +795,37 @@ namespace Elwig.Windows {
|
|||||||
GraphList.Items.Refresh();
|
GraphList.Items.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GebundenType_Checked(object sender, RoutedEventArgs e) {
|
private void ContractedType_Checked(object sender, RoutedEventArgs e) {
|
||||||
if (FillingInputs) return;
|
if (FillingInputs) return;
|
||||||
if (SelectedGraphEntry == null) {
|
if (SelectedGraphEntry == null) {
|
||||||
DisableTextBox(GebundenFlatBonus);
|
DisableTextBox(ContractedFlatBonus);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (GebundenTypeNone.IsChecked == true) {
|
if (ContractedTypeNone.IsChecked == true) {
|
||||||
SelectedGraphEntry.RemoveGebundenGraph();
|
SelectedGraphEntry.RemoveContractedGraph();
|
||||||
DisableTextBox(GebundenFlatBonus);
|
DisableTextBox(ContractedFlatBonus);
|
||||||
} else if (GebundenTypeFixed.IsChecked == true) {
|
} else if (ContractedTypeFixed.IsChecked == true) {
|
||||||
SelectedGraphEntry.GebundenFlatBonus = double.TryParse(GebundenFlatBonus.Text, out var val) ? val : 0.1;
|
SelectedGraphEntry.ContractedFlatBonus = double.TryParse(ContractedFlatBonus.Text, out var val) ? val : 0.1;
|
||||||
SelectedGraphEntry.AddGebundenGraph();
|
SelectedGraphEntry.AddContractedGraph();
|
||||||
EnableTextBox(GebundenFlatBonus);
|
EnableTextBox(ContractedFlatBonus);
|
||||||
} else if (GebundenTypeGraph.IsChecked == true) {
|
} else if (ContractedTypeGraph.IsChecked == true) {
|
||||||
SelectedGraphEntry.AddGebundenGraph();
|
SelectedGraphEntry.AddContractedGraph();
|
||||||
DisableTextBox(GebundenFlatBonus);
|
DisableTextBox(ContractedFlatBonus);
|
||||||
}
|
}
|
||||||
SetHasChanged();
|
SetHasChanged();
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckGebundenTypeFixed() {
|
private void CheckContractedTypeFixed() {
|
||||||
FillingInputs = true;
|
FillingInputs = true;
|
||||||
if (SelectedGraphEntry?.GebundenFlatBonus is double bonus) {
|
if (SelectedGraphEntry?.ContractedFlatBonus is double bonus) {
|
||||||
GebundenTypeFixed.IsChecked = true;
|
ContractedTypeFixed.IsChecked = true;
|
||||||
GebundenFlatBonus.Text = $"{bonus}";
|
ContractedFlatBonus.Text = $"{bonus}";
|
||||||
EnableTextBox(GebundenFlatBonus);
|
EnableTextBox(ContractedFlatBonus);
|
||||||
} else if (SelectedGraphEntry?.GebundenGraph != null) {
|
} else if (SelectedGraphEntry?.ContractedGraph != null) {
|
||||||
GebundenTypeGraph.IsChecked = true;
|
ContractedTypeGraph.IsChecked = true;
|
||||||
GebundenFlatBonus.Text = "";
|
ContractedFlatBonus.Text = "";
|
||||||
DisableTextBox(GebundenFlatBonus);
|
DisableTextBox(ContractedFlatBonus);
|
||||||
}
|
}
|
||||||
FillingInputs = false;
|
FillingInputs = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -398,7 +398,8 @@
|
|||||||
<Grid Grid.Row="1" Grid.Column="2">
|
<Grid Grid.Row="1" Grid.Column="2">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="0.625*"/>
|
<RowDefinition Height="0.625*"/>
|
||||||
<RowDefinition Height="0.875*"/>
|
<RowDefinition Height="0.8125*"/>
|
||||||
|
<RowDefinition Height="0.0625*"/>
|
||||||
<RowDefinition Height="0.875*"/>
|
<RowDefinition Height="0.875*"/>
|
||||||
<RowDefinition Height="0.25*"/>
|
<RowDefinition Height="0.25*"/>
|
||||||
<RowDefinition Height="*"/>
|
<RowDefinition Height="*"/>
|
||||||
@@ -434,7 +435,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Lieferung" Grid.Column="0" Grid.Row="1" Grid.RowSpan="3" Margin="5,5,5,5">
|
<GroupBox Header="Lieferung" Grid.Column="0" Grid.Row="1" Grid.RowSpan="4" Margin="5,5,5,5">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="100"/>
|
<ColumnDefinition Width="100"/>
|
||||||
@@ -517,6 +518,7 @@
|
|||||||
<ComboBox x:Name="CultivationInput" SelectedItem="{Binding WineCultObj, Mode=TwoWay}" ItemsSource="{Binding WineCultSource, Mode=TwoWay}"
|
<ComboBox x:Name="CultivationInput" SelectedItem="{Binding WineCultObj, Mode=TwoWay}" ItemsSource="{Binding WineCultSource, Mode=TwoWay}"
|
||||||
Grid.Row="1" Grid.Column="2" Margin="0,40,10,10"
|
Grid.Row="1" Grid.Column="2" Margin="0,40,10,10"
|
||||||
DisplayMemberPath="Name"
|
DisplayMemberPath="Name"
|
||||||
|
SelectionChanged="CultivationInput_SelectionChanged"
|
||||||
KeyUp="Input_KeyUp"/>
|
KeyUp="Input_KeyUp"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
@@ -553,7 +555,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Menge" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
|
<GroupBox Header="Menge" Grid.Column="1" Grid.Row="2" Grid.RowSpan="2" Margin="5,5,5,5">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="70"/>
|
<ColumnDefinition Width="70"/>
|
||||||
@@ -565,16 +567,23 @@
|
|||||||
TextChanged="WeightInput_TextChanged"
|
TextChanged="WeightInput_TextChanged"
|
||||||
Grid.Column="1" Width="70" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
Grid.Column="1" Width="70" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||||
|
|
||||||
|
<Label Content="Tara:" Margin="10,40,10,10"/>
|
||||||
|
<TextBlock x:Name="Tare" Text="{Binding TareString}" Width="40"
|
||||||
|
Grid.Column="1" Margin="30,44,10,10" TextAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||||
|
|
||||||
<CheckBox x:Name="ManualWeighingInput" IsChecked="{Binding IsManualWeighing, Mode=TwoWay}"
|
<CheckBox x:Name="ManualWeighingInput" IsChecked="{Binding IsManualWeighing, Mode=TwoWay}"
|
||||||
Content="Handwiegung" IsEnabled="False"
|
Content="Handwiegung" IsEnabled="False"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,45,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||||
|
|
||||||
<CheckBox x:Name="GerebeltGewogenInput" IsChecked="{Binding IsNetWeightValue, Mode=TwoWay}"
|
<CheckBox x:Name="GerebeltGewogenInput" IsChecked="{Binding IsNetWeightValue, Mode=TwoWay}"
|
||||||
Content="Gerebelt gewogen" IsThreeState="True"
|
Content="Gerebelt gewogen" IsThreeState="True"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,100,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
||||||
Checked="GerebeltGewogenInput_Changed" Unchecked="GerebeltGewogenInput_Changed" Indeterminate="GerebeltGewogenInput_Changed"/>
|
Checked="GerebeltGewogenInput_Changed" Unchecked="GerebeltGewogenInput_Changed" Indeterminate="GerebeltGewogenInput_Changed"/>
|
||||||
|
|
||||||
|
<Button x:Name="CorrectTareButton" Content="Tara korrigieren" Width="120" Visibility="Hidden"
|
||||||
|
Click="CorrectTareButton_Click"
|
||||||
|
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
|
||||||
<Button x:Name="WeighingAButton" Content="Wiegen A" Width="120"
|
<Button x:Name="WeighingAButton" Content="Wiegen A" Width="120"
|
||||||
Click="WeighingButton_Click"
|
Click="WeighingButton_Click"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
|
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
|
||||||
@@ -593,7 +602,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Sonstiges" Grid.Column="1" Grid.Row="3" Grid.RowSpan="2" Margin="5,5,5,10">
|
<GroupBox Header="Sonstiges" Grid.Column="1" Grid.Row="4" Grid.RowSpan="2" Margin="5,5,5,10">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="100"/>
|
<ColumnDefinition Width="100"/>
|
||||||
@@ -646,7 +655,7 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</GroupBox>
|
</GroupBox>
|
||||||
|
|
||||||
<GroupBox Header="Herkunft" Grid.Column="0" Grid.Row="4" Margin="5,5,5,10">
|
<GroupBox Header="Herkunft" Grid.Column="0" Grid.Row="5" Margin="5,5,5,10">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="100"/>
|
<ColumnDefinition Width="100"/>
|
||||||
@@ -673,7 +682,7 @@
|
|||||||
Margin="0,70,10,10" Grid.Column="1"
|
Margin="0,70,10,10" Grid.Column="1"
|
||||||
DisplayMemberPath="Name"/>
|
DisplayMemberPath="Name"/>
|
||||||
|
|
||||||
<CheckBox x:Name="GebundenInput" IsChecked="{Binding IsGebunden, Mode=TwoWay}"
|
<CheckBox x:Name="ContractedInput" IsChecked="{Binding IsContracted, Mode=TwoWay}"
|
||||||
Content="Gebunden" Margin="10,105,0,0" Grid.Column="0" Grid.ColumnSpan="2" IsThreeState="True"
|
Content="Gebunden" Margin="10,105,0,0" Grid.Column="0" Grid.ColumnSpan="2" IsThreeState="True"
|
||||||
VerticalAlignment="Top" HorizontalAlignment="Left"
|
VerticalAlignment="Top" HorizontalAlignment="Left"
|
||||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Indeterminate="CheckBox_Changed"/>
|
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Indeterminate="CheckBox_Changed"/>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text.Json.Nodes;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
@@ -103,6 +104,7 @@ namespace Elwig.Windows {
|
|||||||
WeighingBButton.Visibility = Visibility.Hidden;
|
WeighingBButton.Visibility = Visibility.Hidden;
|
||||||
WeighingCButton.Visibility = Visibility.Hidden;
|
WeighingCButton.Visibility = Visibility.Hidden;
|
||||||
WeighingDButton.Visibility = Visibility.Hidden;
|
WeighingDButton.Visibility = Visibility.Hidden;
|
||||||
|
DisableWeighingButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu_Statistics_WineQuality_ModeOe.IsChecked = false;
|
Menu_Statistics_WineQuality_ModeOe.IsChecked = false;
|
||||||
@@ -126,7 +128,6 @@ namespace Elwig.Windows {
|
|||||||
this() {
|
this() {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
|
||||||
ViewModel.EnableAllSeasons = true;
|
ViewModel.EnableAllSeasons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -139,7 +140,7 @@ namespace Elwig.Windows {
|
|||||||
if (await ctx.FetchSeasons(Utils.CurrentYear).SingleOrDefaultAsync() == null) {
|
if (await ctx.FetchSeasons(Utils.CurrentYear).SingleOrDefaultAsync() == null) {
|
||||||
InteractionService.ShowWarning("Saison noch nicht erstellt",
|
InteractionService.ShowWarning("Saison noch nicht erstellt",
|
||||||
"Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n" +
|
"Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n" +
|
||||||
"(Stammdaten -> Saisons -> Neu anlegen...)");
|
"(Stammdaten \u2192 Saisons \u2192 Neu anlegen...)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -355,11 +356,11 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (App.Client.IsMatzen || App.Client.IsWinzerkeller || App.Client.IsBaden || App.Client.IsWeinland) {
|
if (App.Client.IsMatzen || App.Client.IsWinzerkeller || App.Client.IsBaden || App.Client.IsWeinland) {
|
||||||
GebundenInput.IsEnabled = false;
|
ContractedInput.IsEnabled = false;
|
||||||
SetDefaultValue(GebundenInput, null);
|
SetDefaultValue(ContractedInput, null);
|
||||||
} else {
|
} else {
|
||||||
GebundenInput.IsEnabled = true;
|
ContractedInput.IsEnabled = true;
|
||||||
UnsetDefaultValue(GebundenInput);
|
UnsetDefaultValue(ContractedInput);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +376,7 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.IsNetWeight = App.Config.WeighingMode == WeighingMode.Net;
|
ViewModel.IsNetWeight = App.Config.WeighingMode == WeighingMode.Net;
|
||||||
ViewModel.IsHandPicked = App.Config.WeighingMode != WeighingMode.Net ? true : null;
|
ViewModel.IsHandPicked = App.Config.WeighingMode != WeighingMode.Net ? true : null;
|
||||||
ViewModel.Unloading = null;
|
ViewModel.Unloading = null;
|
||||||
ViewModel.IsGebunden = null;
|
ViewModel.IsContracted = null;
|
||||||
InitialDefaultInputs();
|
InitialDefaultInputs();
|
||||||
|
|
||||||
//WineQualityLevelInput.IsEnabled = false; // disable wine quality level input in Übernahme
|
//WineQualityLevelInput.IsEnabled = false; // disable wine quality level input in Übernahme
|
||||||
@@ -419,9 +420,9 @@ namespace Elwig.Windows {
|
|||||||
var cursor = Mouse.OverrideCursor != null;
|
var cursor = Mouse.OverrideCursor != null;
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||||
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterAllSeasons, vm.FilterTodayOnly);
|
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterAllSeasons, vm.FilterTodayOnly);
|
||||||
var (filter, deliveries, deliveryPartsNum, varieties, members, stat) = await Task.Run(async () => {
|
var (filterNames, filter, deliveries, deliveryPartsNum, varieties, members, stat) = await Task.Run(async () => {
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
var (filterNames, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
||||||
var deliveries = await deliveryQuery
|
var deliveries = await deliveryQuery
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||||
.Include(d => d.Parts).ThenInclude(p => p.Variety)
|
.Include(d => d.Parts).ThenInclude(p => p.Variety)
|
||||||
@@ -450,11 +451,13 @@ namespace Elwig.Windows {
|
|||||||
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
||||||
var stat = await DeliveryService.GenerateToolTipData(deliveryPartsQuery);
|
var stat = await DeliveryService.GenerateToolTipData(deliveryPartsQuery);
|
||||||
|
|
||||||
return (filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
return (filterNames, filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
||||||
});
|
});
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
if (!cursor) Mouse.OverrideCursor = null;
|
||||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterAllSeasons, ViewModel.FilterTodayOnly)) return;
|
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterAllSeasons, ViewModel.FilterTodayOnly)) return;
|
||||||
|
|
||||||
|
if (!ViewModel.IsReceipt)
|
||||||
|
ViewModel.Title = Utils.GetTitle("Lieferungen", filterNames, filter);
|
||||||
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
||||||
DeliveryList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
await RefreshDeliveryParts();
|
await RefreshDeliveryParts();
|
||||||
@@ -488,7 +491,6 @@ namespace Elwig.Windows {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ViewModel.FilterMember = m;
|
ViewModel.FilterMember = m;
|
||||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int year = 0;
|
int year = 0;
|
||||||
@@ -612,14 +614,34 @@ namespace Elwig.Windows {
|
|||||||
ClearOriginalValues();
|
ClearOriginalValues();
|
||||||
ClearDefaultValues();
|
ClearDefaultValues();
|
||||||
ViewModel.FillInputs(p);
|
ViewModel.FillInputs(p);
|
||||||
|
CorrectTareButton.Visibility = !ViewModel.IsReceipt && ((ViewModel.ActualTare is int t && t != 0) || ViewModel.IsUnloadingBox) ? Visibility.Visible : Visibility.Hidden;
|
||||||
FinishInputFilling();
|
FinishInputFilling();
|
||||||
}
|
}
|
||||||
|
|
||||||
new protected void ClearInputs(bool validate = false) {
|
new protected void ClearInputs(bool validate = false) {
|
||||||
ViewModel.ClearInputs();
|
ViewModel.ClearInputs();
|
||||||
|
CorrectTareButton.Visibility = Visibility.Hidden;
|
||||||
base.ClearInputs(validate);
|
base.ClearInputs(validate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CorrectTareButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
var lastCorrection = (ViewModel.TargetTare ?? ViewModel.ActualTare ?? 0) - (ViewModel.ActualTare ?? 0);
|
||||||
|
var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare);
|
||||||
|
if (correction == null) return;
|
||||||
|
ViewModel.Weight += lastCorrection - correction;
|
||||||
|
if (ViewModel.Weight != null && ViewModel.WeighingData is string s) {
|
||||||
|
ViewModel.TargetTare = correction == 0 ? null : (ViewModel.ActualTare ?? 0) + correction;
|
||||||
|
ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare;
|
||||||
|
var obj = JsonNode.Parse(s)!.AsObject();
|
||||||
|
if (correction == 0) {
|
||||||
|
obj.Remove("tare_correction");
|
||||||
|
} else {
|
||||||
|
obj["tare_correction"] = correction;
|
||||||
|
}
|
||||||
|
ViewModel.WeighingData = obj.ToJsonString(Utils.JsonOpts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void WeighingButton_Click(object sender, RoutedEventArgs evt) {
|
private void WeighingButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
int index = Array.IndexOf(WeighingButtons, sender as Button);
|
int index = Array.IndexOf(WeighingButtons, sender as Button);
|
||||||
if (index >= 0) WeighingButton_Click(index);
|
if (index >= 0) WeighingButton_Click(index);
|
||||||
@@ -651,12 +673,18 @@ namespace Elwig.Windows {
|
|||||||
private void OnWeighingResult(IScale scale, WeighingResult res) {
|
private void OnWeighingResult(IScale scale, WeighingResult res) {
|
||||||
if ((res.NetWeight ?? 0) > 0 && res.FullWeighingId != null) {
|
if ((res.NetWeight ?? 0) > 0 && res.FullWeighingId != null) {
|
||||||
ViewModel.Weight = res.NetWeight;
|
ViewModel.Weight = res.NetWeight;
|
||||||
|
ViewModel.ActualTare = res.TareWeight;
|
||||||
|
ViewModel.TargetTare = null;
|
||||||
|
ViewModel.Tare = ViewModel.ActualTare is int t && t != 0 ? t : null;
|
||||||
ViewModel.ScaleTerminalId = scale.ScaleTerminalId;
|
ViewModel.ScaleTerminalId = scale.ScaleTerminalId;
|
||||||
ViewModel.WeighingData = res.ToJson().ToJsonString();
|
ViewModel.WeighingData = res.ToJson().ToJsonString();
|
||||||
ViewModel.ManualWeighingReason = null;
|
ViewModel.ManualWeighingReason = null;
|
||||||
ManualWeighingInput.IsChecked = false;
|
ManualWeighingInput.IsChecked = false;
|
||||||
} else {
|
} else {
|
||||||
ViewModel.Weight = null;
|
ViewModel.Weight = null;
|
||||||
|
ViewModel.ActualTare = null;
|
||||||
|
ViewModel.TargetTare = null;
|
||||||
|
ViewModel.Tare = null;
|
||||||
ViewModel.ScaleTerminalId = null;
|
ViewModel.ScaleTerminalId = null;
|
||||||
ViewModel.WeighingData = null;
|
ViewModel.WeighingData = null;
|
||||||
}
|
}
|
||||||
@@ -685,7 +713,7 @@ namespace Elwig.Windows {
|
|||||||
private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) {
|
private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) {
|
||||||
if (!HasContextLoaded) return;
|
if (!HasContextLoaded) return;
|
||||||
if (TodayOnlyInput.IsChecked == true && AllSeasonsInput.IsChecked == false) {
|
if (TodayOnlyInput.IsChecked == true && AllSeasonsInput.IsChecked == false) {
|
||||||
ViewModel.FilterSeason = Utils.Today.Year;
|
ViewModel.FilterSeason = DateTime.Today.Year;
|
||||||
ViewModel.FilterTodayOnly = true;
|
ViewModel.FilterTodayOnly = true;
|
||||||
}
|
}
|
||||||
await RefreshList();
|
await RefreshList();
|
||||||
@@ -746,12 +774,12 @@ namespace Elwig.Windows {
|
|||||||
MgNrInput.CaretIndex = caret;
|
MgNrInput.CaretIndex = caret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
private async void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
||||||
var valid = InputLostFocus((TextBox)sender, Validator.CheckMgNr);
|
var valid = InputLostFocus((TextBox)sender, Validator.CheckMgNr);
|
||||||
ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null);
|
ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MemberInput_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
private async void MemberInput_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||||
var m = MemberInput.SelectedItem as Member;
|
var m = MemberInput.SelectedItem as Member;
|
||||||
ViewModel.MgNr = m?.MgNr;
|
ViewModel.MgNr = m?.MgNr;
|
||||||
ViewModel.MemberAddress = m?.FullAddress;
|
ViewModel.MemberAddress = m?.FullAddress;
|
||||||
@@ -768,6 +796,8 @@ namespace Elwig.Windows {
|
|||||||
SetDefaultValue(WineKgInput);
|
SetDefaultValue(WineKgInput);
|
||||||
ComboBox_SelectionChanged(WineKgInput, null);
|
ComboBox_SelectionChanged(WineKgInput, null);
|
||||||
}
|
}
|
||||||
|
if (IsCreating && Mouse.OverrideCursor == null)
|
||||||
|
await CheckOrganic();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EmptyScale() {
|
private void EmptyScale() {
|
||||||
@@ -777,6 +807,9 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
|
private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!await CheckOrganic(true))
|
||||||
|
return;
|
||||||
|
|
||||||
FinishButton.IsEnabled = false;
|
FinishButton.IsEnabled = false;
|
||||||
NewDeliveryPartButton.IsEnabled = false;
|
NewDeliveryPartButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
@@ -796,7 +829,7 @@ namespace Elwig.Windows {
|
|||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
InteractionService.ShowDbException("Lieferung aktualisieren", exc);
|
InteractionService.ShowDbException("Lieferung aktualisieren", exc);
|
||||||
FinishButton.IsEnabled = true;
|
FinishButton.IsEnabled = true;
|
||||||
SaveButton.IsEnabled = true;
|
NewDeliveryPartButton.IsEnabled = true;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
DeliveryPartList.IsEnabled = true;
|
DeliveryPartList.IsEnabled = true;
|
||||||
return;
|
return;
|
||||||
@@ -805,14 +838,18 @@ namespace Elwig.Windows {
|
|||||||
EmptyScale();
|
EmptyScale();
|
||||||
|
|
||||||
await EnsureContextRenewed();
|
await EnsureContextRenewed();
|
||||||
Mouse.OverrideCursor = null;
|
|
||||||
ControlUtils.SelectItemWithPk(DeliveryList, p?.Year, p?.DId);
|
ControlUtils.SelectItemWithPk(DeliveryList, p?.Year, p?.DId);
|
||||||
DeliveryPartList.SelectedItem = null;
|
DeliveryPartList.SelectedItem = null;
|
||||||
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().LastOrDefault());
|
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().LastOrDefault());
|
||||||
InitialInputs();
|
InitialInputs();
|
||||||
|
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void FinishButton_Click(object sender, RoutedEventArgs evt) {
|
private async void FinishButton_Click(object sender, RoutedEventArgs evt) {
|
||||||
|
if (!await CheckOrganic(true))
|
||||||
|
return;
|
||||||
|
|
||||||
FinishButton.IsEnabled = false;
|
FinishButton.IsEnabled = false;
|
||||||
NewDeliveryPartButton.IsEnabled = false;
|
NewDeliveryPartButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
@@ -832,7 +869,7 @@ namespace Elwig.Windows {
|
|||||||
} catch (Exception exc) {
|
} catch (Exception exc) {
|
||||||
InteractionService.ShowDbException("Lieferung aktualisieren", exc);
|
InteractionService.ShowDbException("Lieferung aktualisieren", exc);
|
||||||
FinishButton.IsEnabled = true;
|
FinishButton.IsEnabled = true;
|
||||||
SaveButton.IsEnabled = true;
|
NewDeliveryPartButton.IsEnabled = true;
|
||||||
Mouse.OverrideCursor = null;
|
Mouse.OverrideCursor = null;
|
||||||
DeliveryPartList.IsEnabled = true;
|
DeliveryPartList.IsEnabled = true;
|
||||||
return;
|
return;
|
||||||
@@ -971,6 +1008,8 @@ namespace Elwig.Windows {
|
|||||||
DeliveryList.IsEnabled = false;
|
DeliveryList.IsEnabled = false;
|
||||||
DeliveryPartList.IsEnabled = false;
|
DeliveryPartList.IsEnabled = false;
|
||||||
|
|
||||||
|
if (!ViewModel.IsReceipt)
|
||||||
|
EnableWeighingButtons();
|
||||||
HideNewEditDeleteButtons();
|
HideNewEditDeleteButtons();
|
||||||
ShowSaveResetCancelButtons();
|
ShowSaveResetCancelButtons();
|
||||||
UnlockInputs();
|
UnlockInputs();
|
||||||
@@ -1008,6 +1047,9 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
|
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||||
|
if (!await CheckOrganic(true))
|
||||||
|
return;
|
||||||
|
|
||||||
SaveButton.IsEnabled = false;
|
SaveButton.IsEnabled = false;
|
||||||
Mouse.OverrideCursor = Cursors.Wait;
|
Mouse.OverrideCursor = Cursors.Wait;
|
||||||
|
|
||||||
@@ -1034,6 +1076,8 @@ namespace Elwig.Windows {
|
|||||||
DeliveryList.IsEnabled = true;
|
DeliveryList.IsEnabled = true;
|
||||||
DeliveryPartList.IsEnabled = true;
|
DeliveryPartList.IsEnabled = true;
|
||||||
|
|
||||||
|
if (!ViewModel.IsReceipt)
|
||||||
|
DisableWeighingButtons();
|
||||||
HideSaveResetCancelButtons();
|
HideSaveResetCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
@@ -1067,6 +1111,8 @@ namespace Elwig.Windows {
|
|||||||
DeliveryList.IsEnabled = true;
|
DeliveryList.IsEnabled = true;
|
||||||
DeliveryPartList.IsEnabled = true;
|
DeliveryPartList.IsEnabled = true;
|
||||||
|
|
||||||
|
if (!ViewModel.IsReceipt)
|
||||||
|
DisableWeighingButtons();
|
||||||
HideSaveResetCancelButtons();
|
HideSaveResetCancelButtons();
|
||||||
ShowNewEditDeleteButtons();
|
ShowNewEditDeleteButtons();
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
@@ -1171,6 +1217,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void DisableWeighingButtons() {
|
private void DisableWeighingButtons() {
|
||||||
|
CorrectTareButton.IsEnabled = false;
|
||||||
WeighingManualButton.IsEnabled = false;
|
WeighingManualButton.IsEnabled = false;
|
||||||
WeighingAButton.IsEnabled = false;
|
WeighingAButton.IsEnabled = false;
|
||||||
WeighingBButton.IsEnabled = false;
|
WeighingBButton.IsEnabled = false;
|
||||||
@@ -1179,6 +1226,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void EnableWeighingButtons() {
|
private void EnableWeighingButtons() {
|
||||||
|
CorrectTareButton.IsEnabled = true;
|
||||||
WeighingManualButton.IsEnabled = true;
|
WeighingManualButton.IsEnabled = true;
|
||||||
var n = App.CommandScales.Count;
|
var n = App.CommandScales.Count;
|
||||||
WeighingAButton.IsEnabled = n > 0 && App.CommandScales[0].IsReady;
|
WeighingAButton.IsEnabled = n > 0 && App.CommandScales[0].IsReady;
|
||||||
@@ -1373,13 +1421,15 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
private void UnloadingInput_Checked(object sender, RoutedEventArgs evt) {
|
private void UnloadingInput_Checked(object sender, RoutedEventArgs evt) {
|
||||||
if (!IsEditing && !IsCreating) return;
|
if (!IsEditing && !IsCreating) return;
|
||||||
|
if (!ViewModel.IsReceipt)
|
||||||
|
CorrectTareButton.Visibility = (ViewModel.ActualTare is int t && t != 0) || ViewModel.IsUnloadingBox ? Visibility.Visible : Visibility.Hidden;
|
||||||
var mod = ViewModel.Modifiers.ToList();
|
var mod = ViewModel.Modifiers.ToList();
|
||||||
var source = ViewModel.ModifiersSource.ToList();
|
var source = ViewModel.ModifiersSource.ToList();
|
||||||
if (App.Client.IsMatzen) {
|
if (App.Client.IsMatzen) {
|
||||||
var kl = mod.Where(m => m.Name.StartsWith("Klasse ")).Select(m => m.ModId).LastOrDefault("_")[0];
|
var kl = mod.Where(m => m.Name.StartsWith("Klasse ")).Select(m => m.ModId).LastOrDefault("_")[0];
|
||||||
if (ViewModel.IsUnloadingPumped && (kl == 'A' || kl == '_')) {
|
if (ViewModel.IsUnloadingPumped && (kl == 'A' || kl == '_')) {
|
||||||
kl = 'B';
|
kl = 'B';
|
||||||
} else if (ViewModel.IsUnloadingDumper && kl == '_') {
|
} else if (ViewModel.IsUnloadingDumper && (kl == 'B' || kl == '_')) {
|
||||||
kl = 'A';
|
kl = 'A';
|
||||||
} else {
|
} else {
|
||||||
kl = '_';
|
kl = '_';
|
||||||
@@ -1464,7 +1514,7 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
InputTextChanged((TextBox)sender);
|
InputTextChanged((TextBox)sender, new ValidationResult(ViewModel.Weight > 0, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void TemperatureAcidInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void TemperatureAcidInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
@@ -1501,5 +1551,43 @@ namespace Elwig.Windows {
|
|||||||
if (MemberInput.SelectedItem is not Member m) return;
|
if (MemberInput.SelectedItem is not Member m) return;
|
||||||
App.FocusMember(m.MgNr);
|
App.FocusMember(m.MgNr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void CultivationInput_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||||
|
if (IsCreating && Mouse.OverrideCursor == null)
|
||||||
|
await CheckOrganic();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> CheckOrganic(bool confirm = false) {
|
||||||
|
if (MemberInput.SelectedValue is not Member m || CultivationInput.SelectedItem is not WineCult c) {
|
||||||
|
return true;
|
||||||
|
} else if (c.IsOrganic) {
|
||||||
|
if (m.IsOrganic) {
|
||||||
|
var valid = true;
|
||||||
|
if (IsCreating) {
|
||||||
|
try {
|
||||||
|
var certs = await OrganicService.GetTracesCertificates(m);
|
||||||
|
valid = certs.Any(c => c.IsValidForWineProduction);
|
||||||
|
} catch { }
|
||||||
|
}
|
||||||
|
if (valid)
|
||||||
|
return true;
|
||||||
|
if (confirm) {
|
||||||
|
return InteractionService.AskConfirmation("Kein gültiges Bio-Zertifikat", "Soll die Bio-Lieferung wirklich gespeichert werden,\nobwohl für das Mitglied kein gültiges Bio-Zertifikat gefunden werden konnte?");
|
||||||
|
} else {
|
||||||
|
InteractionService.ShowWarning("Kein gültiges Bio-Zertifikat", "Achtung! Für diesen Bio-Betrieb konnte kein gültiges Bio-Zertifikat gefunden werden!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (confirm) {
|
||||||
|
return InteractionService.AskConfirmation("Kein Bio-Betrieb", "Soll die Bio-Lieferung wirklich gespeichert werden, obwohl das Mitglied keinen Bio-Betrieb hat?");
|
||||||
|
} else {
|
||||||
|
InteractionService.ShowWarning("Kein Bio-Betrieb", "Achtung! Bio-Lieferung ohne Bio-Betrieb!");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Anmeldungen - Elwig" Height="700" Width="980" MinWidth="600" MinHeight="400">
|
Title="{Binding Title}" Height="700" Width="980" MinWidth="600" MinHeight="400">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryAncmtAdminViewModel/>
|
<vm:DeliveryAncmtAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user