Compare commits

..
39 Commits
Author SHA1 Message Date
lorenz.stechauner d91e8c7e99 Bump version to 1.2.0.0
Deploy / Build and Deploy (push) Successful in 2m5s
2026-10-03 00:50:31 +02:00
lorenz.stechauner 09642e643c ClientParameters: Add option to hide business share history on MemberDataSheet
Test / Run tests (push) Successful in 2m16s
2026-10-03 00:07:04 +02:00
lorenz.stechauner b262e17293 Elwig: Update dependencies 2026-10-02 23:48:11 +02:00
lorenz.stechauner 4f4d026b7b AppDbUpdater: Fix update to v42 2026-10-02 23:48:11 +02:00
lorenz.stechauner abb9e5a577 MemberAdminWindow: Add pending member movement export 2026-10-02 23:47:56 +02:00
lorenz.stechauner 0e586cc438 DeliveryAdminWindow: Invalidate non-positive weight
Test / Run tests (push) Successful in 2m12s
2026-10-02 10:31:47 +02:00
lorenz.stechauner 829ad106cf DeliverySplittingDialog: Use color for wine variety
Test / Run tests (push) Successful in 3m3s
2026-10-02 09:26:46 +02:00
lorenz.stechauner ba7c37fd70 Helpers/Export: Code cleanup
Test / Run tests (push) Successful in 3m6s
2026-10-01 12:29:47 +02:00
lorenz.stechauner 66a1185dc3 MemberAdminWindow: Swap postal dest and Ort.Name
Test / Run tests (push) Successful in 2m38s
2026-09-30 15:41:47 +02:00
lorenz.stechauner db8afa59b7 Changelog: Use '-' instead of '*'
Test / Run tests (push) Successful in 2m25s
2026-09-30 12:14:30 +02:00
lorenz.stechauner 3d96c31a70 Elwig: Rename AreaCom to AreaCmt 2026-09-30 12:14:30 +02:00
lorenz.stechauner a18d687f18 [#67] OrganicService: Use ConcurrentDictionary 2026-09-30 12:14:30 +02:00
lorenz.stechauner 5f2788eb9e Elwig: Rename buchführend, funktionär, volllieferant, and gebunden 2026-09-30 12:14:25 +02:00
lorenz.stechauner 4988081bfd Tests: Add PaymentVariantServiceTest 2026-09-30 11:54:33 +02:00
lorenz.stechauner 03872ca5c2 SystecITScale: Fix typo in error message 2026-09-30 11:54:26 +02:00
lorenz.stechauner b886abc632 Test: Fix E2ETests 2026-09-29 22:30:29 +02:00
lorenz.stechauner cba949d2eb App: Only backup when not in debug mode
Test / Run tests (push) Successful in 2m19s
2026-09-29 21:12:15 +02:00
lorenz.stechauner c2bc5b221a ViewModels: Use partial properties 2026-09-29 21:08:25 +02:00
lorenz.stechauner 5845693f17 [#67] OrganicService: Use any valid certificate
Test / Run tests (push) Successful in 2m6s
2026-09-29 19:31:14 +02:00
lorenz.stechauner aea7c39734 Tests: Update dependencies
Test / Run tests (push) Successful in 2m29s
2026-09-29 19:25:41 +02:00
lorenz.stechauner c54a998c96 Elwig: Update dependencies 2026-09-29 19:25:06 +02:00
lorenz.stechauner 5bb84944bc [#67] DeliveryAdminWindow: Check if member IsOrganic and has valid certs when cultivation IsOrganic
Test / Run tests (push) Successful in 2m13s
2026-09-29 19:10:18 +02:00
lorenz.stechauner 34b40535a6 [#67] DeliveryAncmtAdminWindow: Check if member IsOrganic when delivery schedule IsOrganic 2026-09-29 19:04:47 +02:00
lorenz.stechauner 3dca099248 [#67] Elwig: Add OrganicService 2026-09-29 19:04:13 +02:00
lorenz.stechauner 155a599878 App: Add ShutdownNow() and ShutdownGracefully() 2026-09-29 19:04:12 +02:00
lorenz.stechauner fda337c3cb Helpers: Add Normalizer to normalize street names in addresses 2026-09-29 19:04:12 +02:00
lorenz.stechauner d8126e254d BusinessDocument: Do not show billing address name when UseBillingAddress is false 2026-09-29 19:04:12 +02:00
lorenz.stechauner 96441a6701 [#67] BusinessDocument: Add OrganicOperatorId to footer 2026-09-29 19:04:01 +02:00
lorenz.stechauner 03867bcd74 [#67] BusinessDocument: Add OrganicAuthorityCode and OrganicOperatorId to member Aside 2026-09-29 19:03:53 +02:00
lorenz.stechauner 83dfde9203 Entities/MemberHistory: Add CompanyHasSigned 2026-09-29 19:03:51 +02:00
lorenz.stechauner 805c5efda8 [#67] ClientParameters: Add ClientOrganicOperatorId 2026-09-29 19:03:44 +02:00
lorenz.stechauner e86edc080a [#67] Entities/WineCult: Add IsOrganic 2026-09-29 19:03:36 +02:00
lorenz.stechauner 0d5d1d4d3d [#67] Entities/Member: Add OrganicOperatorId 2026-09-29 19:03:23 +02:00
lorenz.stechauner ffd3dc9631 [#67] Entities/Member: Add OrganicAuthorityCode 2026-09-29 19:03:07 +02:00
lorenz.stechauner d592fef352 BusinessDocument: Use more columns in Aside table
Test / Run tests (push) Successful in 2m5s
2026-09-22 11:19:41 +02:00
lorenz.stechauner f2b84053e6 DeliveryNote: Remove right padding for weight cells
Test / Run tests (push) Successful in 1m51s
2026-09-22 10:54:23 +02:00
lorenz.stechauner 7fef895491 DeliveryService: Add red/white distinction to tool tips
Test / Run tests (push) Successful in 1m53s
2026-09-16 17:28:38 +02:00
lorenz.stechauner 0e9121c462 TareCorrectionDialog: Allow actual tare to be null 2026-09-16 17:23:12 +02:00
lorenz.stechauner 15e191d74e Export/Database: Do not delete import source files 2026-09-16 17:12:52 +02:00
126 changed files with 6348 additions and 1927 deletions
+436 -401
View File
File diff suppressed because it is too large Load Diff
-6
View File
@@ -7,12 +7,6 @@
<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}"/>
+28 -21
View File
@@ -18,12 +18,13 @@ 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; set; } = false; public static bool ForceShutdown { get; set; } = false;
@@ -102,7 +103,7 @@ namespace Elwig {
InteractionService.ShowException("Fehlerhafte Datenbank", "Schwerwiegender Fehler in der Datenbank, unbedingt den Programmierern melden!", exc); InteractionService.ShowException("Fehlerhafte Datenbank", "Schwerwiegender Fehler in der Datenbank, unbedingt den Programmierern melden!", exc);
if (InteractionService.AskQuestion("Backup wiederherstellen", "Soll die Datenbank aus einem Backup wiederhergestellt werden?\n\nAchtung: Das kann zu Datenverlust führen!", false)) 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(); await BackupService.RestoreDatabase();
Shutdown(); ShutdownNow();
return; return;
} }
@@ -119,7 +120,7 @@ namespace Elwig {
InteractionService.ShowException("Fehler", "Fehler beim Laden der Mandantendaten, unbedingt den Programmierern melden!", exc); InteractionService.ShowException("Fehler", "Fehler beim Laden der Mandantendaten, unbedingt den Programmierern melden!", exc);
if (InteractionService.AskQuestion("Backup wiederherstellen", "Soll die Datenbank aus einem Backup wiederhergestellt werden?\n\nAchtung: Das kann zu Datenverlust führen!", false)) 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(); await BackupService.RestoreDatabase();
Shutdown(); ShutdownNow();
return; return;
} }
BranchNum = branches.Count; BranchNum = branches.Count;
@@ -133,7 +134,7 @@ namespace Elwig {
Utils.RunBackground("PDF Initialization", async () => 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) { if (Config.BackupAuto && !Config.Debug) {
Utils.RunBackground("Automatisches Backup", async () => { Utils.RunBackground("Automatisches Backup", async () => {
Directory.CreateDirectory(Config.BackupPath); Directory.CreateDirectory(Config.BackupPath);
await Task.Delay(500); await Task.Delay(500);
@@ -183,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()]);
} }
@@ -191,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) {
@@ -210,21 +211,29 @@ namespace Elwig {
window.Show(); window.Show();
} }
public async Task OnClosing() { public static void ShutdownNow() {
try { ForceShutdown = true;
await BackupService.TryDatabaseBackup(); Current.Shutdown();
} catch (Exception exc) {
InteractionService.ShowException("Automatisches Backup", exc);
}
} }
protected override void OnExit(ExitEventArgs evt) { 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();
} }
Pdf.Cleanup(); Pdf.Cleanup();
base.OnExit(evt);
Shutdown();
} }
public static void SetBranch(Branch b) { public static void SetBranch(Branch b) {
@@ -335,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) {
@@ -354,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);
} }
@@ -387,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"
@@ -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"
@@ -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}";
+2 -2
View File
@@ -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}"/>
+6 -6
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -1,4 +1,5 @@
<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"
+6 -4
View File
@@ -8,10 +8,11 @@ namespace Elwig.Dialogs {
public int ActualTare { get; private set; } public int ActualTare { get; private set; }
public int TargetTare { get; private set; } public int TargetTare { get; private set; }
public TareCorrectionDialog(int actualTare, int? targetTare = null) { public TareCorrectionDialog(int? actualTare, int? targetTare = null) {
InitializeComponent(); InitializeComponent();
ActualTare = actualTare; ActualTare = actualTare ?? 0;
TargetTare = targetTare ?? actualTare; TargetTare = targetTare ?? actualTare ?? 0;
ActualTareInput.IsReadOnly = actualTare != null;
ActualTareInput.Text = ActualTare.ToString(); ActualTareInput.Text = ActualTare.ToString();
TargetTareInput.Text = TargetTare.ToString(); TargetTareInput.Text = TargetTare.ToString();
TargetTareInput.SelectAll(); TargetTareInput.SelectAll();
@@ -19,12 +20,13 @@ namespace Elwig.Dialogs {
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) { private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
DialogResult = true; DialogResult = true;
ActualTare = int.Parse(ActualTareInput.Text);
TargetTare = int.Parse(TargetTareInput.Text); TargetTare = int.Parse(TargetTareInput.Text);
Close(); Close();
} }
private void UpdateButtons() { private void UpdateButtons() {
ConfirmButton.IsEnabled = TargetTareInput.Text.Length > 0; ConfirmButton.IsEnabled = ActualTareInput.Text.Length > 0 && TargetTareInput.Text.Length > 0;
} }
private void TareInput_TextChanged(object sender, TextChangedEventArgs evt) { private void TareInput_TextChanged(object sender, TextChangedEventArgs evt) {
+37 -18
View File
@@ -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());
} }
+4 -4
View File
@@ -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) {
+4 -4
View File
@@ -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) {
+14 -11
View File
@@ -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,13 +130,13 @@ 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); .SetKeepTogether(true);
@@ -148,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}", right: 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));
@@ -238,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;
+25 -24
View File
@@ -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;
@@ -273,11 +274,11 @@ namespace Elwig.Documents {
.AddCells(NewBusinessSharesCells(new())); .AddCells(NewBusinessSharesCells(new()));
} }
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;
+14 -14
View File
@@ -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)));
} }
} }
+22 -22
View File
@@ -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;
} }
+6 -6
View File
@@ -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.2.2</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,15 +23,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="bblanchon.PDFium.Win32" Version="155.0.8044" /> <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.18.0" /> <PackageReference Include="MailKit" Version="4.18.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.12" /> <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.12" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4191.47" /> <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" />
+71 -21
View File
@@ -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, []);
+62 -4
View File
@@ -1,15 +1,18 @@
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;
@@ -68,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)
@@ -87,8 +90,11 @@ namespace Elwig.Helpers {
await cnx.IntegrityCheck(); await cnx.IntegrityCheck();
await cnx.ForeignKeyCheck(); await cnx.ForeignKeyCheck();
foreach (var script in toExecute) { 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);
}
} }
await cnx.IntegrityCheck(); await cnx.IntegrityCheck();
@@ -103,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;
}
}
} }
} }
+15 -15
View File
@@ -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));
+10 -10
View File
@@ -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;
+12 -12
View File
@@ -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]);
} }
+17 -17
View File
@@ -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(), []);
} }
} }
} }
+2 -2
View File
@@ -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) {
+17 -3
View File
@@ -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),
+1 -5
View File
@@ -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) {
+8 -4
View File
@@ -212,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 {
@@ -221,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;
} }
} }
@@ -233,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);
File.Move(filename, App.Config.DatabaseFile, false); if (keepSource) {
File.Copy(filename, App.Config.DatabaseFile, false);
} else {
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");
@@ -246,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);
} }
+1 -10
View File
@@ -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");
-15
View File
@@ -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();
}
}
}
+54 -48
View File
@@ -63,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,
@@ -75,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) {
@@ -105,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");
@@ -159,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(kgs, currentWbKgs, 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));
} }
} }
} }
@@ -184,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(kgs, currentWbKgs, 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));
} }
} }
} }
@@ -235,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)) {
@@ -365,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) {
@@ -447,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" +
@@ -481,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);
} }
@@ -501,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) {
@@ -535,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 {
@@ -572,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));
} }
} }
@@ -638,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,
@@ -710,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>(),
@@ -762,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,
@@ -782,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>(),
@@ -790,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,
@@ -802,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,
@@ -817,7 +823,7 @@ namespace Elwig.Helpers.Export {
}; };
} }
public static (AreaComContract, List<(AreaCom, (DateTime CreatedAt, DateTime ModifiedAt)?)>, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaComContract(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, 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>();
@@ -842,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>(),
@@ -871,7 +877,7 @@ 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, AT_Kg> kgs, Dictionary<int, WbKg> currentWbKgs, 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)) { if (!currentWbKgs.Values.Any(k => k.KgNr == kgnr)) {
@@ -895,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>(),
@@ -955,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;
@@ -1029,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>(),
-8
View File
@@ -1,8 +0,0 @@
using Elwig.Models.Dtos;
namespace Elwig.Helpers.Export {
/// <summary>
/// Interface for exporting banking data
/// </summary>
public interface IBankingExporter : IExporter<Transaction> { }
}
+4 -2
View File
@@ -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,35 +216,59 @@ 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"); """);
foreach (var (name, span, units) in table.ColumnNames.Zip(table.ColumnSpans, table.ColumnUnits)) {
var hasUnits = units.Length > 0;
await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
}
await Content.WriteAsync(" </table:table-row>\r\n <table:table-row>\r\n");
foreach (var (span, units) in table.ColumnSpans.Zip(table.ColumnUnits)) {
if (units.Length == 0) {
await Content.WriteAsync($" <table:covered-table-cell table:number-columns-repeated=\"{span}\"/>\r\n");
continue;
}
foreach (var u in units) {
await Content.WriteAsync(FormatCell(u == null ? null : $"[{u}]", style: "th"));
}
}
await Content.WriteAsync(" </table:table-row>\r\n");
foreach (var row in table.GetData()) { var firstSection = true;
await FormatRow(row, table.ColumnUnits, mergeSubRowCells); 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)) {
var hasUnits = units.Length > 0;
await Content.WriteAsync(FormatCell(name, colSpan: span, rowSpan: hasUnits ? 1 : 2, style: "th"));
}
await Content.WriteAsync(" </table:table-row>\r\n <table:table-row>\r\n");
foreach (var (span, units) in table.ColumnSpans.Zip(table.ColumnUnits)) {
if (units.Length == 0) {
await Content.WriteAsync($" <table:covered-table-cell table:number-columns-repeated=\"{span}\"/>\r\n");
continue;
}
foreach (var u in units) {
await Content.WriteAsync(FormatCell(u == null ? null : $"[{u}]", style: "th"));
}
}
await Content.WriteAsync(" </table:table-row>\r\n");
foreach (var row in sec.Rows) {
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" : "");
+3 -10
View File
@@ -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", "");
} }
+3 -1
View File
@@ -13,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 {
@@ -192,13 +193,14 @@ 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);
+303
View File
@@ -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));
}
}
}
+43 -16
View File
@@ -303,7 +303,7 @@ 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) { public static int? ShowTareCorrectionDialog(int? actualTare, int? targetTare = null) {
var d = new TareCorrectionDialog(actualTare, targetTare); var d = new TareCorrectionDialog(actualTare, targetTare);
return d.ShowDialog() == true ? d.TargetTare - d.ActualTare : null; return d.ShowDialog() == true ? d.TargetTare - d.ActualTare : null;
} }
@@ -323,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;
@@ -334,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;
} }
@@ -342,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() {
@@ -357,10 +382,12 @@ 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) {
if (!first2) l.Add(new Text(Separator)); foreach (var item in group) {
l.Add(item as ILeafElement ?? new Text(item.ToString() ?? "")); if (!first2) l.Add(new Text(Separator));
first2 = false; l.Add(item as ILeafElement ?? new Text(item.ToString() ?? ""));
first2 = false;
}
} }
first1 = false; first1 = false;
} }
@@ -635,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) {
@@ -675,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(',')
)); ));
+67 -8
View File
@@ -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);
}
} }
} }
+1 -1
View File
@@ -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;
} }
@@ -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")]
+54 -35
View File
@@ -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)));
} }
} }
} }
@@ -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")]
+9 -9
View File
@@ -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() : [];
} }
} }
+142
View File
@@ -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 = [];
}
}
+36 -36
View File
@@ -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; }
} }
+6 -6
View File
@@ -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; }
} }
+3
View File
@@ -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; }
+2 -2
View File
@@ -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; }
@@ -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; }
+15 -9
View File
@@ -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));
} }
+7 -4
View File
@@ -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}" : "");
+1 -1
View File
@@ -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;
} }
+3
View File
@@ -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"},
+65
View File
@@ -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,23 +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); 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}");
} }
@@ -96,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,
@@ -168,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)
@@ -254,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))!;
@@ -263,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))!;
+112 -59
View File
@@ -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 {
@@ -37,7 +39,7 @@ namespace Elwig.Services {
vm.GradationKmwString = ""; vm.GradationKmwString = "";
vm.Weight = null; vm.Weight = null;
vm.ActualTare = 0; vm.ActualTare = null;
vm.TargetTare = null; vm.TargetTare = null;
vm.Tare = null; vm.Tare = null;
vm.IsManualWeighing = false; vm.IsManualWeighing = false;
@@ -58,9 +60,9 @@ namespace Elwig.Services {
vm.WineOrigin = ControlUtils.GetItemFromSourceWithPk(vm.WineOriginSource, p.HkId) as WineOrigin; vm.WineOrigin = ControlUtils.GetItemFromSourceWithPk(vm.WineOriginSource, p.HkId) as WineOrigin;
vm.Weight = p.Weight; vm.Weight = p.Weight;
vm.ActualTare = p.WeighingInfo.Tare ?? 0; vm.ActualTare = p.WeighingInfo.Tare;
vm.TargetTare = vm.ActualTare + p.WeighingInfo.TareCorrection; vm.TargetTare = vm.ActualTare + p.WeighingInfo.TareCorrection;
vm.Tare = vm.TargetTare ?? (vm.ActualTare != 0 ? vm.ActualTare : null); 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;
@@ -73,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;
@@ -179,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)) {
@@ -554,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,
@@ -975,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)
@@ -1013,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 })
@@ -1034,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),
@@ -1049,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),
@@ -1063,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)
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) { .GroupBy(g => g.Type)
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, stat.Weight)); .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)) {
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)
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Avg).ThenBy(g => g.SortId)) { .GroupBy(g => g.Type)
gGrid.Add((null, g.SortId, g.Min, g.Avg, g.Max)); .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)) {
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}]";
@@ -1094,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,5 +1,7 @@
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;
@@ -10,6 +12,10 @@ 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 = $"{DateTime.Today:dd.MM.yyyy}"; vm.DateNoticeString = $"{DateTime.Today:dd.MM.yyyy}";
@@ -26,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;
@@ -63,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,
@@ -95,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);
});
}
} }
} }
+132 -50
View File
@@ -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());
if (m.MgNr != vm.MgNr)
return;
await App.MainDispatcher.BeginInvoke(() => { await App.MainDispatcher.BeginInvoke(() => {
if (m.MgNr != vm.MgNr)
return;
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);
+163
View File
@@ -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')}";
}
}
}
+2 -2
View File
@@ -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}";
+14 -14
View File
@@ -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;
} }
@@ -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; }
} }
} }
+65 -65
View File
@@ -9,175 +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 string? _tareString = "-"; public partial string? TareString { get; set; } = "-";
public int? Tare { public int? Tare {
get => int.TryParse(TareString?.Replace(Utils.GroupSeparator, "").Replace(" kg", ""), out var w) ? w : null; get => int.TryParse(TareString?.Replace(Utils.GroupSeparator, "").Replace(" kg", ""), out var w) ? w : null;
set => TareString = value == null ? "-" : $"{value:N0} kg{(TargetTare != null ? "*" : "")}"; set => TareString = value == null ? "-" : $"{value:N0} kg{(TargetTare != null ? "*" : "")}";
} }
public int ActualTare; public int? ActualTare { get; set; }
public int? TargetTare; public int? TargetTare { get; set; }
[ObservableProperty] [ObservableProperty]
private bool _isManualWeighing; public partial bool IsManualWeighing { get; set; }
[ObservableProperty] [ObservableProperty]
private bool? _isNetWeightValue = false; 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;
@@ -191,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; }
} }
} }
+27 -27
View File
@@ -9,80 +9,80 @@ namespace Elwig.ViewModels {
public partial class DeliveryAncmtAdminViewModel : ObservableObject { public partial class DeliveryAncmtAdminViewModel : ObservableObject {
[ObservableProperty] [ObservableProperty]
private string _title = "Anmeldungen - Elwig"; public partial string Title { get; set; } = "Anmeldungen - Elwig";
[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 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;
} }
} }
+98 -82
View File
@@ -6,187 +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.Media;
namespace Elwig.ViewModels { namespace Elwig.ViewModels {
public partial class MemberAdminViewModel : ObservableObject { public partial class MemberAdminViewModel : ObservableObject {
[ObservableProperty] [ObservableProperty]
private string _title = "Mitglieder - Elwig"; public partial string Title { get; set; } = "Mitglieder - Elwig";
public int? TransferPredecessorAreaComs = null; public int? TransferPredecessorAreaCmts { get; set; } = null;
public int? CancelAreaComs = 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;
@@ -199,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;
} }
} }
+35 -35
View File
@@ -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; } = "-";
} }
} }
+32 -8
View File
@@ -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) {
if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) { try {
evt.Cancel = true; if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) {
return; evt.Cancel = true;
} 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="&#x2013;" TextAlignment="Center" Margin="0,0,0,0"/> <TextBlock Text="&#x2013;" 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="&#xE712;" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0" <Button x:Name="AreaCmtTypeDetailsButton" Content="&#xE712;" 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"/>
@@ -12,13 +12,13 @@ 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();
@@ -30,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);
@@ -50,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 (filterNames, 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 (filterNames, 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()
@@ -68,11 +68,11 @@ 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 (filterNames, 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;
@@ -83,16 +83,16 @@ namespace Elwig.Windows {
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();
@@ -170,7 +170,7 @@ namespace Elwig.Windows {
.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)
@@ -228,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;
@@ -241,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) {
@@ -260,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;
@@ -273,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,
@@ -287,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) {
@@ -415,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;
@@ -495,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) {
+34 -17
View File
@@ -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>
@@ -551,12 +561,12 @@
</ComboBox> </ComboBox>
<Label Content="Mitgliederbewegungen:" Margin="10,40,10,10"/> <Label Content="Mitgliederbewegungen:" Margin="10,40,10,10"/>
<CheckBox x:Name="ParameterBusinessShareHistoryInput" Content="Mit Elwig erfassen" Margin="160,45,10,15" <CheckBox x:Name="ParameterBusinessShareHistoryInput" Content="Mit Elwig erfassen" Margin="160,45,10,15"
HorizontalAlignment="Left" HorizontalAlignment="Left"
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) &quot;schlechtere&quot; Flächenbindungen aufzuteilen" <CheckBox x:Name="ParameterAllowAttrIntoLowerInput" Content="Erlauben Lieferungen auch auf (konfigurierte) &quot;schlechtere&quot; 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 &quot;besseren&quot; Flächenbindungen vermeiden" <CheckBox x:Name="ParameterAvoidUnderDeliveriesInput" Content="Unterlieferungen durch Abzug bei &quot;besseren&quot; 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>
+5 -5
View File
@@ -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();
+12 -6
View File
@@ -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 { }
+7 -7
View File
@@ -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>
+91 -91
View File
@@ -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;
} }
+2 -1
View File
@@ -518,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>
@@ -681,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"/>
+70 -20
View File
@@ -356,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);
} }
} }
@@ -376,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
@@ -614,7 +614,7 @@ namespace Elwig.Windows {
ClearOriginalValues(); ClearOriginalValues();
ClearDefaultValues(); ClearDefaultValues();
ViewModel.FillInputs(p); ViewModel.FillInputs(p);
CorrectTareButton.Visibility = !ViewModel.IsReceipt && (ViewModel.ActualTare != 0 || ViewModel.IsUnloadingBox) ? Visibility.Visible : Visibility.Hidden; CorrectTareButton.Visibility = !ViewModel.IsReceipt && ((ViewModel.ActualTare is int t && t != 0) || ViewModel.IsUnloadingBox) ? Visibility.Visible : Visibility.Hidden;
FinishInputFilling(); FinishInputFilling();
} }
@@ -625,13 +625,13 @@ namespace Elwig.Windows {
} }
private void CorrectTareButton_Click(object sender, RoutedEventArgs evt) { private void CorrectTareButton_Click(object sender, RoutedEventArgs evt) {
var lastCorrection = (ViewModel.TargetTare ?? ViewModel.ActualTare) - ViewModel.ActualTare; var lastCorrection = (ViewModel.TargetTare ?? ViewModel.ActualTare ?? 0) - (ViewModel.ActualTare ?? 0);
var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare); var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare);
if (correction == null) return; if (correction == null) return;
ViewModel.Weight += lastCorrection - correction; ViewModel.Weight += lastCorrection - correction;
ViewModel.TargetTare = correction == 0 ? null : ViewModel.ActualTare + correction; if (ViewModel.Weight != null && ViewModel.WeighingData is string s) {
ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare; ViewModel.TargetTare = correction == 0 ? null : (ViewModel.ActualTare ?? 0) + correction;
if (ViewModel.WeighingData is string s) { ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare;
var obj = JsonNode.Parse(s)!.AsObject(); var obj = JsonNode.Parse(s)!.AsObject();
if (correction == 0) { if (correction == 0) {
obj.Remove("tare_correction"); obj.Remove("tare_correction");
@@ -673,16 +673,16 @@ 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 ?? 0; ViewModel.ActualTare = res.TareWeight;
ViewModel.TargetTare = null; ViewModel.TargetTare = null;
ViewModel.Tare = ViewModel.ActualTare != 0 ? ViewModel.ActualTare : 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 = 0; ViewModel.ActualTare = null;
ViewModel.TargetTare = null; ViewModel.TargetTare = null;
ViewModel.Tare = null; ViewModel.Tare = null;
ViewModel.ScaleTerminalId = null; ViewModel.ScaleTerminalId = null;
@@ -774,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;
@@ -796,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() {
@@ -805,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;
@@ -824,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;
@@ -833,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;
@@ -860,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;
@@ -1038,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;
@@ -1410,7 +1422,7 @@ 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) if (!ViewModel.IsReceipt)
CorrectTareButton.Visibility = ViewModel.ActualTare != 0 || ViewModel.IsUnloadingBox ? Visibility.Visible : Visibility.Hidden; 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) {
@@ -1502,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) {
@@ -1539,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;
}
}
} }
} }
+26 -1
View File
@@ -208,8 +208,28 @@ namespace Elwig.Windows {
} }
} }
private void DeliveryScheduleInput_SelectionChanged(object sender, RoutedEventArgs evt) { private bool CheckOrganic(bool confirm = false) {
if (DeliveryScheduleInput.SelectedItem is not DeliverySchedule s || MemberInput.SelectedItem is not Member m) {
return true;
} else if (s.IsOrganic) {
if (m.IsOrganic) {
return true;
} else {
if (confirm) {
return InteractionService.AskConfirmation("Kein Bio-Betrieb", "Soll die Bio-Anmeldung wirklich gespeichert werden, obwohl das Mitglied keinen Bio-Betrieb hat?");
} else {
InteractionService.ShowWarning("Kein Bio-Betrieb", "Achtung! Bio-Anmeldung ohne Bio-Betrieb!");
}
}
return false;
} else {
return true;
}
}
private void DeliveryScheduleInput_SelectionChanged(object sender, RoutedEventArgs evt) {
if (IsEditing || IsCreating)
CheckOrganic();
} }
private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) { private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) {
@@ -258,6 +278,8 @@ namespace Elwig.Windows {
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;
if (IsCreating)
CheckOrganic();
} }
protected override void ShortcutNew() { protected override void ShortcutNew() {
@@ -334,6 +356,9 @@ namespace Elwig.Windows {
} }
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
if (!CheckOrganic(true))
return;
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
+7 -7
View File
@@ -126,7 +126,7 @@
<RadioButton GroupName="Recipients" x:Name="RecipientsActiveMembersInput" Content="aktive Mitglieder" <RadioButton GroupName="Recipients" x:Name="RecipientsActiveMembersInput" Content="aktive Mitglieder"
Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
<RadioButton GroupName="Recipients" x:Name="RecipientsAreaComMembersInput" Content="Mitglieder mit Flächenbindung" <RadioButton GroupName="Recipients" x:Name="RecipientsAreaCmtMembersInput" Content="Mitglieder mit Flächenbindung"
Margin="10,30,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,30,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/>
<RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryAncmtMembersInput" Content="Mitglieder mit Anmeldung" <RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryAncmtMembersInput" Content="Mitglieder mit Anmeldung"
@@ -167,19 +167,19 @@
Margin="180,225,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="180,225,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
Checked="MemberInput_Checked"/> Checked="MemberInput_Checked"/>
<Label Content="Funktionär:" x:Name="MemberFunktionärLabel" Margin="10,250,0,10"/> <Label Content="Funktionär:" x:Name="MemberOfficerLabel" Margin="10,250,0,10"/>
<RadioButton x:Name="MemberFunktionärYesInput" Content="Ja" GroupName="MemberFunktionär" <RadioButton x:Name="MemberOfficerYesInput" Content="Ja" GroupName="MemberOfficer"
Margin="80,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="80,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
Checked="MemberInput_Checked"/> Checked="MemberInput_Checked"/>
<RadioButton x:Name="MemberFunktionärNoInput" Content="Nein" GroupName="MemberFunktionär" <RadioButton x:Name="MemberOfficerNoInput" Content="Nein" GroupName="MemberOfficer"
Margin="125,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="125,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
Checked="MemberInput_Checked"/> Checked="MemberInput_Checked"/>
<RadioButton x:Name="MemberFunktionärIndifferentInput" Content="Egal" GroupName="MemberFunktionär" <RadioButton x:Name="MemberOfficerIndifferentInput" Content="Egal" GroupName="MemberOfficer"
Margin="180,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="180,255,10,10" VerticalAlignment="Top" HorizontalAlignment="Left"
Checked="MemberInput_Checked"/> Checked="MemberInput_Checked"/>
<Label Content="Vtrg.:" x:Name="MemberAreaComLabel" Margin="10,280,0,10"/> <Label Content="Vtrg.:" x:Name="MemberAreaCmtLabel" Margin="10,280,0,10"/>
<ctrl:CheckComboBox x:Name="MemberAreaComInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId" <ctrl:CheckComboBox x:Name="MemberAreaCmtInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId"
IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten" IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten"
Margin="50,280,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" Margin="50,280,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25"
SelectionChanged="MemberInput_SelectionChanged"/> SelectionChanged="MemberInput_SelectionChanged"/>
+18 -18
View File
@@ -122,7 +122,7 @@ namespace Elwig.Windows {
RecipientsActiveMembersInput.IsChecked = true; RecipientsActiveMembersInput.IsChecked = true;
MemberOrganicIndifferentInput.IsChecked = true; MemberOrganicIndifferentInput.IsChecked = true;
MemberFunktionärIndifferentInput.IsChecked = true; MemberOfficerIndifferentInput.IsChecked = true;
DeliveryConfirmationFooterInput.Text = App.Client.TextDeliveryConfirmation; DeliveryConfirmationFooterInput.Text = App.Client.TextDeliveryConfirmation;
CreditNoteFooterInput.Text = App.Client.TextCreditNote; CreditNoteFooterInput.Text = App.Client.TextCreditNote;
@@ -181,13 +181,13 @@ namespace Elwig.Windows {
MemberKgInput.SelectAll(); MemberKgInput.SelectAll();
MemberKgInput.SelectionChanged += MemberInput_SelectionChanged; MemberKgInput.SelectionChanged += MemberInput_SelectionChanged;
} }
ControlUtils.RenewItemsSource(MemberAreaComInput, await ctx.AreaCommitmentTypes ControlUtils.RenewItemsSource(MemberAreaCmtInput, await ctx.AreaCommitmentTypes
.OrderBy(a => a.VtrgId) .OrderBy(a => a.VtrgId)
.ToListAsync(), MemberInput_SelectionChanged); .ToListAsync(), MemberInput_SelectionChanged);
if (MemberAreaComInput.SelectedItems.Count == 0) { if (MemberAreaCmtInput.SelectedItems.Count == 0) {
MemberAreaComInput.SelectionChanged -= MemberInput_SelectionChanged; MemberAreaCmtInput.SelectionChanged -= MemberInput_SelectionChanged;
MemberAreaComInput.SelectAll(); MemberAreaCmtInput.SelectAll();
MemberAreaComInput.SelectionChanged += MemberInput_SelectionChanged; MemberAreaCmtInput.SelectionChanged += MemberInput_SelectionChanged;
} }
ControlUtils.RenewItemsSource(MemberDeliveryAncmtInput, await ctx.DeliverySchedules ControlUtils.RenewItemsSource(MemberDeliveryAncmtInput, await ctx.DeliverySchedules
.Where(s => s.Year == Year) .Where(s => s.Year == Year)
@@ -408,12 +408,12 @@ namespace Elwig.Windows {
MemberOrganicYesInput.Visibility = vis; MemberOrganicYesInput.Visibility = vis;
MemberOrganicNoInput.Visibility = vis; MemberOrganicNoInput.Visibility = vis;
MemberOrganicIndifferentInput.Visibility = vis; MemberOrganicIndifferentInput.Visibility = vis;
MemberFunktionärLabel.Visibility = vis; MemberOfficerLabel.Visibility = vis;
MemberFunktionärYesInput.Visibility = vis; MemberOfficerYesInput.Visibility = vis;
MemberFunktionärNoInput.Visibility = vis; MemberOfficerNoInput.Visibility = vis;
MemberFunktionärIndifferentInput.Visibility = vis; MemberOfficerIndifferentInput.Visibility = vis;
MemberAreaComInput.Visibility = RecipientsAreaComMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden; MemberAreaCmtInput.Visibility = RecipientsAreaCmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
MemberAreaComLabel.Visibility = RecipientsAreaComMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden; MemberAreaCmtLabel.Visibility = RecipientsAreaCmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
MemberDeliveryAncmtInput.Visibility = RecipientsDeliveryAncmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden; MemberDeliveryAncmtInput.Visibility = RecipientsDeliveryAncmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
MemberDeliveryAncmtLabel.Visibility = RecipientsDeliveryAncmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden; MemberDeliveryAncmtLabel.Visibility = RecipientsDeliveryAncmtMembersInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
MemberCustomInput.Visibility = RecipientsCustomInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden; MemberCustomInput.Visibility = RecipientsCustomInput.IsChecked == true ? Visibility.Visible : Visibility.Hidden;
@@ -459,14 +459,14 @@ namespace Elwig.Windows {
} else if (MemberOrganicNoInput.IsChecked == true) { } else if (MemberOrganicNoInput.IsChecked == true) {
query = query.Where(m => !m.IsOrganic); query = query.Where(m => !m.IsOrganic);
} }
if (MemberFunktionärYesInput.IsChecked == true) { if (MemberOfficerYesInput.IsChecked == true) {
query = query.Where(m => m.IsFunktionär); query = query.Where(m => m.IsOfficer);
} else if (MemberFunktionärNoInput.IsChecked == true) { } else if (MemberOfficerNoInput.IsChecked == true) {
query = query.Where(m => !m.IsFunktionär); query = query.Where(m => !m.IsOfficer);
} }
if (RecipientsAreaComMembersInput.IsChecked == true) { if (RecipientsAreaCmtMembersInput.IsChecked == true) {
var vtrg = MemberAreaComInput.SelectedItems.Cast<AreaComType>().Select(a => a.VtrgId).ToList(); var vtrg = MemberAreaCmtInput.SelectedItems.Cast<AreaCmtType>().Select(a => a.VtrgId).ToList();
query = query.Where(m => m.IsActive && m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Year)).Any(c => vtrg.Contains(c.VtrgId))); query = query.Where(m => m.IsActive && m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Year)).Any(c => vtrg.Contains(c.VtrgId)));
} else if (RecipientsDeliveryAncmtMembersInput.IsChecked == true) { } else if (RecipientsDeliveryAncmtMembersInput.IsChecked == true) {
var dsnrs = MemberDeliveryAncmtInput.SelectedItems.Cast<DeliverySchedule>().Select(s => s.DsNr).ToList(); var dsnrs = MemberDeliveryAncmtInput.SelectedItems.Cast<DeliverySchedule>().Select(s => s.DsNr).ToList();
+3 -3
View File
@@ -301,12 +301,12 @@
<TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">Ungebunden:</TextBlock> <TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">Ungebunden:</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="1" TextAlignment="Right" x:Name="SeasonStatMembersTotal">-</TextBlock> <TextBlock Grid.Row="1" Grid.Column="1" TextAlignment="Right" x:Name="SeasonStatMembersTotal">-</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="1" TextAlignment="Right" x:Name="SeasonStatMembersGeb">-</TextBlock> <TextBlock Grid.Row="2" Grid.Column="1" TextAlignment="Right" x:Name="SeasonStatMembersCtrd">-</TextBlock>
<TextBlock Grid.Row="3" Grid.Column="1" TextAlignment="Right">-</TextBlock> <TextBlock Grid.Row="3" Grid.Column="1" TextAlignment="Right">-</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightTotal">-</TextBlock> <TextBlock Grid.Row="1" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightTotal">-</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightGeb">-</TextBlock> <TextBlock Grid.Row="2" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightCtrd">-</TextBlock>
<TextBlock Grid.Row="3" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightUngeb">-</TextBlock> <TextBlock Grid.Row="3" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightUnCtrd">-</TextBlock>
<TextBlock Grid.Row="1" Grid.Column="3" TextAlignment="Right">-</TextBlock> <TextBlock Grid.Row="1" Grid.Column="3" TextAlignment="Right">-</TextBlock>
<TextBlock Grid.Row="2" Grid.Column="3" TextAlignment="Right" x:Name="SeasonStatArea">-</TextBlock> <TextBlock Grid.Row="2" Grid.Column="3" TextAlignment="Right" x:Name="SeasonStatArea">-</TextBlock>
+20 -24
View File
@@ -50,27 +50,23 @@ namespace Elwig.Windows {
_syncTimer.Start(); _syncTimer.Start();
} }
private async void Window_Closing(object sender, CancelEventArgs evt) { private void Window_Closing(object sender, CancelEventArgs evt) {
evt.Cancel = !App.ForceShutdown;
if (App.NumWindows > 1 && !App.ForceShutdown) { if (App.NumWindows > 1 && !App.ForceShutdown) {
foreach (var w in Application.Current.Windows.Cast<Window>().Where(w => ((w as AdministrationWindow)?.IsEditing ?? false) || ((w as AdministrationWindow)?.IsCreating ?? false))) { foreach (var w in Application.Current.Windows.Cast<Window>().Where(w => w is AdministrationWindow adm && (adm.IsEditing || adm.IsCreating))) {
try { try {
w.Close(); w.Close();
} catch { } } catch { }
} }
Thread.Sleep(100); Thread.Sleep(100);
if (App.NumWindows > 1 && !Application.Current.Windows.Cast<Window>().Any(w => ((w as AdministrationWindow)?.IsEditing ?? false) || ((w as AdministrationWindow)?.IsCreating ?? false))) { if (App.NumWindows > 1) {
if (!InteractionService.AskConfirmation("Elwig beenden", "Es sind noch weitere Fenster geöffnet.\nSollen alle Fenster geschlossen werden?")) { var areAdminWindowsOpen = Application.Current.Windows.Cast<Window>().Any(w => w is AdministrationWindow adm && (adm.IsEditing || adm.IsCreating));
if (areAdminWindowsOpen && !InteractionService.AskConfirmation("Elwig beenden", "Es sind noch weitere Fenster geöffnet.\nSollen alle Fenster geschlossen werden?")) {
evt.Cancel = true;
return; return;
} }
App.ForceShutdown = true;
} }
} }
App.CurrentApp.ShutdownGracefully();
Mouse.OverrideCursor = Cursors.AppStarting;
await (Application.Current as App)!.OnClosing();
Application.Current.Shutdown();
} }
private void Menu_Help_About_Click(object sender, RoutedEventArgs evt) { private void Menu_Help_About_Click(object sender, RoutedEventArgs evt) {
@@ -410,26 +406,26 @@ namespace Elwig.Windows {
BreakdownMemberVarietyButton.IsEnabled = valid; BreakdownMemberVarietyButton.IsEnabled = valid;
SeasonStatMembersTotal.Text = "-"; SeasonStatMembersTotal.Text = "-";
SeasonStatMembersGeb.Text = "-"; SeasonStatMembersCtrd.Text = "-";
SeasonStatWeightTotal.Text = "-"; SeasonStatWeightTotal.Text = "-";
SeasonStatWeightGeb.Text = "-"; SeasonStatWeightCtrd.Text = "-";
SeasonStatWeightUngeb.Text = "-"; SeasonStatWeightUnCtrd.Text = "-";
SeasonStatArea.Text = "-"; SeasonStatArea.Text = "-";
if (valid) { if (valid) {
await Task.Run(async () => { await Task.Run(async () => {
var membersTotal = await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync(); var membersTotal = await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync();
var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value); var areaCmts = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value);
var membersGeb = await areaComs.Select(c => c.Member).Distinct().CountAsync(); var membersCtrd = await areaCmts.Select(c => c.Member).Distinct().CountAsync();
var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight); var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight);
var gebWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value); var ctrdWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value);
var area = await areaComs.SumAsync(c => c.Area); var area = await areaCmts.SumAsync(c => c.Area);
await App.MainDispatcher.BeginInvoke(() => { await App.MainDispatcher.BeginInvoke(() => {
if (year != SeasonInput.Value) return; if (year != SeasonInput.Value) return;
SeasonStatMembersTotal.Text = $"{membersTotal:N0}"; SeasonStatMembersTotal.Text = $"{membersTotal:N0}";
SeasonStatMembersGeb.Text = $"{membersGeb:N0}"; SeasonStatMembersCtrd.Text = $"{membersCtrd:N0}";
SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg"; SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg";
SeasonStatWeightGeb.Text = $"{gebWeight:N0} kg"; SeasonStatWeightCtrd.Text = $"{ctrdWeight:N0} kg";
SeasonStatWeightUngeb.Text = $"{weightTotal - gebWeight:N0} kg"; SeasonStatWeightUnCtrd.Text = $"{weightTotal - ctrdWeight:N0} kg";
SeasonStatArea.Text = $"{area:N0} m²"; SeasonStatArea.Text = $"{area:N0} m²";
}); });
}); });
@@ -466,7 +462,7 @@ namespace Elwig.Windows {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year); var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year);
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year); var tbl2 = await AreaCmtUnderDeliveryData.ForSeason(ctx.AreaCmtUnderDeliveryRows, year);
using var ods = new OdsFile(filename); using var ods = new OdsFile(filename);
if (App.Client.HasRedWhite) { if (App.Client.HasRedWhite) {
await ods.AddTable(tbl1.Red); await ods.AddTable(tbl1.Red);
@@ -528,8 +524,8 @@ namespace Elwig.Windows {
App.HintContextChange(); App.HintContextChange();
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var tbl1 = await MemberAreaComTotalsData.ForSeason(ctx.MemberAreaComTotalsRows, year); var tbl1 = await MemberAreaCmtTotalsData.ForSeason(ctx.MemberAreaCmtTotalsRows, year);
var tbl2 = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year); var tbl2 = await MemberAreaCmtsData.ForSeason(ctx.MemberAreaCmtsRows, year);
using var ods = new OdsFile(filename); using var ods = new OdsFile(filename);
await ods.AddTable(tbl1); await ods.AddTable(tbl1);
await ods.AddTable(tbl2); await ods.AddTable(tbl2);
+77 -42
View File
@@ -110,7 +110,7 @@
Click="Menu_CreditNote_Email_Click"/> Click="Menu_CreditNote_Email_Click"/>
</MenuItem> </MenuItem>
<MenuItem Header="Mitgliederliste" x:Name="Menu_List"> <MenuItem Header="Mitgliederliste" x:Name="Menu_List">
<MenuItem x:Name="Menu_List_SaveActive" Header="...mit Aktiven speichern (Excel)" <MenuItem x:Name="Menu_List_SaveActive" Header="...mit Aktiven speichern... (Excel)"
Click="Menu_List_SaveActive_Click" InputGestureText="Strg+L"/> Click="Menu_List_SaveActive_Click" InputGestureText="Strg+L"/>
<MenuItem x:Name="Menu_List_ShowActive" Header="...mit Aktiven anzeigen (PDF)" <MenuItem x:Name="Menu_List_ShowActive" Header="...mit Aktiven anzeigen (PDF)"
Click="Menu_List_ShowActive_Click" InputGestureText="Strg+O"/> Click="Menu_List_ShowActive_Click" InputGestureText="Strg+O"/>
@@ -119,7 +119,7 @@
<MenuItem x:Name="Menu_List_PrintActive" Header="...mit Aktiven drucken" <MenuItem x:Name="Menu_List_PrintActive" Header="...mit Aktiven drucken"
Click="Menu_List_PrintActive_Click" InputGestureText="Strg+Shift+O"/> Click="Menu_List_PrintActive_Click" InputGestureText="Strg+Shift+O"/>
<Separator/> <Separator/>
<MenuItem x:Name="Menu_List_SaveFilters" Header="...aus Filtern speichern (Excel)" <MenuItem x:Name="Menu_List_SaveFilters" Header="...aus Filtern speichern... (Excel)"
Click="Menu_List_SaveFilters_Click"/> Click="Menu_List_SaveFilters_Click"/>
<MenuItem x:Name="Menu_List_ShowFilters" Header="...aus Filtern anzeigen (PDF)" <MenuItem x:Name="Menu_List_ShowFilters" Header="...aus Filtern anzeigen (PDF)"
Click="Menu_List_ShowFilters_Click"/> Click="Menu_List_ShowFilters_Click"/>
@@ -128,7 +128,7 @@
<MenuItem x:Name="Menu_List_PrintFilters" Header="...aus Filtern drucken" <MenuItem x:Name="Menu_List_PrintFilters" Header="...aus Filtern drucken"
Click="Menu_List_PrintFilters_Click"/> Click="Menu_List_PrintFilters_Click"/>
<Separator/> <Separator/>
<MenuItem x:Name="Menu_List_SaveAll" Header="...mit allen speichern (Excel)" <MenuItem x:Name="Menu_List_SaveAll" Header="...mit allen speichern... (Excel)"
Click="Menu_List_SaveAll_Click"/> Click="Menu_List_SaveAll_Click"/>
<MenuItem x:Name="Menu_List_ShowAll" Header="...mit allen anzeigen (PDF)" <MenuItem x:Name="Menu_List_ShowAll" Header="...mit allen anzeigen (PDF)"
Click="Menu_List_ShowAll_Click"/> Click="Menu_List_ShowAll_Click"/>
@@ -147,6 +147,10 @@
IsCheckable="True" IsChecked="{Binding MemberListOrderByOrt, Mode=TwoWay}" IsCheckable="True" IsChecked="{Binding MemberListOrderByOrt, Mode=TwoWay}"
Click="Menu_List_Order_Click"/> Click="Menu_List_Order_Click"/>
</MenuItem> </MenuItem>
<MenuItem Header="Geschäftsanteile" x:Name="Menu_BusinessShares">
<MenuItem x:Name="Menu_BusinessShares_SavePending" Header="Ausstehende Mitlg.-Bewegungen speichern... (Excel)"
Click="Menu_BusinessShares_SavePending_Click"/>
</MenuItem>
<MenuItem Header="Export"> <MenuItem Header="Export">
<MenuItem x:Name="Menu_Export_ExportSelected" Header="...von ausgewähltem Mitglied speichern..." IsEnabled="False" <MenuItem x:Name="Menu_Export_ExportSelected" Header="...von ausgewähltem Mitglied speichern..." IsEnabled="False"
Click="Menu_Export_ExportSelected_Click"/> Click="Menu_Export_ExportSelected_Click"/>
@@ -204,7 +208,7 @@
<Bold>Aktiv</Bold>: aktiv, !Aktiv (nicht-aktiv)<LineBreak/> <Bold>Aktiv</Bold>: aktiv, !Aktiv (nicht-aktiv)<LineBreak/>
<Bold>Bio-Betrieb</Bold>: BIO, !bio (ausgenommen Bio)<LineBreak/> <Bold>Bio-Betrieb</Bold>: BIO, !bio (ausgenommen Bio)<LineBreak/>
<Bold>Buchführend</Bold>: buchf[ührend], Pauschal[iert], !buchf[ührend]<LineBreak/> <Bold>Buchführend</Bold>: buchf[ührend], Pauschal[iert], !buchf[ührend]<LineBreak/>
<Bold>Volllieferant</Bold>: voll[lieferant], !Voll[lieferant] (nicht-Volllieferant)<LineBreak/> <Bold>Vollablieferer</Bold>: voll[ablieferer], voll[lieferant], !Voll[lieferant] (nicht-Vollablieferer)<LineBreak/>
<Bold>Funktionär</Bold>: Funkt[ionär], !funkt[ionär] (nicht-Funktionär)<LineBreak/> <Bold>Funktionär</Bold>: Funkt[ionär], !funkt[ionär] (nicht-Funktionär)<LineBreak/>
<Bold>Telefon-Nr.</Bold>: z.B. +436641234, ....<LineBreak/> <Bold>Telefon-Nr.</Bold>: z.B. +436641234, ....<LineBreak/>
<Bold>Kontaktdaten</Bold>: email (mind. 1 E-Mail-Adr.), telnr (mind. 1 Tel.-Nr.), !email (keine E-Mail-Adr.), !telnr (keine Tel.-Nr.)<LineBreak/> <Bold>Kontaktdaten</Bold>: email (mind. 1 E-Mail-Adr.), telnr (mind. 1 Tel.-Nr.), !email (keine E-Mail-Adr.), !telnr (keine Tel.-Nr.)<LineBreak/>
@@ -371,14 +375,15 @@
<Label Content="Adresse:" Margin="10,130,0,0"/> <Label Content="Adresse:" Margin="10,130,0,0"/>
<TextBox x:Name="AddressInput" Text="{Binding Address, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="AddressInput" Text="{Binding Address, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="3" Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="3"
TextChanged="TextBox_TextChanged"/> TextChanged="AddressInput_TextChanged"/>
<Label Content="PLZ/Ort:" Margin="10,160,0,0" Grid.Column="0"/> <Label Content="PLZ/Ort:" Margin="10,160,0,0" Grid.Column="0"/>
<TextBox x:Name="PlzInput" Margin="0,160,0,0" Text="{Binding PlzString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="PlzInput" Margin="0,160,0,0" Text="{Binding PlzString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Width="42" Grid.Column="1" HorizontalAlignment="Left" Width="42" Grid.Column="1" HorizontalAlignment="Left"
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/> TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
<ComboBox x:Name="OrtInput" SelectedItem="{Binding Ort, Mode=TwoWay}" ItemsSource="{Binding OrtSource, Mode=TwoWay}" <ComboBox x:Name="OrtInput" SelectedItem="{Binding Ort, Mode=TwoWay}" ItemsSource="{Binding OrtSource, Mode=TwoWay}"
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name" DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
SelectionChanged="OrtInput_SelectionChanged"
Margin="47,160,10,0" Grid.Column="1" Grid.ColumnSpan="3"/> Margin="47,160,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
@@ -547,37 +552,47 @@
<GroupBox Header="Betrieb" Grid.Column="1" Grid.Row="0" Grid.RowSpan="1" Margin="5,5,5,5"> <GroupBox Header="Betrieb" Grid.Column="1" Grid.Row="0" Grid.RowSpan="1" Margin="5,5,5,5">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="90"/> <ColumnDefinition Width="85"/>
<ColumnDefinition Width="150"/> <ColumnDefinition Width="69"/>
<ColumnDefinition/> <ColumnDefinition Width="*"/>
<ColumnDefinition Width="55"/>
<ColumnDefinition Width="101"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Content="UID:" Margin="10,10,0,0" Grid.Column="0" ToolTip="USt-IdNr. / Umsatzsteuer-Identifikationsnummer"/> <Label Content="Betriebs-Nr.:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="UstIdNrInput" Text="{Binding UstIdNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,10,10,0" Grid.Column="1" Width="96" HorizontalAlignment="Left"
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
<Label Content="Betriebs-Nr.:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="LfbisNrInput" Text="{Binding LfbisNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="LfbisNrInput" Text="{Binding LfbisNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,40,10,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right" Margin="0,10,5,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/> TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
<CheckBox x:Name="BuchführendInput" Content="Buchführend" IsChecked="{Binding IsBuchführend, Mode=TwoWay}" IsEnabled="False" <Label Content="UID:" Margin="10,40,0,0" Grid.Column="0" ToolTip="USt-IdNr. / Umsatzsteuer-Identifikationsnummer"/>
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" <TextBox x:Name="UstIdNrInput" Text="{Binding UstIdNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="2" HorizontalAlignment="Left" Margin="10,15,0,0" VerticalAlignment="Top"/> Margin="0,40,5,0" Grid.Column="0" Grid.ColumnSpan="2" Width="96" HorizontalAlignment="Right"
TextChanged="UstIdNrInput_TextChanged" LostFocus="UstIdNrInput_LostFocus"/>
<CheckBox x:Name="OrganicInput" Content="Bio" IsChecked="{Binding IsOrganic, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="OrganicInput" Content="Bio" IsChecked="{Binding IsOrganic, Mode=TwoWay}" IsEnabled="False"
Checked="OrganicInput_Changed" Unchecked="OrganicInput_Changed"
Grid.Column="2" HorizontalAlignment="Left" Margin="5,15,0,0" VerticalAlignment="Top"/>
<CheckBox x:Name="AccountingInput" Content="Buchführend" IsChecked="{Binding IsAccounting, Mode=TwoWay}" IsEnabled="False"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
Grid.Column="2" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top"/> Grid.Column="2" HorizontalAlignment="Left" Margin="5,45,0,0" VerticalAlignment="Top"/>
<Button x:Name="OrganicButton" Content="easy-cert.com" IsEnabled="{Binding IsMemberSelected}"
Height="25" FontSize="12" <Label Content="Kontrollstelle:" Margin="0,10,5,0" Grid.Column="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" ToolTip="Bio-Kontrollstelle"/>
Click="OrganicButton_Click" <TextBox x:Name="OrganicAuthorityCodeInput" Text="{Binding OrganicAuthorityCode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="60,40,0,0"/> Margin="0,10,10,0" Grid.Column="4" Width="91" HorizontalAlignment="Left"
TextChanged="OrganicAuthorityCodeInput_TextChanged" LostFocus="OrganicAuthorityCodeInput_LostFocus"/>
<Label Content="OOC-ID:" Margin="0,40,0,0" Grid.Column="3" HorizontalAlignment="Left" ToolTip="Bio-EU-Operator-ID / Organic Operator Certificate ID"/>
<TextBox x:Name="OrganicOperatorIdInput" Text="{Binding OrganicOperatorId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,40,10,0" Grid.Column="4" Width="91" HorizontalAlignment="Left"
TextChanged="OrganicOperatorIdInput_TextChanged" LostFocus="OrganicOperatorIdInput_LostFocus"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
<GroupBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Margin="5,5,5,5"> <GroupBox Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Margin="5,5,5,5">
<GroupBox.Header> <GroupBox.Header>
<TextBlock>Rechnungsadresse (optional) <Run FontSize="10">für Lieferschein, Anlfrg.-Bstng., Tr.-Gutschr.</Run></TextBlock> <TextBlock>Rechnungsadresse (optional)
<Run FontSize="10">für Lieferschein, Anlfrg.-Bstng., Tr.-Gutschr.</Run>
</TextBlock>
</GroupBox.Header> </GroupBox.Header>
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -593,14 +608,15 @@
<Label Content="Adresse:" Margin="10,40,0,0" Grid.Column="0"/> <Label Content="Adresse:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="BillingAddressInput" Text="{Binding BillingAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="BillingAddressInput" Text="{Binding BillingAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,40,10,0" Grid.Column="1" Margin="0,40,10,0" Grid.Column="1"
TextChanged="TextBox_TextChanged"/> TextChanged="AddressInput_TextChanged"/>
<Label Content="PLZ/Ort:" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="PLZ/Ort:" Margin="10,70,0,0" Grid.Column="0"/>
<TextBox x:Name="BillingPlzInput" Text="{Binding BillingPlzString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="BillingPlzInput" Text="{Binding BillingPlzString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left" Margin="0,70,0,0" Width="42" Grid.Column="1" HorizontalAlignment="Left"
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/> TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
<ComboBox x:Name="BillingOrtInput" SelectedItem="{Binding BillingOrt, Mode=TwoWay}" ItemsSource="{Binding BillingOrtSource, Mode=TwoWay}" <ComboBox x:Name="BillingOrtInput" SelectedItem="{Binding BillingOrt, Mode=TwoWay}" ItemsSource="{Binding BillingOrtSource, Mode=TwoWay}"
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name" DisplayMemberPath="FullDest" TextSearch.TextPath="Ort.Name"
SelectionChanged="OrtInput_SelectionChanged"
Margin="47,70,10,0" Grid.Column="1"/> Margin="47,70,10,0" Grid.Column="1"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
@@ -608,7 +624,8 @@
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/> <ColumnDefinition Width="120"/>
<ColumnDefinition Width="120"/> <ColumnDefinition Width="90"/>
<ColumnDefinition Width="90"/>
<ColumnDefinition/> <ColumnDefinition/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
@@ -645,46 +662,64 @@
<CheckBox x:Name="ActiveInput" Content="Aktiv" IsChecked="{Binding IsActive, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="ActiveInput" Content="Aktiv" IsChecked="{Binding IsActive, Mode=TwoWay}" IsEnabled="False"
Checked="ActiveInput_Changed" Unchecked="ActiveInput_Changed" Checked="ActiveInput_Changed" Unchecked="ActiveInput_Changed"
Grid.Column="2" HorizontalAlignment="Left" Margin="10,15,0,0" VerticalAlignment="Top"/> Grid.Column="2" HorizontalAlignment="Left" Margin="0,15,0,0" VerticalAlignment="Top"/>
<CheckBox x:Name="VollLieferantInput" Content="Volllieferant" IsChecked="{Binding IsVollLieferant, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="FullDeliveryInput" Content="Vollablieferer" IsChecked="{Binding IsFullDelivery, Mode=TwoWay}" IsEnabled="False"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
Grid.Column="2" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top"/> Grid.Column="2" HorizontalAlignment="Left" Margin="0,45,0,0" VerticalAlignment="Top"/>
<CheckBox x:Name="FunkionärInput" Content="Funktionär" IsChecked="{Binding IsFunktionär, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="OfficerInput" Content="Funktionär" IsChecked="{Binding IsOfficer, Mode=TwoWay}" IsEnabled="False"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
Grid.Column="2" HorizontalAlignment="Left" Margin="10,75,0,0" VerticalAlignment="Top"/> Grid.Column="2" HorizontalAlignment="Left" Margin="0,75,0,0" VerticalAlignment="Top"/>
<Label Content="Bio-Zertifikate:" Margin="0,-2.5,20,0" Grid.Column="3" HorizontalAlignment="Right"/>
<Button x:Name="OrganicTracesButton" IsEnabled="{Binding IsMemberSelectedOrCreating}" ToolTip="{Binding OrganicToolTip}"
Click="OrganicTracesButton_Click"
HorizontalAlignment="Right" Margin="0,20,10,0" Width="100" Padding="0" Height="35" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2" HorizontalContentAlignment="Stretch">
<StackPanel Orientation="Vertical">
<TextBlock FontSize="12" TextAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,-3">EU TRACES</TextBlock>
<TextBlock FontSize="10" TextAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,0">
<Run Text="{Binding OrganicState}" FontWeight="Bold" Foreground="{Binding OrganicColor}"/><Run Text="{Binding OrganicDetails}"/>
</TextBlock>
</StackPanel>
</Button>
<Button x:Name="OrganicEasyCertButton" IsEnabled="{Binding IsMemberSelectedOrCreating}" Content="Easy-Cert"
Click="OrganicEasyCertButton_Click"
HorizontalAlignment="Right" Margin="0,60,10,0" Width="100" Height="30" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2"/>
<Button x:Name="OrganicBiocButton" IsEnabled="{Binding IsMemberSelectedOrCreating}" Content="BioC"
Click="OrganicBiocButton_Click"
HorizontalAlignment="Right" Margin="0,95,10,0" Width="100" Height="30" VerticalAlignment="Top" Grid.Column="2" Grid.ColumnSpan="2"/>
<Label Content="Stamm-Zwst.:" Margin="10,130,0,0" Grid.Column="0"/> <Label Content="Stamm-Zwst.:" Margin="10,130,0,0" Grid.Column="0"/>
<ComboBox x:Name="BranchInput" SelectedItem="{Binding Branch, Mode=TwoWay}" ItemsSource="{Binding BranchSource, Mode=TwoWay}" <ComboBox x:Name="BranchInput" SelectedItem="{Binding Branch, Mode=TwoWay}" ItemsSource="{Binding BranchSource, Mode=TwoWay}"
DisplayMemberPath="Name" TextSearch.TextPath="Name" DisplayMemberPath="Name" TextSearch.TextPath="Name"
Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="2"/> Margin="0,130,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
<Label Content="Stammgemeinde:" Margin="10,160,0,0" Grid.Column="0"/> <Label Content="Stammgemeinde:" Margin="10,160,0,0" Grid.Column="0"/>
<ComboBox x:Name="DefaultKgInput" SelectedItem="{Binding DefaultKg, Mode=TwoWay}" ItemsSource="{Binding DefaultKgSource, Mode=TwoWay}" <ComboBox x:Name="DefaultKgInput" SelectedItem="{Binding DefaultKg, Mode=TwoWay}" ItemsSource="{Binding DefaultKgSource, Mode=TwoWay}"
DisplayMemberPath="Name" TextSearch.TextPath="Name" DisplayMemberPath="Name" TextSearch.TextPath="Name"
Margin="0,160,40,10" Grid.Column="1" Grid.ColumnSpan="2"/> Margin="0,160,40,10" Grid.Column="1" Grid.ColumnSpan="3"/>
<Button x:Name="KgDetailsButton" Content="&#xE712;" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0" <Button x:Name="KgDetailsButton" Content="&#xE712;" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
Click="KgDetailsButton_Click" Click="KgDetailsButton_Click"
Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,160,10,10"/> Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,160,10,10"/>
<Label Content="Anmerkung:" Margin="10,190,0,0" Grid.Column="0"/> <Label Content="Anmerkung:" Margin="10,190,0,0" Grid.Column="0"/>
<TextBox x:Name="CommentInput" Text="{Binding Comment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="CommentInput" Text="{Binding Comment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,190,10,70" Grid.Column="1" Grid.ColumnSpan="2" FontSize="12" Margin="0,190,10,70" Grid.Column="1" Grid.ColumnSpan="3" FontSize="12"
TextChanged="TextBox_TextChanged" TextChanged="TextBox_TextChanged"
VerticalAlignment="Stretch" Height="auto" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/> VerticalAlignment="Stretch" Height="auto" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/>
<Label Content="Kontaktart:" Margin="10,10,0,40" Grid.Column="0" VerticalAlignment="Bottom"/> <Label Content="Kontaktart:" Margin="10,10,0,40" Grid.Column="0" VerticalAlignment="Bottom"/>
<CheckBox x:Name="ContactPostalInput" Content="Post" IsChecked="{Binding ContactViaPost, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="ContactPostalInput" Content="Post" IsChecked="{Binding ContactViaPost, Mode=TwoWay}" IsEnabled="False"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
HorizontalAlignment="Left" Margin="0,0,0,45" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="2"/> HorizontalAlignment="Left" Margin="0,0,0,45" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="3"/>
<CheckBox x:Name="ContactEmailInput" Content="E-Mail" IsChecked="{Binding ContactViaEmail, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="ContactEmailInput" Content="E-Mail" IsChecked="{Binding ContactViaEmail, Mode=TwoWay}" IsEnabled="False"
Checked="ContactEmailInput_Changed" Unchecked="ContactEmailInput_Changed" Checked="ContactEmailInput_Changed" Unchecked="ContactEmailInput_Changed"
HorizontalAlignment="Left" Margin="60,0,0,45" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="2"/> HorizontalAlignment="Left" Margin="60,0,0,45" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="3"/>
<Label Content="Zuletzt geändert:" Margin="10,10,0,10" Grid.Column="0" VerticalAlignment="Bottom"/> <Label Content="Zuletzt geändert:" Margin="10,10,0,10" Grid.Column="0" VerticalAlignment="Bottom"/>
<TextBlock x:Name="LastModified" Text="{Binding ModifiedAtShort}" <TextBlock x:Name="LastModified" Text="{Binding ModifiedAtShort}"
Margin="0,10,0,15" Grid.Column="1" TextWrapping="NoWrap" VerticalAlignment="Bottom"> Margin="0,10,0,15" Grid.Column="1" Grid.ColumnSpan="2" TextWrapping="NoWrap" VerticalAlignment="Bottom">
<TextBlock.ToolTip> <TextBlock.ToolTip>
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
@@ -711,7 +746,7 @@
<Button x:Name="DeliveryButton" IsEnabled="{Binding IsMemberSelected}" <Button x:Name="DeliveryButton" IsEnabled="{Binding IsMemberSelected}"
Click="DeliveryButton_Click" Click="DeliveryButton_Click"
HorizontalAlignment="Right" Margin="10,00,10,37" Width="160" VerticalAlignment="Bottom" Grid.ColumnSpan="3" HorizontalContentAlignment="Stretch"> HorizontalAlignment="Right" Margin="10,00,10,37" Width="160" VerticalAlignment="Bottom" Grid.ColumnSpan="4" HorizontalContentAlignment="Stretch">
<Grid> <Grid>
<TextBlock Margin="0,0,10,0" TextAlignment="Center">Lieferungen</TextBlock> <TextBlock Margin="0,0,10,0" TextAlignment="Center">Lieferungen</TextBlock>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE8A7;" <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE8A7;"
@@ -720,7 +755,7 @@
</Button> </Button>
<Button x:Name="AreaCommitmentButton" IsEnabled="{Binding IsMemberSelected}" <Button x:Name="AreaCommitmentButton" IsEnabled="{Binding IsMemberSelected}"
Click="AreaCommitmentButton_Click" Click="AreaCommitmentButton_Click"
HorizontalAlignment="Right" Margin="10,10,10,5" Width="160" VerticalAlignment="Bottom" Grid.ColumnSpan="3" HorizontalContentAlignment="Stretch"> HorizontalAlignment="Right" Margin="10,10,10,5" Width="160" VerticalAlignment="Bottom" Grid.ColumnSpan="4" HorizontalContentAlignment="Stretch">
<Grid> <Grid>
<TextBlock Margin="0,0,15,0" TextAlignment="Center">Flächenbindungen</TextBlock> <TextBlock Margin="0,0,15,0" TextAlignment="Center">Flächenbindungen</TextBlock>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE8A7;" <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE8A7;"
+125 -33
View File
@@ -1,6 +1,7 @@
using Elwig.Dialogs; using Elwig.Dialogs;
using Elwig.Documents; using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Helpers.Export;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services; using Elwig.Services;
using Elwig.ViewModels; using Elwig.ViewModels;
@@ -114,6 +115,7 @@ namespace Elwig.Windows {
} }
if (!App.Client.EnableMemberHistory) { if (!App.Client.EnableMemberHistory) {
Menu_BusinessShares.Visibility = Visibility.Collapsed;
BusinessSharesButton.Visibility = Visibility.Hidden; BusinessSharesButton.Visibility = Visibility.Hidden;
} }
@@ -474,8 +476,8 @@ namespace Elwig.Windows {
IsCreating = true; IsCreating = true;
MemberList.IsEnabled = false; MemberList.IsEnabled = false;
ViewModel.SelectedMember = null; ViewModel.SelectedMember = null;
ViewModel.TransferPredecessorAreaComs = null; ViewModel.TransferPredecessorAreaCmts = null;
ViewModel.CancelAreaComs = null; ViewModel.CancelAreaCmts = null;
HideNewEditDeleteButtons(); HideNewEditDeleteButtons();
ShowSaveResetCancelButtons(); ShowSaveResetCancelButtons();
UnlockInputs(); UnlockInputs();
@@ -495,14 +497,16 @@ namespace Elwig.Windows {
IsEditing = true; IsEditing = true;
MemberList.IsEnabled = false; MemberList.IsEnabled = false;
ViewModel.TransferPredecessorAreaComs = null; ViewModel.TransferPredecessorAreaCmts = null;
ViewModel.CancelAreaComs = null; ViewModel.CancelAreaCmts = null;
HideNewEditDeleteButtons(); HideNewEditDeleteButtons();
ShowSaveResetCancelButtons(); ShowSaveResetCancelButtons();
UnlockInputs(); UnlockInputs();
UpdateContactInfoVisibility(true); UpdateContactInfoVisibility(true);
ViewModel.EnableSearchInputs = false; ViewModel.EnableSearchInputs = false;
UpdateOrganic();
} }
protected override void ShortcutDelete() { protected override void ShortcutDelete() {
@@ -515,17 +519,17 @@ namespace Elwig.Windows {
if (ViewModel.SelectedMember is not Member m) if (ViewModel.SelectedMember is not Member m)
return; return;
int areaComs = 0, deliveries = 0, credits = 0; int areaCmts = 0, deliveries = 0, credits = 0;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
areaComs = await ctx.AreaCommitments.Where(c => c.MgNr == m.MgNr).CountAsync(); areaCmts = await ctx.AreaCommitments.Where(c => c.MgNr == m.MgNr).CountAsync();
deliveries = await ctx.Deliveries.Where(d => d.MgNr == m.MgNr).CountAsync(); deliveries = await ctx.Deliveries.Where(d => d.MgNr == m.MgNr).CountAsync();
credits = await ctx.Credits.Where(c => c.MgNr == m.MgNr).CountAsync(); credits = await ctx.Credits.Where(c => c.MgNr == m.MgNr).CountAsync();
} }
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits); var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaCmts, deliveries, credits);
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs); await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaCmts);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
InteractionService.ShowDbException("Mitglied löschen", exc); InteractionService.ShowDbException("Mitglied löschen", exc);
@@ -578,8 +582,8 @@ namespace Elwig.Windows {
} }
private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) { private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) {
ViewModel.TransferPredecessorAreaComs = null; ViewModel.TransferPredecessorAreaCmts = null;
ViewModel.CancelAreaComs = null; ViewModel.CancelAreaCmts = null;
if (IsEditing) { if (IsEditing) {
RefreshInputs(); RefreshInputs();
} else if (IsCreating) { } else if (IsCreating) {
@@ -593,8 +597,8 @@ namespace Elwig.Windows {
IsEditing = false; IsEditing = false;
IsCreating = false; IsCreating = false;
MemberList.IsEnabled = true; MemberList.IsEnabled = true;
ViewModel.TransferPredecessorAreaComs = null; ViewModel.TransferPredecessorAreaCmts = null;
ViewModel.CancelAreaComs = null; ViewModel.CancelAreaCmts = null;
HideSaveResetCancelButtons(); HideSaveResetCancelButtons();
ShowNewEditDeleteButtons(); ShowNewEditDeleteButtons();
RefreshInputs(); RefreshInputs();
@@ -608,7 +612,7 @@ namespace Elwig.Windows {
} }
private void AreaCommitmentButton_Click(object sender, RoutedEventArgs evt) { private void AreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
App.FocusMemberAreaComs(ViewModel.SelectedMember!.MgNr); App.FocusMemberAreaCmts(ViewModel.SelectedMember!.MgNr);
} }
private void DeliveryButton_Click(object sender, RoutedEventArgs evt) { private void DeliveryButton_Click(object sender, RoutedEventArgs evt) {
@@ -807,6 +811,10 @@ namespace Elwig.Windows {
await App.Client.UpdateValues(); await App.Client.UpdateValues();
} }
private async void Menu_BusinessShares_SavePending_Click(object sender, RoutedEventArgs evt) {
await MemberBusinessSharesService.GenerateMemberMovements(MemberBusinessSharesService.ExportSubject.Pending, ExportMode.SaveList);
}
private void FocusSearchInput(object sender, RoutedEventArgs evt) { private void FocusSearchInput(object sender, RoutedEventArgs evt) {
if (!IsEditing && !IsCreating) { if (!IsEditing && !IsCreating) {
SearchInput.Focus(); SearchInput.Focus();
@@ -918,10 +926,10 @@ namespace Elwig.Windows {
if (ViewModel.MgNr == mgnr) if (ViewModel.MgNr == mgnr)
return; return;
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var areaComs = await ctx.AreaCommitments var areaCmts = await ctx.AreaCommitments
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason)) .Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
.ToListAsync(); .ToListAsync();
if (areaComs.Count == 0) if (areaCmts.Count == 0)
return; return;
var oldMember = await ctx.FetchMembers(mgnr).SingleAsync(); var oldMember = await ctx.FetchMembers(mgnr).SingleAsync();
@@ -929,10 +937,10 @@ namespace Elwig.Windows {
$"{ViewModel.Prefix}{(!string.IsNullOrWhiteSpace(ViewModel.Prefix) ? " " : "")}" + $"{ViewModel.Prefix}{(!string.IsNullOrWhiteSpace(ViewModel.Prefix) ? " " : "")}" +
$"{ViewModel.GivenName}{(!string.IsNullOrWhiteSpace(ViewModel.GivenName) ? " " : "")}" + $"{ViewModel.GivenName}{(!string.IsNullOrWhiteSpace(ViewModel.GivenName) ? " " : "")}" +
$"{ViewModel.Suffix}{(!string.IsNullOrWhiteSpace(ViewModel.Suffix) ? " " : "")}"; $"{ViewModel.Suffix}{(!string.IsNullOrWhiteSpace(ViewModel.Suffix) ? " " : "")}";
var d = new AreaComTransferDialog(oldMember.AdministrativeName, newName, areaComs.Count, areaComs.Sum(c => c.Area)); var d = new AreaCmtTransferDialog(oldMember.AdministrativeName, newName, areaCmts.Count, areaCmts.Sum(c => c.Area));
if (d.ShowDialog() != true) if (d.ShowDialog() != true)
return; return;
ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason; ViewModel.TransferPredecessorAreaCmts = d.SuccessorSeason;
if (IsEditing) if (IsEditing)
SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save
UpdateButtons(); UpdateButtons();
@@ -966,38 +974,27 @@ namespace Elwig.Windows {
} }
} }
private void OrganicButton_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return;
var url = "https://www.easy-cert.com/htm/suchergebnis.htm?" +
//$"CustomerNumber={m.LfbisNr}&" +
$"Name={(m.BillingAddress?.FullName ?? m.FullName).Replace(' ', '+')}&" +
$"PostalCode={(m.BillingAddress?.PostalDest ?? m.PostalDest).AtPlz?.Plz}";
Process.Start(new ProcessStartInfo(url) {
UseShellExecute = true,
});
}
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) { private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m || m.PredecessorMgNr == null) return; if (ViewModel.SelectedMember is not Member m || m.PredecessorMgNr == null) return;
FocusMember((int)m.PredecessorMgNr); FocusMember((int)m.PredecessorMgNr);
} }
private async void ActiveInput_Changed(object sender, RoutedEventArgs evt) { private async void ActiveInput_Changed(object sender, RoutedEventArgs evt) {
CheckBox_Changed(sender, evt);
if (MemberList.SelectedItem is not Member m) if (MemberList.SelectedItem is not Member m)
return; return;
if ((IsEditing || IsCreating) && ViewModel.IsActive == false && ViewModel.MgNr is int mgnr) { if ((IsEditing || IsCreating) && ViewModel.IsActive == false && ViewModel.MgNr is int mgnr) {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var areaComs = await ctx.AreaCommitments var areaCmts = await ctx.AreaCommitments
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason)) .Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
.ToListAsync(); .ToListAsync();
if (areaComs.Count > 0) { if (areaCmts.Count > 0) {
var d = new AreaComTransferDialog(m.AdministrativeName, areaComs.Count, areaComs.Sum(c => c.Area)); var d = new AreaCmtTransferDialog(m.AdministrativeName, areaCmts.Count, areaCmts.Sum(c => c.Area));
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
ViewModel.CancelAreaComs = d.CancelSeason; ViewModel.CancelAreaCmts = d.CancelSeason;
} }
} }
} }
CheckBox_Changed(sender, evt);
} }
private void JuridicalPersonInput_Changed(object sender, RoutedEventArgs evt) { private void JuridicalPersonInput_Changed(object sender, RoutedEventArgs evt) {
@@ -1020,5 +1017,100 @@ namespace Elwig.Windows {
ValidateRequiredInputs(); ValidateRequiredInputs();
UpdateButtons(); UpdateButtons();
} }
new protected void AddressInput_TextChanged(object sender, TextChangedEventArgs? evt) {
if ((IsCreating || IsEditing) && sender is TextBox b) {
InputTextChanged(b, (i, r) => Validator.CheckAddress(i, r, b == BillingAddressInput ? ViewModel.BillingOrt?.Ort.Name : ViewModel.Ort?.Ort.Name));
} else {
TextBox_TextChanged(sender, evt);
}
}
private void OrtInput_SelectionChanged(object sender, SelectionChangedEventArgs? evt) {
if (!IsCreating && !IsEditing)
return;
if (sender == BillingOrtInput) {
InputTextChanged(BillingAddressInput, (i, r) => Validator.CheckAddress(i, r, ViewModel.BillingOrt?.Ort.Name));
} else {
InputTextChanged(AddressInput, (i, r) => Validator.CheckAddress(i, r, ViewModel.Ort?.Ort.Name));
}
}
private void OrganicInput_Changed(object sender, RoutedEventArgs evt) {
CheckBox_Changed(sender, evt);
if (IsEditing || IsCreating) {
UpdateOrganic();
}
}
private new void LfbisNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
base.LfbisNrInput_TextChanged(sender, evt);
if (IsEditing || IsCreating) {
UpdateOrganic();
}
}
private void UpdateOrganic() {
if (!ViewModel.IsOrganic || string.IsNullOrWhiteSpace(ViewModel.LfbisNr) || !GetInputValid(LfbisNrInput)) {
ViewModel.OrganicState = null;
ViewModel.OrganicColor = Brushes.Black;
ViewModel.OrganicDetails = "-";
ViewModel.OrganicToolTip = null;
return;
} else {
ViewModel.OrganicState = null;
ViewModel.OrganicColor = Brushes.Black;
ViewModel.OrganicToolTip = null;
ViewModel.OrganicDetails = "...";
var lfbisNr = ViewModel.LfbisNr;
Utils.RunBackground("Bio-Zertifikatsdaten laden", async () => {
if (App.MainDispatcher == null) return;
var certs = await OrganicService.FetchTracesCertificates(lfbisNr: lfbisNr);
await App.MainDispatcher.BeginInvoke(() => {
if (certs.Length == 0) {
ViewModel.FillOrganicInputs(null);
} else {
var cert = certs[0];
ViewModel.FillOrganicInputs(cert);
ViewModel.OrganicAuthorityCode = cert.AuthorityCode;
ViewModel.OrganicOperatorId = cert.OperatorId;
}
});
});
}
}
private void OrganicTracesButton_Click(object sender, RoutedEventArgs evt) {
string? url = null;
if ((IsCreating || IsEditing) && !string.IsNullOrWhiteSpace(ViewModel.LfbisNr) && GetInputValid(LfbisNrInput)) {
url = OrganicService.GetTracesSearchUrl(lfbisNr: ViewModel.LfbisNr);
} else if (ViewModel.SelectedMember is Member m) {
url = OrganicService.GetTracesSearchUrl(m);
}
if (url != null)
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
}
private void OrganicEasyCertButton_Click(object sender, RoutedEventArgs evt) {
string? url = null;
if ((IsCreating || IsEditing) && !string.IsNullOrWhiteSpace(ViewModel.LfbisNr) && GetInputValid(LfbisNrInput)) {
url = OrganicService.GetEasyCertSearchUrl(ViewModel.LfbisNr);
} else if (ViewModel.SelectedMember is Member m && m.LfbisNr != null) {
url = OrganicService.GetEasyCertSearchUrl(m.LfbisNr);
}
if (url != null)
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
}
private void OrganicBiocButton_Click(object sender, RoutedEventArgs evt) {
string? url = null;
if ((IsCreating || IsEditing) && !string.IsNullOrWhiteSpace(ViewModel.LfbisNr) && GetInputValid(LfbisNrInput)) {
url = OrganicService.GetBiocSearchUrl(ViewModel.LfbisNr);
} else if (ViewModel.SelectedMember is Member m && m.LfbisNr != null) {
url = OrganicService.GetBiocSearchUrl(m.LfbisNr);
}
if (url != null)
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
}
} }
} }
@@ -173,8 +173,11 @@
Margin="0,100,10,0" Width="78" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right" Margin="0,100,10,0" Width="78" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right"
TextChanged="DateNoticeInput_TextChanged" LostFocus="DateInput_LostFocus"/> TextChanged="DateNoticeInput_TextChanged" LostFocus="DateInput_LostFocus"/>
<CheckBox x:Name="HasCompanySignedInput" IsChecked="{Binding CompanyHasSigned, Mode=TwoWay}" Content="Von WG unterfertigt"
Margin="88,105,10,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
<CheckBox x:Name="HasMemberSignedInput" IsChecked="{Binding MemberHasSigned, Mode=TwoWay}" Content="Von Mg. unterfertigt" <CheckBox x:Name="HasMemberSignedInput" IsChecked="{Binding MemberHasSigned, Mode=TwoWay}" Content="Von Mg. unterfertigt"
Margin="88,105,10,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="TOp" Margin="88,135,10,0" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/> Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
<Label Content="Wirksam:" Margin="10,130,0,0" Grid.Column="0"/> <Label Content="Wirksam:" Margin="10,130,0,0" Grid.Column="0"/>
+3 -3
View File
@@ -99,9 +99,9 @@ namespace Elwig.Windows {
var allMembers = await ctx.Members.Where(m => m.DefaultKgNr == k.KgNr).CountAsync(); var allMembers = await ctx.Members.Where(m => m.DefaultKgNr == k.KgNr).CountAsync();
StatusDefaultKgs.Text += $"{activeMembers:N0} ({allMembers:N0})"; StatusDefaultKgs.Text += $"{activeMembers:N0} ({allMembers:N0})";
var year = Utils.CurrentNextSeason; var year = Utils.CurrentNextSeason;
var activeAreaComs = await Utils.ActiveAreaCommitments(ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr), year).CountAsync(); var activeAreaCmts = await Utils.ActiveAreaCommitments(ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr), year).CountAsync();
var allAreaComs = await ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr).CountAsync(); var allAreaCmts = await ctx.AreaCommitments.Where(c => c.Contract.KgNr == k.KgNr).CountAsync();
StatusAreaCommitments.Text += $"{activeAreaComs:N0} ({allAreaComs:N0})"; StatusAreaCommitments.Text += $"{activeAreaCmts:N0} ({allAreaCmts:N0})";
var deliveryParts = await ctx.DeliveryParts.Where(p => p.KgNr == k.KgNr).CountAsync(); var deliveryParts = await ctx.DeliveryParts.Where(p => p.KgNr == k.KgNr).CountAsync();
var deliveries = await ctx.Deliveries.Where(d => d.Parts.Any(p => p.KgNr == k.KgNr)).CountAsync(); var deliveries = await ctx.Deliveries.Where(d => d.Parts.Any(p => p.KgNr == k.KgNr)).CountAsync();
StatusDeliveries.Text += $"{deliveries:N0} ({deliveryParts:N0})"; StatusDeliveries.Text += $"{deliveries:N0} ({deliveryParts:N0})";
@@ -54,9 +54,9 @@ namespace Elwig.Windows {
var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t); var contracts = await ctx.AreaCommitmentTypes.ToDictionaryAsync(t => t.VtrgId, t => t);
var (tbl1, _, _) = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year); var (tbl1, _, _) = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, Year);
var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, Year); var tbl2 = await AreaCmtUnderDeliveryData.ForSeason(ctx.AreaCmtUnderDeliveryRows, Year);
var weight = tbl1.Rows.ToDictionary(r => r.MgNr, r => r.WeightTotal); var weight = tbl1.Rows.ToDictionary(r => r.MgNr, r => r.WeightTotal);
var areaComs = tbl2.Rows.ToDictionary(r => r.MgNr, r => r.VtrgIds.Zip(r.UnderDeliveries).ToDictionary(r => r.First, r => r.Second)); var areaCmts = tbl2.Rows.ToDictionary(r => r.MgNr, r => r.VtrgIds.Zip(r.UnderDeliveries).ToDictionary(r => r.First, r => r.Second));
CustomPayments = await ctx.CustomPayments.Where(p => p.Year == Year).ToDictionaryAsync(p => p.MgNr, p => p); CustomPayments = await ctx.CustomPayments.Where(p => p.Year == Year).ToDictionaryAsync(p => p.MgNr, p => p);
var history = await ctx.MemberHistory var history = await ctx.MemberHistory
@@ -93,7 +93,7 @@ namespace Elwig.Windows {
(season.PenaltyPerShareAmount * Math.Floor(m.OverUnder / season.MinKgPerShare ?? 0m) ?? 0) + (season.PenaltyPerShareAmount * Math.Floor(m.OverUnder / season.MinKgPerShare ?? 0m) ?? 0) +
(m.Weight == 0 ? (-season.PenaltyNone ?? 0) + (-season.PenaltyPerShareNone * m.SharesActive ?? 0) : 0) (m.Weight == 0 ? (-season.PenaltyNone ?? 0) + (-season.PenaltyPerShareNone * m.SharesActive ?? 0) : 0)
: (decimal?)null, : (decimal?)null,
PenaltyAc = areaComs.TryGetValue(m.MgNr, out var c) ? c.Select(r => { PenaltyAc = areaCmts.TryGetValue(m.MgNr, out var c) ? c.Select(r => {
var con = contracts[r.Key]; var con = contracts[r.Key];
return (r.Value.Kg * con.PenaltyPerKg ?? 0) + (r.Value.Kg < 0 ? con.PenaltyAmount ?? 0 : 0) + (r.Value.Percent == -100 ? con.PenaltyNone ?? 0 : 0); return (r.Value.Kg * con.PenaltyPerKg ?? 0) + (r.Value.Kg < 0 ? con.PenaltyAmount ?? 0 : 0) + (r.Value.Percent == -100 ? con.PenaltyNone ?? 0 : 0);
}).Sum() : (decimal?)null, }).Sum() : (decimal?)null,
+2 -2
View File
@@ -13,7 +13,7 @@ About
**Product:** Elwig **Product:** Elwig
**Description:** Electronic Management for Vintners' Cooperatives **Description:** Electronic Management for Vintners' Cooperatives
**Type:** ERP system **Type:** ERP system
**Version:** 1.1.2.2 ([Changelog](./CHANGELOG.md)) **Version:** 1.2.0.0 ([Changelog](./CHANGELOG.md))
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE) **License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
**Website:** https://elwig.at/ **Website:** https://elwig.at/
**Source code:** https://git.necronda.net/winzer/elwig **Source code:** https://git.necronda.net/winzer/elwig
@@ -33,7 +33,7 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
**Produkt:** Elwig **Produkt:** Elwig
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung **Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
**Typ:** Warenwirtschaftssystem (ERP-System) **Typ:** Warenwirtschaftssystem (ERP-System)
**Version:** 1.1.2.2 ([Änderungsprotokoll](./CHANGELOG.md)) **Version:** 1.2.0.0 ([Änderungsprotokoll](./CHANGELOG.md))
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE) **Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
**Website:** https://elwig.at/ **Website:** https://elwig.at/
**Quellcode:** https://git.necronda.net/winzer/elwig **Quellcode:** https://git.necronda.net/winzer/elwig

Some files were not shown because too many files have changed in this diff Show More