Compare commits

..

8 Commits

Author SHA1 Message Date
3f769eb7d7 Bump version to 1.0.1.0
All checks were successful
Test / Run tests (push) Successful in 1m58s
Deploy / Build and Deploy (push) Successful in 1m53s
2025-09-18 23:44:15 +02:00
8bc053053c App: Add auto update check on network change to active
All checks were successful
Test / Run tests (push) Successful in 1m55s
2025-09-18 23:37:10 +02:00
a0dcaf7b4f Elwig: Update database to include new BKI wine varieties
All checks were successful
Test / Run tests (push) Successful in 2m43s
2025-09-18 23:29:38 +02:00
844fc5217a Utils: Add User-Agent to default http client
All checks were successful
Test / Run tests (push) Successful in 1m53s
2025-09-17 15:09:28 +02:00
542afa5892 Bump version to 1.0.0.6
All checks were successful
Test / Run tests (push) Successful in 1m38s
Deploy / Build and Deploy (push) Successful in 1m37s
2025-09-17 09:58:20 +02:00
9e02b15ff1 Elwig: Fix extensions in SaveFileDialog
All checks were successful
Test / Run tests (push) Successful in 1m49s
2025-09-17 09:55:19 +02:00
463769b549 App: Fix auto selection of weighing mode
All checks were successful
Test / Run tests (push) Successful in 2m17s
2025-09-17 09:33:34 +02:00
2c383d0c55 AboutWindow: Fix typo in description 2025-09-17 09:33:11 +02:00
15 changed files with 119 additions and 26 deletions

View File

@@ -2,6 +2,40 @@
Changelog Changelog
========= =========
[v1.0.1.0][v1.0.1.0] (2025-09-18) {#v1.0.1.0}
---------------------------------------------
### Neue Funktionen {#v1.0.1.0-features}
* Neue Weinsorten gemäß Kürzelliste der Bundeskellereiinspektion hinzugefügt. (a0dcaf7b4f)
### Sonstiges {#v1.0.1.0-misc}
* HTTP-Anfragen haben jetzt das Feld `User-Agent` gesetzt. (844fc5217a)
* Auto-Update-Funktion wird auch beim Erlangen von Netzwerkverbindung ausgeführt. (8bc053053c)
[v1.0.1.0]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.1.0
[v1.0.0.6][v1.0.0.6] (2025-09-17) {#v1.0.0.6}
---------------------------------------------
### Behobene Fehler {#v1.0.0.6-bugfixes}
* Die automatische Erkennung des Wiege-Modus hat im WKW nicht funktioniert. (463769b549)
### Sonstiges {#v1.0.0.6-misc}
* Tippfehler im Über-Fenster (`AboutWindow`) behoben. (2c383d0c55)
* `SaveFileDialog` mit Multi-File-Extensions verbessert. (9e02b15ff1)
[v1.0.0.6]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.0.6
[v1.0.0.5][v1.0.0.5] (2025-09-15) {#v1.0.0.5} [v1.0.0.5][v1.0.0.5] (2025-09-15) {#v1.0.0.5}
--------------------------------------------- ---------------------------------------------

View File

@@ -35,7 +35,7 @@
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="WineVarietyTemplateExpanded"> <DataTemplate x:Key="WineVarietyTemplateExpanded">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SortId}" Foreground="{Binding Color}" MinWidth="36" Margin="0,0,10,0"/> <TextBlock Text="{Binding SortIdFormat}" Foreground="{Binding Color}" MinWidth="36" Margin="0,0,10,0"/>
<TextBlock Text="{Binding Name}" Foreground="{Binding Color}"/> <TextBlock Text="{Binding Name}" Foreground="{Binding Color}"/>
<TextBlock Text="{Binding CommentFormat}" FontSize="10" VerticalAlignment="Bottom" Margin="0,0,0,2"/> <TextBlock Text="{Binding CommentFormat}" FontSize="10" VerticalAlignment="Bottom" Margin="0,0,0,2"/>
</StackPanel> </StackPanel>

View File

@@ -11,6 +11,7 @@ using System.Collections.Generic;
using System.Data; using System.Data;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.NetworkInformation;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -115,16 +116,6 @@ namespace Elwig {
BranchNum = branches.Count; BranchNum = branches.Count;
} }
if (Config.WeighingMode == null) {
if (App.Client.IsMatzen || App.Client.IsWolkersdorf) {
Config.WeighingMode = WeighingMode.Net;
} else if (App.Client.IsHaugsdorf || App.Client.IsSitzendorf) {
Config.WeighingMode = WeighingMode.Box;
} else if (App.Client.IsBaden || App.Client.IsGrInzersdorf) {
Config.WeighingMode = WeighingMode.Gross;
}
}
Utils.RunBackground("Temp File Cleanup", () => { Utils.RunBackground("Temp File Cleanup", () => {
Utils.CleanupTempFiles(); Utils.CleanupTempFiles();
return Task.CompletedTask; return Task.CompletedTask;
@@ -141,6 +132,7 @@ namespace Elwig {
await CheckForUpdates(); await CheckForUpdates();
}); });
} }
NetworkChange.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
_autoUpdateTimer.Tick += new EventHandler(OnAutoUpdateTimer); _autoUpdateTimer.Tick += new EventHandler(OnAutoUpdateTimer);
_autoUpdateTimer.Start(); _autoUpdateTimer.Start();
} }
@@ -172,6 +164,16 @@ namespace Elwig {
Shutdown(); Shutdown();
} }
if (Config.WeighingMode == null) {
if (Client.IsMatzen || Client.IsWolkersdorf) {
Config.WeighingMode = WeighingMode.Net;
} else if (Client.IsHaugsdorf || Client.IsSitzendorf) {
Config.WeighingMode = WeighingMode.Box;
} else if (Client.IsBaden || Client.IsGrInzersdorf) {
Config.WeighingMode = WeighingMode.Gross;
}
}
base.OnStartup(evt); base.OnStartup(evt);
var window = new MainWindow(); var window = new MainWindow();
@@ -228,6 +230,16 @@ namespace Elwig {
} }
} }
private void OnNetworkAvailabilityChanged(object? sender, NetworkAvailabilityEventArgs evt) {
if (!evt.IsAvailable) return;
if (Utils.HasInternetConnectivity()) {
Utils.RunBackground("Auto Updater", async () => {
await Task.Delay(500);
await CheckForUpdates();
});
}
}
public static async Task CheckForUpdates(bool showAlert = false) { public static async Task CheckForUpdates(bool showAlert = false) {
if (Config.UpdateUrl == null) return; if (Config.UpdateUrl == null) return;
var latest = await Utils.GetLatestInstallerUrl(Config.UpdateUrl); var latest = await Utils.GetLatestInstallerUrl(Config.UpdateUrl);

View File

@@ -7,7 +7,7 @@
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<PreserveCompilationContext>true</PreserveCompilationContext> <PreserveCompilationContext>true</PreserveCompilationContext>
<ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon> <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
<Version>1.0.0.5</Version> <Version>1.0.1.0</Version>
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>

View File

@@ -248,9 +248,10 @@ namespace Elwig.Helpers {
return c + 1; return c + 1;
} }
public async Task<WineQualLevel> GetWineQualityLevel(double kmw) { public async Task<WineQualLevel> GetWineQualityLevel(double kmw, string? maxQualId = null) {
return await WineQualityLevels return await WineQualityLevels
.Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw)) .Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw))
.Where(q => maxQualId == null || q.QualId == "WEI" || q.QualId == maxQualId)
.OrderBy(q => q.MinKmw) .OrderBy(q => q.MinKmw)
.LastAsync(); .LastAsync();
} }

View File

@@ -9,7 +9,7 @@ namespace Elwig.Helpers {
public static class AppDbUpdater { public static class AppDbUpdater {
// Don't forget to update value in Tests/fetch-resources.bat! // Don't forget to update value in Tests/fetch-resources.bat!
public static readonly int RequiredSchemaVersion = 32; public static readonly int RequiredSchemaVersion = 33;
private static int VersionOffset = 0; private static int VersionOffset = 0;

View File

@@ -23,7 +23,6 @@ using System.Reflection;
using System.Collections; using System.Collections;
using Elwig.Documents; using Elwig.Documents;
using MimeKit; using MimeKit;
using System.Windows.Input;
using LinqKit; using LinqKit;
using System.Linq.Expressions; using System.Linq.Expressions;
using Elwig.Models; using Elwig.Models;
@@ -430,6 +429,8 @@ namespace Elwig.Helpers {
var client = new HttpClient() { var client = new HttpClient() {
Timeout = TimeSpan.FromSeconds(5), Timeout = TimeSpan.FromSeconds(5),
}; };
client.DefaultRequestHeaders.UserAgent.Clear();
client.DefaultRequestHeaders.UserAgent.ParseAdd($"Elwig/{App.Version} ({App.Client.NameToken}, {App.BranchName}, {Environment.MachineName}, {Environment.OSVersion})");
client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Clear();
if (accept != null) if (accept != null)
client.DefaultRequestHeaders.Accept.Add(new(accept)); client.DefaultRequestHeaders.Accept.Add(new(accept));

View File

@@ -11,16 +11,24 @@ namespace Elwig.Models.Entities {
[Column("type")] [Column("type")]
public string Type { get; private set; } = null!; public string Type { get; private set; } = null!;
[Column("max_qualid")]
public string MaxQualId { get; private set; } = null!;
[ForeignKey("MaxQualId")]
public virtual WineQualLevel MaxQualityLevel { get; private set; } = null!;
[Column("name")] [Column("name")]
public string Name { get; private set; } = null!; public string Name { get; private set; } = null!;
[Column("comment")] [Column("comment")]
public string? Comment { get; private set; } public string? Comment { get; private set; }
public string SortIdFormat => IsQuw ? SortId : $"({SortId})";
public string CommentFormat => (Comment != null) ? $" ({Comment})" : ""; public string CommentFormat => (Comment != null) ? $" ({Comment})" : "";
public bool IsRed => Type == "R"; public bool IsRed => Type == "R";
public bool IsWhite => Type == "W"; public bool IsWhite => Type == "W";
public bool IsQuw => MaxQualId == "QUW";
public Brush? Color => IsWhite ? Brushes.DarkGreen : IsRed ? Brushes.DarkRed : null; public Brush? Color => IsWhite ? Brushes.DarkGreen : IsRed ? Brushes.DarkRed : null;
public WineVar() { } public WineVar() { }
@@ -28,6 +36,7 @@ namespace Elwig.Models.Entities {
public WineVar(string sortId, string name) { public WineVar(string sortId, string name) {
SortId = sortId; SortId = sortId;
Name = name; Name = name;
MaxQualId = "QUW";
} }
public override string ToString() { public override string ToString() {

View File

@@ -0,0 +1,17 @@
-- schema version 32 to 33
ALTER TABLE wine_variety ADD COLUMN max_qualid TEXT NOT NULL DEFAULT 'QUW';
UPDATE wine_quality_level SET qualid = 'ALW' WHERE qualid = 'AUL';
UPDATE wine_variety SET comment = 'Muscato' WHERE sortid = 'MO';
INSERT INTO wine_variety (sortid, type, max_qualid, name, comment) VALUES
('DR', 'W', 'QUW', 'Donauriesling', NULL),
('DV', 'W', 'QUW', 'Donauveltliner', NULL),
('BN', 'W', 'RSW', 'Bronner', NULL),
('CB', 'W', 'RSW', 'Cabernet Blanc', NULL),
('CJ', 'R', 'RSW', 'Cabernet Jura', NULL),
('JO', 'W', 'RSW', 'Johanniter', NULL),
('OR', 'W', 'RSW', 'Orangetraube', NULL),
('PI', 'R', 'RSW', 'Pinot Nova', NULL),
('RE', 'R', 'RSW', 'Regent', NULL),
('SI', 'W', 'RSW', 'Solaris', NULL);

View File

@@ -721,9 +721,11 @@ namespace Elwig.Services {
FileName = subject == ExportSubject.Selected ? $"Lieferung_{vm.SelectedDelivery?.LsNr}.elwig.zip" : $"Lieferungen_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip", FileName = subject == ExportSubject.Selected ? $"Lieferung_{vm.SelectedDelivery?.LsNr}.elwig.zip" : $"Lieferungen_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip",
DefaultExt = "elwig.zip", DefaultExt = "elwig.zip",
Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip", Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip",
Title = $"{DeliveryJournal.Name} speichern unter - Elwig" Title = $"{DeliveryJournal.Name} speichern unter - Elwig",
AddExtension = false,
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
if (!d.FileName.EndsWith(".elwig.zip")) d.FileName += ".elwig.zip";
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
try { try {

View File

@@ -496,11 +496,13 @@ namespace Elwig.Services {
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
var d = new SaveFileDialog() { var d = new SaveFileDialog() {
FileName = subject == ExportSubject.Selected ? $"Mitglied_{vm.SelectedMember?.MgNr}.elwig.zip" : $"Mitglieder_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip", FileName = subject == ExportSubject.Selected ? $"Mitglied_{vm.SelectedMember?.MgNr}.elwig.zip" : $"Mitglieder_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip",
DefaultExt = ".elwig.zip", DefaultExt = "elwig.zip",
Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip", Filter = "Elwig-Export-Datei (*.elwig.zip)|*.elwig.zip",
Title = $"{MemberList.Name} speichern unter - Elwig" Title = $"{MemberList.Name} speichern unter - Elwig",
AddExtension = false,
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
if (!d.FileName.EndsWith(".elwig.zip")) d.FileName += ".elwig.zip";
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
try { try {

View File

@@ -4,11 +4,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Elwig.Windows" xmlns:local="clr-namespace:Elwig.Windows"
Title="Über - Elwig" Height="340" Width="480" ResizeMode="NoResize"> Title="Über - Elwig" Height="340" Width="460" ResizeMode="NoResize">
<Grid> <Grid>
<TextBlock Margin="20,10" FontSize="12"> <TextBlock Margin="20,10" FontSize="12">
<Bold>Produkt:</Bold> Elwig<LineBreak/> <Bold>Produkt:</Bold> Elwig<LineBreak/>
<Bold>Beschreibung:</Bold> Elektronische Winzergenossenschaftsveraltung<LineBreak/> <Bold>Beschreibung:</Bold> Elektronische Winzergenossenschaftsverwaltung<LineBreak/>
<Bold>Typ:</Bold> Warenwirschaftssystem<LineBreak/> <Bold>Typ:</Bold> Warenwirschaftssystem<LineBreak/>
<Bold>Version:</Bold> <Run x:Name="Version">0.0.0.0</Run> (<Hyperlink NavigateUri="https://elwig.at/changelog" RequestNavigate="Hyperlink_RequestNavigate">Änderungsprotokoll</Hyperlink>)<LineBreak/> <Bold>Version:</Bold> <Run x:Name="Version">0.0.0.0</Run> (<Hyperlink NavigateUri="https://elwig.at/changelog" RequestNavigate="Hyperlink_RequestNavigate">Änderungsprotokoll</Hyperlink>)<LineBreak/>
<Bold>Lizenz:</Bold> <Hyperlink NavigateUri="https://www.gnu.org/licenses/gpl-3.0.html" RequestNavigate="Hyperlink_RequestNavigate">GNU General Public License 3.0 (GPLv3)</Hyperlink><LineBreak/> <Bold>Lizenz:</Bold> <Hyperlink NavigateUri="https://www.gnu.org/licenses/gpl-3.0.html" RequestNavigate="Hyperlink_RequestNavigate">GNU General Public License 3.0 (GPLv3)</Hyperlink><LineBreak/>
@@ -26,7 +26,7 @@
Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink> Paketierung: <Hyperlink NavigateUri="https://www.firegiant.com/wixtoolset/" RequestNavigate="Hyperlink_RequestNavigate">WiX Toolset</Hyperlink>
</TextBlock> </TextBlock>
<Image Source="\Resources\Images\Elwig.png" RenderOptions.BitmapScalingMode="HighQuality" Height="96" <Image Source="\Resources\Images\Elwig.png" RenderOptions.BitmapScalingMode="HighQuality" Height="64"
HorizontalAlignment="Right" Margin="10" VerticalAlignment="Top"/> HorizontalAlignment="Right" Margin="10" VerticalAlignment="Top"/>
</Grid> </Grid>
</Window> </Window>

View File

@@ -1207,6 +1207,7 @@ namespace Elwig.Windows {
AttributeInput.SelectedIndex = 0; AttributeInput.SelectedIndex = 0;
CultivationInput.SelectedIndex = 0; CultivationInput.SelectedIndex = 0;
} }
UpdateWineQualityLevels();
} }
private void SortIdInput_TextChanged(object sender, TextChangedEventArgs evt) { private void SortIdInput_TextChanged(object sender, TextChangedEventArgs evt) {
@@ -1220,6 +1221,13 @@ namespace Elwig.Windows {
private void WineVarietyInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { private void WineVarietyInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
if (WineVarietyInput.SelectedItem is WineVar s) if (WineVarietyInput.SelectedItem is WineVar s)
ViewModel.SortId = s.SortId; ViewModel.SortId = s.SortId;
UpdateWineQualityLevels();
if (!ViewModel.WineVar?.IsQuw ?? false) {
App.MainDispatcher.BeginInvoke(() => {
MessageBox.Show("Die eingegebene Sorte darf nicht als Qualitätswein\nübernommen werden!", "Kein Qualitätswein",
MessageBoxButton.OK, MessageBoxImage.Warning);
});
}
} }
private void UpdateWineQualityLevels() { private void UpdateWineQualityLevels() {
@@ -1227,12 +1235,17 @@ namespace Elwig.Windows {
if (!GetInputValid(GradationKmwInput)) { if (!GetInputValid(GradationKmwInput)) {
UnsetDefaultValue(WineQualityLevelInput); UnsetDefaultValue(WineQualityLevelInput);
ComboBox_SelectionChanged(WineQualityLevelInput, null); ComboBox_SelectionChanged(WineQualityLevelInput, null);
WineQualityLevelInput.ItemsSource = ctx.WineQualityLevels.Where(q => q.QualId == "WEI").ToList(); WineQualityLevelInput.ItemsSource = ctx.WineQualityLevels.ToList();
return; return;
} }
var kmw = (double)ViewModel.GradationKmw!; var kmw = (double)ViewModel.GradationKmw!;
WineQualityLevelInput.ItemsSource = ctx.WineQualityLevels.Where(q => q.MinKmw == null || q.MinKmw <= kmw).ToList(); var max = ViewModel.WineVar?.MaxQualId;
var qual = ctx.GetWineQualityLevel(kmw).GetAwaiter().GetResult(); var quw = ViewModel.WineVar?.IsQuw ?? true;
WineQualityLevelInput.ItemsSource = ctx.WineQualityLevels
.Where(q => q.MinKmw == null || q.MinKmw <= kmw)
.Where(q => quw || q.QualId == "WEI" || q.QualId == max)
.ToList();
var qual = ctx.GetWineQualityLevel(kmw, !quw ? max : null).GetAwaiter().GetResult();
SetDefaultValue(WineQualityLevelInput, qual); SetDefaultValue(WineQualityLevelInput, qual);
if (WineQualityLevelInput.SelectedItem == null || (WineQualityLevelInput.SelectedItem is WineQualLevel selected && !selected.IsPredicate)) { if (WineQualityLevelInput.SelectedItem == null || (WineQualityLevelInput.SelectedItem is WineQualLevel selected && !selected.IsPredicate)) {
ControlUtils.SelectItem(WineQualityLevelInput, qual); ControlUtils.SelectItem(WineQualityLevelInput, qual);
@@ -1373,7 +1386,7 @@ namespace Elwig.Windows {
return; return;
} }
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var defQual = ctx.GetWineQualityLevel(double.Parse(GradationKmwInput.Text)).GetAwaiter().GetResult(); var defQual = ctx.GetWineQualityLevel(ViewModel.GradationKmw!.Value, !(ViewModel.WineVar?.IsQuw ?? true) ? ViewModel.WineVar?.MaxQualId : null).GetAwaiter().GetResult();
AbgewertetInput.IsChecked = !qual.IsPredicate && defQual != qual; AbgewertetInput.IsChecked = !qual.IsPredicate && defQual != qual;
} }

View File

@@ -158,8 +158,10 @@ namespace Elwig.Windows {
FileName = $"database_{Utils.Today:yyyy-MM-dd}.sql.zip", FileName = $"database_{Utils.Today:yyyy-MM-dd}.sql.zip",
DefaultExt = "sql.zip", DefaultExt = "sql.zip",
Filter = "Komprimierte SQL-Datei (*.sql.zip)|*.sql.zip", Filter = "Komprimierte SQL-Datei (*.sql.zip)|*.sql.zip",
AddExtension = false,
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
if (!d.FileName.EndsWith(".sql.zip")) d.FileName += ".sql.zip";
Mouse.OverrideCursor = Cursors.Wait; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => { await Task.Run(async () => {
await Database.ExportSql(d.FileName, true); await Database.ExportSql(d.FileName, true);

View File

@@ -1 +1 @@
curl --fail -s -L "https://elwig.at/files/create.sql?v=32" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql" curl --fail -s -L "https://elwig.at/files/create.sql?v=33" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"