Compare commits

..

6 Commits

Author SHA1 Message Date
lorenz.stechauner 495aa8a691 DeliveryNote: Add option to redact modifier value
Test / Run tests (push) Successful in 2m26s
2025-12-11 13:05:40 +01:00
lorenz.stechauner 811916a8b9 Controls/CheckComboBox: Apply AllItemsSelectedContent only when more than 1 items are selected 2025-12-11 13:05:40 +01:00
lorenz.stechauner 3b6333a6a2 Tests: Update dependencies
Test / Run tests (push) Successful in 2m22s
2025-11-29 12:34:33 +01:00
lorenz.stechauner 9b37330362 Elwig: Update dependencies 2025-11-29 12:34:33 +01:00
lorenz.stechauner 889a17b21c Upgrade to .NET 10 2025-11-29 12:34:33 +01:00
lorenz.stechauner ac6d559e5d Helpers/Utils: Fix mail log for single mails 2025-11-29 12:34:29 +01:00
17 changed files with 60 additions and 27 deletions
+6
View File
@@ -55,6 +55,12 @@
<TextBlock Text="{Binding ValueStr}"/> <TextBlock Text="{Binding ValueStr}"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="PublicModifierTemplate">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" MinWidth="250" Margin="0,0,10,0"/>
<TextBlock Text="{Binding PublicValueStr}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="WineAttributeTemplate"> <DataTemplate x:Key="WineAttributeTemplate">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
+8 -3
View File
@@ -124,19 +124,24 @@ namespace Elwig.Controls {
SelectItemsReverse(); SelectItemsReverse();
var dmp = !string.IsNullOrEmpty(ListDisplayMemberPath) ? ListDisplayMemberPath : !string.IsNullOrEmpty(DisplayMemberPath) ? DisplayMemberPath : null; var dmp = !string.IsNullOrEmpty(ListDisplayMemberPath) ? ListDisplayMemberPath : !string.IsNullOrEmpty(DisplayMemberPath) ? DisplayMemberPath : null;
if (SelectedItems.Count == ItemsSource.Cast<object>().Count() && AllItemsSelectedContent != null) { if (SelectedItems.Count == ItemsSource.Cast<object>().Count() && AllItemsSelectedContent != null) {
_textBox.Text = AllItemsSelectedContent;
AllItemsSelected = true; AllItemsSelected = true;
} else if (SelectedItems.Count == 0) { } else if (SelectedItems.Count == 0) {
_textBox.Text = "";
AllItemsSelected = false; AllItemsSelected = false;
} else {
AllItemsSelected = null;
}
if (SelectedItems.Count > 1 && SelectedItems.Count == ItemsSource.Cast<object>().Count() && AllItemsSelectedContent != null) {
_textBox.Text = AllItemsSelectedContent;
} else if (SelectedItems.Count == 0) {
_textBox.Text = "";
} else { } else {
_textBox.Text = string.Join(Delimiter, _textBox.Text = string.Join(Delimiter,
dmp == null ? SelectedItems.Cast<object>() : dmp == null ? SelectedItems.Cast<object>() :
SelectedItems.Cast<object>() SelectedItems.Cast<object>()
.Select(i => i.GetType().GetProperty(dmp)?.GetValue(i)) .Select(i => i.GetType().GetProperty(dmp)?.GetValue(i))
); );
AllItemsSelected = null;
} }
RaiseEvent(new SelectionChangedEventArgs(SelectionChangedEvent, evt.RemovedItems, evt.AddedItems)); RaiseEvent(new SelectionChangedEventArgs(SelectionChangedEvent, evt.RemovedItems, evt.AddedItems));
} }
+1 -1
View File
@@ -48,7 +48,7 @@ namespace Elwig.Documents {
if (CustomPayment?.ModComment != null) { if (CustomPayment?.ModComment != null) {
MemberModifier = CustomPayment.ModComment; MemberModifier = CustomPayment.ModComment;
} else if (mod != null) { } else if (mod != null) {
MemberModifier = $"{mod.Name} ({mod.ValueStr})"; MemberModifier = $"{mod.Name} ({mod.PublicValueStr})";
} else { } else {
MemberModifier = "Sonstige Zu-/Abschläge"; MemberModifier = "Sonstige Zu-/Abschläge";
} }
+1 -1
View File
@@ -55,7 +55,7 @@
@if (part.Modifiers.Count() > 0) { @if (part.Modifiers.Count() > 0) {
var first = true; var first = true;
foreach (var mod in part.Modifiers) { foreach (var mod in part.Modifiers) {
<tr class="tight @(first ? "first" : "")"><td></td><td>@Raw(first ? "<i>Zu-/Abschläge:</i>" : "")</td><td colspan="3"><b>@mod.Name</b></td><td style="white-space: pre;">@mod.ValueStr</td></tr> <tr class="tight @(first ? "first" : "")"><td></td><td>@Raw(first ? "<i>Zu-/Abschläge:</i>" : "")</td><td colspan="3"><b>@mod.Name</b></td><td style="white-space: pre;">@mod.PublicValueStr</td></tr>
first = false; first = false;
} }
} }
+9 -9
View File
@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net10.0-windows</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<PreserveCompilationContext>true</PreserveCompilationContext> <PreserveCompilationContext>true</PreserveCompilationContext>
@@ -22,12 +22,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
<PackageReference Include="LinqKit" Version="1.3.8" /> <PackageReference Include="LinqKit" Version="1.3.9" />
<PackageReference Include="MailKit" Version="4.14.1" /> <PackageReference Include="MailKit" Version="4.14.1" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" /> <PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="10.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.10" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="10.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.10" /> <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="10.0.0" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3595.46" /> <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3595.46" />
<PackageReference Include="NJsonSchema" Version="11.5.2" /> <PackageReference Include="NJsonSchema" Version="11.5.2" />
<PackageReference Include="PdfiumViewer" Version="2.13.0" /> <PackageReference Include="PdfiumViewer" Version="2.13.0" />
@@ -35,10 +35,10 @@
<PackageReference Include="RazorLight" Version="2.3.1" /> <PackageReference Include="RazorLight" Version="2.3.1" />
<PackageReference Include="ScottPlot.WPF" Version="5.1.57" /> <PackageReference Include="ScottPlot.WPF" Version="5.1.57" />
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" /> <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" />
<PackageReference Include="System.IO.Hashing" Version="9.0.10" /> <PackageReference Include="System.IO.Hashing" Version="10.0.0" />
<PackageReference Include="System.IO.Ports" Version="9.0.10" /> <PackageReference Include="System.IO.Ports" Version="10.0.0" />
<PackageReference Include="System.Management" Version="9.0.10" /> <PackageReference Include="System.Management" Version="10.0.0" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.10" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="10.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>
+1 -1
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 = 33; public static readonly int RequiredSchemaVersion = 34;
private static int VersionOffset = 0; private static int VersionOffset = 0;
+9 -3
View File
@@ -502,6 +502,7 @@ namespace Elwig.Helpers {
if (App.Config.Smtp == null) if (App.Config.Smtp == null)
return false; return false;
return await Task.Run(async () => { return await Task.Run(async () => {
await AddSentMailBody(subject, text, 1);
SmtpClient? client = null; SmtpClient? client = null;
try { try {
client = await GetSmtpClient(); client = await GetSmtpClient();
@@ -519,6 +520,11 @@ namespace Elwig.Helpers {
} }
msg.Body = body; msg.Body = body;
await client!.SendAsync(msg); await client!.SendAsync(msg);
await AddSentMails([(
"email", member.MgNr, member.AdministrativeName,
member.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).ToArray(),
subject, docs.Select(d => d.Title).ToArray()
)]);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
return false; return false;
@@ -539,7 +545,7 @@ namespace Elwig.Helpers {
await doc.Generate(); await doc.Generate();
var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]); var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]);
if (success) if (success)
MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!", "E-Mail verschickt", MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mail im Posteingang des Empfängers aufscheint.", "E-Mail verschickt",
MessageBoxButton.OK, MessageBoxImage.Information); MessageBoxButton.OK, MessageBoxImage.Information);
} else if (mode == ExportMode.SavePdf) { } else if (mode == ExportMode.SavePdf) {
var d = new SaveFileDialog() { var d = new SaveFileDialog() {
@@ -654,9 +660,9 @@ namespace Elwig.Helpers {
} }
public static async Task<string?> FindSentMailBody(DateTime target) { public static async Task<string?> FindSentMailBody(DateTime target) {
var dt = $"{target:yyyy-MM-dd_HH-mm-ss}_"; var dt = $"{target:yyyy-MM-dd_HH-mm-ss}";
var filename = Directory.GetFiles(App.MailsPath, "????-??-??_??-??-??_*.txt") var filename = Directory.GetFiles(App.MailsPath, "????-??-??_??-??-??_*.txt")
.Where(n => Path.GetFileName(n).CompareTo(dt) <= 0) .Where(n => Path.GetFileName(n)[..19].CompareTo(dt) <= 0)
.Order() .Order()
.LastOrDefault(); .LastOrDefault();
if (filename == null) if (filename == null)
+5
View File
@@ -16,6 +16,9 @@ namespace Elwig.Models.Entities {
[Column("active")] [Column("active")]
public bool IsActive { get; set; } public bool IsActive { get; set; }
[Column("redacted")]
public bool IsRedacted { get; set; }
[Column("ordering")] [Column("ordering")]
public int Ordering { get; set; } public int Ordering { get; set; }
@@ -46,6 +49,8 @@ namespace Elwig.Models.Entities {
(Rel != null) ? $"{Utils.GetSign(Rel.Value)}{(Math.Abs(Rel.Value) < 0.1m ? "\u2007" : "")}{Math.Abs(Rel.Value):0.00##\u00a0%}" : (Rel != null) ? $"{Utils.GetSign(Rel.Value)}{(Math.Abs(Rel.Value) < 0.1m ? "\u2007" : "")}{Math.Abs(Rel.Value):0.00##\u00a0%}" :
""; "";
public string? PublicValueStr => IsRedacted ? null : ValueStr;
public override string ToString() { public override string ToString() {
return Name; return Name;
} }
@@ -9,7 +9,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PublishDir>bin\Publish</PublishDir> <PublishDir>bin\Publish</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol> <PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId> <_TargetId>Folder</_TargetId>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net10.0-windows</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained> <SelfContained>true</SelfContained>
<PublishSingleFile>false</PublishSingleFile> <PublishSingleFile>false</PublishSingleFile>
+3
View File
@@ -0,0 +1,3 @@
-- schema version 33 to 34
ALTER TABLE modifier ADD COLUMN redacted INTEGER NOT NULL CHECK (redacted IN (TRUE, FALSE)) DEFAULT FALSE;
+5 -1
View File
@@ -8,7 +8,7 @@
xmlns:local="clr-namespace:Elwig.Windows" xmlns:local="clr-namespace:Elwig.Windows"
xmlns:ctrl="clr-namespace:Elwig.Controls" xmlns:ctrl="clr-namespace:Elwig.Controls"
mc:Ignorable="d" mc:Ignorable="d"
Title="Stammdaten - Elwig" Height="500" MinHeight="400" Width="850" MinWidth="810" Title="Stammdaten - Elwig" Height="520" MinHeight="400" Width="860" MinWidth="810"
Loaded="Window_Loaded"> Loaded="Window_Loaded">
<Window.Resources> <Window.Resources>
<Style TargetType="Label"> <Style TargetType="Label">
@@ -532,6 +532,10 @@
<CheckBox x:Name="SeasonModifierActiveInput" Content="In Übernahme-Fenster anzeigen" <CheckBox x:Name="SeasonModifierActiveInput" Content="In Übernahme-Fenster anzeigen"
Grid.Column="1" Grid.ColumnSpan="2" Margin="10,134,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,134,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="SeasonModifier_Changed" Unchecked="SeasonModifier_Changed"/> Checked="SeasonModifier_Changed" Unchecked="SeasonModifier_Changed"/>
<CheckBox x:Name="SeasonModifierRedactedInput" Content="Wert auf Lieferschein verbergen"
Grid.Column="1" Grid.ColumnSpan="2" Margin="10,154,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="SeasonModifier_Changed" Unchecked="SeasonModifier_Changed"/>
</Grid> </Grid>
</GroupBox> </GroupBox>
</Grid> </Grid>
+3
View File
@@ -135,12 +135,14 @@ namespace Elwig.Windows {
SeasonModifierRelInput.Text = ""; SeasonModifierRelInput.Text = "";
SeasonModifierAbsInput.Text = ""; SeasonModifierAbsInput.Text = "";
SeasonModifierActiveInput.IsChecked = false; SeasonModifierActiveInput.IsChecked = false;
SeasonModifierRedactedInput.IsChecked = false;
} else { } else {
SeasonModifierIdInput.Text = mod.ModId; SeasonModifierIdInput.Text = mod.ModId;
SeasonModifierNameInput.Text = mod.Name; SeasonModifierNameInput.Text = mod.Name;
SeasonModifierRelInput.Text = (mod.Rel * 100)?.ToString() ?? ""; SeasonModifierRelInput.Text = (mod.Rel * 100)?.ToString() ?? "";
SeasonModifierAbsInput.Text = mod.Abs?.ToString() ?? ""; SeasonModifierAbsInput.Text = mod.Abs?.ToString() ?? "";
SeasonModifierActiveInput.IsChecked = mod.IsActive; SeasonModifierActiveInput.IsChecked = mod.IsActive;
SeasonModifierRedactedInput.IsChecked = mod.IsRedacted;
} }
_modUpdate = false; _modUpdate = false;
} }
@@ -157,6 +159,7 @@ namespace Elwig.Windows {
mod.Rel = decimal.TryParse(SeasonModifierRelInput.Text, out var vRel) ? vRel / 100 : null; mod.Rel = decimal.TryParse(SeasonModifierRelInput.Text, out var vRel) ? vRel / 100 : null;
mod.AbsValue = decimal.TryParse(SeasonModifierAbsInput.Text, out var vAbs) ? Utils.DecToDb(vAbs, s.Precision) : null; mod.AbsValue = decimal.TryParse(SeasonModifierAbsInput.Text, out var vAbs) ? Utils.DecToDb(vAbs, s.Precision) : null;
mod.IsActive = SeasonModifierActiveInput.IsChecked ?? false; mod.IsActive = SeasonModifierActiveInput.IsChecked ?? false;
mod.IsRedacted = SeasonModifierRedactedInput.IsChecked ?? false;
CollectionViewSource.GetDefaultView(_modList).Refresh(); CollectionViewSource.GetDefaultView(_modList).Refresh();
UpdateButtons(); UpdateButtons();
@@ -95,6 +95,7 @@ namespace Elwig.Windows {
if (App.Client.IsMatzen) { if (App.Client.IsMatzen) {
RequiredInputs = [.. RequiredInputs, ModifiersInput]; RequiredInputs = [.. RequiredInputs, ModifiersInput];
} }
ModifiersInput.ItemTemplate = (DataTemplate)ModifiersInput.FindResource("PublicModifierTemplate");
} else { } else {
WeighingManualButton.Visibility = Visibility.Hidden; WeighingManualButton.Visibility = Visibility.Hidden;
WeighingAButton.Visibility = Visibility.Hidden; WeighingAButton.Visibility = Visibility.Hidden;
+3 -3
View File
@@ -929,13 +929,13 @@ namespace Elwig.Windows {
await Utils.AddSentMails([( await Utils.AddSentMails([(
"email", m.MgNr, m.AdministrativeName, "email", m.MgNr, m.AdministrativeName,
m.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).ToArray(), m.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).ToArray(),
subject, subject, docs.Select(d => d.Title).ToArray()
docs.Select(d => d.Title).ToArray()
)]); )]);
} }
}); });
MessageBox.Show("Erfolgreich alle E-Mails verschickt!", "Rundschreiben verschicken", MessageBoxButton.OK, MessageBoxImage.Information); MessageBox.Show("Erfolgreich alle E-Mails verschickt!\n\nEs kann einige Minuten dauern, bis die E-Mails in den Posteingängen der Empfänger aufscheinen.", "Rundschreiben verschicken",
MessageBoxButton.OK, MessageBoxImage.Information);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} finally { } finally {
+1 -1
View File
@@ -6,7 +6,7 @@ namespace Tests.E2ETests {
public const int WINDOW_OPEN_SLEEP = 2000; public const int WINDOW_OPEN_SLEEP = 2000;
public static readonly string ApplicationPath = Path.GetFullPath(@"..\..\..\..\Elwig\bin\Debug\net8.0-windows\Elwig.exe"); public static readonly string ApplicationPath = Path.GetFullPath(@"..\..\..\..\Elwig\bin\Debug\net10.0-windows\Elwig.exe");
public static readonly string ConfigPath = Path.GetFullPath(@"..\..\..\..\Tests\config.test.ini"); public static readonly string ConfigPath = Path.GetFullPath(@"..\..\..\..\Tests\config.test.ini");
public static readonly string TestDatabasePath = Path.GetFullPath(@"..\..\..\..\Tests\ElwigTestDB.sqlite3"); public static readonly string TestDatabasePath = Path.GetFullPath(@"..\..\..\..\Tests\ElwigTestDB.sqlite3");
+2 -2
View File
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net10.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
@@ -19,7 +19,7 @@
</Target> </Target>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageReference Include="Appium.WebDriver" Version="4.4.5" /> <PackageReference Include="Appium.WebDriver" Version="4.4.5" />
<PackageReference Include="NReco.PdfRenderer" Version="1.6.0" /> <PackageReference Include="NReco.PdfRenderer" Version="1.6.0" />
<PackageReference Include="NUnit" Version="4.4.0" /> <PackageReference Include="NUnit" Version="4.4.0" />
+1 -1
View File
@@ -1 +1 @@
curl --fail -s -L "https://elwig.at/files/create.sql?v=33" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql" curl --fail -s -L "https://elwig.at/files/create.sql?v=34" -u "elwig:ganzGeheim123!" -o "Resources\Sql\Create.sql"