Compare commits
36
Commits
v1.1.2.1
...
895969b6ae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
895969b6ae | ||
|
|
54126814f3 | ||
|
|
b886abc632 | ||
|
|
cba949d2eb | ||
|
|
c2bc5b221a | ||
|
|
5845693f17 | ||
|
|
aea7c39734 | ||
|
|
c54a998c96 | ||
|
|
5bb84944bc | ||
|
|
34b40535a6 | ||
|
|
3dca099248 | ||
|
|
155a599878 | ||
|
|
fda337c3cb | ||
|
|
d8126e254d | ||
|
|
96441a6701 | ||
|
|
03867bcd74 | ||
|
|
83dfde9203 | ||
|
|
805c5efda8 | ||
|
|
e86edc080a | ||
|
|
0d5d1d4d3d | ||
|
|
ffd3dc9631 | ||
|
|
d592fef352 | ||
|
|
f2b84053e6 | ||
|
|
7fef895491 | ||
|
|
0e9121c462 | ||
|
|
15e191d74e | ||
|
|
abf06c558f | ||
|
|
6436762e8d | ||
|
|
6441fa4f50 | ||
|
|
6bed370eba | ||
|
|
4cc33b56c8 | ||
|
|
f4cc443521 | ||
|
|
8ba051198f | ||
|
|
fea779bd95 | ||
|
|
e66780ccd0 | ||
|
|
cc01f92005 |
No files matched your search
@@ -2,6 +2,30 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
[v1.1.2.2][v1.1.2.2] (2026-09-14) {#v1.1.2.2}
|
||||
---------------------------------------------
|
||||
|
||||
### Neue Funktionen {#v1.1.2.2-features}
|
||||
|
||||
* Bei einigen Fenstern werden in den Titeln nun die aktiven Filter der Suche angezeigt. (fea779bd95)
|
||||
* Im Lieferungen-Fenster (`DeliveryAdminWindow`) ist es nun möglich die Tara nachträglich zu korrigieren. (8ba051198f, 6436762e8d)
|
||||
|
||||
### Behobene Fehler {#v1.1.2.2-bugfixes}
|
||||
|
||||
* Bei Lieferscheinen (`DeliveryNote`) hat bei Anmerkungen zu Teil-Lfrg. ein `:` gefehlt.
|
||||
Außerdem wurden Seitenumbrüche so platziert, dass sie nicht mehr innerhalb einer Teil-Lfrg. liegen. (e66780ccd0, f4cc443521)
|
||||
|
||||
### Sonstiges {#v1.1.2.2-misc}
|
||||
|
||||
* Bei Datenbank-Fehler sind die Fehlermeldungen nun genauer bzw. auf deutsch übersetzt. (cc01f92005)
|
||||
* Im Mitglieder-Fenster (`MemberAdminWindow`) wurden Überschriften und Tooltips leicht angepasst. (6441fa4f50)
|
||||
* Abhängigkeiten aktualisiert. (4cc33b56c8, 6bed370eba)
|
||||
|
||||
[v1.1.2.2]: https://git.necronda.net/winzer/elwig/releases/tag/v1.1.2.2
|
||||
|
||||
|
||||
|
||||
|
||||
[v1.1.2.1][v1.1.2.1] (2026-08-27) {#v1.1.2.1}
|
||||
---------------------------------------------
|
||||
|
||||
|
||||
+25
-18
@@ -18,12 +18,13 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Elwig {
|
||||
public partial class App : Application {
|
||||
|
||||
protected static App CurrentApp;
|
||||
public static App CurrentApp;
|
||||
public static int NumWindows => CurrentApp.Windows.Count;
|
||||
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);
|
||||
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();
|
||||
Shutdown();
|
||||
ShutdownNow();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +120,7 @@ namespace Elwig {
|
||||
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))
|
||||
await BackupService.RestoreDatabase();
|
||||
Shutdown();
|
||||
ShutdownNow();
|
||||
return;
|
||||
}
|
||||
BranchNum = branches.Count;
|
||||
@@ -133,7 +134,7 @@ namespace Elwig {
|
||||
Utils.RunBackground("PDF Initialization", async () => Pdf.Init());
|
||||
Utils.RunBackground("JSON Schema Initialization", BillingData.Init);
|
||||
|
||||
if (Config.BackupAuto) {
|
||||
if (Config.BackupAuto && !Config.Debug) {
|
||||
Utils.RunBackground("Automatisches Backup", async () => {
|
||||
Directory.CreateDirectory(Config.BackupPath);
|
||||
await Task.Delay(500);
|
||||
@@ -183,7 +184,7 @@ namespace Elwig {
|
||||
if (Config.Branch != null) {
|
||||
if (!branches.ContainsKey(Config.Branch.ToLower())) {
|
||||
InteractionService.ShowError("Ungültige Zweigstelle", "Ungültige Zweigstelle in Konfigurationsdatei!");
|
||||
Shutdown();
|
||||
ShutdownNow();
|
||||
} else {
|
||||
SetBranch(branches[Config.Branch.ToLower()]);
|
||||
}
|
||||
@@ -191,7 +192,7 @@ namespace Elwig {
|
||||
SetBranch(branches.First().Value);
|
||||
} else {
|
||||
InteractionService.ShowError("Ungültige Zweigstelle", "Erkennen der lokalen Zweigstelle nicht möglich!");
|
||||
Shutdown();
|
||||
ShutdownNow();
|
||||
}
|
||||
|
||||
if (Config.WeighingMode == null) {
|
||||
@@ -210,21 +211,29 @@ namespace Elwig {
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public async Task OnClosing() {
|
||||
try {
|
||||
await BackupService.TryDatabaseBackup();
|
||||
} catch (Exception exc) {
|
||||
InteractionService.ShowException("Automatisches Backup", exc);
|
||||
}
|
||||
public static void ShutdownNow() {
|
||||
ForceShutdown = true;
|
||||
Current.Shutdown();
|
||||
}
|
||||
|
||||
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();
|
||||
foreach (var s in EventScales) {
|
||||
s.Dispose();
|
||||
}
|
||||
Pdf.Cleanup();
|
||||
base.OnExit(evt);
|
||||
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
public static void SetBranch(Branch b) {
|
||||
@@ -335,8 +344,7 @@ namespace Elwig {
|
||||
await MainDispatcher.BeginInvoke(() => {
|
||||
var d = new UpdateDialog(latest.Value.Version, latest.Value.Url, latest.Value.Size);
|
||||
if (d.ShowDialog() == true) {
|
||||
ForceShutdown = true;
|
||||
Current.Shutdown();
|
||||
ShutdownNow();
|
||||
}
|
||||
});
|
||||
} else if (showAlert) {
|
||||
@@ -354,8 +362,7 @@ namespace Elwig {
|
||||
await Database.Import(filename);
|
||||
});
|
||||
InteractionService.ShowInformation("Datenbank ersetzen", "Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!");
|
||||
ForceShutdown = true;
|
||||
Current.Shutdown();
|
||||
ShutdownNow();
|
||||
} catch (Exception exc) {
|
||||
InteractionService.ShowException("Datenbank ersetzen", "Fehler beim Ersetzen", exc);
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<Window x:Class="Elwig.Dialogs.ManualWeighingDialog"
|
||||
AutomationProperties.AutomationId="ManualWeighingDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Elwig.Dialogs"
|
||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
FocusManager.FocusedElement="{Binding ElementName=WeightInput}"
|
||||
@@ -37,11 +39,9 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="Gewicht:" Margin="10,20,10,10"/>
|
||||
<Grid Grid.Column="1" Width="70" Height="25" Margin="0,20,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
|
||||
<TextBox x:Name="WeightInput" TextAlignment="Right" Padding="2,2,17,2"
|
||||
TextChanged="WeightInput_TextChanged"/>
|
||||
<Label Content="kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10" Padding="2,4,2,4"/>
|
||||
</Grid>
|
||||
<ctrl:UnitTextBox x:Name="WeightInput" Grid.Column="1" Width="62" Height="25" Unit="kg"
|
||||
Margin="0,20,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" Padding="2"
|
||||
TextChanged="WeightInput_TextChanged"/>
|
||||
|
||||
<Label Content="Grund:" Margin="10,50,10,10"/>
|
||||
<TextBox x:Name="ReasonInput" Grid.Column="1" Margin="0,50,10,10"
|
||||
|
||||
@@ -6,8 +6,8 @@ using System.Windows.Controls;
|
||||
namespace Elwig.Dialogs {
|
||||
public partial class ManualWeighingDialog : Window {
|
||||
|
||||
public int Weight = 0;
|
||||
public string? Reason = null;
|
||||
public int Weight { get; private set; }
|
||||
public string? Reason { get; private set; }
|
||||
|
||||
public ManualWeighingDialog(string? reason = null) {
|
||||
InitializeComponent();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
<Window x:Class="Elwig.Dialogs.TareCorrectionDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Elwig.Dialogs"
|
||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||
ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
FocusManager.FocusedElement="{Binding ElementName=TargetTareInput}"
|
||||
Title="Tara korrigieren" Height="170" Width="300">
|
||||
<Window.Resources>
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="Padding" Value="2,4,2,4"/>
|
||||
<Setter Property="Height" Value="25"/>
|
||||
</Style>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Padding" Value="2"/>
|
||||
<Setter Property="Height" Value="25"/>
|
||||
<Setter Property="TextWrapping" Value="NoWrap"/>
|
||||
</Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="HorizontalAlignment" Value="Right"/>
|
||||
<Setter Property="VerticalAlignment" Value="Bottom"/>
|
||||
<Setter Property="Width" Value="100"/>
|
||||
<Setter Property="Height" Value="25"/>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="70"/>
|
||||
<ColumnDefinition Width="3*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="Ist-Tara:" Margin="10,20,0,10" Grid.Column="1"/>
|
||||
<ctrl:UnitTextBox x:Name="ActualTareInput" Grid.Column="2" Width="56" Height="25" Unit="kg" IsReadOnly="True"
|
||||
Margin="0,20,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" Padding="2"
|
||||
TextChanged="TareInput_TextChanged"/>
|
||||
|
||||
<Label Content="Soll-Tara:" Margin="10,50,0,10" Grid.Column="1"/>
|
||||
<ctrl:UnitTextBox x:Name="TargetTareInput" Grid.Column="2" Width="56" Height="25" Unit="kg"
|
||||
Margin="0,50,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" FontSize="14" Padding="2"
|
||||
TextChanged="TareInput_TextChanged"/>
|
||||
|
||||
<Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" Grid.ColumnSpan="3" IsEnabled="False" IsDefault="True"
|
||||
Click="ConfirmButton_Click"/>
|
||||
<Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" Grid.ColumnSpan="3" IsCancel="True"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
@@ -0,0 +1,38 @@
|
||||
using Elwig.Helpers;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace Elwig.Dialogs {
|
||||
public partial class TareCorrectionDialog : Window {
|
||||
|
||||
public int ActualTare { get; private set; }
|
||||
public int TargetTare { get; private set; }
|
||||
|
||||
public TareCorrectionDialog(int? actualTare, int? targetTare = null) {
|
||||
InitializeComponent();
|
||||
ActualTare = actualTare ?? 0;
|
||||
TargetTare = targetTare ?? actualTare ?? 0;
|
||||
ActualTareInput.IsReadOnly = actualTare != null;
|
||||
ActualTareInput.Text = ActualTare.ToString();
|
||||
TargetTareInput.Text = TargetTare.ToString();
|
||||
TargetTareInput.SelectAll();
|
||||
}
|
||||
|
||||
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
|
||||
DialogResult = true;
|
||||
ActualTare = int.Parse(ActualTareInput.Text);
|
||||
TargetTare = int.Parse(TargetTareInput.Text);
|
||||
Close();
|
||||
}
|
||||
|
||||
private void UpdateButtons() {
|
||||
ConfirmButton.IsEnabled = ActualTareInput.Text.Length > 0 && TargetTareInput.Text.Length > 0;
|
||||
}
|
||||
|
||||
private void TareInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
if (sender is not TextBox b) return;
|
||||
Validator.CheckInteger(b, true, 4);
|
||||
UpdateButtons();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,23 +30,27 @@ namespace Elwig.Documents {
|
||||
get {
|
||||
IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member;
|
||||
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) {
|
||||
var cell = NewCell(text, colspan: colspan).SetPaddingsMM(0.25f, 0.5f, 0.25f, isName ? 1 : 0);
|
||||
if (colspan > 1) {
|
||||
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, center ? 0 : right ? 1 : 0.5f, 0.25f, isName ? 1 : 0);
|
||||
if (colspan == 26) {
|
||||
cell.SetTextAlignment(TextAlignment.CENTER).SetFont(BF)
|
||||
.SetBackgroundColor(new DeviceRgb(0xe0, 0xe0, 0xe0))
|
||||
.SetBorderTop(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
||||
.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;
|
||||
}
|
||||
|
||||
protected Cell NewAsideCell(string text, int colspan = 1, bool isName = false) {
|
||||
return NewAsideCell(new KernedParagraph(text, 10), colspan, isName);
|
||||
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, right, center);
|
||||
}
|
||||
|
||||
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) {
|
||||
base.BeforeRenderBody(doc, pdf);
|
||||
var uid = new KernedParagraph(Member.UstIdNr ?? "-", 10);
|
||||
if (!Member.IsBuchführend) uid.Add(Normal(" ")).Add(Italic("(pauschaliert)"));
|
||||
Aside = new Table(ColsMM(22.5, 42.5))
|
||||
.SetFont(NF).SetFontSize(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))
|
||||
.SetWidth(UnitValue.CreatePointValue(65 * PtInMM)).SetFixedLayout()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||
.SetFont(NF).SetFontSize(10)
|
||||
.SetBorder(new SolidBorder(new DeviceRgb(0x80, 0x80, 0x80), BorderThickness))
|
||||
.AddCell(NewAsideCell("Mitglied", 2))
|
||||
.AddCell(NewAsideCell("Mitglieds-Nr.:", isName: true)).AddCell(NewAsideCell($"{Member.MgNr}"))
|
||||
.AddCell(NewAsideCell("Betriebs-Nr.:", isName: true)).AddCell(NewAsideCell(Member.LfbisNr ?? ""))
|
||||
.AddCell(NewAsideCell("UID:", isName: true)).AddCell(NewAsideCell(uid));
|
||||
.AddCell(NewAsideCell("Mitglied", 26));
|
||||
if (Member.IsOrganic) {
|
||||
Aside
|
||||
.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.IsBuchführend ? "(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.IsBuchführend ? "(buchführend)" : "(pauschaliert)")), 10, center: true));
|
||||
}
|
||||
}
|
||||
|
||||
protected void RenderAddress(Canvas canvas, Rectangle pageSize) {
|
||||
@@ -122,11 +137,15 @@ namespace Elwig.Documents {
|
||||
return new KernedParagraph(10)
|
||||
.AddAll(Utils.GenerateFooter("\n", " \u00b7 ")
|
||||
.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.EmailAddress != null ? link1 : null)
|
||||
.Item(c.Website != null ? link2 : null)
|
||||
.Item("Betriebs-Nr.", c.LfbisNr).Item("Bio-KSt.", c.OrganicAuthority).NextLine()
|
||||
.Item(c.Address).Item($"{c.Plz} {c.Ort}").Item("Österreich").NextGroup()
|
||||
.Item("Tel.", c.PhoneNr).Item("Fax", c.FaxNr).NextGroup()
|
||||
.Item(c.EmailAddress != null ? link1 : null).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)
|
||||
.RebalanceLines()
|
||||
.ToLeafElements());
|
||||
}
|
||||
|
||||
|
||||
@@ -125,10 +125,10 @@ namespace Elwig.Documents {
|
||||
|
||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
base.BeforeRenderBody(doc, pdf);
|
||||
Aside?.AddCell(NewAsideCell("Gutschrift", 2))
|
||||
.AddCell(NewAsideCell("TG-Nr.:", isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-"))
|
||||
.AddCell(NewAsideCell("Datum:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}"))
|
||||
.AddCell(NewAsideCell("Überw. am:", isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.TransferDate:dd.MM.yyyy}"));
|
||||
Aside?.AddCell(NewAsideCell("Gutschrift", 26))
|
||||
.AddCell(NewAsideCell("Tr.-Gutschr.-Nr.:", 12, isName: true)).AddCell(NewAsideCell(Payment?.Credit != null ? $"{Payment.Credit.Year}/{Payment.Credit.TgNr:000}" : "-", 14))
|
||||
.AddCell(NewAsideCell("Datum:", 12, isName: true)).AddCell(NewAsideCell($"{Payment?.Variant.Date:dd.MM.yyyy}", 14))
|
||||
.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) {
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace Elwig.Documents {
|
||||
_year = year;
|
||||
ShowDateAndLocation = true;
|
||||
UseBillingAddress = true;
|
||||
DocumentId = $"Anl.-Best. {_year}/{m.MgNr}";
|
||||
DocumentId = $"Anlfrg.-Bstng. {_year}/{m.MgNr}";
|
||||
Data = data;
|
||||
}
|
||||
|
||||
@@ -55,10 +55,10 @@ namespace Elwig.Documents {
|
||||
base.BeforeRenderBody(doc, pdf);
|
||||
var firstDay = Data.Rows.MinBy(r => r.Date)?.Date;
|
||||
var lastDay = Data.Rows.MaxBy(r => r.Date)?.Date;
|
||||
Aside?.AddCell(NewAsideCell("Saison", 2))
|
||||
.AddCell(NewAsideCell("Lieferungen:", isName: true)).AddCell(NewAsideCell($"{Data.Rows.DistinctBy(r => r.LsNr).Count():N0} (Teil-Lfrg.: {Data.RowNum:N0})"))
|
||||
.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("Menge:", isName: true)).AddCell(NewAsideCell($"{MemberStats.Sum(s => s.Weight):N0} kg"));
|
||||
Aside?.AddCell(NewAsideCell("Saison", 26))
|
||||
.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:", 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:", 12, isName: true)).AddCell(NewAsideCell($"{MemberStats.Sum(s => s.Weight):N0} kg", 14));
|
||||
}
|
||||
|
||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
|
||||
@@ -72,10 +72,10 @@ namespace Elwig.Documents {
|
||||
|
||||
protected override void BeforeRenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
base.BeforeRenderBody(doc, pdf);
|
||||
Aside?.AddCell(NewAsideCell("Lieferung", 2))
|
||||
.AddCell(NewAsideCell("LS-Nr.:", isName: true)).AddCell(NewAsideCell(Delivery.LsNr))
|
||||
.AddCell(NewAsideCell("Datum/Zeit:", isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}"))
|
||||
.AddCell(NewAsideCell("Zweigstelle:", isName: true)).AddCell(NewAsideCell(Delivery.Branch.Name));
|
||||
Aside?.AddCell(NewAsideCell("Lieferung", 26))
|
||||
.AddCell(NewAsideCell("Lieferschein-Nr.:", 12, isName: true)).AddCell(NewAsideCell(Delivery.LsNr, 14))
|
||||
.AddCell(NewAsideCell("Datum/Zeit:", 12, isName: true)).AddCell(NewAsideCell($"{Delivery.Date:dd.MM.yyyy} / {Delivery.Time:HH:mm}", 14))
|
||||
.AddCell(NewAsideCell("Zweigstelle:", 12, isName: true)).AddCell(NewAsideCell(Delivery.Branch.Name, 14));
|
||||
}
|
||||
|
||||
protected override void RenderBody(iText.Layout.Document doc, PdfDocument pdf) {
|
||||
@@ -121,7 +121,7 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
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()
|
||||
.SetBorder(Border.NO_BORDER).SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||
|
||||
@@ -130,15 +130,16 @@ namespace Elwig.Documents {
|
||||
.AddHeaderCell(NewTh("Attribut", colspan: 2, rowspan: 2, left: true))
|
||||
.AddHeaderCell(NewTh("Qualitätsstufe", rowspan: 2, left: true))
|
||||
.AddHeaderCell(NewTh("Gradation", colspan: 2))
|
||||
.AddHeaderCell(NewTh("Menge"))
|
||||
.AddHeaderCell(NewTh("Menge").SetPaddingRight(0))
|
||||
.AddHeaderCell(NewTh("[°Oe]", 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)) {
|
||||
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()
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE);
|
||||
.SetBorderCollapse(BorderCollapsePropertyValue.COLLAPSE)
|
||||
.SetKeepTogether(true);
|
||||
|
||||
int rowspan = 1 + (part.Cultivation != null ? 1 : 0) + 1 + part.Modifiers.Count() + 1 + (part.Comment != null ? 1 : 0) + (part.Temperature != null || part.Acid != null ? 1 : 0);
|
||||
sub.AddCell(NewDeliveryMainTd($"{part.DPNr:N0}", center: true))
|
||||
@@ -147,11 +148,14 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewDeliveryMainTd(part.Quality.Name))
|
||||
.AddCell(NewDeliveryMainTd($"{part.Oe:N0}", 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) {
|
||||
var cult = new KernedParagraph(8);
|
||||
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())
|
||||
.AddCell(NewTd(cult, colspan: 5))
|
||||
.AddCell(NewTd(colspan: 3));
|
||||
@@ -196,9 +200,17 @@ namespace Elwig.Documents {
|
||||
.Add(Italic("Brutto:"))
|
||||
.Add(Normal($" {info.Gross:N0} kg \u2013 "))
|
||||
.Add(Italic("Tara:"))
|
||||
.Add(Normal($" {info.Tare:N0} kg \u2013 "))
|
||||
.Add(Normal($" {info.Tare:N0} kg "));
|
||||
if (info.TareCorrection != null && info.TareCorrection != 0)
|
||||
weighing.Add(Bold($"(Korr.: {Utils.GetSign(info.TareCorrection.Value)}{Math.Abs(info.TareCorrection.Value)} kg)")).Add(" ");
|
||||
weighing
|
||||
.Add(Normal("\u2013 "))
|
||||
.Add(Italic("Netto:"))
|
||||
.Add(Normal($" {info.Net:N0} kg \u2013 "))
|
||||
.Add(Normal($" {info.Net:N0} kg "));
|
||||
if (info.TareCorrection != null && info.TareCorrection != 0)
|
||||
weighing.Add(Normal($"({Utils.GetSign(-info.TareCorrection.Value)}{Math.Abs(info.TareCorrection.Value)} kg) "));
|
||||
weighing
|
||||
.Add(Normal("\u2013 "))
|
||||
.Add(Italic(part.IsNetWeight ? "gerebelt gewogen" : "nicht gerebelt gewogen"));
|
||||
} else {
|
||||
weighing.Add(" ")
|
||||
@@ -210,7 +222,7 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewCell(colspan: 3));
|
||||
if (part.Comment != null) {
|
||||
sub.AddCell(NewCell())
|
||||
.AddCell(NewCell(new KernedParagraph(8).Add(Italic("Anmerkung")).Add(Normal(" " + part.Comment)), colspan: 5))
|
||||
.AddCell(NewCell(new KernedParagraph(8).Add(Italic("Anmerkung:")).Add(Normal(" " + part.Comment)), colspan: 5))
|
||||
.AddCell(NewCell(colspan: 3));
|
||||
}
|
||||
if (part.Temperature != null || part.Acid != null) {
|
||||
@@ -220,7 +232,7 @@ namespace Elwig.Documents {
|
||||
if (part.Temperature != null && part.Acid != null)
|
||||
p.Add(Normal(", "));
|
||||
if (part.Acid != null)
|
||||
p.Add(Italic("Säure")).Add(Normal($" {part.Acid:N1} g/l"));
|
||||
p.Add(Italic("Säure:")).Add(Normal($" {part.Acid:N1} g/l"));
|
||||
sub.AddCell(NewCell())
|
||||
.AddCell(NewCell(p, colspan: 5))
|
||||
.AddCell(NewCell(colspan: 3));
|
||||
@@ -229,10 +241,10 @@ namespace Elwig.Documents {
|
||||
}
|
||||
|
||||
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.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;
|
||||
|
||||
@@ -161,7 +161,8 @@ namespace Elwig.Documents {
|
||||
.AddCell(NewDataTh("Buchführend:", colspan: 2)).AddCell(NewTd(new KernedParagraph(Member.IsBuchführend ? "Ja " : "Nein ", 10)
|
||||
.Add(Normal($"({(Member.IsBuchführend ? 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("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(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))))
|
||||
|
||||
+9
-9
@@ -9,7 +9,7 @@
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<PreserveCompilationContext>true</PreserveCompilationContext>
|
||||
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
|
||||
<Version>1.1.2.1</Version>
|
||||
<Version>1.1.2.2</Version>
|
||||
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<ApplicationManifest>App.manifest</ApplicationManifest>
|
||||
@@ -23,21 +23,21 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="154.0.8021" />
|
||||
<PackageReference Include="bblanchon.PDFium.Win32" Version="156.0.8076" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
|
||||
<PackageReference Include="itext" Version="9.7.0" />
|
||||
<PackageReference Include="itext.bouncy-castle-adapter" Version="9.7.0" />
|
||||
<PackageReference Include="LinqKit" Version="1.3.11" />
|
||||
<PackageReference Include="MailKit" Version="4.17.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.11" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.11" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4129.50" />
|
||||
<PackageReference Include="MailKit" Version="4.18.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.12" />
|
||||
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.4258.31" />
|
||||
<PackageReference Include="NJsonSchema" Version="11.6.1" />
|
||||
<PackageReference Include="ScottPlot.WPF" Version="5.1.59" />
|
||||
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.5" />
|
||||
<PackageReference Include="System.IO.Hashing" Version="10.0.11" />
|
||||
<PackageReference Include="System.IO.Ports" Version="10.0.11" />
|
||||
<PackageReference Include="System.Management" Version="10.0.11" />
|
||||
<PackageReference Include="System.IO.Hashing" Version="10.0.12" />
|
||||
<PackageReference Include="System.IO.Ports" Version="10.0.12" />
|
||||
<PackageReference Include="System.Management" Version="10.0.12" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -170,16 +170,25 @@ namespace Elwig.Helpers {
|
||||
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) {
|
||||
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();
|
||||
return cnx;
|
||||
}
|
||||
|
||||
public static async Task<SqliteConnection> ConnectAsync(string? connectionString = null) {
|
||||
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();
|
||||
return cnx;
|
||||
}
|
||||
@@ -234,6 +243,8 @@ namespace Elwig.Helpers {
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Schedule).AutoInclude();
|
||||
modelBuilder.Entity<DeliveryAncmt>().Navigation(a => a.Variety).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.ToMember).AutoInclude();
|
||||
modelBuilder.Entity<MemberHistory>().Navigation(s => s.Currency).AutoInclude();
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
using Elwig.Services;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Elwig.Helpers {
|
||||
public static class AppDbUpdater {
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -68,11 +71,11 @@ namespace Elwig.Helpers {
|
||||
})
|
||||
.OrderBy(s => s.Item1).ThenBy(s => s.Item2)];
|
||||
|
||||
List<string> toExecute = [];
|
||||
List<(int ToVersion, string File)> toExecute = [];
|
||||
var vers = fromVersion;
|
||||
while (vers < toVersion) {
|
||||
var (_, to, name) = scripts.Last(s => s.From == vers);
|
||||
toExecute.Add(name);
|
||||
toExecute.Add((to, name));
|
||||
vers = to;
|
||||
}
|
||||
if (toExecute.Count == 0)
|
||||
@@ -87,8 +90,11 @@ namespace Elwig.Helpers {
|
||||
await cnx.IntegrityCheck();
|
||||
await cnx.ForeignKeyCheck();
|
||||
|
||||
foreach (var script in toExecute) {
|
||||
foreach (var (to, script) in toExecute) {
|
||||
await cnx.ExecuteEmbeddedScript(asm, script);
|
||||
if (to == 42) {
|
||||
await UpdateDbSchema_41_To_42(cnx);
|
||||
}
|
||||
}
|
||||
|
||||
await cnx.IntegrityCheck();
|
||||
@@ -103,5 +109,57 @@ namespace Elwig.Helpers {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,8 @@ namespace Elwig.Helpers {
|
||||
public string? Bic;
|
||||
public string? UstIdNr;
|
||||
public string? LfbisNr;
|
||||
public string? OrganicAuthority;
|
||||
public string? OrganicOperatorId;
|
||||
public string? OrganicAuthorityCode;
|
||||
|
||||
public string? PhoneNr;
|
||||
public string? FaxNr;
|
||||
@@ -114,7 +115,8 @@ namespace Elwig.Helpers {
|
||||
UstIdNr = parameters.GetValueOrDefault("CLIENT_USTIDNR");
|
||||
Bic = parameters.GetValueOrDefault("CLIENT_BIC");
|
||||
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 {
|
||||
"1" or "TRUE" or "YES" or "JA" => true,
|
||||
@@ -273,7 +275,8 @@ namespace Elwig.Helpers {
|
||||
("CLIENT_USTIDNR", UstIdNr),
|
||||
("CLIENT_BIC", Bic),
|
||||
("CLIENT_IBAN", Iban),
|
||||
("CLIENT_ORGANIC_AUTHORITY", OrganicAuthority),
|
||||
("CLIENT_ORGANIC_OPERATORID", OrganicOperatorId),
|
||||
("CLIENT_ORGANIC_AUTHORITYCODE", OrganicAuthorityCode),
|
||||
("ENABLE_MEMBERHISTORY", EnableMemberHistory ? "YES" : "NO"),
|
||||
("MODE_BUSINESSSHARES", businessShares),
|
||||
("MODE_DELIVERYNOTE_STATS", deliveryNoteStats),
|
||||
|
||||
@@ -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) {
|
||||
var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3");
|
||||
try {
|
||||
@@ -221,7 +221,7 @@ namespace Elwig.Helpers.Export {
|
||||
foreach (var entry in zip.Entries) {
|
||||
if (entry.Name.EndsWith(".sqlite3")) {
|
||||
entry.ExtractToFile(newName);
|
||||
await ImportSqlite(newName);
|
||||
await ImportSqlite(newName, keepSource: false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -233,7 +233,11 @@ namespace Elwig.Helpers.Export {
|
||||
|
||||
var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3");
|
||||
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();
|
||||
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")) {
|
||||
await cnx.ExecuteBatch(await reader.ReadToEndAsync());
|
||||
}
|
||||
await ImportSqlite(newName);
|
||||
await ImportSqlite(newName, keepSource: false);
|
||||
} finally {
|
||||
if (File.Exists(newName)) File.Delete(newName);
|
||||
}
|
||||
|
||||
@@ -638,6 +638,8 @@ namespace Elwig.Helpers.Export {
|
||||
["zwstid"] = m.ZwstId,
|
||||
["lfbis_nr"] = m.LfbisNr,
|
||||
["ustid_nr"] = m.UstIdNr,
|
||||
["ooc_id"] = m.OrganicOperatorId,
|
||||
["org_auth_code"] = m.OrganicAuthorityCode,
|
||||
["juridical_pers"] = m.IsJuridicalPerson,
|
||||
["volllieferant"] = m.IsVollLieferant,
|
||||
["buchführend"] = m.IsBuchführend,
|
||||
@@ -710,6 +712,8 @@ namespace Elwig.Helpers.Export {
|
||||
ZwstId = json["zwstid"]?.AsValue().GetValue<string>(),
|
||||
LfbisNr = json["lfbis_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,
|
||||
IsVollLieferant = json["volllieferant"]?.AsValue().GetValue<bool>() ?? false,
|
||||
IsBuchführend = json["buchführend"]?.AsValue().GetValue<bool>() ?? false,
|
||||
@@ -762,7 +766,8 @@ namespace Elwig.Helpers.Export {
|
||||
["reason"] = h.Reason,
|
||||
["source"] = h.Source,
|
||||
["shares"] = h.Shares,
|
||||
["signed"] = h.MemberHasSigned,
|
||||
["signed_company"] = h.CompanyHasSigned,
|
||||
["signed_member"] = h.MemberHasSigned,
|
||||
["value_per_share"] = h.ValuePerShare,
|
||||
["currency"] = h.CurrencyCode,
|
||||
["deduct_year"] = h.DeductYear,
|
||||
@@ -782,7 +787,8 @@ namespace Elwig.Helpers.Export {
|
||||
Reason = json["reason"]!.AsValue().GetValue<string>(),
|
||||
Source = json["source"]!.AsValue().GetValue<string>(),
|
||||
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>(),
|
||||
CurrencyCode = json["currency"]?.AsValue().GetValue<string>(),
|
||||
DeductYear = json["deduct_year"]?.AsValue().GetValue<int>(),
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Elwig.Helpers {
|
||||
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() {
|
||||
Text = text,
|
||||
TextAlignment = alignRight ? TextAlignment.Right : alignCenter ? TextAlignment.Center : TextAlignment.Left,
|
||||
Margin = new(0, 12 * row, 0, 0),
|
||||
FontWeight = bold ? FontWeights.Bold : FontWeights.Normal,
|
||||
};
|
||||
if (color != null) tb.Foreground = color;
|
||||
tb.SetValue(Grid.ColumnProperty, col);
|
||||
tb.SetValue(Grid.ColumnSpanProperty, colSpan);
|
||||
grid.Children.Add(tb);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
+46
-9
@@ -303,6 +303,11 @@ namespace Elwig.Helpers {
|
||||
return d.ShowDialog() == true ? (d.Weight, d.Reason) : null;
|
||||
}
|
||||
|
||||
public static int? ShowTareCorrectionDialog(int? actualTare, int? targetTare = null) {
|
||||
var d = new TareCorrectionDialog(actualTare, targetTare);
|
||||
return d.ShowDialog() == true ? d.TargetTare - d.ActualTare : null;
|
||||
}
|
||||
|
||||
public static (string?, int[])? ShowDeliverySplittingDialog(Delivery delivery) {
|
||||
var d = new DeliverySplittingDialog(delivery);
|
||||
return d.ShowDialog() == true ? (d.MgNr?.ToString() ?? d.LsNr, d.Weights ?? []) : null;
|
||||
@@ -318,7 +323,7 @@ namespace Elwig.Helpers {
|
||||
}
|
||||
|
||||
public class Footer {
|
||||
private readonly List<List<object>> Items = [[]];
|
||||
private readonly List<List<List<object>>> Items = [[[]]];
|
||||
private readonly string LineBreak;
|
||||
private readonly string Separator;
|
||||
|
||||
@@ -329,7 +334,7 @@ namespace Elwig.Helpers {
|
||||
|
||||
public Footer Item(object? text) {
|
||||
if (text == null) return this;
|
||||
Items[^1].Add(text);
|
||||
Items[^1][^1].Add(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -337,13 +342,38 @@ namespace Elwig.Helpers {
|
||||
return text == null ? this : Item($"{name}: {text}");
|
||||
}
|
||||
|
||||
public Footer NextGroup() {
|
||||
Items[^1].Add([]);
|
||||
return this;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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() {
|
||||
@@ -352,10 +382,12 @@ namespace Elwig.Helpers {
|
||||
foreach (var line in Items) {
|
||||
if (!first1) l.Add(new Text(LineBreak));
|
||||
var first2 = true;
|
||||
foreach (var item in line) {
|
||||
if (!first2) l.Add(new Text(Separator));
|
||||
l.Add(item as ILeafElement ?? new Text(item.ToString() ?? ""));
|
||||
first2 = false;
|
||||
foreach (var group in line) {
|
||||
foreach (var item in group) {
|
||||
if (!first2) l.Add(new Text(Separator));
|
||||
l.Add(item as ILeafElement ?? new Text(item.ToString() ?? ""));
|
||||
first2 = false;
|
||||
}
|
||||
}
|
||||
first1 = false;
|
||||
}
|
||||
@@ -670,7 +702,7 @@ namespace Elwig.Helpers {
|
||||
p[2],
|
||||
int.Parse(p[3]),
|
||||
p[4],
|
||||
p[5].Split(',').Select(a => a.Replace(" | ", "\n")).ToArray(),
|
||||
[.. p[5].Split(',').Select(a => a.Replace(" | ", "\n"))],
|
||||
p[6],
|
||||
p[7].Split(',')
|
||||
));
|
||||
@@ -712,5 +744,10 @@ namespace Elwig.Helpers {
|
||||
var filename = Path.Combine(App.MailsPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{NormalizeFileName(subject)}.txt");
|
||||
await File.WriteAllTextAsync(filename, $"# {subject}\r\n# Vorgesehene Empfänger: {recipients}\r\n\r\n" + body, Utils.UTF8);
|
||||
}
|
||||
|
||||
public static string GetTitle(string window, IEnumerable<string> filterNames, IEnumerable<string> filter) {
|
||||
var f = string.Join(" / ", filterNames.Union(filter.Select(f => $"\"{f}\"")));
|
||||
return window + (f.Length == 0 ? "" : ": " + f) + " - Elwig";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -623,6 +623,37 @@ namespace Elwig.Helpers {
|
||||
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) {
|
||||
string text = "";
|
||||
int pos = input.CaretIndex;
|
||||
@@ -631,15 +662,18 @@ namespace Elwig.Helpers {
|
||||
if (v < 2 && char.IsAsciiLetter(ch)) {
|
||||
v++;
|
||||
text += ch;
|
||||
} else if ((v == 2 || v == 6) && ch == '-') {
|
||||
v++;
|
||||
} else if ((v == 2 || v == 5) && ch == '-' && text[^1] != '-') {
|
||||
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 (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++;
|
||||
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++;
|
||||
text += ch;
|
||||
}
|
||||
@@ -647,11 +681,16 @@ namespace Elwig.Helpers {
|
||||
v++;
|
||||
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) {
|
||||
pos = text.Length;
|
||||
} else if (text.StartsWith("AT") && v >= 10) {
|
||||
} else if ((text.StartsWith("AT") || text.StartsWith("DE")) && v >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -662,7 +701,7 @@ namespace Elwig.Helpers {
|
||||
if (text.Length == 0)
|
||||
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) {
|
||||
return new(false, "Bio-Kontrollstellen-Code ist ungültig");
|
||||
}
|
||||
@@ -672,5 +711,25 @@ namespace Elwig.Helpers {
|
||||
|
||||
return new(true, null);
|
||||
}
|
||||
|
||||
public static ValidationResult CheckAddress(TextBox input, bool required, string? locality = null) {
|
||||
var text = input.Text;
|
||||
var (name, nr) = Utils.SplitAddress(text);
|
||||
if (!string.IsNullOrWhiteSpace(nr)) {
|
||||
var street = Normalizer.NormalizeStreetName(name.Replace(",", ""), locality);
|
||||
var idx = input.CaretIndex;
|
||||
input.Text = $"{street} {nr}".Trim();
|
||||
if (idx >= (text.Length - nr.Length)) {
|
||||
input.CaretIndex = street.Length + (idx - (text.Length - nr.Length)) + 1;
|
||||
} else if (idx > 0) {
|
||||
input.CaretIndex = idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (text.Length == 0)
|
||||
return required ? new(false, "Adresse ist nicht optional") : new(true, null);
|
||||
|
||||
return new(true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ namespace Elwig.Helpers.Weighing {
|
||||
throw new WeighingException($"Fehler {error}: {msg}");
|
||||
} else if (error[0] == '3') {
|
||||
switch (error[1]) {
|
||||
case '1': msg = "Übertragunsfehler"; break;
|
||||
case '1': msg = "Übertragungsfehler"; break;
|
||||
case '2': msg = "Ungültiger Befehl"; break;
|
||||
case '3': msg = "Ungültiger Parameter"; break;
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace Elwig.Models.Entities {
|
||||
[Column("weighing_data")]
|
||||
public string? WeighingData { get; set; }
|
||||
[NotMapped]
|
||||
public (string? ScaleId, string? Id, int? Gross, int? Tare, int? Net, DateOnly? Date, TimeOnly? Time) WeighingInfo {
|
||||
public (string? ScaleId, string? Id, int? Gross, int? Tare, int? TareCorrection, int? Net, DateOnly? Date, TimeOnly? Time) WeighingInfo {
|
||||
get {
|
||||
try {
|
||||
var obj = JsonNode.Parse(WeighingData!)!.AsObject();
|
||||
@@ -133,12 +133,13 @@ namespace Elwig.Models.Entities {
|
||||
obj["id"]?.AsValue().GetValue<string>(),
|
||||
obj["gross_weight"]?.AsValue().GetValue<int>(),
|
||||
obj["tare_weight"]?.AsValue().GetValue<int>(),
|
||||
obj["tare_correction"]?.AsValue().GetValue<int>(),
|
||||
obj["net_weight"]?.AsValue().GetValue<int>(),
|
||||
DateOnly.TryParseExact(obj["date"]?.AsValue().GetValue<string>(), "yyyy-MM-dd", out var d) ? d : null,
|
||||
TimeOnly.TryParseExact(obj["time"]?.AsValue().GetValue<string>(), ["HH:mm:ss", "HH:mm"], out var t) ? t : null
|
||||
);
|
||||
} catch {
|
||||
return (null, null, null, null, null, null, null);
|
||||
return (null, null, null, null, null, null, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ namespace Elwig.Models.Entities {
|
||||
|
||||
[Column("cultid")]
|
||||
public string? CultId { get; set; }
|
||||
[NotMapped]
|
||||
public bool IsOrganic => Cultivation?.IsOrganic ?? false;
|
||||
|
||||
[Column("max_weight")]
|
||||
public int? MaxWeight { get; set; }
|
||||
|
||||
@@ -96,6 +96,12 @@ namespace Elwig.Models.Entities {
|
||||
[Column("ustid_nr")]
|
||||
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")]
|
||||
public bool IsJuridicalPerson { get; set; }
|
||||
|
||||
|
||||
@@ -76,7 +76,10 @@ namespace Elwig.Models.Entities {
|
||||
[Column("shares")]
|
||||
public int Shares { get; set; }
|
||||
|
||||
[Column("signed")]
|
||||
[Column("signed_company")]
|
||||
public bool CompanyHasSigned { get; set; }
|
||||
|
||||
[Column("signed_member")]
|
||||
public bool MemberHasSigned { get; set; }
|
||||
|
||||
[Column("value_per_share")]
|
||||
|
||||
@@ -11,6 +11,9 @@ namespace Elwig.Models.Entities {
|
||||
[Column("name")]
|
||||
public required string Name { get; set; }
|
||||
|
||||
[Column("organic")]
|
||||
public bool IsOrganic { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
public string? Description { get; set; }
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
-- 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;
|
||||
|
||||
|
||||
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 = 'Untere Weißgerberstraße' WHERE address = 'U. Weißgasse Straße';
|
||||
UPDATE member SET address = 'Edgar-Penzig-Franz-Straße' WHERE address = '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';
|
||||
@@ -43,6 +43,8 @@ namespace Elwig.Services {
|
||||
public static async Task<(List<string>, IQueryable<AreaComContract>, IQueryable<AreaCom>, List<string>)> GetFilters(this AreaComAdminViewModel vm, AppDbContext ctx) {
|
||||
List<string> filterNames = [];
|
||||
IQueryable<AreaCom> areaComQuery = ctx.AreaCommitments.Where(a => a.MgNr == vm.FilterMember.MgNr).OrderBy(a => a.FbNr);
|
||||
filterNames.Add(vm.FilterMember.AdministrativeName);
|
||||
|
||||
if (vm.FilterSeason is int season) {
|
||||
areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, season);
|
||||
filterNames.Add($"laufend {season}");
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
using Elwig.Documents;
|
||||
using Elwig.Helpers.Export;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Export;
|
||||
using Elwig.Models.Dtos;
|
||||
using Elwig.Models.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using Elwig.ViewModels;
|
||||
using iText.Commons.Internal.Runtime;
|
||||
using LinqKit;
|
||||
using System.Globalization;
|
||||
using System.Linq.Expressions;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
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.Media;
|
||||
|
||||
namespace Elwig.Services {
|
||||
public static class DeliveryService {
|
||||
@@ -35,8 +37,13 @@ namespace Elwig.Services {
|
||||
|
||||
vm.SortId = "";
|
||||
vm.GradationKmwString = "";
|
||||
vm.WeightString = "";
|
||||
|
||||
vm.Weight = null;
|
||||
vm.ActualTare = null;
|
||||
vm.TargetTare = null;
|
||||
vm.Tare = null;
|
||||
vm.IsManualWeighing = false;
|
||||
|
||||
vm.PartComment = "";
|
||||
vm.TemperatureString = "";
|
||||
vm.AcidString = "";
|
||||
@@ -51,7 +58,11 @@ namespace Elwig.Services {
|
||||
vm.WineKg = ControlUtils.GetItemFromSourceWithPk(vm.WineKgSource, p.KgNr) as AT_Kg;
|
||||
vm.WineRd = ControlUtils.GetItemFromSourceWithPk(vm.WineRdSource, p.KgNr, p.RdNr) as WbRd;
|
||||
vm.WineOrigin = ControlUtils.GetItemFromSourceWithPk(vm.WineOriginSource, p.HkId) as WineOrigin;
|
||||
vm.WeightString = $"{p.Weight:N0}";
|
||||
|
||||
vm.Weight = p.Weight;
|
||||
vm.ActualTare = p.WeighingInfo.Tare;
|
||||
vm.TargetTare = vm.ActualTare + p.WeighingInfo.TareCorrection;
|
||||
vm.Tare = vm.TargetTare ?? (vm.ActualTare is int t && t != 0 ? t : null);
|
||||
vm.IsManualWeighing = p.IsManualWeighing;
|
||||
vm.IsNetWeight = p.IsNetWeight;
|
||||
|
||||
@@ -966,30 +977,40 @@ namespace Elwig.Services {
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddWeightToolTipRow(Grid grid, int row, string? h1, string? h2, int weight, int? total1, int total2) {
|
||||
var bold = h2 == null;
|
||||
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
|
||||
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, 1, bold);
|
||||
grid.AddToolTipCell($"{weight:N0} kg", row, 2, bold: bold, alignRight: true);
|
||||
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 = h3 == null;
|
||||
var color = type == "R" ? Brushes.Firebrick : type == "W" ? Brushes.ForestGreen : null;
|
||||
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? (h3 == null) ? 3 : 2 : 1, bold: bold, color: color);
|
||||
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)
|
||||
grid.AddToolTipCell($"{weight * 100.0 / total1:N1} %", row, 3, bold: bold, alignRight: true);
|
||||
if (total2 != 0)
|
||||
grid.AddToolTipCell($"{weight * 100.0 / total2:N1} %", row, 4, bold: bold, alignRight: true);
|
||||
grid.AddToolTipCell($"{weight * 100.0 / total1:N1} %", row, 4, bold: bold, alignRight: true, color: color);
|
||||
if (total2 != null && total2 != 0)
|
||||
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) {
|
||||
var bold = h2 == null;
|
||||
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? 2 : 1, bold);
|
||||
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, bold: bold);
|
||||
grid.AddToolTipCell($"{min:N1}°", row, 2, bold: bold, alignRight: true);
|
||||
grid.AddToolTipCell($"{avg:N1}°", row, 3, bold: bold, alignRight: true);
|
||||
grid.AddToolTipCell($"{max:N1}°", row, 4, bold: bold, alignRight: true);
|
||||
private static void AddGradationToolTipRow(Grid grid, int row, string? h1, string? h2, string? h3, double min, double avg, double max, string? type) {
|
||||
var bold = h3 == null;
|
||||
var color = type == "R" ? Brushes.Firebrick : type == "W" ? Brushes.ForestGreen : null;
|
||||
if (h1 != null) grid.AddToolTipCell(h1 + ":", row, 0, (h2 == null) ? (h3 == null) ? 3 : 2 : 1, bold: bold, color: color);
|
||||
if (h2 != null) grid.AddToolTipCell(h2 + ":", row, 1, (h3 == null) ? 2 : 1, bold: bold, color: color);
|
||||
if (h3 != null) grid.AddToolTipCell(h3 + ":", row, 2, bold: bold, color: color);
|
||||
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) {
|
||||
var wGrid = new List<(string?, string?, int, int?, int)>();
|
||||
private static string? GetGroupName(params string?[] parts) {
|
||||
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 gGrid = new List<(string?, string?, double, double, double)>();
|
||||
var gGrid = new List<(string?, string?, string?, double, double, double, string?)>();
|
||||
var gText = "-";
|
||||
|
||||
var stat = (await deliveryParts.GroupBy(p => 0)
|
||||
@@ -1004,11 +1025,11 @@ namespace Elwig.Services {
|
||||
.Single();
|
||||
|
||||
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) {
|
||||
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
|
||||
.GroupBy(p => new { Attr = p.Attribute!.Name, Cult = p.Cultivation!.Name })
|
||||
@@ -1025,9 +1046,10 @@ namespace Elwig.Services {
|
||||
.ThenBy(g => g.Cult)
|
||||
.ToListAsync();
|
||||
var sortGroups = await deliveryParts
|
||||
.GroupBy(p => p.SortId)
|
||||
.GroupBy(p => new { p.SortId, p.Variety.Type })
|
||||
.Select(g => new {
|
||||
SortId = g.Key,
|
||||
g.Key.SortId,
|
||||
g.Key.Type,
|
||||
Weight = g.Sum(p => p.Weight),
|
||||
Min = g.Min(p => p.Kmw),
|
||||
Avg = g.Sum(p => p.Kmw * p.Weight) / g.Sum(p => p.Weight),
|
||||
@@ -1040,11 +1062,13 @@ namespace Elwig.Services {
|
||||
.GroupBy(p => new {
|
||||
Attr = p.Attribute!.Name,
|
||||
Cult = p.Cultivation!.Name,
|
||||
p.Variety.Type,
|
||||
p.SortId,
|
||||
})
|
||||
.Select(g => new {
|
||||
g.Key.Attr,
|
||||
g.Key.Cult,
|
||||
g.Key.Type,
|
||||
g.Key.SortId,
|
||||
Weight = g.Sum(p => p.Weight),
|
||||
Min = g.Min(p => p.Kmw),
|
||||
@@ -1054,27 +1078,62 @@ namespace Elwig.Services {
|
||||
.OrderByDescending(g => g.Weight)
|
||||
.ThenBy(g => g.Attr)
|
||||
.ThenBy(g => g.Cult)
|
||||
.ThenBy(g => g.Type)
|
||||
.ThenBy(g => g.SortId)
|
||||
.ToListAsync();
|
||||
|
||||
foreach (var attrG in attrGroups) {
|
||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
||||
wGrid.Add((name, null, attrG.Weight, attrG.Weight, stat.Weight));
|
||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||
wGrid.Add((null, g.SortId, g.Weight, attrG.Weight, stat.Weight));
|
||||
var name = GetGroupName(attrG.Attr, attrG.Cult);
|
||||
var typeGroups = groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult)
|
||||
.GroupBy(g => g.Type)
|
||||
.Select(g => new { Type = g.Key, Weight = g.Sum(p => p.Weight) })
|
||||
.OrderByDescending(g => g.Weight).ThenBy(g => g.Type)
|
||||
.ToList();
|
||||
wGrid.Add((name, null, null, attrG.Weight, null, attrG.Weight, stat.Weight, typeGroups.Count == 1 ? typeGroups.First().Type : null));
|
||||
if (typeGroups.Count == 1) {
|
||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||
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) {
|
||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
||||
gGrid.Add((name, null, attrG.Min, attrG.Avg, attrG.Max));
|
||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Avg).ThenBy(g => g.SortId)) {
|
||||
gGrid.Add((null, g.SortId, g.Min, g.Avg, g.Max));
|
||||
var name = GetGroupName(attrG.Attr, attrG.Cult);
|
||||
var typeGroups = groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult)
|
||||
.GroupBy(g => g.Type)
|
||||
.Select(g => new {
|
||||
Type = g.Key,
|
||||
Weight = g.Sum(p => p.Weight),
|
||||
Min = g.Min(p => p.Min),
|
||||
Avg = g.Sum(p => p.Avg * p.Weight) / g.Sum(p => p.Weight),
|
||||
Max = g.Max(p => p.Max),
|
||||
})
|
||||
.OrderByDescending(g => g.Weight).ThenBy(g => g.Type)
|
||||
.ToList();
|
||||
gGrid.Add((name, null, null, attrG.Min, attrG.Avg, attrG.Max, typeGroups.Count == 1 ? typeGroups.First().Type : null));
|
||||
if (typeGroups.Count == 1) {
|
||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Avg).ThenBy(g => g.SortId)) {
|
||||
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) {
|
||||
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) {
|
||||
wText += $" [{name}]";
|
||||
gText += $" [{name}]";
|
||||
@@ -1085,40 +1144,43 @@ namespace Elwig.Services {
|
||||
|
||||
}
|
||||
} 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}]")))}";
|
||||
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}]")))}";
|
||||
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}" + (GetGroupName(g.Attr, g.Cult) is string s ? $" [{s}]" : "")))}";
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
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(50) });
|
||||
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||
wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||
int rowNum = 0;
|
||||
foreach (var row in weightData) {
|
||||
if (rowNum != 0 && row.Item2 == null) rowNum++;
|
||||
AddWeightToolTipRow(wGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
|
||||
if (rowNum != 0 && row.Item2 == null && row.Item3 == null) rowNum++;
|
||||
AddWeightToolTipRow(wGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5, row.Item6, row.Item7, row.Item8);
|
||||
}
|
||||
|
||||
var gGrid = new Grid();
|
||||
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.AddToolTipCell("Min.", 0, 2, alignCenter: true);
|
||||
gGrid.AddToolTipCell("⌀", 0, 3, alignCenter: true);
|
||||
gGrid.AddToolTipCell("Max.", 0, 4, alignCenter: true);
|
||||
gGrid.AddToolTipCell("Min.", 0, 3, alignCenter: true);
|
||||
gGrid.AddToolTipCell("⌀", 0, 4, alignCenter: true);
|
||||
gGrid.AddToolTipCell("Max.", 0, 5, alignCenter: true);
|
||||
rowNum = 1;
|
||||
foreach (var row in gradationData) {
|
||||
if (rowNum != 1 && row.Item2 == null) rowNum++;
|
||||
AddGradationToolTipRow(gGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
|
||||
if (rowNum != 1 && row.Item2 == null && row.Item3 == null) rowNum++;
|
||||
AddGradationToolTipRow(gGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5, row.Item6, row.Item7);
|
||||
}
|
||||
|
||||
return (wGrid, gGrid);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -117,8 +118,35 @@ namespace Elwig.Services {
|
||||
|
||||
public static void ShowException(string title, string? text, Exception exc, bool showExcType = false, bool isError = true) {
|
||||
text = text == null ? "" : text + (text.EndsWith('.') || text.EndsWith('!') || text.EndsWith('?') ? "" : ":") + "\n\n";
|
||||
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
|
||||
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
|
||||
if ((exc.InnerException ?? exc) is SqliteException sql) {
|
||||
if (sql.SqliteErrorCode == 5 || sql.SqliteErrorCode == 6) {
|
||||
// SQLITE_BUSY / SQLITE_LOCKED
|
||||
text += "Die Datenbank wurde gerade von einem anderen Gerät/Prozess verwendet. Bitte noch einmal versuchen!\n\n" + sql.Message;
|
||||
} else if (sql.SqliteErrorCode == 19) {
|
||||
// SQLITE_CONSTRAINT
|
||||
switch (sql.SqliteExtendedErrorCode) {
|
||||
case 1555: // SQLITE_CONSTRAINT_PRIMARYKEY - indicating that a PRIMARY KEY constraint failed
|
||||
case 2067: // SQLITE_CONSTRAINT_UNIQUE - indicating that a UNIQUE constraint failed
|
||||
case 2579: // SQLITE_CONSTRAINT_ROWID - indicating that a rowid is not unique
|
||||
text += "Dieser Datensatz existiert bereits!\n\n";
|
||||
break;
|
||||
case 787: // SQLITE_CONSTRAINT_FOREIGNKEY - indicating that a foreign key constraint failed
|
||||
case 1299: // SQLITE_CONSTRAINT_NOTNULL - indicating that a NOT NULL constraint failed
|
||||
case 275: // SQLITE_CONSTRAINT_CHECK - indicating that a CHECK constraint failed
|
||||
case 1811: // SQLITE_CONSTRAINT_TRIGGER - indicating that a RAISE function within a trigger fired, causing the SQL statement to abort
|
||||
case 531: // SQLITE_CONSTRAINT_COMMITHOOK - indicating that a commit hook callback returned non-zero that thus caused the SQL statement to be rolled back
|
||||
text += "Der Datensatz ist inkonsistent!\n\n";
|
||||
break;
|
||||
}
|
||||
text += sql.Message;
|
||||
} else {
|
||||
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
|
||||
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
|
||||
}
|
||||
} else {
|
||||
text += exc.Message + (showExcType ? $" ({exc.GetType().Name})" : "");
|
||||
if (exc.InnerException != null) text += "\n\n" + exc.InnerException.Message;
|
||||
}
|
||||
if (isError) {
|
||||
ShowError(title, text);
|
||||
} else {
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Elwig.Services {
|
||||
vm.DateEffective = h.DateEffective;
|
||||
vm.Reason = h.Reason + (h.Reason == MemberHistory.REASON_TRANSFER ? $"_{(h.ToMgNr == mgnr ? "from" : "to")}" : "");
|
||||
vm.Shares = h.Shares;
|
||||
vm.CompanyHasSigned = h.CompanyHasSigned;
|
||||
vm.MemberHasSigned = h.MemberHasSigned;
|
||||
vm.ValuePerShare = h.ValuePerShare;
|
||||
vm.OtherMgNr = h.FromMgNr != null && h.FromMgNr != mgnr ? h.FromMgNr : h.ToMgNr != null && h.ToMgNr != mgnr ? h.ToMgNr : null;
|
||||
@@ -63,6 +64,7 @@ namespace Elwig.Services {
|
||||
Reason = vm.Reason?.Split("_")[0] ?? MemberHistory.REASON_CONVERT,
|
||||
Source = "manual",
|
||||
Shares = vm.Shares ?? 0,
|
||||
CompanyHasSigned = vm.CompanyHasSigned,
|
||||
MemberHasSigned = vm.MemberHasSigned,
|
||||
ValuePerShare = vm.ValuePerShare,
|
||||
CurrencyCode = vm.ValuePerShare != null ? "EUR" : null,
|
||||
|
||||
@@ -10,6 +10,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Elwig.Services {
|
||||
public static class MemberService {
|
||||
@@ -19,6 +20,7 @@ namespace Elwig.Services {
|
||||
};
|
||||
|
||||
public static async Task InitInputs(this MemberAdminViewModel vm) {
|
||||
vm.IsMemberSelectedOrCreating = true;
|
||||
using var ctx = new AppDbContext();
|
||||
vm.MgNr = await ctx.NextMgNr();
|
||||
vm.EntryDate = DateTime.Now.ToString("dd.MM.yyyy");
|
||||
@@ -31,6 +33,7 @@ namespace Elwig.Services {
|
||||
|
||||
public static void ClearInputs(this MemberAdminViewModel vm) {
|
||||
vm.IsMemberSelected = false;
|
||||
vm.IsMemberSelectedOrCreating = false;
|
||||
vm.MemberHasEmail = false;
|
||||
vm.MemberCanSendEmail = false;
|
||||
vm.EnableMemberReferenceButton = false;
|
||||
@@ -49,10 +52,15 @@ namespace Elwig.Services {
|
||||
vm.ModifiedAtShort = "-";
|
||||
vm.ExportedAt = "-";
|
||||
vm.ImportedAt = "-";
|
||||
vm.OrganicState = null;
|
||||
vm.OrganicColor = Brushes.Black;
|
||||
vm.OrganicDetails = "-";
|
||||
vm.OrganicToolTip = null;
|
||||
}
|
||||
|
||||
public static void FillInputs(this MemberAdminViewModel vm, Member m) {
|
||||
vm.IsMemberSelected = true;
|
||||
vm.IsMemberSelectedOrCreating = true;
|
||||
vm.MgNr = m.MgNr;
|
||||
vm.PredecessorMgNr = m.PredecessorMgNr;
|
||||
vm.IsJuridicalPerson = m.IsJuridicalPerson;
|
||||
@@ -106,6 +114,8 @@ namespace Elwig.Services {
|
||||
|
||||
vm.UstIdNr = m.UstIdNr;
|
||||
vm.LfbisNr = m.LfbisNr;
|
||||
vm.OrganicOperatorId = m.OrganicOperatorId;
|
||||
vm.OrganicAuthorityCode = m.OrganicAuthorityCode;
|
||||
vm.IsBuchführend = m.IsBuchführend;
|
||||
vm.IsOrganic = m.IsOrganic;
|
||||
|
||||
@@ -187,10 +197,9 @@ namespace Elwig.Services {
|
||||
.GroupBy(d => d.Year)
|
||||
.ToDictionaryAsync(g => g.Key, g => g.Any());
|
||||
|
||||
if (m.MgNr != vm.MgNr)
|
||||
return;
|
||||
|
||||
await App.MainDispatcher.BeginInvoke(() => {
|
||||
if (m.MgNr != vm.MgNr)
|
||||
return;
|
||||
var (d1Grid, _) = DeliveryService.GenerateToolTip(d1GridData, []);
|
||||
var (d2Grid, _) = DeliveryService.GenerateToolTip(d2GridData, []);
|
||||
var grid = AreaComService.GenerateToolTip(gridData);
|
||||
@@ -203,13 +212,76 @@ namespace Elwig.Services {
|
||||
vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}";
|
||||
vm.StatusAreaCommitment = text;
|
||||
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.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) {
|
||||
@@ -555,6 +627,8 @@ namespace Elwig.Services {
|
||||
|
||||
UstIdNr = string.IsNullOrWhiteSpace(vm.UstIdNr) ? null : vm.UstIdNr,
|
||||
LfbisNr = string.IsNullOrWhiteSpace(vm.LfbisNr) ? null : vm.LfbisNr,
|
||||
OrganicOperatorId = string.IsNullOrWhiteSpace(vm.OrganicOperatorId) ? null : vm.OrganicOperatorId,
|
||||
OrganicAuthorityCode = string.IsNullOrWhiteSpace(vm.OrganicAuthorityCode) ? null : vm.OrganicAuthorityCode,
|
||||
IsBuchführend = vm.IsBuchführend,
|
||||
IsOrganic = vm.IsOrganic,
|
||||
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using System;
|
||||
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 Dictionary<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')}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,94 +8,94 @@ namespace Elwig.ViewModels {
|
||||
public partial class AreaComAdminViewModel : ObservableObject {
|
||||
|
||||
[ObservableProperty]
|
||||
private string _title = "Flächenbindungen - Elwig";
|
||||
public partial string Title { get; set; } = "Flächenbindungen - Elwig";
|
||||
|
||||
public required Member FilterMember { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _searchQuery = "";
|
||||
public partial string? SearchQuery { get; set; } = "";
|
||||
public List<string> TextFilter {
|
||||
get => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||
set => SearchQuery = string.Join(' ', value.Where(e => e.Length > 0));
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _filterSeasonString;
|
||||
public partial string? FilterSeasonString { get; set; }
|
||||
public int? FilterSeason {
|
||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||
set => FilterSeasonString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _fbNrString;
|
||||
public partial string? FbNrString { get; set; }
|
||||
public int? FbNr {
|
||||
get => int.TryParse(FbNrString, out var mgnr) ? mgnr : null;
|
||||
set => FbNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _mgNrString;
|
||||
public partial string? MgNrString { get; set; }
|
||||
public int? MgNr {
|
||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||
set => MgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _yearFromString;
|
||||
public partial string? YearFromString { get; set; }
|
||||
public int? YearFrom {
|
||||
get => int.TryParse(YearFromString, out var year) ? year : null;
|
||||
set => YearFromString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _yearToString;
|
||||
public partial string? YearToString { get; set; }
|
||||
public int? YearTo {
|
||||
get => int.TryParse(YearToString, out var year) ? year : null;
|
||||
set => YearToString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _period;
|
||||
public partial string? Period { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private AreaComType? _areaComType;
|
||||
public partial AreaComType? AreaComType { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<AreaComType> _areaComTypeSource = [];
|
||||
public partial IEnumerable<AreaComType> AreaComTypeSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _wineCultObj;
|
||||
public partial object? WineCultObj { get; set; }
|
||||
public WineCult? WineCult {
|
||||
get => WineCultObj as WineCult;
|
||||
set => WineCultObj = value ?? WineCultSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _wineCultSource = [];
|
||||
public partial IEnumerable<object> WineCultSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _comment;
|
||||
public partial string? Comment { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private AT_Kg? _kg;
|
||||
public partial AT_Kg? Kg { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<AT_Kg> _kgSource = [];
|
||||
public partial IEnumerable<AT_Kg> KgSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _rdObj;
|
||||
public partial object? RdObj { get; set; }
|
||||
public WbRd? Rd {
|
||||
get => RdObj as WbRd;
|
||||
set => RdObj = value ?? RdSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _rdSource = [];
|
||||
public partial IEnumerable<object> RdSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _gstNr;
|
||||
public partial string? GstNr { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _areaString;
|
||||
public partial string? AreaString { get; set; }
|
||||
public int? Area {
|
||||
get => int.TryParse(AreaString, out var area) ? area : null;
|
||||
set => AreaString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusAreaCommitments = "-";
|
||||
public partial string StatusAreaCommitments { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusContracts = "-";
|
||||
public partial string StatusContracts { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusArea = "-";
|
||||
public partial string StatusArea { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private Grid? _statusAreaToolTip;
|
||||
public partial Grid? StatusAreaToolTip { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,167 +9,175 @@ using System.Windows.Controls;
|
||||
namespace Elwig.ViewModels {
|
||||
public partial class DeliveryAdminViewModel : ObservableObject {
|
||||
|
||||
public bool IsReceipt = false;
|
||||
public bool IsReceipt { get; set; } = false;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _title = "Lieferungen - Elwig";
|
||||
public partial string Title { get; set; } = "Lieferungen - Elwig";
|
||||
|
||||
public Member? FilterMember { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _searchQuery = "";
|
||||
public partial string? SearchQuery { get; set; } = "";
|
||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _lastScaleError;
|
||||
public partial string? LastScaleError { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _manualWeighingReason;
|
||||
public partial string? ManualWeighingReason { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _scaleTerminalId;
|
||||
public partial string? ScaleTerminalId { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _weighingData;
|
||||
public partial string? WeighingData { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _filterTodayOnly;
|
||||
public partial bool FilterTodayOnly { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _filterAllSeasons;
|
||||
public partial bool FilterAllSeasons { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _enableAllSeasons;
|
||||
public partial bool EnableAllSeasons { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _filterSeasonString;
|
||||
public partial string? FilterSeasonString { get; set; }
|
||||
public int? FilterSeason {
|
||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||
set => FilterSeasonString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private Delivery? _selectedDelivery;
|
||||
public partial Delivery? SelectedDelivery { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Delivery> _deliveries = [];
|
||||
public partial IEnumerable<Delivery> Deliveries { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _mgNrString;
|
||||
public partial string? MgNrString { get; set; }
|
||||
public int? MgNr {
|
||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||
set => MgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private Member? _member;
|
||||
public partial Member? Member { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Member> _memberSource = [];
|
||||
public partial IEnumerable<Member> MemberSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _memberAddress;
|
||||
public partial string? MemberAddress { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _lsNr;
|
||||
public partial string? LsNr { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _date;
|
||||
public partial string? Date { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _time;
|
||||
public partial string? Time { get; set; }
|
||||
[ObservableProperty]
|
||||
private Branch? _branch;
|
||||
public partial Branch? Branch { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Branch> _branchSource = [];
|
||||
public partial IEnumerable<Branch> BranchSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _comment;
|
||||
public partial string? Comment { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _sortId;
|
||||
public partial string? SortId { get; set; }
|
||||
[ObservableProperty]
|
||||
private WineVar? _wineVar;
|
||||
public partial WineVar? WineVar { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineVar> _wineVarSource = [];
|
||||
public partial IEnumerable<WineVar> WineVarSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _wineAttrObj;
|
||||
public partial object? WineAttrObj { get; set; }
|
||||
public WineAttr? WineAttr {
|
||||
get => WineAttrObj as WineAttr;
|
||||
set => WineAttrObj = value ?? WineAttrSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _wineAttrSource = [];
|
||||
public partial IEnumerable<object> WineAttrSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _wineCultObj;
|
||||
public partial object? WineCultObj { get; set; }
|
||||
public WineCult? WineCult {
|
||||
get => WineCultObj as WineCult;
|
||||
set => WineCultObj = value ?? WineCultSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _wineCultSource = [];
|
||||
public partial IEnumerable<object> WineCultSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _gradationOeString;
|
||||
public partial string? GradationOeString { get; set; }
|
||||
public double? GradationOe {
|
||||
get => double.TryParse(GradationOeString, out var oe) ? oe : null;
|
||||
set => GradationOeString = $"{value:0}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _gradationKmwString;
|
||||
public partial string? GradationKmwString { get; set; }
|
||||
public double? GradationKmw {
|
||||
get => double.TryParse(GradationKmwString, out var kmw) ? kmw : null;
|
||||
set => GradationKmwString = $"{value:0.0}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private WineQualLevel? _wineQualityLevel;
|
||||
public partial WineQualLevel? WineQualityLevel { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineQualLevel> _wineQualityLevelSource = [];
|
||||
public partial IEnumerable<WineQualLevel> WineQualityLevelSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private bool _abgewertet;
|
||||
public partial bool Abgewertet { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _weightString;
|
||||
public partial string? WeightString { get; set; }
|
||||
public int? Weight {
|
||||
get => int.TryParse(WeightString?.Replace(Utils.GroupSeparator, ""), out var w) ? w : null;
|
||||
set => WeightString = $"{value:N0}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private bool _isManualWeighing;
|
||||
public partial string? TareString { get; set; } = "-";
|
||||
public int? Tare {
|
||||
get => int.TryParse(TareString?.Replace(Utils.GroupSeparator, "").Replace(" kg", ""), out var w) ? w : null;
|
||||
set => TareString = value == null ? "-" : $"{value:N0} kg{(TargetTare != null ? "*" : "")}";
|
||||
}
|
||||
public int? ActualTare { get; set; }
|
||||
public int? TargetTare { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool? _isNetWeightValue = false;
|
||||
public partial bool IsManualWeighing { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial bool? IsNetWeightValue { get; set; } = false;
|
||||
public bool IsNetWeight {
|
||||
get => IsNetWeightValue ?? false;
|
||||
set => IsNetWeightValue = value;
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private WineOrigin? _wineOrigin;
|
||||
public partial WineOrigin? WineOrigin { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineOrigin> _wineOriginSource = [];
|
||||
public partial IEnumerable<WineOrigin> WineOriginSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _wineKgObj;
|
||||
public partial object? WineKgObj { get; set; }
|
||||
public AT_Kg? WineKg {
|
||||
get => WineKgObj as AT_Kg;
|
||||
set => WineKgObj = value ?? WineKgSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _wineKgSource = [];
|
||||
public partial IEnumerable<object> WineKgSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _wineRdObj;
|
||||
public partial object? WineRdObj { get; set; }
|
||||
public WbRd? WineRd {
|
||||
get => WineRdObj as WbRd;
|
||||
set => WineRdObj = value ?? WineRdSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _wineRdSource = [];
|
||||
public partial IEnumerable<object> WineRdSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private bool? _isGebunden;
|
||||
public partial bool? IsGebunden { get; set; }
|
||||
|
||||
public ObservableCollection<Modifier> Modifiers { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Modifier> _modifiersSource = [];
|
||||
public partial IEnumerable<Modifier> ModifiersSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _partComment;
|
||||
public partial string? PartComment { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _temperatureString;
|
||||
public partial string? TemperatureString { get; set; }
|
||||
public double? Temperature {
|
||||
get => double.TryParse(TemperatureString, out var t) ? t : null;
|
||||
set => TemperatureString = $"{value:0.0}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _acidString;
|
||||
public partial string? AcidString { get; set; }
|
||||
public double? Acid {
|
||||
get => double.TryParse(AcidString, out var a) ? a : null;
|
||||
set => AcidString = $"{value:0.0}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private bool? _isHandPicked;
|
||||
public partial bool? IsHandPicked { get; set; }
|
||||
|
||||
public string? Unloading {
|
||||
get => IsUnloadingDumper ? DeliveryPart.Dumper : IsUnloadingPumped ? DeliveryPart.Pumped : IsUnloadingBox ? DeliveryPart.Box : null;
|
||||
@@ -183,28 +191,28 @@ namespace Elwig.ViewModels {
|
||||
}
|
||||
}
|
||||
[ObservableProperty]
|
||||
private bool _isUnloadingDumper;
|
||||
public partial bool IsUnloadingDumper { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isUnloadingPumped;
|
||||
public partial bool IsUnloadingPumped { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isUnloadingBox;
|
||||
public partial bool IsUnloadingBox { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isUnloadingOther;
|
||||
public partial bool IsUnloadingOther { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusMembers = "-";
|
||||
public partial string StatusMembers { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusDeliveries = "-";
|
||||
public partial string StatusDeliveries { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusVarieties = "-";
|
||||
public partial string StatusVarieties { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusWeight = "-";
|
||||
public partial string StatusWeight { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusGradation = "-";
|
||||
public partial string StatusGradation { get; set; } = "-";
|
||||
|
||||
[ObservableProperty]
|
||||
private Grid? _statusWeightToolTip;
|
||||
public partial Grid? StatusWeightToolTip { get; set; }
|
||||
[ObservableProperty]
|
||||
private Grid? _statusGradationToolTip;
|
||||
public partial Grid? StatusGradationToolTip { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,77 +9,80 @@ namespace Elwig.ViewModels {
|
||||
public partial class DeliveryAncmtAdminViewModel : ObservableObject {
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _searchQuery = "";
|
||||
public partial string Title { get; set; } = "Anmeldungen - Elwig";
|
||||
|
||||
[ObservableProperty]
|
||||
public partial string? SearchQuery { get; set; } = "";
|
||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _filterOnlyUpcoming;
|
||||
public partial bool FilterOnlyUpcoming { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _filterFromAllSchedules;
|
||||
public partial bool FilterFromAllSchedules { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _filterSeasonString;
|
||||
public partial string? FilterSeasonString { get; set; }
|
||||
public int? FilterSeason {
|
||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||
set => FilterSeasonString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private DeliveryAncmt? _selectedDeliveryAncmt;
|
||||
public partial DeliveryAncmt? SelectedDeliveryAncmt { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliveryAncmt> _deliveryAncmts = [];
|
||||
public partial IEnumerable<DeliveryAncmt> DeliveryAncmts { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private DeliverySchedule? _selectedDeliverySchedule;
|
||||
public partial DeliverySchedule? SelectedDeliverySchedule { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliverySchedule> _deliverySchedules = [];
|
||||
public partial IEnumerable<DeliverySchedule> DeliverySchedules { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private bool _enableSearchInputs = true;
|
||||
public partial bool EnableSearchInputs { get; set; } = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _mgNrString;
|
||||
public partial string? MgNrString { get; set; }
|
||||
public int? MgNr {
|
||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||
set => MgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private Member? _member;
|
||||
public partial Member? Member { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Member> _memberSource = [];
|
||||
public partial IEnumerable<Member> MemberSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _memberAddress;
|
||||
public partial string? MemberAddress { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private DeliverySchedule? _deliverySchedule;
|
||||
public partial DeliverySchedule? DeliverySchedule { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliverySchedule> _deliveryScheduleSource = [];
|
||||
public partial IEnumerable<DeliverySchedule> DeliveryScheduleSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _sortId;
|
||||
public partial string? SortId { get; set; }
|
||||
[ObservableProperty]
|
||||
private WineVar? _wineVariety;
|
||||
public partial WineVar? WineVariety { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineVar> _wineVarietySource = [];
|
||||
public partial IEnumerable<WineVar> WineVarietySource { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _weightString;
|
||||
public partial string? WeightString { get; set; }
|
||||
public int? Weight {
|
||||
get => int.TryParse(WeightString, out var w) ? w : null;
|
||||
set => WeightString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusAncmts = "-";
|
||||
public partial string StatusAncmts { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusWeight = "-";
|
||||
public partial string StatusWeight { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusAncmtCreated = "-";
|
||||
public partial string StatusAncmtCreated { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusAncmtModified = "-";
|
||||
public partial string StatusAncmtModified { get; set; } = "-";
|
||||
|
||||
[ObservableProperty]
|
||||
private Grid? _statusWeightToolTip;
|
||||
public partial Grid? StatusWeightToolTip { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
||||
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||
[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 {
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _searchQuery = "";
|
||||
public partial string? SearchQuery { get; set; } = "";
|
||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _filterOnlyUpcoming;
|
||||
public partial bool FilterOnlyUpcoming { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _filterSeasonString;
|
||||
public partial string? FilterSeasonString { get; set; }
|
||||
public int? FilterSeason {
|
||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||
set => FilterSeasonString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private DeliverySchedule? _selectedDeliverySchedule;
|
||||
public partial DeliverySchedule? SelectedDeliverySchedule { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliverySchedule> _deliverySchedules = [];
|
||||
public partial IEnumerable<DeliverySchedule> DeliverySchedules { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private bool _enableSearchInputs = true;
|
||||
public partial bool EnableSearchInputs { get; set; } = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string _dateString = "";
|
||||
public partial string DateString { get; set; } = "";
|
||||
public DateOnly? Date {
|
||||
get => DateOnly.TryParseExact(DateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => DateString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private Branch? _branch;
|
||||
public partial Branch? Branch { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Branch> _branchSource = [];
|
||||
public partial IEnumerable<Branch> BranchSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string _description = "";
|
||||
public partial string Description { get; set; } = "";
|
||||
[ObservableProperty]
|
||||
private string? _maxWeightString = "";
|
||||
public partial string? MaxWeightString { get; set; } = "";
|
||||
public int? MaxWeight {
|
||||
get => int.TryParse(MaxWeightString, out var w) ? w : null;
|
||||
set => MaxWeightString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private bool _isCancelled;
|
||||
public partial bool IsCancelled { get; set; }
|
||||
public ObservableCollection<WineVar> MainVarieties { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineVar> _mainVarietiesSource = [];
|
||||
public partial IEnumerable<WineVar> MainVarietiesSource { get; set; } = [];
|
||||
public ObservableCollection<WineVar> OtherVarieties { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineVar> _otherVarietiesSource = [];
|
||||
public partial IEnumerable<WineVar> OtherVarietiesSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _attributeSource = [];
|
||||
public partial IEnumerable<object> AttributeSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _attributeObj;
|
||||
public partial object? AttributeObj { get; set; }
|
||||
public WineAttr? Attribute {
|
||||
get => AttributeObj as WineAttr;
|
||||
set => AttributeObj = value ?? AttributeSource.FirstOrDefault();
|
||||
}
|
||||
[ObservableProperty]
|
||||
private IEnumerable<object> _cultivationSource = [];
|
||||
public partial IEnumerable<object> CultivationSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private object? _cultivationObj;
|
||||
public partial object? CultivationObj { get; set; }
|
||||
public WineCult? Cultivation {
|
||||
get => CultivationObj as WineCult;
|
||||
set => CultivationObj = value ?? CultivationSource.FirstOrDefault();
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private string _ancmtFromDateString = "";
|
||||
public partial string AncmtFromDateString { get; set; } = "";
|
||||
public DateOnly? AncmtFromDate {
|
||||
get => DateOnly.TryParseExact(AncmtFromDateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => AncmtFromDateString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string _ancmtFromTimeString = "";
|
||||
public partial string AncmtFromTimeString { get; set; } = "";
|
||||
public TimeOnly? AncmtFromTime {
|
||||
get => TimeOnly.TryParseExact(AncmtFromTimeString, "HH:mm", out var t) ? t : null;
|
||||
set => AncmtFromTimeString = $"{value:HH:mm}";
|
||||
@@ -92,13 +92,13 @@ namespace Elwig.ViewModels {
|
||||
}
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string _ancmtToDateString = "";
|
||||
public partial string AncmtToDateString { get; set; } = "";
|
||||
public DateOnly? AncmtToDate {
|
||||
get => DateOnly.TryParseExact(AncmtToDateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => AncmtToDateString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string _ancmtToTimeString = "";
|
||||
public partial string AncmtToTimeString { get; set; } = "";
|
||||
public TimeOnly? AncmtToTime {
|
||||
get => TimeOnly.TryParseExact(AncmtToTimeString, "HH:mm", out var t) ? t : null;
|
||||
set => AncmtToTimeString = $"{value:HH:mm}";
|
||||
@@ -112,8 +112,8 @@ namespace Elwig.ViewModels {
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
||||
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
||||
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
@@ -6,185 +6,203 @@ using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
|
||||
namespace Elwig.ViewModels {
|
||||
public partial class MemberAdminViewModel : ObservableObject {
|
||||
|
||||
public int? TransferPredecessorAreaComs = null;
|
||||
public int? CancelAreaComs = null;
|
||||
[ObservableProperty]
|
||||
public partial string Title { get; set; } = "Mitglieder - Elwig";
|
||||
|
||||
public int? TransferPredecessorAreaComs { get; set; } = null;
|
||||
public int? CancelAreaComs { get; set; } = null;
|
||||
|
||||
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _searchQuery = "";
|
||||
public partial string? SearchQuery { get; set; } = "";
|
||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _showOnlyActiveMembers = true;
|
||||
public partial bool ShowOnlyActiveMembers { get; set; } = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private Member? _selectedMember;
|
||||
public partial Member? SelectedMember { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Member> _members = [];
|
||||
public partial IEnumerable<Member> Members { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isMemberSelected;
|
||||
public partial bool IsMemberSelected { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _memberHasEmail;
|
||||
public partial bool IsMemberSelectedOrCreating { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _memberCanSendEmail;
|
||||
public partial bool MemberHasEmail { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _enableMemberReferenceButton;
|
||||
public partial bool MemberCanSendEmail { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _enableSearchInputs = true;
|
||||
public partial bool EnableMemberReferenceButton { get; set; }
|
||||
[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]
|
||||
private bool _memberListOrderByMgNr;
|
||||
public partial bool MemberListOrderByMgNr { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _memberListOrderByName;
|
||||
public partial bool MemberListOrderByName { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _memberListOrderByOrt;
|
||||
public partial bool MemberListOrderByOrt { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _mgNrString;
|
||||
public partial string? MgNrString { get; set; }
|
||||
public int? MgNr {
|
||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||
set => MgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _predecessorMgNrString;
|
||||
public partial string? PredecessorMgNrString { get; set; }
|
||||
public int? PredecessorMgNr {
|
||||
get => int.TryParse(PredecessorMgNrString, out var mgnr) ? mgnr : null;
|
||||
set => PredecessorMgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private bool _isJuridicalPerson;
|
||||
public partial bool IsJuridicalPerson { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _prefix;
|
||||
public partial string? Prefix { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _givenName;
|
||||
public partial string? GivenName { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _name;
|
||||
public partial string? Name { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _suffix;
|
||||
public partial string? Suffix { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _forTheAttentionOf;
|
||||
public partial string? ForTheAttentionOf { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _birthday;
|
||||
public partial string? Birthday { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _age;
|
||||
public partial string? Age { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isDeceased;
|
||||
public partial bool IsDeceased { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _address;
|
||||
public partial string? Address { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _plzString;
|
||||
public partial string? PlzString { get; set; }
|
||||
public int? Plz {
|
||||
get => int.TryParse(PlzString, out var plz) ? plz : null;
|
||||
set => PlzString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private AT_PlzDest? _ort;
|
||||
public partial AT_PlzDest? Ort { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<AT_PlzDest> _ortSource = [];
|
||||
public partial IEnumerable<AT_PlzDest> OrtSource { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _billingName;
|
||||
public partial string? BillingName { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _billingAddress;
|
||||
public partial string? BillingAddress { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _billingPlzString;
|
||||
public partial string? BillingPlzString { get; set; }
|
||||
public int? BillingPlz {
|
||||
get => int.TryParse(BillingPlzString, out var plz) ? plz : null;
|
||||
set => BillingPlzString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private AT_PlzDest? _billingOrt;
|
||||
public partial AT_PlzDest? BillingOrt { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<AT_PlzDest> _billingOrtSource = [];
|
||||
public partial IEnumerable<AT_PlzDest> BillingOrtSource { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _iban;
|
||||
public partial string? Iban { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _bic;
|
||||
public partial string? Bic { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _ustIdNr;
|
||||
public partial string? UstIdNr { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _lfbisNr;
|
||||
public partial string? LfbisNr { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isBuchführend;
|
||||
public partial string? OrganicOperatorId { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isOrganic;
|
||||
public partial string? OrganicAuthorityCode { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial bool IsBuchführend { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial bool IsOrganic { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _entryDate;
|
||||
public partial string? OrganicState { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _exitDate;
|
||||
public partial string? OrganicDetails { get; set; } = "-";
|
||||
[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 {
|
||||
get => int.TryParse(BusinessShares1String, out var shares) ? shares : null;
|
||||
set => BusinessShares1String = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _businessShares2String;
|
||||
public partial string? BusinessShares2String { get; set; }
|
||||
public int? BusinessShares2 {
|
||||
get => int.TryParse(BusinessShares2String, out var shares) ? shares : null;
|
||||
set => BusinessShares2String = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _businessShares3String;
|
||||
public partial string? BusinessShares3String { get; set; }
|
||||
public int? BusinessShares3 {
|
||||
get => int.TryParse(BusinessShares3String, out var shares) ? shares : null;
|
||||
set => BusinessShares3String = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _accountingNr;
|
||||
public partial string? AccountingNr { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isActive;
|
||||
public partial bool IsActive { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isVollLieferant;
|
||||
public partial bool IsVollLieferant { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isFunktionär;
|
||||
public partial bool IsFunktionär { get; set; }
|
||||
[ObservableProperty]
|
||||
private Branch? _branch;
|
||||
public partial Branch? Branch { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Branch> _branchSource = [];
|
||||
public partial IEnumerable<Branch> BranchSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private AT_Kg? _defaultKg;
|
||||
public partial AT_Kg? DefaultKg { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<AT_Kg> _defaultKgSource = [];
|
||||
public partial IEnumerable<AT_Kg> DefaultKgSource { get; set; } = [];
|
||||
[ObservableProperty]
|
||||
private string? _comment;
|
||||
public partial string? Comment { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _contactViaPost;
|
||||
public partial bool ContactViaPost { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _contactViaEmail;
|
||||
public partial bool ContactViaEmail { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string _createdAt = "-";
|
||||
public partial string CreatedAt { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _modifiedAt = "-";
|
||||
public partial string ModifiedAt { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _modifiedAtShort = "-";
|
||||
public partial string ModifiedAtShort { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _exportedAt = "-";
|
||||
public partial string ExportedAt { get; set; } = "-";
|
||||
[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 partial class PhoneNr(int? type = null, string? number = null, string? comment = null) : ObservableObject {
|
||||
[ObservableProperty]
|
||||
public int _type = type ?? -1;
|
||||
public partial int Type { get; set; } = type ?? -1;
|
||||
[ObservableProperty]
|
||||
public string? _number = number;
|
||||
public partial string? Number { get; set; } = number;
|
||||
[ObservableProperty]
|
||||
public string? _comment = comment;
|
||||
public partial string? Comment { get; set; } = comment;
|
||||
|
||||
public override bool Equals(object? obj) {
|
||||
return obj is PhoneNr nr && Type == nr.Type && Number == nr.Number && Comment == nr.Comment;
|
||||
@@ -197,37 +215,37 @@ namespace Elwig.ViewModels {
|
||||
public ObservableCollection<PhoneNr> PhoneNrs { get; private set; } = [new(), new(), new(), new(), new(), new(), new(), new(), new()];
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusMembers = "-";
|
||||
public partial string StatusMembers { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string? _statusMembersToolTip;
|
||||
public partial string? StatusMembersToolTip { get; set; }
|
||||
[ObservableProperty]
|
||||
private TextBlock? _statusBusinessShares;
|
||||
public partial TextBlock? StatusBusinessShares { get; set; }
|
||||
[ObservableProperty]
|
||||
private string _statusDeliveriesLastSeason = "-";
|
||||
public partial string StatusDeliveriesLastSeason { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusDeliveriesLastSeasonInfo = "letzte Saison";
|
||||
public partial string StatusDeliveriesLastSeasonInfo { get; set; } = "letzte Saison";
|
||||
[ObservableProperty]
|
||||
private Grid? _statusDeliveriesLastSeasonToolTip;
|
||||
public partial Grid? StatusDeliveriesLastSeasonToolTip { get; set; }
|
||||
[ObservableProperty]
|
||||
private string _statusDeliveriesThisSeason = "-";
|
||||
public partial string StatusDeliveriesThisSeason { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusDeliveriesThisSeasonInfo = "aktuelle Saison";
|
||||
public partial string StatusDeliveriesThisSeasonInfo { get; set; } = "aktuelle Saison";
|
||||
[ObservableProperty]
|
||||
private Grid? _statusDeliveriesThisSeasonToolTip;
|
||||
public partial Grid? StatusDeliveriesThisSeasonToolTip { get; set; }
|
||||
[ObservableProperty]
|
||||
private string _statusAreaCommitment = "-";
|
||||
public partial string StatusAreaCommitment { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private Grid? _statusAreaCommitmentToolTip;
|
||||
public partial Grid? StatusAreaCommitmentToolTip { get; set; }
|
||||
[ObservableProperty]
|
||||
private string _statusAreaCommitmentInfo = "aktuelle Saison";
|
||||
public partial string StatusAreaCommitmentInfo { get; set; } = "aktuelle Saison";
|
||||
|
||||
[ObservableProperty]
|
||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
||||
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
||||
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||
[ObservableProperty]
|
||||
private Visibility _personalNameVisibility = Visibility.Visible;
|
||||
public partial Visibility PersonalNameVisibility { get; set; } = Visibility.Visible;
|
||||
[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 {
|
||||
|
||||
[ObservableProperty]
|
||||
private string _title = "Geschäftsanteilbewegungen - Elwig";
|
||||
public partial string Title { get; set; } = "Geschäftsanteilbewegungen - Elwig";
|
||||
|
||||
public required Member FilterMember { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private MemberHistory? _selectedHistoryEntry;
|
||||
public partial MemberHistory? SelectedHistoryEntry { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<MemberHistory> _history = [];
|
||||
public partial IEnumerable<MemberHistory> History { get; set; } = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _dateNoticeString;
|
||||
public partial string? DateNoticeString { get; set; }
|
||||
public DateOnly? DateNotice {
|
||||
get => DateOnly.TryParseExact(DateNoticeString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => DateNoticeString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _dateEffectiveString;
|
||||
public partial string? DateEffectiveString { get; set; }
|
||||
public DateOnly? DateEffective {
|
||||
get => DateOnly.TryParseExact(DateEffectiveString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => DateEffectiveString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _reason;
|
||||
public partial string? Reason { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _sharesString;
|
||||
public partial string? SharesString { get; set; }
|
||||
public int? Shares {
|
||||
get => int.TryParse(SharesString, out var shares) ? shares : null;
|
||||
set => SharesString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _otherMgNrString;
|
||||
public partial string? OtherMgNrString { get; set; }
|
||||
public int? OtherMgNr {
|
||||
get => int.TryParse(OtherMgNrString, out var mgnr) ? mgnr : null;
|
||||
set => OtherMgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _deductYearString;
|
||||
public partial string? DeductYearString { get; set; }
|
||||
public int? DeductYear {
|
||||
get => int.TryParse(DeductYearString, out var year) ? year : null;
|
||||
set => DeductYearString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private bool _deduct;
|
||||
public partial bool Deduct { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _memberHasSigned;
|
||||
public partial bool CompanyHasSigned { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _valuePerShareString;
|
||||
public partial bool MemberHasSigned { get; set; }
|
||||
[ObservableProperty]
|
||||
public partial string? ValuePerShareString { get; set; }
|
||||
public decimal? ValuePerShare {
|
||||
get => decimal.TryParse(ValuePerShareString, out var v) ? v : null;
|
||||
set => ValuePerShareString = $"{value:0.00}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string? _totalAmount;
|
||||
public partial string? TotalAmount { get; set; }
|
||||
[ObservableProperty]
|
||||
private string? _comment;
|
||||
public partial string? Comment { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
||||
public partial Visibility ControlButtonsVisibility { get; set; } = Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
||||
public partial Visibility EditingButtonsVisibility { get; set; } = Visibility.Hidden;
|
||||
[ObservableProperty]
|
||||
private Visibility _personalNameVisibility = Visibility.Visible;
|
||||
public partial Visibility PersonalNameVisibility { get; set; } = Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
private Visibility _juridicalNameVisibility = Visibility.Hidden;
|
||||
public partial Visibility JuridicalNameVisibility { get; set; } = Visibility.Hidden;
|
||||
}
|
||||
}
|
||||
@@ -9,87 +9,87 @@ namespace Elwig.ViewModels {
|
||||
public partial class PaymentVariantsViewModel : ObservableObject {
|
||||
|
||||
[ObservableProperty]
|
||||
private PaymentVar? _selectedPaymentVariant;
|
||||
public partial PaymentVar? SelectedPaymentVariant { get; set; }
|
||||
[ObservableProperty]
|
||||
private IEnumerable<PaymentVar> _paymentVariants = [];
|
||||
public partial IEnumerable<PaymentVar> PaymentVariants { get; set; } = [];
|
||||
|
||||
public BillingData? BillingData;
|
||||
public bool SeasonLocked = false; // never locked
|
||||
public bool WeightModifierChanged;
|
||||
public BillingData? BillingData { get; set; }
|
||||
public bool SeasonLocked { get; set; } = false; // never locked
|
||||
public bool WeightModifierChanged { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private string _name = "";
|
||||
public partial string Name { get; set; } = "";
|
||||
[ObservableProperty]
|
||||
private string _comment = "";
|
||||
public partial string Comment { get; set; } = "";
|
||||
[ObservableProperty]
|
||||
private string _dateString = "";
|
||||
public partial string DateString { get; set; } = "";
|
||||
public DateOnly? Date {
|
||||
get => DateOnly.TryParseExact(DateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => DateString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string _transferDateString = "";
|
||||
public partial string TransferDateString { get; set; } = "";
|
||||
public DateOnly? TransferDate {
|
||||
get => DateOnly.TryParseExact(TransferDateString, "dd.MM.yyyy", out var d) ? d : null;
|
||||
set => TransferDateString = $"{value:dd.MM.yyyy}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string _weightModifierString = "";
|
||||
public partial string WeightModifierString { get; set; } = "";
|
||||
public double? WeightModifier {
|
||||
get => double.TryParse(WeightModifierString, out var d) ? d : null;
|
||||
set => WeightModifierString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private string _data = "";
|
||||
public partial string Data { get; set; } = "";
|
||||
[ObservableProperty]
|
||||
private bool _considerModifiers;
|
||||
public partial bool ConsiderModifiers { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _considerPenalties;
|
||||
public partial bool ConsiderPenalties { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _considerPenalty;
|
||||
public partial bool ConsiderPenalty { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _considerAuto;
|
||||
public partial bool ConsiderAuto { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _considerCustom;
|
||||
public partial bool ConsiderCustom { get; set; }
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _isPaymentVariantSelected;
|
||||
public partial bool IsPaymentVariantSelected { get; set; }
|
||||
[ObservableProperty]
|
||||
private bool _isReadOnly = true;
|
||||
public partial bool IsReadOnly { get; set; } = true;
|
||||
[ObservableProperty]
|
||||
private bool _dataIsReadOnly = true;
|
||||
public partial bool DataIsReadOnly { get; set; } = true;
|
||||
[ObservableProperty]
|
||||
private bool _isEnabled = false;
|
||||
public partial bool IsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private bool _saveIsEnabled = false;
|
||||
public partial bool SaveIsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private bool _deleteIsEnabled = false;
|
||||
public partial bool DeleteIsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private bool _calculateIsEnabled = false;
|
||||
public partial bool CalculateIsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private bool _exportIsEnabled = false;
|
||||
public partial bool ExportIsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private bool _commitIsEnabled = false;
|
||||
public partial bool CommitIsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private Visibility _commitVisibility = Visibility.Visible;
|
||||
public partial Visibility CommitVisibility { get; set; } = Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
private bool _revertIsEnabled = false;
|
||||
public partial bool RevertIsEnabled { get; set; } = false;
|
||||
[ObservableProperty]
|
||||
private Visibility _revertVisibility = Visibility.Hidden;
|
||||
public partial Visibility RevertVisibility { get; set; } = Visibility.Hidden;
|
||||
[ObservableProperty]
|
||||
private string _arrow = "\xF0AF";
|
||||
public partial string Arrow { get; set; } = "\xF0AF";
|
||||
[ObservableProperty]
|
||||
private string _editText = "Bearbeiten";
|
||||
public partial string EditText { get; set; } = "Bearbeiten";
|
||||
|
||||
[ObservableProperty]
|
||||
private string _statusModifierSum = "-";
|
||||
public partial string StatusModifierSum { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusTotalSum = "-";
|
||||
public partial string StatusTotalSum { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusVatSum = "-";
|
||||
public partial string StatusVatSum { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusDeductionSum = "-";
|
||||
public partial string StatusDeductionSum { get; set; } = "-";
|
||||
[ObservableProperty]
|
||||
private string _statusPaymentSum = "-";
|
||||
public partial string StatusPaymentSum { get; set; } = "-";
|
||||
}
|
||||
}
|
||||
@@ -108,12 +108,20 @@ namespace Elwig.Windows {
|
||||
LockInputs();
|
||||
}
|
||||
|
||||
public void TryClose() {
|
||||
var evt = new CancelEventArgs();
|
||||
OnClosing(this, evt);
|
||||
if (!evt.Cancel) Close();
|
||||
}
|
||||
|
||||
private void OnClosing(object? sender, CancelEventArgs evt) {
|
||||
if ((IsCreating || IsEditing) && HasChanged) {
|
||||
if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) {
|
||||
evt.Cancel = true;
|
||||
return;
|
||||
}
|
||||
if (!IsClosing && (IsCreating || IsEditing) && HasChanged) {
|
||||
try {
|
||||
if (!InteractionService.AskConfirmation("Schließen bestätigen", "Soll das Fenster wirklich geschlossen werden?")) {
|
||||
evt.Cancel = true;
|
||||
return;
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
IsClosing = true;
|
||||
}
|
||||
@@ -434,7 +442,7 @@ namespace Elwig.Windows {
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
protected void TextBox_TextChanged(object sender, RoutedEventArgs? evt) {
|
||||
protected void TextBox_TextChanged(object sender, TextChangedEventArgs? evt) {
|
||||
var input = (Control)sender;
|
||||
var tb = input as TextBox;
|
||||
if (SenderIsRequired(input) && tb?.Text.Length == 0) {
|
||||
@@ -576,6 +584,14 @@ namespace Elwig.Windows {
|
||||
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) {
|
||||
InputTextChanged((TextBox)sender, Validator.CheckOrganicAuthorityCode);
|
||||
}
|
||||
@@ -595,5 +611,13 @@ namespace Elwig.Windows {
|
||||
protected void AreaComTypeDetailsButton_Click(object sender, RoutedEventArgs? evt) {
|
||||
App.FocusBaseDataAreaComType();
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ namespace Elwig.Windows {
|
||||
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
|
||||
using var ctx = new AppDbContext();
|
||||
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||
ExemptInputs = [
|
||||
AreaCommitmentList, RevisionList,
|
||||
NewAreaCommitmentButton, EditAreaCommitmentButton, DeleteAreaCommitmentButton, SaveButton,
|
||||
@@ -51,9 +50,9 @@ namespace Elwig.Windows {
|
||||
var cursor = Mouse.OverrideCursor != null;
|
||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||
var query = (vm.SearchQuery, vm.FilterSeason);
|
||||
var (filter, contracts, areaComs, areaComCount, stat) = await Task.Run(async () => {
|
||||
var (filterNames, filter, contracts, areaComs, areaComCount, stat) = await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
||||
var (filterNames, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
||||
var contracts = await contractQuery
|
||||
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
||||
.ToListAsync();
|
||||
@@ -73,11 +72,12 @@ namespace Elwig.Windows {
|
||||
var season = await ctx.FetchSeasons().FirstOrDefaultAsync();
|
||||
var stat = await AreaComService.GenerateToolTipData(areaComQuery, season?.MaxKgPerHa ?? 10_000);
|
||||
|
||||
return (filter, contracts, areaComs, areaComCount, stat);
|
||||
return (filterNames, filter, contracts, areaComs, areaComCount, stat);
|
||||
});
|
||||
if (!cursor) Mouse.OverrideCursor = null;
|
||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason)) return;
|
||||
|
||||
ViewModel.Title = Utils.GetTitle("Flächenbindungen", filterNames, filter);
|
||||
ControlUtils.RenewItemsSource(AreaCommitmentList, contracts,
|
||||
AreaCommitmentList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||
RefreshInputs();
|
||||
@@ -164,7 +164,6 @@ namespace Elwig.Windows {
|
||||
return;
|
||||
}
|
||||
ViewModel.FilterMember = m;
|
||||
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||
|
||||
ControlUtils.RenewItemsSource(KgInput, await ctx.WbKgs
|
||||
.Include(k => k.AtKg.WbKg!.Rds)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
<Label Content="Adresse:"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="0" Margin="10,160,0,10"/>
|
||||
<TextBox x:Name="ClientAddressInput"
|
||||
TextChanged="TextBox_TextChanged"
|
||||
TextChanged="AddressInput_TextChanged"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Stretch" Grid.Column="1" Margin="0,160,10,10"/>
|
||||
|
||||
<Label Content="PLZ/Ort:"
|
||||
@@ -109,24 +109,30 @@
|
||||
<TextBox x:Name="ClientBicInput" Margin="0,250,10,0" Grid.Column="1"
|
||||
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.:"
|
||||
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"
|
||||
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"/>
|
||||
|
||||
<Label Content="Bio-Kontrollstelle:"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,130,110,10"/>
|
||||
<TextBox x:Name="ClientOrganicAuthorityInput"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right" Grid.Column="3" Margin="10,130,10,10" Width="90"
|
||||
<Label Content="UID:"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,130,0,10"/>
|
||||
<TextBox x:Name="ClientUstIdNrInput"
|
||||
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"/>
|
||||
|
||||
<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.:"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="2" Margin="10,160,0,10"/>
|
||||
<TextBox x:Name="ClientPhoneNrInput" Margin="0,160,10,10" Grid.Column="3"
|
||||
@@ -320,6 +326,10 @@
|
||||
<Label Content="Beschreibung:" Margin="10,70,0,10"/>
|
||||
<TextBox x:Name="WineCultivationDescriptionInput" Grid.Column="1" Margin="0,70,10,10"
|
||||
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>
|
||||
</TabItem>
|
||||
|
||||
@@ -72,10 +72,12 @@ namespace Elwig.Windows {
|
||||
WineCultivationIdInput.Text = "";
|
||||
WineCultivationNameInput.Text = "";
|
||||
WineCultivationDescriptionInput.Text = "";
|
||||
WineCultivationOrganicInput.IsChecked = false;
|
||||
} else {
|
||||
WineCultivationIdInput.Text = cult.CultId;
|
||||
WineCultivationNameInput.Text = cult.Name;
|
||||
WineCultivationDescriptionInput.Text = cult.Description;
|
||||
WineCultivationOrganicInput.IsChecked = cult.IsOrganic;
|
||||
}
|
||||
_cultUpdate = false;
|
||||
}
|
||||
@@ -105,7 +107,8 @@ namespace Elwig.Windows {
|
||||
_cultChanged = _cultChanged ||
|
||||
WineCultivationIdInput.Text != cult.CultId ||
|
||||
WineCultivationNameInput.Text != cult.Name ||
|
||||
WineCultivationDescriptionInput.Text != (cult.Description ?? "");
|
||||
WineCultivationDescriptionInput.Text != (cult.Description ?? "") ||
|
||||
WineCultivationOrganicInput.IsChecked != cult.IsOrganic;
|
||||
|
||||
var old = _cultIds.GetValueOrDefault(cult);
|
||||
var id = WineCultivationIdInput.Text ?? "";
|
||||
@@ -113,7 +116,8 @@ namespace Elwig.Windows {
|
||||
cult.CultId = id;
|
||||
cult.Name = WineCultivationNameInput.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();
|
||||
UpdateButtons();
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Elwig.Windows {
|
||||
BranchAddressInput, BranchPhoneNrInput, BranchFaxNrInput, BranchMobileNrInput,
|
||||
WineAttributeIdInput, WineAttributeNameInput, WineAttributeActiveInput,
|
||||
WineAttributeMaxKgPerHaInput, WineAttributeStrictInput, WineAttributeFillLowerInput,
|
||||
WineCultivationIdInput, WineCultivationNameInput, WineCultivationDescriptionInput,
|
||||
WineCultivationIdInput, WineCultivationNameInput, WineCultivationDescriptionInput, WineCultivationOrganicInput,
|
||||
AreaCommitmentTypeIdInput, AreaCommitmentTypeWineVariantInput, AreaCommitmentTypeWineAttributeInput,
|
||||
AreaCommitmentTypeMinKgPerHaInput, AreaCommitmentTypePenaltyPerKgInput,
|
||||
AreaCommitmentTypePenaltyInput, AreaCommitmentTypePenaltyNoneInput,
|
||||
@@ -67,6 +67,7 @@ namespace Elwig.Windows {
|
||||
WineCultivationIdInput.IsReadOnly = true;
|
||||
WineCultivationNameInput.IsReadOnly = true;
|
||||
WineCultivationDescriptionInput.IsReadOnly = true;
|
||||
WineCultivationOrganicInput.IsEnabled = false;
|
||||
|
||||
AreaCommitmentTypeWineVariantInput.IsEnabled = false;
|
||||
AreaCommitmentTypeWineAttributeInput.IsEnabled = false;
|
||||
@@ -115,6 +116,7 @@ namespace Elwig.Windows {
|
||||
WineCultivationIdInput.IsReadOnly = false;
|
||||
WineCultivationNameInput.IsReadOnly = false;
|
||||
WineCultivationDescriptionInput.IsReadOnly = false;
|
||||
WineCultivationOrganicInput.IsEnabled = true;
|
||||
|
||||
AreaCommitmentTypeWineVariantInput.IsEnabled = true;
|
||||
AreaCommitmentTypeWineAttributeInput.IsEnabled = true;
|
||||
@@ -329,7 +331,8 @@ namespace Elwig.Windows {
|
||||
ClientBicInput.Text = p.Bic;
|
||||
ClientUstIdNrInput.Text = p.UstIdNr;
|
||||
ClientLfbisNrInput.Text = p.LfbisNr;
|
||||
ClientOrganicAuthorityInput.Text = p.OrganicAuthority;
|
||||
ClientOrganicOperatorIdInput.Text = p.OrganicOperatorId;
|
||||
ClientOrganicAuthorityCodeInput.Text = p.OrganicAuthorityCode;
|
||||
ClientPhoneNrInput.Text = p.PhoneNr;
|
||||
ClientFaxNrInput.Text = p.FaxNr;
|
||||
ClientEmailAddressInput.Text = p.EmailAddress;
|
||||
@@ -369,7 +372,8 @@ namespace Elwig.Windows {
|
||||
p.Bic = string.IsNullOrWhiteSpace(ClientBicInput.Text) ? null : ClientBicInput.Text;
|
||||
p.UstIdNr = string.IsNullOrWhiteSpace(ClientUstIdNrInput.Text) ? null : ClientUstIdNrInput.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.FaxNr = string.IsNullOrWhiteSpace(ClientFaxNrInput.Text) ? null : ClientFaxNrInput.Text;
|
||||
p.EmailAddress = string.IsNullOrWhiteSpace(ClientEmailAddressInput.Text) ? null : ClientEmailAddressInput.Text;
|
||||
|
||||
@@ -398,7 +398,8 @@
|
||||
<Grid Grid.Row="1" Grid.Column="2">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="0.625*"/>
|
||||
<RowDefinition Height="0.875*"/>
|
||||
<RowDefinition Height="0.8125*"/>
|
||||
<RowDefinition Height="0.0625*"/>
|
||||
<RowDefinition Height="0.875*"/>
|
||||
<RowDefinition Height="0.25*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
@@ -434,7 +435,7 @@
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Lieferung" Grid.Column="0" Grid.Row="1" Grid.RowSpan="3" Margin="5,5,5,5">
|
||||
<GroupBox Header="Lieferung" Grid.Column="0" Grid.Row="1" Grid.RowSpan="4" Margin="5,5,5,5">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100"/>
|
||||
@@ -517,6 +518,7 @@
|
||||
<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"
|
||||
DisplayMemberPath="Name"
|
||||
SelectionChanged="CultivationInput_SelectionChanged"
|
||||
KeyUp="Input_KeyUp"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
@@ -553,7 +555,7 @@
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Menge" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
|
||||
<GroupBox Header="Menge" Grid.Column="1" Grid.Row="2" Grid.RowSpan="2" Margin="5,5,5,5">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="70"/>
|
||||
@@ -565,16 +567,23 @@
|
||||
TextChanged="WeightInput_TextChanged"
|
||||
Grid.Column="1" Width="70" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||
|
||||
<Label Content="Tara:" Margin="10,40,10,10"/>
|
||||
<TextBlock x:Name="Tare" Text="{Binding TareString}" Width="40"
|
||||
Grid.Column="1" Margin="30,44,10,10" TextAlignment="Center" HorizontalAlignment="Left" VerticalAlignment="Top"/>
|
||||
|
||||
<CheckBox x:Name="ManualWeighingInput" IsChecked="{Binding IsManualWeighing, Mode=TwoWay}"
|
||||
Content="Handwiegung" IsEnabled="False"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,45,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
|
||||
|
||||
<CheckBox x:Name="GerebeltGewogenInput" IsChecked="{Binding IsNetWeightValue, Mode=TwoWay}"
|
||||
Content="Gerebelt gewogen" IsThreeState="True"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,100,10,10" Grid.Column="0" Grid.ColumnSpan="2"
|
||||
Checked="GerebeltGewogenInput_Changed" Unchecked="GerebeltGewogenInput_Changed" Indeterminate="GerebeltGewogenInput_Changed"/>
|
||||
|
||||
<Button x:Name="CorrectTareButton" Content="Tara korrigieren" Width="120" Visibility="Hidden"
|
||||
Click="CorrectTareButton_Click"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
|
||||
<Button x:Name="WeighingAButton" Content="Wiegen A" Width="120"
|
||||
Click="WeighingButton_Click"
|
||||
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
|
||||
@@ -593,7 +602,7 @@
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Sonstiges" Grid.Column="1" Grid.Row="3" Grid.RowSpan="2" Margin="5,5,5,10">
|
||||
<GroupBox Header="Sonstiges" Grid.Column="1" Grid.Row="4" Grid.RowSpan="2" Margin="5,5,5,10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100"/>
|
||||
@@ -646,7 +655,7 @@
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Herkunft" Grid.Column="0" Grid.Row="4" Margin="5,5,5,10">
|
||||
<GroupBox Header="Herkunft" Grid.Column="0" Grid.Row="5" Margin="5,5,5,10">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="100"/>
|
||||
|
||||
@@ -9,6 +9,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.Json.Nodes;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
@@ -103,6 +104,7 @@ namespace Elwig.Windows {
|
||||
WeighingBButton.Visibility = Visibility.Hidden;
|
||||
WeighingCButton.Visibility = Visibility.Hidden;
|
||||
WeighingDButton.Visibility = Visibility.Hidden;
|
||||
DisableWeighingButtons();
|
||||
}
|
||||
|
||||
Menu_Statistics_WineQuality_ModeOe.IsChecked = false;
|
||||
@@ -126,7 +128,6 @@ namespace Elwig.Windows {
|
||||
this() {
|
||||
using var ctx = new AppDbContext();
|
||||
ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||
ViewModel.EnableAllSeasons = true;
|
||||
}
|
||||
|
||||
@@ -419,9 +420,9 @@ namespace Elwig.Windows {
|
||||
var cursor = Mouse.OverrideCursor != null;
|
||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterAllSeasons, vm.FilterTodayOnly);
|
||||
var (filter, deliveries, deliveryPartsNum, varieties, members, stat) = await Task.Run(async () => {
|
||||
var (filterNames, filter, deliveries, deliveryPartsNum, varieties, members, stat) = await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
||||
var (filterNames, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
||||
var deliveries = await deliveryQuery
|
||||
.Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier)
|
||||
.Include(d => d.Parts).ThenInclude(p => p.Variety)
|
||||
@@ -450,11 +451,13 @@ namespace Elwig.Windows {
|
||||
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
||||
var stat = await DeliveryService.GenerateToolTipData(deliveryPartsQuery);
|
||||
|
||||
return (filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
||||
return (filterNames, filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
||||
});
|
||||
if (!cursor) Mouse.OverrideCursor = null;
|
||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterAllSeasons, ViewModel.FilterTodayOnly)) return;
|
||||
|
||||
if (!ViewModel.IsReceipt)
|
||||
ViewModel.Title = Utils.GetTitle("Lieferungen", filterNames, filter);
|
||||
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
||||
DeliveryList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||
await RefreshDeliveryParts();
|
||||
@@ -488,7 +491,6 @@ namespace Elwig.Windows {
|
||||
return;
|
||||
}
|
||||
ViewModel.FilterMember = m;
|
||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||
}
|
||||
|
||||
int year = 0;
|
||||
@@ -612,14 +614,34 @@ namespace Elwig.Windows {
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
ViewModel.FillInputs(p);
|
||||
CorrectTareButton.Visibility = !ViewModel.IsReceipt && ((ViewModel.ActualTare is int t && t != 0) || ViewModel.IsUnloadingBox) ? Visibility.Visible : Visibility.Hidden;
|
||||
FinishInputFilling();
|
||||
}
|
||||
|
||||
new protected void ClearInputs(bool validate = false) {
|
||||
ViewModel.ClearInputs();
|
||||
CorrectTareButton.Visibility = Visibility.Hidden;
|
||||
base.ClearInputs(validate);
|
||||
}
|
||||
|
||||
private void CorrectTareButton_Click(object sender, RoutedEventArgs evt) {
|
||||
var lastCorrection = (ViewModel.TargetTare ?? ViewModel.ActualTare ?? 0) - (ViewModel.ActualTare ?? 0);
|
||||
var correction = Utils.ShowTareCorrectionDialog(ViewModel.ActualTare, ViewModel.TargetTare);
|
||||
if (correction == null) return;
|
||||
ViewModel.Weight += lastCorrection - correction;
|
||||
if (ViewModel.WeighingData is string s) {
|
||||
ViewModel.TargetTare = correction == 0 ? null : (ViewModel.ActualTare ?? 0) + correction;
|
||||
ViewModel.Tare = ViewModel.TargetTare ?? ViewModel.ActualTare;
|
||||
var obj = JsonNode.Parse(s)!.AsObject();
|
||||
if (correction == 0) {
|
||||
obj.Remove("tare_correction");
|
||||
} else {
|
||||
obj["tare_correction"] = correction;
|
||||
}
|
||||
ViewModel.WeighingData = obj.ToJsonString(Utils.JsonOpts);
|
||||
}
|
||||
}
|
||||
|
||||
private void WeighingButton_Click(object sender, RoutedEventArgs evt) {
|
||||
int index = Array.IndexOf(WeighingButtons, sender as Button);
|
||||
if (index >= 0) WeighingButton_Click(index);
|
||||
@@ -651,12 +673,18 @@ namespace Elwig.Windows {
|
||||
private void OnWeighingResult(IScale scale, WeighingResult res) {
|
||||
if ((res.NetWeight ?? 0) > 0 && res.FullWeighingId != null) {
|
||||
ViewModel.Weight = res.NetWeight;
|
||||
ViewModel.ActualTare = res.TareWeight;
|
||||
ViewModel.TargetTare = null;
|
||||
ViewModel.Tare = ViewModel.ActualTare is int t && t != 0 ? t : null;
|
||||
ViewModel.ScaleTerminalId = scale.ScaleTerminalId;
|
||||
ViewModel.WeighingData = res.ToJson().ToJsonString();
|
||||
ViewModel.ManualWeighingReason = null;
|
||||
ManualWeighingInput.IsChecked = false;
|
||||
} else {
|
||||
ViewModel.Weight = null;
|
||||
ViewModel.ActualTare = null;
|
||||
ViewModel.TargetTare = null;
|
||||
ViewModel.Tare = null;
|
||||
ViewModel.ScaleTerminalId = null;
|
||||
ViewModel.WeighingData = null;
|
||||
}
|
||||
@@ -746,12 +774,12 @@ namespace Elwig.Windows {
|
||||
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);
|
||||
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;
|
||||
ViewModel.MgNr = m?.MgNr;
|
||||
ViewModel.MemberAddress = m?.FullAddress;
|
||||
@@ -768,6 +796,8 @@ namespace Elwig.Windows {
|
||||
SetDefaultValue(WineKgInput);
|
||||
ComboBox_SelectionChanged(WineKgInput, null);
|
||||
}
|
||||
if (IsCreating && Mouse.OverrideCursor == null)
|
||||
await CheckOrganic();
|
||||
}
|
||||
|
||||
private void EmptyScale() {
|
||||
@@ -777,6 +807,9 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (!await CheckOrganic(true))
|
||||
return;
|
||||
|
||||
FinishButton.IsEnabled = false;
|
||||
NewDeliveryPartButton.IsEnabled = false;
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
@@ -796,7 +829,7 @@ namespace Elwig.Windows {
|
||||
} catch (Exception exc) {
|
||||
InteractionService.ShowDbException("Lieferung aktualisieren", exc);
|
||||
FinishButton.IsEnabled = true;
|
||||
SaveButton.IsEnabled = true;
|
||||
NewDeliveryPartButton.IsEnabled = true;
|
||||
Mouse.OverrideCursor = null;
|
||||
DeliveryPartList.IsEnabled = true;
|
||||
return;
|
||||
@@ -805,14 +838,18 @@ namespace Elwig.Windows {
|
||||
EmptyScale();
|
||||
|
||||
await EnsureContextRenewed();
|
||||
Mouse.OverrideCursor = null;
|
||||
ControlUtils.SelectItemWithPk(DeliveryList, p?.Year, p?.DId);
|
||||
DeliveryPartList.SelectedItem = null;
|
||||
DeliveryPartList.ScrollIntoView(DeliveryPartList.ItemsSource.Cast<object>().LastOrDefault());
|
||||
InitialInputs();
|
||||
|
||||
Mouse.OverrideCursor = null;
|
||||
}
|
||||
|
||||
private async void FinishButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (!await CheckOrganic(true))
|
||||
return;
|
||||
|
||||
FinishButton.IsEnabled = false;
|
||||
NewDeliveryPartButton.IsEnabled = false;
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
@@ -832,7 +869,7 @@ namespace Elwig.Windows {
|
||||
} catch (Exception exc) {
|
||||
InteractionService.ShowDbException("Lieferung aktualisieren", exc);
|
||||
FinishButton.IsEnabled = true;
|
||||
SaveButton.IsEnabled = true;
|
||||
NewDeliveryPartButton.IsEnabled = true;
|
||||
Mouse.OverrideCursor = null;
|
||||
DeliveryPartList.IsEnabled = true;
|
||||
return;
|
||||
@@ -971,6 +1008,8 @@ namespace Elwig.Windows {
|
||||
DeliveryList.IsEnabled = false;
|
||||
DeliveryPartList.IsEnabled = false;
|
||||
|
||||
if (!ViewModel.IsReceipt)
|
||||
EnableWeighingButtons();
|
||||
HideNewEditDeleteButtons();
|
||||
ShowSaveResetCancelButtons();
|
||||
UnlockInputs();
|
||||
@@ -1008,6 +1047,9 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
if (!await CheckOrganic(true))
|
||||
return;
|
||||
|
||||
SaveButton.IsEnabled = false;
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
|
||||
@@ -1034,6 +1076,8 @@ namespace Elwig.Windows {
|
||||
DeliveryList.IsEnabled = true;
|
||||
DeliveryPartList.IsEnabled = true;
|
||||
|
||||
if (!ViewModel.IsReceipt)
|
||||
DisableWeighingButtons();
|
||||
HideSaveResetCancelButtons();
|
||||
ShowNewEditDeleteButtons();
|
||||
LockInputs();
|
||||
@@ -1067,6 +1111,8 @@ namespace Elwig.Windows {
|
||||
DeliveryList.IsEnabled = true;
|
||||
DeliveryPartList.IsEnabled = true;
|
||||
|
||||
if (!ViewModel.IsReceipt)
|
||||
DisableWeighingButtons();
|
||||
HideSaveResetCancelButtons();
|
||||
ShowNewEditDeleteButtons();
|
||||
RefreshInputs();
|
||||
@@ -1171,6 +1217,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void DisableWeighingButtons() {
|
||||
CorrectTareButton.IsEnabled = false;
|
||||
WeighingManualButton.IsEnabled = false;
|
||||
WeighingAButton.IsEnabled = false;
|
||||
WeighingBButton.IsEnabled = false;
|
||||
@@ -1179,6 +1226,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void EnableWeighingButtons() {
|
||||
CorrectTareButton.IsEnabled = true;
|
||||
WeighingManualButton.IsEnabled = true;
|
||||
var n = App.CommandScales.Count;
|
||||
WeighingAButton.IsEnabled = n > 0 && App.CommandScales[0].IsReady;
|
||||
@@ -1373,6 +1421,8 @@ namespace Elwig.Windows {
|
||||
|
||||
private void UnloadingInput_Checked(object sender, RoutedEventArgs evt) {
|
||||
if (!IsEditing && !IsCreating) return;
|
||||
if (!ViewModel.IsReceipt)
|
||||
CorrectTareButton.Visibility = (ViewModel.ActualTare is int t && t != 0) || ViewModel.IsUnloadingBox ? Visibility.Visible : Visibility.Hidden;
|
||||
var mod = ViewModel.Modifiers.ToList();
|
||||
var source = ViewModel.ModifiersSource.ToList();
|
||||
if (App.Client.IsMatzen) {
|
||||
@@ -1501,5 +1551,43 @@ namespace Elwig.Windows {
|
||||
if (MemberInput.SelectedItem is not Member m) return;
|
||||
App.FocusMember(m.MgNr);
|
||||
}
|
||||
|
||||
private async void CultivationInput_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||
if (IsCreating && Mouse.OverrideCursor == null)
|
||||
await CheckOrganic();
|
||||
}
|
||||
|
||||
private async Task<bool> CheckOrganic(bool confirm = false) {
|
||||
if (MemberInput.SelectedValue is not Member m || CultivationInput.SelectedItem is not WineCult c) {
|
||||
return true;
|
||||
} else if (c.IsOrganic) {
|
||||
if (m.IsOrganic) {
|
||||
var valid = true;
|
||||
if (IsCreating) {
|
||||
try {
|
||||
var certs = await OrganicService.GetTracesCertificates(m);
|
||||
valid = certs.Any(c => c.IsValidForWineProduction);
|
||||
} catch { }
|
||||
}
|
||||
if (valid)
|
||||
return true;
|
||||
if (confirm) {
|
||||
return InteractionService.AskConfirmation("Kein gültiges Bio-Zertifikat", "Soll die Bio-Lieferung wirklich gespeichert werden,\nobwohl für das Mitglied kein gültiges Bio-Zertifikat gefunden werden konnte?");
|
||||
} else {
|
||||
InteractionService.ShowWarning("Kein gültiges Bio-Zertifikat", "Achtung! Für diesen Bio-Betrieb konnte kein gültiges Bio-Zertifikat gefunden werden!");
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (confirm) {
|
||||
return InteractionService.AskConfirmation("Kein Bio-Betrieb", "Soll die Bio-Lieferung wirklich gespeichert werden, obwohl das Mitglied keinen Bio-Betrieb hat?");
|
||||
} else {
|
||||
InteractionService.ShowWarning("Kein Bio-Betrieb", "Achtung! Bio-Lieferung ohne Bio-Betrieb!");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:local="clr-namespace:Elwig.Windows"
|
||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||
Title="Anmeldungen - Elwig" Height="700" Width="980" MinWidth="600" MinHeight="400">
|
||||
Title="{Binding Title}" Height="700" Width="980" MinWidth="600" MinHeight="400">
|
||||
<Window.DataContext>
|
||||
<vm:DeliveryAncmtAdminViewModel/>
|
||||
</Window.DataContext>
|
||||
|
||||
@@ -103,9 +103,9 @@ namespace Elwig.Windows {
|
||||
var cursor = Mouse.OverrideCursor != null;
|
||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterOnlyUpcoming, vm.FilterOnlyUpcoming);
|
||||
var (filter, deliveryAncmts, stat) = await Task.Run(async () => {
|
||||
var (filterNames, filter, deliveryAncmts, stat) = await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, deliveryAncmtQuery, filter) = await vm.GetFilters(ctx);
|
||||
var (filterNames, deliveryAncmtQuery, filter) = await vm.GetFilters(ctx);
|
||||
var deliveryAncmts = await deliveryAncmtQuery.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
||||
@@ -130,11 +130,12 @@ namespace Elwig.Windows {
|
||||
|
||||
var stat = await DeliveryAncmtService.GenerateToolTipData(deliveryAncmtQuery);
|
||||
|
||||
return (filter, deliveryAncmts, stat);
|
||||
return (filterNames, filter, deliveryAncmts, stat);
|
||||
});
|
||||
if (!cursor) Mouse.OverrideCursor = null;
|
||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterOnlyUpcoming, ViewModel.FilterOnlyUpcoming)) return;
|
||||
|
||||
ViewModel.Title = Utils.GetTitle("Anmeldungen", filterNames, filter);
|
||||
ControlUtils.RenewItemsSource(DeliveryAncmtList, deliveryAncmts,
|
||||
DeliveryAncmtList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||
if (updateSort && DeliveryAncmtList.SelectedItem != null)
|
||||
@@ -207,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) {
|
||||
@@ -257,6 +278,8 @@ namespace Elwig.Windows {
|
||||
var m = MemberInput.SelectedItem as Member;
|
||||
ViewModel.MgNr = m?.MgNr;
|
||||
ViewModel.MemberAddress = m?.FullAddress;
|
||||
if (IsCreating)
|
||||
CheckOrganic();
|
||||
}
|
||||
|
||||
protected override void ShortcutNew() {
|
||||
@@ -333,6 +356,9 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
if (!CheckOrganic(true))
|
||||
return;
|
||||
|
||||
Mouse.OverrideCursor = Cursors.Wait;
|
||||
SaveButton.IsEnabled = false;
|
||||
|
||||
|
||||
@@ -50,27 +50,23 @@ namespace Elwig.Windows {
|
||||
_syncTimer.Start();
|
||||
}
|
||||
|
||||
private async void Window_Closing(object sender, CancelEventArgs evt) {
|
||||
evt.Cancel = !App.ForceShutdown;
|
||||
|
||||
private void Window_Closing(object sender, CancelEventArgs evt) {
|
||||
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 {
|
||||
w.Close();
|
||||
} catch { }
|
||||
}
|
||||
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 (!InteractionService.AskConfirmation("Elwig beenden", "Es sind noch weitere Fenster geöffnet.\nSollen alle Fenster geschlossen werden?")) {
|
||||
if (App.NumWindows > 1) {
|
||||
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;
|
||||
}
|
||||
App.ForceShutdown = true;
|
||||
}
|
||||
}
|
||||
|
||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
await (Application.Current as App)!.OnClosing();
|
||||
Application.Current.Shutdown();
|
||||
App.CurrentApp.ShutdownGracefully();
|
||||
}
|
||||
|
||||
private void Menu_Help_About_Click(object sender, RoutedEventArgs evt) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:Elwig.Windows"
|
||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150">
|
||||
Title="{Binding Title}" Height="700" Width="1250" MinHeight="650" MinWidth="1150">
|
||||
<Window.DataContext>
|
||||
<vm:MemberAdminViewModel/>
|
||||
</Window.DataContext>
|
||||
@@ -371,7 +371,7 @@
|
||||
<Label Content="Adresse:" Margin="10,130,0,0"/>
|
||||
<TextBox x:Name="AddressInput" Text="{Binding Address, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
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"/>
|
||||
<TextBox x:Name="PlzInput" Margin="0,160,0,0" Text="{Binding PlzString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
@@ -379,6 +379,7 @@
|
||||
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||
<ComboBox x:Name="OrtInput" SelectedItem="{Binding Ort, Mode=TwoWay}" ItemsSource="{Binding OrtSource, Mode=TwoWay}"
|
||||
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
||||
SelectionChanged="OrtInput_SelectionChanged"
|
||||
Margin="47,160,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
@@ -547,35 +548,48 @@
|
||||
<GroupBox Header="Betrieb" Grid.Column="1" Grid.Row="0" Grid.RowSpan="1" Margin="5,5,5,5">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="150"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="85"/>
|
||||
<ColumnDefinition Width="69"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="55"/>
|
||||
<ColumnDefinition Width="101"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="UID:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||
<Label Content="Betriebs-Nr.:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||
<TextBox x:Name="LfbisNrInput" Text="{Binding LfbisNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,10,5,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right"
|
||||
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
|
||||
|
||||
<Label Content="UID:" Margin="10,40,0,0" Grid.Column="0" ToolTip="USt-IdNr. / Umsatzsteuer-Identifikationsnummer"/>
|
||||
<TextBox x:Name="UstIdNrInput" Text="{Binding UstIdNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,10,10,0" Grid.Column="1" Width="96" HorizontalAlignment="Left"
|
||||
Margin="0,40,5,0" Grid.Column="0" Grid.ColumnSpan="2" Width="96" HorizontalAlignment="Right"
|
||||
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}"
|
||||
Margin="0,40,10,0" Grid.Column="1" Width="64" HorizontalAlignment="Left" TextAlignment="Right"
|
||||
TextChanged="LfbisNrInput_TextChanged" LostFocus="LfbisNrInput_LostFocus"/>
|
||||
<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="BuchführendInput" Content="Buchführend" IsChecked="{Binding IsBuchführend, Mode=TwoWay}" IsEnabled="False"
|
||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||
Grid.Column="2" HorizontalAlignment="Left" Margin="10,15,0,0" VerticalAlignment="Top"/>
|
||||
Grid.Column="2" HorizontalAlignment="Left" Margin="5,45,0,0" VerticalAlignment="Top"/>
|
||||
|
||||
<CheckBox x:Name="OrganicInput" Content="Bio" IsChecked="{Binding IsOrganic, Mode=TwoWay}" IsEnabled="False"
|
||||
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
|
||||
Grid.Column="2" HorizontalAlignment="Left" Margin="10,45,0,0" VerticalAlignment="Top"/>
|
||||
<Button x:Name="OrganicButton" Content="easy-cert.com" IsEnabled="{Binding IsMemberSelected}"
|
||||
Height="25" FontSize="12"
|
||||
Click="OrganicButton_Click"
|
||||
Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="60,40,0,0"/>
|
||||
<Label Content="Kontrollstelle:" Margin="0,10,5,0" Grid.Column="2" Grid.ColumnSpan="2" HorizontalAlignment="Right" ToolTip="Bio-Kontrollstelle"/>
|
||||
<TextBox x:Name="OrganicAuthorityCodeInput" Text="{Binding OrganicAuthorityCode, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
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>
|
||||
</GroupBox>
|
||||
<GroupBox Header="Rechnungsadresse (optional)" 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>
|
||||
<TextBlock>Rechnungsadresse (optional)
|
||||
<Run FontSize="10">für Lieferschein, Anlfrg.-Bstng., Tr.-Gutschr.</Run>
|
||||
</TextBlock>
|
||||
</GroupBox.Header>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="65"/>
|
||||
@@ -590,7 +604,7 @@
|
||||
<Label Content="Adresse:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||
<TextBox x:Name="BillingAddressInput" Text="{Binding BillingAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
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"/>
|
||||
<TextBox x:Name="BillingPlzInput" Text="{Binding BillingPlzString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
@@ -598,6 +612,7 @@
|
||||
TextChanged="PlzInput_TextChanged" LostFocus="PlzInput_LostFocus" Tag="PLZ"/>
|
||||
<ComboBox x:Name="BillingOrtInput" SelectedItem="{Binding BillingOrt, Mode=TwoWay}" ItemsSource="{Binding BillingOrtSource, Mode=TwoWay}"
|
||||
ItemTemplate="{StaticResource PostalDestTemplate}" TextSearch.TextPath="Ort.Name"
|
||||
SelectionChanged="OrtInput_SelectionChanged"
|
||||
Margin="47,70,10,0" Grid.Column="1"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
@@ -605,7 +620,8 @@
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="120"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition Width="90"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
@@ -619,7 +635,7 @@
|
||||
Margin="0,40,10,0" Width="78" Grid.Column="1" HorizontalAlignment="Left" TextAlignment="Right"
|
||||
TextChanged="DateInput_TextChanged" LostFocus="DateInput_LostFocus"/>
|
||||
|
||||
<Label Content="BH-Konto:" Margin="10,70,0,0" Grid.Column="0"/>
|
||||
<Label Content="BH-Konto:" Margin="10,70,0,0" Grid.Column="0" ToolTip="Buchhaltungskonto"/>
|
||||
<TextBox x:Name="AccountingNrInput" Text="{Binding AccountingNr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Margin="0,70,10,0" Width="63" Grid.Column="1" HorizontalAlignment="Left"
|
||||
TextChanged="TextBox_TextChanged"/>
|
||||
@@ -642,46 +658,64 @@
|
||||
|
||||
<CheckBox x:Name="ActiveInput" Content="Aktiv" IsChecked="{Binding IsActive, Mode=TwoWay}" IsEnabled="False"
|
||||
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"
|
||||
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"
|
||||
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"/>
|
||||
<ComboBox x:Name="BranchInput" SelectedItem="{Binding Branch, Mode=TwoWay}" ItemsSource="{Binding BranchSource, Mode=TwoWay}"
|
||||
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"/>
|
||||
<ComboBox x:Name="DefaultKgInput" SelectedItem="{Binding DefaultKg, Mode=TwoWay}" ItemsSource="{Binding DefaultKgSource, Mode=TwoWay}"
|
||||
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="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
|
||||
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"/>
|
||||
<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"
|
||||
VerticalAlignment="Stretch" Height="auto" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/>
|
||||
|
||||
<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"
|
||||
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"
|
||||
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"/>
|
||||
<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>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -708,7 +742,7 @@
|
||||
|
||||
<Button x:Name="DeliveryButton" IsEnabled="{Binding IsMemberSelected}"
|
||||
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>
|
||||
<TextBlock Margin="0,0,10,0" TextAlignment="Center">Lieferungen</TextBlock>
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""
|
||||
@@ -717,7 +751,7 @@
|
||||
</Button>
|
||||
<Button x:Name="AreaCommitmentButton" IsEnabled="{Binding IsMemberSelected}"
|
||||
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>
|
||||
<TextBlock Margin="0,0,15,0" TextAlignment="Center">Flächenbindungen</TextBlock>
|
||||
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""
|
||||
|
||||
@@ -147,9 +147,9 @@ namespace Elwig.Windows {
|
||||
var cursor = Mouse.OverrideCursor != null;
|
||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
||||
var query = (vm.SearchQuery, vm.ShowOnlyActiveMembers);
|
||||
var (members, stat) = await Task.Run(async () => {
|
||||
var (filterNames, members, stat, filter) = await Task.Run(async () => {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, memberQuery, filter) = await vm.GetFilters(ctx);
|
||||
var (filterNames, memberQuery, filter) = await vm.GetFilters(ctx);
|
||||
var members = await memberQuery
|
||||
.Include(m => m.EmailAddresses)
|
||||
.Include(m => m.TelephoneNumbers)
|
||||
@@ -184,11 +184,12 @@ namespace Elwig.Windows {
|
||||
SharesActive = g.Sum(m => m.Shares + m.SharesRed + m.SharesWhite),
|
||||
}).ToListAsync()).Select(g => (g.Count, g.Shares, g.SharesRed, g.SharesWhite, g.SharesDormant, g.SharesTotal, g.SharesActive)).ToList();
|
||||
|
||||
return (members, stat[0]);
|
||||
return (filterNames, members, stat[0], filter);
|
||||
});
|
||||
if (!cursor) Mouse.OverrideCursor = null;
|
||||
if (query != (ViewModel.SearchQuery, ViewModel.ShowOnlyActiveMembers)) return;
|
||||
|
||||
ViewModel.Title = Utils.GetTitle("Mitglieder", filterNames, filter);
|
||||
ControlUtils.RenewItemsSource(MemberList, members,
|
||||
MemberList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||
if (updateSort && MemberList.SelectedItem != null)
|
||||
@@ -502,6 +503,8 @@ namespace Elwig.Windows {
|
||||
UnlockInputs();
|
||||
UpdateContactInfoVisibility(true);
|
||||
ViewModel.EnableSearchInputs = false;
|
||||
|
||||
UpdateOrganic();
|
||||
}
|
||||
|
||||
protected override void ShortcutDelete() {
|
||||
@@ -965,23 +968,13 @@ 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) {
|
||||
if (ViewModel.SelectedMember is not Member m || m.PredecessorMgNr == null) return;
|
||||
FocusMember((int)m.PredecessorMgNr);
|
||||
}
|
||||
|
||||
private async void ActiveInput_Changed(object sender, RoutedEventArgs evt) {
|
||||
CheckBox_Changed(sender, evt);
|
||||
if (MemberList.SelectedItem is not Member m)
|
||||
return;
|
||||
if ((IsEditing || IsCreating) && ViewModel.IsActive == false && ViewModel.MgNr is int mgnr) {
|
||||
@@ -996,7 +989,6 @@ namespace Elwig.Windows {
|
||||
}
|
||||
}
|
||||
}
|
||||
CheckBox_Changed(sender, evt);
|
||||
}
|
||||
|
||||
private void JuridicalPersonInput_Changed(object sender, RoutedEventArgs evt) {
|
||||
@@ -1019,5 +1011,100 @@ namespace Elwig.Windows {
|
||||
ValidateRequiredInputs();
|
||||
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"
|
||||
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"
|
||||
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"/>
|
||||
|
||||
<Label Content="Wirksam:" Margin="10,130,0,0" Grid.Column="0"/>
|
||||
|
||||
@@ -13,7 +13,7 @@ About
|
||||
**Product:** Elwig
|
||||
**Description:** Electronic Management for Vintners' Cooperatives
|
||||
**Type:** ERP system
|
||||
**Version:** 1.1.2.1 ([Changelog](./CHANGELOG.md))
|
||||
**Version:** 1.1.2.2 ([Changelog](./CHANGELOG.md))
|
||||
**License:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||
**Website:** https://elwig.at/
|
||||
**Source code:** https://git.necronda.net/winzer/elwig
|
||||
@@ -33,7 +33,7 @@ Packaging: [WiX Toolset](https://www.firegiant.com/wixtoolset/)
|
||||
**Produkt:** Elwig
|
||||
**Beschreibung:** Elektronische Winzergenossenschaftsverwaltung
|
||||
**Typ:** Warenwirtschaftssystem (ERP-System)
|
||||
**Version:** 1.1.2.1 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||
**Version:** 1.1.2.2 ([Änderungsprotokoll](./CHANGELOG.md))
|
||||
**Lizenz:** [GNU General Public License 3.0 (GPLv3)](./LICENSE)
|
||||
**Website:** https://elwig.at/
|
||||
**Quellcode:** https://git.necronda.net/winzer/elwig
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using Elwig;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Billing;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Reflection;
|
||||
@@ -26,16 +25,6 @@ namespace Tests {
|
||||
App.SetBranch(ctx.Branches.Include(b => b.PostalDest).Single());
|
||||
}
|
||||
|
||||
[OneTimeSetUp]
|
||||
public async Task Setup_3_BillingData() {
|
||||
await BillingData.Init();
|
||||
}
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Setup_4_Culture() {
|
||||
Utils.OverrideCulture();
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public async Task TeardownDatabase() {
|
||||
AppDbContext.ConnectionStringOverride = null;
|
||||
|
||||
@@ -67,7 +67,10 @@ namespace Tests.E2ETests {
|
||||
window.FindElement(By.WpfId("MemberInput")).SendKeys("Mustermann Max");
|
||||
window.FindElement(By.WpfId("WineVarietyInput")).SelectItem("Zweigelt");
|
||||
window.FindElement(By.WpfId("GradationKmwInput")).SendKeys("18");
|
||||
window.FindElement(By.Name("Wiegen")).Click();
|
||||
window.FindElement(By.WpfId("WeighingManualButton")).Click();
|
||||
var dialog = Session.CreateWindowDriver("ManualWeighingDialog");
|
||||
dialog.FindElement(By.WpfId("WeightInput")).SendKeys("2468");
|
||||
dialog.FindElement(By.WpfId("ConfirmButton")).Click();
|
||||
FinishDeliveryNote(window);
|
||||
window.Close();
|
||||
}
|
||||
@@ -76,7 +79,7 @@ namespace Tests.E2ETests {
|
||||
public void Test_3_AttributeCultivationModifier() {
|
||||
var window = OpenReceiptWindow();
|
||||
window.FindElement(By.WpfId("MgNrInput")).SendKeys("102" + Keys.Enter + "GVK");
|
||||
window.FindElement(By.WpfId("CultivationInput")).SelectItem("Bio");
|
||||
window.FindElement(By.WpfId("CultivationInput")).SelectItem("KIP");
|
||||
window.FindElement(By.WpfId("GradationOeInput")).SendKeys("73" + Keys.Enter + Keys.Enter);
|
||||
FinishDeliveryNote(window);
|
||||
window.Close();
|
||||
|
||||
@@ -20,7 +20,18 @@ namespace Tests.E2ETests {
|
||||
Session.App.FindElement(By.Name("Mitglieder")).Click();
|
||||
Thread.Sleep(Utils.WINDOW_OPEN_SLEEP);
|
||||
var window = Session.CreateWindowDriver("MemberAdminWindow");
|
||||
Assert.That(window.Title, Is.EqualTo("Mitglieder - Elwig"));
|
||||
Assert.That(window.Title, Is.EqualTo("Mitglieder: aktive Mitglieder - Elwig"));
|
||||
window.Close();
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_Open_DeliveryAncmtWindow() {
|
||||
Assert.DoesNotThrow(() => {
|
||||
Session.App.FindElement(By.Name("Anmeldungen")).Click();
|
||||
Thread.Sleep(Utils.WINDOW_OPEN_SLEEP);
|
||||
var window = Session.CreateWindowDriver("DeliveryAncmtWindow");
|
||||
Assert.That(window.Title, Is.EqualTo($"Anmeldungen: {DateTime.Today.Year} - Elwig"));
|
||||
window.Close();
|
||||
});
|
||||
}
|
||||
@@ -31,7 +42,7 @@ namespace Tests.E2ETests {
|
||||
Session.App.FindElement(By.Name("Lieferungen")).Click();
|
||||
Thread.Sleep(Utils.WINDOW_OPEN_SLEEP);
|
||||
var window = Session.CreateWindowDriver("DeliveryAdminWindow");
|
||||
Assert.That(window.Title, Is.EqualTo("Lieferungen - Elwig"));
|
||||
Assert.That(window.Title, Is.EqualTo($"Lieferungen: {DateTime.Now.Year} - Elwig"));
|
||||
window.Close();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -57,8 +57,8 @@ namespace Tests.E2ETests {
|
||||
Window.FindElement(By.WpfId("IbanInput")).SendKeys("AT611904300234573201");
|
||||
Window.FindElement(By.WpfId("BicInput")).SendKeys("RLNWATWWWDF");
|
||||
|
||||
Window.FindElement(By.WpfId("UstIdNrInput")).SendKeys("ATU66192906"); // TODO: Testdaten?
|
||||
Window.FindElement(By.WpfId("LfbisNrInput")).SendKeys("1251074"); // TODO: Testdaten?
|
||||
Window.FindElement(By.WpfId("UstIdNrInput")).SendKeys("ATU01234565");
|
||||
Window.FindElement(By.WpfId("LfbisNrInput")).SendKeys("0123455");
|
||||
|
||||
Window.FindElement(By.WpfId("BuchführendInput")).Click();
|
||||
Window.FindElement(By.WpfId("OrganicInput")).Click();
|
||||
@@ -68,7 +68,7 @@ namespace Tests.E2ETests {
|
||||
Window.FindElement(By.WpfId("BillingPlzInput")).SendKeys("2120");
|
||||
Window.FindElement(By.WpfId("BillingOrtInput")).SelectItem(2);
|
||||
|
||||
Window.FindElement(By.WpfId("BusinessSharesInput")).SendKeys("10");
|
||||
Window.FindElement(By.WpfId("BusinessShares1Input")).SendKeys("10");
|
||||
Window.FindElement(By.WpfId("BranchInput")).SelectItem("Matzen");
|
||||
Window.FindElement(By.WpfId("DefaultKgInput")).SelectItem(3);
|
||||
|
||||
@@ -84,15 +84,15 @@ namespace Tests.E2ETests {
|
||||
Window.FindElement(By.WpfId("SearchInput")).SendKeys("9999");
|
||||
Thread.Sleep(500);
|
||||
var memberListRow = Window.FindElement(By.WpfId("MemberList")).FindElement(By.ClassName("DataGridRow"));
|
||||
Assert.Multiple(() => {
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(memberListRow, Is.Not.Null);
|
||||
Assert.That(memberListRow.FindElement(By.Name("9999 ")), Is.Not.Null);
|
||||
Assert.That(memberListRow.FindElement(By.Name("Norbert")), Is.Not.Null);
|
||||
Assert.That(memberListRow.FindElement(By.Name("Neuling")), Is.Not.Null);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Test, DependsOnTest("Test_1_CreateMember")]
|
||||
public void Test_2_EditMember() {
|
||||
Window!.FindElement(By.WpfId("SearchInput")).SendKeys("9999");
|
||||
Thread.Sleep(500);
|
||||
@@ -104,7 +104,7 @@ namespace Tests.E2ETests {
|
||||
|
||||
Window.FindElement(By.WpfId("EditMemberButton")).Click();
|
||||
|
||||
var businessSharesInput = Window.FindElement(By.WpfId("BusinessSharesInput"));
|
||||
var businessSharesInput = Window.FindElement(By.WpfId("BusinessShares1Input"));
|
||||
Assert.That(businessSharesInput, Is.Not.Null);
|
||||
|
||||
var businessShares = int.Parse(businessSharesInput.Text);
|
||||
@@ -117,7 +117,7 @@ namespace Tests.E2ETests {
|
||||
Assert.That(newBusinessShares, Is.EqualTo(businessShares + 5));
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Test, DependsOnTest("Test_2_EditMember")]
|
||||
public void Test_3_DeleteMember() {
|
||||
Window!.FindElement(By.WpfId("SearchInput")).SendKeys("9999");
|
||||
Thread.Sleep(500);
|
||||
@@ -128,12 +128,12 @@ namespace Tests.E2ETests {
|
||||
Assert.That(memberListRows, Has.Count.EqualTo(1));
|
||||
|
||||
var memberListRow = memberListRows.First();
|
||||
Assert.Multiple(() => {
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(memberListRow, Is.Not.Null);
|
||||
Assert.That(memberListRow.FindElement(By.Name("9999 ")), Is.Not.Null);
|
||||
Assert.That(memberListRow.FindElement(By.Name("Norbert")), Is.Not.Null);
|
||||
Assert.That(memberListRow.FindElement(By.Name("Neuling")), Is.Not.Null);
|
||||
});
|
||||
}
|
||||
|
||||
Window.FindElement(By.WpfId("DeleteMemberButton")).Click();
|
||||
var dialog = Session.CreateWindowDriver("DeleteMemberDialog");
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
using Elwig.Services;
|
||||
|
||||
namespace Tests {
|
||||
[SetUpFixture]
|
||||
public class InteractionSetup {
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Setup() {
|
||||
InteractionService.Override = (mode, title, text) => {
|
||||
Assert.Fail($"User interaction requested: {mode} - {title} - {text}");
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Teardown() {
|
||||
InteractionService.Override = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
-- inserts for HelperTests.BillingTest
|
||||
|
||||
INSERT INTO wine_cultivation (cultid, name, description) VALUES
|
||||
('KIP', 'KIP', 'Kontrollierte Integrierte Produktion'),
|
||||
('B', 'Bio', 'AT-BIO-302');
|
||||
INSERT INTO wine_cultivation (cultid, name, description, organic) VALUES
|
||||
('KIP', 'KIP', 'Kontrollierte Integrierte Produktion', FALSE),
|
||||
('B', 'Bio', 'Biologische Produktion', TRUE);
|
||||
|
||||
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
|
||||
('K', 'Kabinett', TRUE, NULL, FALSE, 0),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-- inserts for DocumentTests
|
||||
|
||||
INSERT INTO wine_cultivation (cultid, name, description) VALUES
|
||||
('B', 'Bio', 'AT-BIO-302');
|
||||
INSERT INTO wine_cultivation (cultid, name, description, organic) VALUES
|
||||
('B', 'Bio', 'Biologische Produktion', TRUE);
|
||||
|
||||
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
|
||||
('K', 'Kabinett', TRUE, NULL, FALSE, 0);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
-- inserts for E2ETests
|
||||
|
||||
INSERT INTO wine_cultivation (cultid, name, description) VALUES
|
||||
('KIP', 'KIP', 'Kontrollierte Integrierte Produktion'),
|
||||
('B', 'Bio', 'AT-BIO-302');
|
||||
INSERT INTO wine_cultivation (cultid, name, description, organic) VALUES
|
||||
('KIP', 'KIP', 'Kontrollierte Integrierte Produktion', FALSE),
|
||||
('B', 'Bio', 'Biologische Produktion', TRUE);
|
||||
|
||||
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
|
||||
('K', 'Kabinett', TRUE, NULL, FALSE, 0),
|
||||
|
||||
@@ -34,7 +34,7 @@ INSERT INTO AT_plz_dest (plz, okz, dest) VALUES
|
||||
(2122, 05137, 'Riedenthal');
|
||||
|
||||
INSERT INTO client_parameter (param, value) VALUES
|
||||
('CLIENT_NAME_TOKEN', 'WGT'),
|
||||
('CLIENT_NAME_TOKEN', 'WGX'),
|
||||
('CLIENT_NAME_SHORT', 'WG Test'),
|
||||
('CLIENT_NAME', 'Winzergenossenschaft Test'),
|
||||
('CLIENT_NAME_SUFFIX', NULL),
|
||||
@@ -66,11 +66,11 @@ INSERT INTO wb_kg (kgnr, glnr) VALUES
|
||||
(15216, 2),
|
||||
(15224, 2);
|
||||
|
||||
INSERT INTO member (mgnr, given_name, name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr, iban, lfbis_nr, ustid_nr) VALUES
|
||||
(101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109, 'AT811234567890123457', '0123463', NULL ),
|
||||
(102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684'),
|
||||
(103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224, 'AT271234567890123459', '0123480', NULL ),
|
||||
(104, 'Waltraud', 'Winzer', 'X', FALSE, TRUE , 40, 212005138, 'Wiener Straße 15', 15224, 'AT971234567890123460', '0123498', 'ATU12345693');
|
||||
INSERT INTO member (mgnr, given_name, name, zwstid, volllieferant, buchführend, country, postal_dest, address, default_kgnr, iban, lfbis_nr, ustid_nr, org_auth_code) VALUES
|
||||
(101, 'Max', 'Mustermann', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 1', 06109, 'AT811234567890123457', '0123463', NULL , NULL ),
|
||||
(102, 'Wernhardt', 'Weinbauer', 'X', FALSE, FALSE, 40, 222303524, 'Winzerstraße 2', 06109, 'AT541234567890123458', '0123471', 'ATU12345684', NULL ),
|
||||
(103, 'Matthäus', 'Musterbauer', 'X', FALSE, FALSE, 40, 212005138, 'Brünner Straße 10', 15224, 'AT271234567890123459', '0123480', NULL , 'AT-BIO-302'),
|
||||
(104, 'Waltraud', 'Winzer', 'X', FALSE, TRUE , 40, 212005138, 'Wiener Straße 15', 15224, 'AT971234567890123460', '0123498', 'ATU12345693', NULL );
|
||||
|
||||
INSERT INTO member_billing_address (mgnr, name, country, postal_dest, address) VALUES
|
||||
(102, 'W&B Weinbauer GesbR', 40, 222303524, 'Winzerstraße 2'),
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
-- inserts for ServiceTests
|
||||
|
||||
|
||||
INSERT INTO wine_cultivation (cultid, name, description) VALUES
|
||||
('B', 'Bio', 'AT-BIO-302');
|
||||
INSERT INTO wine_cultivation (cultid, name, description, organic) VALUES
|
||||
('B', 'Bio', 'Biologische Produktion', TRUE);
|
||||
|
||||
INSERT INTO wine_attribute (attrid, name, active, max_kg_per_ha, strict, fill_lower) VALUES
|
||||
('K', 'Kabinett', TRUE, NULL, FALSE, 0);
|
||||
@@ -139,3 +138,8 @@ INSERT INTO payment_member (year, avnr, mgnr, net_amount) VALUES
|
||||
INSERT INTO credit (year, tgnr, mgnr, avnr, net_amount, prev_net_amount, vat, modifiers, prev_modifiers) VALUES
|
||||
(2021, 1, 203, 1, 10000000, 0, 0.1, 0, 0),
|
||||
(2021, 2, 204, 1, 10000000, 0, 0.1, 0, 0);
|
||||
|
||||
INSERT INTO payment_variant (year, avnr, name, date, transfer_date, test_variant, calc_time, comment, data) VALUES
|
||||
(2021, 2, 'Berechnen', '2022-01-20', '2022-01-20', TRUE, NULL, NULL, '{"mode":"elwig","version":1,"payment":0.5,"curves":[]}'),
|
||||
(2021, 3, 'Löschen', '2022-01-20', '2022-01-20', TRUE, NULL, NULL, '{"mode":"elwig","version":1,"payment":0.5,"curves":[]}'),
|
||||
(2021, 4, 'Duplizieren', '2022-01-21', '2022-01-21', TRUE, NULL, NULL, '{"mode":"elwig","version":1,"payment":0.5,"curves":[]}');
|
||||
@@ -0,0 +1,20 @@
|
||||
using Elwig;
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Helpers.Billing;
|
||||
|
||||
namespace Tests {
|
||||
[SetUpFixture]
|
||||
class Setup {
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void Setup_1_Config() {
|
||||
Utils.OverrideCulture();
|
||||
App.Config.Debug = true;
|
||||
}
|
||||
|
||||
[OneTimeSetUp]
|
||||
public async Task Setup_2_Init() {
|
||||
await BillingData.Init();
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -19,16 +19,16 @@
|
||||
</Target>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.9.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.10.1" />
|
||||
<PackageReference Include="Appium.WebDriver" Version="4.4.5" />
|
||||
<PackageReference Include="NReco.PdfRenderer" Version="1.6.0" />
|
||||
<PackageReference Include="NUnit" Version="4.6.1" />
|
||||
<PackageReference Include="NUnit" Version="5.0.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.3.0" />
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.14.0">
|
||||
<PackageReference Include="NUnit.Analyzers" Version="4.15.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="10.0.1">
|
||||
<PackageReference Include="coverlet.collector" Version="10.1.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
public async Task Test_01_OneDeliveryPart() {
|
||||
using var doc = await DeliveryNote.Initialize(2020, 1);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
MUSTERMANN Max
|
||||
Winzerstraße 1
|
||||
@@ -26,14 +26,14 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
Waage/Terminal: ?/1, ID: 321 – 09:02, 01.10.2020
|
||||
Brutto: 3 219 kg – Tara: 0 kg – Netto: 3 219 kg – gerebelt gewogen
|
||||
"""));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_02_TwoDeliveryParts() {
|
||||
using var doc = await DeliveryNote.Initialize(2020, 4);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
W&B Weinbauer GesbR
|
||||
WEINBAUER Wernhardt
|
||||
@@ -58,14 +58,14 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
Waage/Terminal: ?/?, ID: ? (gerebelt gewogen)
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("Gesamt: 81 16,5 4 483"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_03_DeliveryPartsWithAttribute() {
|
||||
using var doc = await DeliveryNote.Initialize(2020, 3);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
MUSTERMANN Max
|
||||
Winzerstraße 1
|
||||
@@ -95,14 +95,14 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
Waage/Terminal: ?/?, ID: ? (gerebelt gewogen)
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("Gesamt: 81 16,5 6 970"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_04_DeliveryPartsWithCultivation() {
|
||||
using var doc = await DeliveryNote.Initialize(2020, 7);
|
||||
var text = await Utils.GeneratePdfText(doc);
|
||||
Assert.Multiple(() => {
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.That(text, Contains.Substring("""
|
||||
MUSTERBAUER Matthäus
|
||||
Brünner Straße 10
|
||||
@@ -115,20 +115,20 @@ namespace Tests.UnitTests.DocumentTests {
|
||||
Assert.That(text, Contains.Substring("Das Mitglied erklärt, dass die gelieferte Ware dem österreichischen Weingesetz entspricht"));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
1 Grüner Veltliner Wein 80 16,3 3 198
|
||||
Bewirtschaftung: Bio (AT-BIO-302)
|
||||
Bewirtschaftung: Bio (Biologische Produktion) – Kontrollstelle: AT-BIO-302
|
||||
Herkunft: Österreich
|
||||
/ Wolkersdorfer Hochleithen / Wolkersdorf im Weinviertel / KG Wolkersdorf
|
||||
Waage/Terminal: ?/?, ID: ? (gerebelt gewogen)
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("""
|
||||
2 Grüner Veltliner Qualitätswein 75 15,4 2 134
|
||||
Bewirtschaftung: Bio (AT-BIO-302)
|
||||
Bewirtschaftung: Bio (Biologische Produktion) – Kontrollstelle: AT-BIO-302
|
||||
Herkunft: Österreich / Weinland / Niederösterreich
|
||||
/ Wolkersdorfer Hochleithen / Wolkersdorf im Weinviertel / KG Wolkersdorf
|
||||
Waage/Terminal: ?/?, ID: ? (gerebelt gewogen)
|
||||
"""));
|
||||
Assert.That(text, Contains.Substring("Gesamt: 78 15,9 5 332"));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -331,7 +331,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
vm.GradationKmw = 15.9;
|
||||
vm.GradationOe = 79;
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, false, false, true));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, false, false, true));
|
||||
|
||||
d = await GetDelivery("20231010X001");
|
||||
Assert.That(d, Is.Not.Null);
|
||||
@@ -370,7 +370,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
vm.MgNr = 102;
|
||||
vm.Member = vm.MemberSource.First(m => m.MgNr == vm.MgNr);
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, false, false, true));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, false, false, true));
|
||||
|
||||
d = await GetDelivery("20231010X002");
|
||||
Assert.That(d, Is.Not.Null);
|
||||
@@ -399,7 +399,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
vm.Date = "15.10.2023";
|
||||
vm.Time = "12:00";
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, true, true, false));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.UpdateDeliveryPart(vm, p.Year, p.DId, p.DPNr, true, true, false));
|
||||
|
||||
d = await GetDelivery("20231010X003");
|
||||
Assert.That(d, Is.Null);
|
||||
@@ -420,7 +420,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 0, 0]));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 0, 0]));
|
||||
d = await GetDelivery("20231001X001");
|
||||
Assert.That(d, Is.Not.Null);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -446,7 +446,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [600, 0, 0]));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [600, 0, 0]));
|
||||
d = await GetDelivery("20231001X002");
|
||||
Assert.That(d, Is.Not.Null);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -475,7 +475,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 700, -5]));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 700, -5]));
|
||||
d = await GetDelivery("20231001X003");
|
||||
Assert.That(d, Is.Not.Null);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -507,7 +507,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps[2].QualId, Is.Not.EqualTo("WEI"));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 1100, int.MaxValue]));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.DepreciateDelivery(d.Year, d.DId, [1000, 1100, int.MaxValue]));
|
||||
d = await GetDelivery("20231001X004");
|
||||
Assert.That(d, Is.Not.Null);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -539,7 +539,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, 0, 0], 102));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, 0, 0], 102));
|
||||
d1 = await GetDelivery("20231002X001");
|
||||
d2 = await GetDelivery("20231002X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -579,7 +579,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [400, -1, -2], 102));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [400, -1, -2], 102));
|
||||
d1 = await GetDelivery("20231003X001");
|
||||
d2 = await GetDelivery("20231003X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -617,7 +617,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [200, 1000, int.MinValue], 102));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [200, 1000, int.MinValue], 102));
|
||||
d1 = await GetDelivery("20231004X001");
|
||||
d2 = await GetDelivery("20231004X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -659,7 +659,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps1[2].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, int.MaxValue, 1100], 102));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToMember(d1.Year, d1.DId, [1000, int.MaxValue, 1100], 102));
|
||||
d1 = await GetDelivery("20231005X001");
|
||||
d2 = await GetDelivery("20231005X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -695,7 +695,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 1000, -4], d2.LsNr));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 1000, -4], d2.LsNr));
|
||||
d1 = await GetDelivery("20231006X001");
|
||||
d2 = await GetDelivery("20231006X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -735,7 +735,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 300, int.MinValue], d2.LsNr));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [0, 300, int.MinValue], d2.LsNr));
|
||||
d1 = await GetDelivery("20231007X001");
|
||||
d2 = await GetDelivery("20231007X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -774,7 +774,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [850, 1000, -4], d2.LsNr));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [850, 1000, -4], d2.LsNr));
|
||||
d1 = await GetDelivery("20231008X001");
|
||||
d2 = await GetDelivery("20231008X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -815,7 +815,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(ps2[0].Weight, Is.EqualTo(1000));
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [1200, int.MaxValue, 1000], d2.LsNr));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.SplitDeliveryToLsNr(d1.Year, d1.DId, [1200, int.MaxValue, 1000], d2.LsNr));
|
||||
d1 = await GetDelivery("20231009X001");
|
||||
d2 = await GetDelivery("20231009X002");
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
@@ -837,7 +837,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.That(await ctx.Deliveries.FindAsync(2022, 2), Is.Not.Null);
|
||||
}
|
||||
Assert.DoesNotThrowAsync(async () => await DeliveryService.DeleteDelivery("20220930X001"));
|
||||
await Assert.DoesNotThrowAsync(async () => await DeliveryService.DeleteDelivery("20220930X001"));
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.That(await ctx.Deliveries.FindAsync(2022, 2), Is.Null);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(await ctx.FetchMembers(205).SingleOrDefaultAsync(), Is.Null);
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||
await Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
@@ -114,7 +114,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(await ctx.FetchMembers(999).SingleOrDefaultAsync(), Is.Null);
|
||||
}
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||
await Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(null));
|
||||
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
@@ -227,7 +227,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
vm.IsActive = false;
|
||||
vm.ExitDate = $"{exitDate:dd.MM.yyyy}";
|
||||
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(202));
|
||||
await Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(202));
|
||||
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
@@ -264,7 +264,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(vm.BillingName, Is.Not.Null);
|
||||
}
|
||||
vm.MgNr = 210;
|
||||
Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
|
||||
await Assert.DoesNotThrowAsync(async () => await vm.UpdateMember(203));
|
||||
|
||||
Member m;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
@@ -288,7 +288,7 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.That(await ctx.FetchMembers(201).SingleOrDefaultAsync(), Is.Not.Null);
|
||||
}
|
||||
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false));
|
||||
await Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(201, false, false, false));
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.That(await ctx.FetchMembers(201).SingleOrDefaultAsync(), Is.Null);
|
||||
}
|
||||
@@ -300,11 +300,11 @@ namespace Tests.UnitTests.ServiceTests {
|
||||
Assert.That(await ctx.FetchMembers(204).SingleOrDefaultAsync(), Is.Not.Null);
|
||||
}
|
||||
for (int i = 0; i < 7; i++) {
|
||||
Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0));
|
||||
await Assert.ThrowsAsync<DbUpdateException>(async () => await MemberService.DeleteMember(204, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0));
|
||||
using var ctx = new AppDbContext();
|
||||
Assert.That(await ctx.FetchMembers(204).SingleOrDefaultAsync(), Is.Not.Null);
|
||||
}
|
||||
Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true));
|
||||
await Assert.DoesNotThrowAsync(async () => await MemberService.DeleteMember(204, true, true, true));
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.That(await ctx.FetchMembers(204).SingleOrDefaultAsync(), Is.Null);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.Services;
|
||||
using Elwig.ViewModels;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Tests.UnitTests.ServiceTests {
|
||||
[TestFixture]
|
||||
public class PaymentVariantServiceTest {
|
||||
|
||||
private static async Task InitViewModel(PaymentVariantsViewModel vm) {
|
||||
using var ctx = new AppDbContext();
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public async Task Test_FillInputs() {
|
||||
var vm = new PaymentVariantsViewModel();
|
||||
await InitViewModel(vm);
|
||||
//await vm.FillInputs();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_CreatePaymentVariant() {
|
||||
HashSet<int> ids;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
ids = await ctx.PaymentVariants.Where(v => v.Year == 2021).Select(v => v.AvNr).ToHashSetAsync();
|
||||
}
|
||||
PaymentVar? n = null;
|
||||
await Assert.DoesNotThrowAsync(async () => {
|
||||
n = await PaymentVariantService.CreatePaymentVariant(2021);
|
||||
});
|
||||
Assert.That(ids, Does.Not.Contain(n?.AvNr));
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.IsNotNull(await ctx.PaymentVariants.FindAsync(2021, n?.AvNr));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_Duplicate() {
|
||||
HashSet<int> ids;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
ids = await ctx.PaymentVariants.Where(v => v.Year == 2021).Select(v => v.AvNr).ToHashSetAsync();
|
||||
}
|
||||
Assert.That(ids, Does.Contain(4));
|
||||
PaymentVar? n = null;
|
||||
using (var ctx = new AppDbContext()) {
|
||||
var v = await ctx.PaymentVariants.FindAsync(2021, 4);
|
||||
await Assert.DoesNotThrowAsync(async () => {
|
||||
n = await PaymentVariantService.Duplicate(v!);
|
||||
});
|
||||
}
|
||||
Assert.That(ids, Does.Not.Contain(n?.AvNr));
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.IsNotNull(await ctx.PaymentVariants.FindAsync(2021, n?.AvNr));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Ignore("Not implemented yet")]
|
||||
public async Task Test_UpdatePaymentVariant() {
|
||||
var vm = new PaymentVariantsViewModel();
|
||||
await InitViewModel(vm);
|
||||
//await vm.UpdatePaymentVariant();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_DeletePaymentVariant() {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.IsNotNull(await ctx.PaymentVariants.FindAsync(2021, 3));
|
||||
}
|
||||
await Assert.DoesNotThrowAsync(async () => await PaymentVariantService.DeletePaymentVariant(2021, 3));
|
||||
using (var ctx = new AppDbContext()) {
|
||||
Assert.IsNull(await ctx.PaymentVariants.FindAsync(2021, 3));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task Test_Calculate_Commit_Revert() {
|
||||
await Assert.DoesNotThrowAsync(async () => {
|
||||
await PaymentVariantService.Calculate(2021, 2);
|
||||
await PaymentVariantService.Commit(2021, 2);
|
||||
await PaymentVariantService.Revert(2021, 2);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGenerate_Summary_List() {
|
||||
var filename = Path.Combine(Path.GetTempPath(), "PaymentVariant.ods");
|
||||
Assert.That(!File.Exists(filename));
|
||||
InteractionService.NextSave = (_, _) => filename;
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
var v = await ctx.PaymentVariants.Where(v => v.Year == 2021 && v.AvNr == 2).SingleAsync();
|
||||
await PaymentVariantService.GenerateSummary(v, ExportMode.SaveList);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.IsNull(InteractionService.NextSave);
|
||||
Assert.That(File.Exists(filename));
|
||||
Assert.That(new FileInfo(filename).Length, Is.GreaterThan(0));
|
||||
}
|
||||
} finally {
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGenerate_Summary_Pdf() {
|
||||
var filename = Path.Combine(Path.GetTempPath(), "PaymentVariant.pdf");
|
||||
Assert.That(!File.Exists(filename));
|
||||
InteractionService.NextSave = (_, _) => filename;
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
var v = await ctx.PaymentVariants.Where(v => v.Year == 2021 && v.AvNr == 2).SingleAsync();
|
||||
await PaymentVariantService.GenerateSummary(v, ExportMode.SavePdf);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.IsNull(InteractionService.NextSave);
|
||||
Assert.That(File.Exists(filename));
|
||||
Assert.That(new FileInfo(filename).Length, Is.GreaterThan(0));
|
||||
}
|
||||
} finally {
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGenerate_Ebics() {
|
||||
var filename = Path.Combine(Path.GetTempPath(), "PaymentVariant.xml");
|
||||
Assert.That(!File.Exists(filename));
|
||||
InteractionService.NextSave = (_, _) => filename;
|
||||
try {
|
||||
await PaymentVariantService.GenerateEbics(2021, 2);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.IsNull(InteractionService.NextSave);
|
||||
Assert.That(File.Exists(filename));
|
||||
Assert.That(new FileInfo(filename).Length, Is.GreaterThan(0));
|
||||
}
|
||||
} finally {
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGenerate_AccountingList() {
|
||||
var filename = Path.Combine(Path.GetTempPath(), "PaymentVariant.ods");
|
||||
Assert.That(!File.Exists(filename));
|
||||
InteractionService.NextSave = (_, _) => filename;
|
||||
try {
|
||||
using var ctx = new AppDbContext();
|
||||
var v = await ctx.PaymentVariants.Where(v => v.Year == 2021 && v.AvNr == 2).SingleAsync();
|
||||
await PaymentVariantService.GenerateAccountingList(v.Year, v.AvNr, v.Name);
|
||||
using (Assert.EnterMultipleScope()) {
|
||||
Assert.IsNull(InteractionService.NextSave);
|
||||
Assert.That(File.Exists(filename));
|
||||
Assert.That(new FileInfo(filename).Length, Is.GreaterThan(0));
|
||||
}
|
||||
} finally {
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,41 +71,41 @@ namespace Tests.UnitTests.WeighingTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_03_Moving() {
|
||||
public async Task Test_03_Moving() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "moving";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Bewegung"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_04_Overloaded() {
|
||||
public async Task Test_04_Overloaded() {
|
||||
Mock.Weight = 10_000;
|
||||
Mock.Error = "overloaded";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Überlast"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_05_InvalidResponse() {
|
||||
public async Task Test_05_InvalidResponse() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "invalid";
|
||||
Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
await Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_06_InvalidCrc() {
|
||||
public async Task Test_06_InvalidCrc() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "crc";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Invalid CRC16 checksum"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_07_InvalidUnit() {
|
||||
public async Task Test_07_InvalidUnit() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "unit";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,20 +78,20 @@ namespace Tests.UnitTests.WeighingTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_03_Moving() {
|
||||
public async Task Test_03_Moving() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Tare = 41;
|
||||
Mock.Error = "moving";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Bewegung"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_04_InvalidResponse() {
|
||||
public async Task Test_04_InvalidResponse() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Tare = 41;
|
||||
Mock.Error = "invalid";
|
||||
Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
await Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,41 +71,41 @@ namespace Tests.UnitTests.WeighingTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_03_Moving() {
|
||||
public async Task Test_03_Moving() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "moving";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Bewegung"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_04_Overloaded() {
|
||||
public async Task Test_04_Overloaded() {
|
||||
Mock.Weight = 10_000;
|
||||
Mock.Error = "overloaded";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Überlast"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_05_InvalidResponse() {
|
||||
public async Task Test_05_InvalidResponse() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "invalid";
|
||||
Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
await Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_06_InvalidCrc() {
|
||||
public async Task Test_06_InvalidCrc() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "crc";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Invalid CRC16 checksum"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_07_InvalidUnit() {
|
||||
public async Task Test_07_InvalidUnit() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Error = "unit";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,20 +78,20 @@ namespace Tests.UnitTests.WeighingTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_03_Moving() {
|
||||
public async Task Test_03_Moving() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Tare = 41;
|
||||
Mock.Error = "moving";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await Scale!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Bewegung"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_04_InvalidResponse() {
|
||||
public async Task Test_04_InvalidResponse() {
|
||||
Mock.Weight = 1_000;
|
||||
Mock.Tare = 41;
|
||||
Mock.Error = "invalid";
|
||||
Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
await Assert.ThrowsAsync<FormatException>(async () => await Scale!.Weigh());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,41 +92,41 @@ namespace Tests.UnitTests.WeighingTests {
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_03_Moving() {
|
||||
public async Task Test_03_Moving() {
|
||||
MockA.Weight = 1_000;
|
||||
MockA.Error = "moving";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Bewegung"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_04_Overloaded() {
|
||||
public async Task Test_04_Overloaded() {
|
||||
MockA.Weight = 10_000;
|
||||
MockA.Error = "overloaded";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Waage in Überlast"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_05_InvalidResponse() {
|
||||
public async Task Test_05_InvalidResponse() {
|
||||
MockA.Weight = 1_000;
|
||||
MockA.Error = "invalid";
|
||||
Assert.ThrowsAsync<FormatException>(async () => await ScaleA!.Weigh());
|
||||
await Assert.ThrowsAsync<FormatException>(async () => await ScaleA!.Weigh());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_06_InvalidCrc() {
|
||||
public async Task Test_06_InvalidCrc() {
|
||||
MockA.Weight = 1_000;
|
||||
MockA.Error = "crc";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
Assert.That(ex.Message, Contains.Substring("Invalid CRC16 checksum"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_07_InvalidUnit() {
|
||||
public async Task Test_07_InvalidUnit() {
|
||||
MockA.Weight = 1_000;
|
||||
MockA.Error = "unit";
|
||||
var ex = Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
var ex = await Assert.ThrowsAsync<WeighingException>(async () => await ScaleA!.Weigh());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ type = SysTec-IT
|
||||
model = IT3000A
|
||||
connection = tcp://127.0.0.1:12345
|
||||
required = false
|
||||
synctime = false
|
||||
|
||||
[scale.2]
|
||||
type = Avery-Async
|
||||
|
||||
@@ -1 +1 @@
|
||||
curl --fail -s -L "https://elwig.at/files/create.sql?v=41" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"
|
||||
curl --fail -s -L "https://elwig.at/files/create.sql?v=42" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"
|
||||
Reference in new issue
Block a user