Compare commits

...

37 Commits

Author SHA1 Message Date
c61c2e3fcd [#64] AreaComAdminWindow: Add dialog for modifying/deleting
All checks were successful
Test / Run tests (push) Successful in 2m21s
2025-07-09 18:14:27 +02:00
267aa3d47c Dialogs: Rename AreaComDialog to AreaComTransferDialog
Some checks failed
Test / Run tests (push) Has been cancelled
2025-07-09 16:56:08 +02:00
7e9a27c75d Services: Move App.HintContextChange() to Windows
Some checks failed
Test / Run tests (push) Has been cancelled
2025-07-09 16:07:47 +02:00
53d82604a1 AreaComAdminWindow: Enhance visual appearance
All checks were successful
Test / Run tests (push) Successful in 1m53s
2025-07-09 00:39:01 +02:00
bb65a1f20e [#62] CreditNote: Add longer custom text to bottom
All checks were successful
Test / Run tests (push) Successful in 1m53s
2025-07-08 16:06:12 +02:00
c6748055fd [#61] Windows: Use red and green color to indicate type of WineVariety
All checks were successful
Test / Run tests (push) Successful in 2m17s
2025-07-08 15:27:13 +02:00
e6746f76b1 Windows: Small fixes 2025-07-08 15:27:13 +02:00
e9f389b885 DeliveryService: Fix spacing in tooltip 2025-07-08 15:27:13 +02:00
919ab3356d [#57] MailWindow: Use Task.Run() 2025-07-08 15:27:13 +02:00
39060f6a1e [#57] PaymentAdjustmentWindow: Use Task.Run() 2025-07-08 15:26:57 +02:00
070dda1bde [#57] ChartWindow: Use Task.Run() 2025-07-07 23:53:08 +02:00
b6bfc60ab8 [#57] DeliveryScheduleAdminWindow: Use Task.Run() 2025-07-07 23:39:55 +02:00
8aaa22fcb4 [#57] DeliveryAncmtAdminWindow: Use Task.Run() 2025-07-07 23:36:08 +02:00
64832e9a53 [#57] PaymentVariantsWindow: Use Task.Run()
All checks were successful
Test / Run tests (push) Successful in 1m49s
2025-07-07 23:31:03 +02:00
7c9844e277 [#57] MainWindow: Use Task.Run()
All checks were successful
Test / Run tests (push) Successful in 1m40s
2025-07-07 22:45:28 +02:00
19d2208fc3 [#57] AreaComAdminWindow: Use Task.Run() 2025-07-07 22:45:28 +02:00
38d0ff969d BaseDataWindow: Use Cursors.Wait instead of Cursors.AppStarting 2025-07-07 22:45:28 +02:00
fb2b998d1b [#57] DeliveryAdminWindow: Use Task.Run() 2025-07-07 22:45:28 +02:00
10d5f49f63 [#57] MemberAdminWinodw: Use Task.Run() 2025-07-07 22:45:28 +02:00
41811925be PaymentVariantsWindow: Add ViewModel and Service
All checks were successful
Test / Run tests (push) Successful in 1m58s
2025-07-07 22:44:30 +02:00
97300b6e30 [#65] MailLogWindow: Fix initial loading
All checks were successful
Test / Run tests (push) Successful in 1m49s
2025-07-03 13:03:01 +02:00
c6c8fd9b68 ChartWindow: Automatically calculate variant when saved 2025-07-03 13:03:01 +02:00
913129f155 PaymentVariantsWindow: Add estimates for uncommited variants 2025-07-03 13:02:57 +02:00
953532cae4 MemberService: Filter area commitments by CurrentLastSeason instead of CurrentYear
All checks were successful
Test / Run tests (push) Successful in 2m15s
2025-06-24 13:31:58 +02:00
267797b55d AreaComDialog: Fix property name (MaintainYearFrom) 2025-06-24 13:30:04 +02:00
4234c7f994 Elwig: Add ITime/XTime to entities and allow to export/import CTime/MTime
All checks were successful
Test / Run tests (push) Successful in 2m30s
2025-06-17 18:06:05 +02:00
3493ff6df1 Tests: Add UnitTests folder
All checks were successful
Test / Run tests (push) Successful in 2m24s
2025-06-03 20:57:53 +02:00
623f55f5b0 App: Rename ExePath to InstallPath
All checks were successful
Test / Run tests (push) Successful in 2m13s
2025-05-27 11:43:34 +02:00
b580e1bf79 App: Use environment variables for paths
All checks were successful
Test / Run tests (push) Successful in 1m42s
2025-05-26 15:18:32 +02:00
b08ca63bed [#59] Documents: Move Documents install folder from ProgramData to Program Files
All checks were successful
Test / Run tests (push) Successful in 2m19s
2025-05-26 15:12:49 +02:00
6a5f4cefa9 [#58] PaymentVariantSummary: Add 'attributlos gebunden' columns 2025-05-23 15:43:39 +02:00
0f3ce39f35 Elwig: Use 'Menge' instead of 'Gewicht' where applicable
All checks were successful
Test / Run tests (push) Successful in 1m59s
2025-05-20 15:55:11 +02:00
336aef5c70 CreditNoteDeliveryData: Include WeighingModifier only if delivery modifiers are considered 2025-05-20 13:09:29 +02:00
0dff3986b7 PaymentVariantsWindow: Add note, that modifiers include Rebelzuschlag
All checks were successful
Test / Run tests (push) Successful in 2m30s
2025-05-20 12:07:28 +02:00
318fb5dc7b Bump version to 0.13.9
All checks were successful
Test / Run tests (push) Successful in 2m7s
Deploy / Build and Deploy (push) Successful in 1m55s
2025-05-05 10:41:18 +02:00
41c5288fc5 Elwig: Update dependencies
Some checks failed
Test / Run tests (push) Failing after 14s
2025-05-05 10:36:30 +02:00
e50e7337e6 Helpers/Utils: Automatically change URL to sync.elwig.at when applicable 2025-05-05 10:36:30 +02:00
114 changed files with 2258 additions and 1364 deletions

View File

@@ -3,6 +3,19 @@ Changelog
========= =========
[v0.13.9][v0.13.9] (2025-05-05) {#v0.13.9}
------------------------------------------
### Sonstiges {#v0.13.9-misc}
* Abhängigkeiten aktualisiert. (bf0db37872, 4af2fa256e, d1c07ee92a, 41c5288fc5)
* Automatisches Aktualisieren der Synchroisations-URL (`https://elwig.at/clients/` -> `https://sync.elwig.at/`). (e50e7337e6)
[v0.13.9]: https://git.necronda.net/winzer/elwig/releases/tag/v0.13.9
[v0.13.8][v0.13.8] (2025-02-21) {#v0.13.8} [v0.13.8][v0.13.8] (2025-02-21) {#v0.13.8}
------------------------------------------ ------------------------------------------

View File

@@ -30,13 +30,13 @@
<DataTemplate x:Key="WineVarietyTemplateCollapsed"> <DataTemplate x:Key="WineVarietyTemplateCollapsed">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/> <TextBlock Text="{Binding Name}" Foreground="{Binding Color}"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="WineVarietyTemplateExpanded"> <DataTemplate x:Key="WineVarietyTemplateExpanded">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SortId}" MinWidth="36" Margin="0,0,10,0"/> <TextBlock Text="{Binding SortId}" Foreground="{Binding Color}" MinWidth="36" Margin="0,0,10,0"/>
<TextBlock Text="{Binding Name}"/> <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>
</DataTemplate> </DataTemplate>

View File

@@ -25,10 +25,13 @@ namespace Elwig {
private readonly DispatcherTimer _autoUpdateTimer = new() { Interval = TimeSpan.FromHours(1) }; private readonly DispatcherTimer _autoUpdateTimer = new() { Interval = TimeSpan.FromHours(1) };
public static readonly string DataPath = @"C:\ProgramData\Elwig\"; public static readonly string DataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Elwig");
public static readonly string MailsPath = Path.Combine(DataPath, "mails"); public static readonly string MailsPath = Path.Combine(DataPath, "mails");
public static readonly string ConfigPath = Path.Combine(DataPath, "config.ini"); public static readonly string ConfigPath = Path.Combine(DataPath, "config.ini");
public static readonly string ExePath = @"C:\Program Files\Elwig\"; public static readonly string InstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Elwig");
public static readonly string DocumentsPath = (Assembly.GetEntryAssembly()?.Location.Contains(@"\bin\") ?? false) ?
Path.Combine(Assembly.GetEntryAssembly()!.Location.Split(@"\bin\")[0], "../Elwig/Documents") :
Path.Combine(InstallPath, "resources/Documents");
public static readonly string TempPath = Path.Combine(Path.GetTempPath(), "Elwig"); public static readonly string TempPath = Path.Combine(Path.GetTempPath(), "Elwig");
public static Config Config { get; private set; } = new(ConfigPath); public static Config Config { get; private set; } = new(ConfigPath);
@@ -197,10 +200,12 @@ namespace Elwig {
var ch = CurrentLastWrite; var ch = CurrentLastWrite;
if (ch > CurrentApp.LastChanged) if (ch > CurrentApp.LastChanged)
CurrentApp.LastChanged = ch; CurrentApp.LastChanged = ch;
MainDispatcher.Invoke(() => {
foreach (Window w in CurrentApp.Windows) { foreach (Window w in CurrentApp.Windows) {
if (w is not ContextWindow c) continue; if (w is not ContextWindow c) continue;
MainDispatcher.BeginInvoke(c.HintContextChange); MainDispatcher.BeginInvoke(c.HintContextChange);
} }
});
} }
private void OnAutoUpdateTimer(object? sender, EventArgs? evt) { private void OnAutoUpdateTimer(object? sender, EventArgs? evt) {

View File

@@ -0,0 +1,71 @@
<Window x:Class="Elwig.Dialogs.AreaComModifyDialog"
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"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="Flächenbindungen bearbeiten" Height="220" Width="450">
<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>
<TextBlock x:Name="QuestionBlock1" TextAlignment="Center" Margin="0,10,0,0"
HorizontalAlignment="Center" VerticalAlignment="Top">
Soll die Flächenbindung (<Run Text="{Binding Area}"/> m², <Run Text="{Binding OrigYearFrom}"/><Run Text="{Binding OrigYearTo}"/>) rückwirkend bearbeitet werden,<LineBreak/>
oder erst ab der angegebenen Saison?
</TextBlock>
<TextBlock x:Name="QuestionBlock2" TextAlignment="Center" Margin="0,10,0,0" Visibility="Hidden"
HorizontalAlignment="Center" VerticalAlignment="Top">
Soll die Flächenbindung (<Run Text="{Binding Area}"/> m², <Run Text="{Binding OrigYearFrom}"/><Run Text="{Binding OrigYearTo}"/>) rückwirkend gelöscht werden,<LineBreak/>
oder erst ab der angegebenen Saison?
</TextBlock>
<Label x:Name="SeasonLabel" Content="Saison:" Margin="0,50,100,0"
HorizontalAlignment="Center" VerticalAlignment="Top"/>
<ctrl:IntegerUpDown x:Name="SeasonInput" Width="56" Height="25" Margin="0,50,0,0" FontSize="14"
Minimum="1900" Maximum="9999"
HorizontalAlignment="Center" VerticalAlignment="Top"
TextChanged="SeasonInput_TextChanged"/>
<CheckBox x:Name="RetroactiveInput" Content="Rückwirkend bearbeiten" Margin="0,80,0,0"
HorizontalAlignment="Center" VerticalAlignment="Top"
Checked="RetroactiveInput_Changed" Unchecked="RetroactiveInput_Changed"
IsChecked="{Binding ModifyRetroactively}"/>
<TextBlock x:Name="DescBlock1" Margin="0,105,0,0" TextAlignment="Center"
HorizontalAlignment="Center" VerticalAlignment="Top">
Die Flächenbindung bleibt bis inkl. Saison <Bold><Run x:Name="CancelSeason1"/></Bold> unverändert,<LineBreak/>
und wird ab inkl. Saison <Bold><Run x:Name="NewSeason1"/></Bold> in geänderter Form übernommen.
</TextBlock>
<TextBlock x:Name="DescBlock2" Margin="0,105,0,0" TextAlignment="Center" Visibility="Hidden"
HorizontalAlignment="Center" VerticalAlignment="Top">
Die Flächenbindung bleibt bis inklusive Saison <Bold><Run x:Name="CancelSeason2"/></Bold> gültig.
</TextBlock>
<Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" Grid.Column="1"
Click="ConfirmButton_Click"/>
<Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" Grid.Column="1" IsCancel="True"/>
</Grid>
</Window>

View File

@@ -0,0 +1,62 @@
using Elwig.Helpers;
using System.Windows;
using System.Windows.Controls;
namespace Elwig.Dialogs {
public partial class AreaComModifyDialog : Window {
public int? YearTo { get; set; }
public bool ModifyRetroactively { get; set; }
public string OrigYearFrom { get; set; }
public string OrigYearTo { get; set; }
public string Area { get; set; }
public AreaComModifyDialog(int? yearFrom, int? yearTo, int area, bool delete) {
Area = $"{area:N0}";
OrigYearFrom = $"{yearFrom}";
OrigYearTo = $"{yearTo}";
InitializeComponent();
Title = delete ? "Flächenbindung löschen" : "Flächenbindung bearbeiten";
RetroactiveInput.Content = delete ? "Rückwirkend löschen" : "Rückwirkend bearbeiten";
if (delete) {
QuestionBlock1.Visibility = Visibility.Hidden;
QuestionBlock2.Visibility = Visibility.Visible;
DescBlock1.Visibility = Visibility.Hidden;
DescBlock2.Visibility = Visibility.Visible;
}
if ((yearTo.HasValue && yearTo < Utils.CurrentNextSeason) || (yearFrom.HasValue && yearFrom >= Utils.CurrentNextSeason)) {
RetroactiveInput.IsChecked = true;
} else {
SeasonInput.Text = $"{Utils.CurrentNextSeason}";
}
}
private void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
YearTo = SeasonInput.Value! - 1;
CancelSeason1.Text = $"{YearTo}";
CancelSeason2.Text = $"{YearTo}";
NewSeason1.Text = $"{YearTo + 1}";
}
private void RetroactiveInput_Changed(object sender, RoutedEventArgs evt) {
if (ModifyRetroactively) {
SeasonInput.IsEnabled = false;
SeasonInput.Text = "";
YearTo = null;
DescBlock1.Visibility = Visibility.Hidden;
DescBlock2.Visibility = Visibility.Hidden;
} else {
SeasonInput.IsEnabled = true;
SeasonInput.Text = $"{Utils.CurrentNextSeason}";
DescBlock1.Visibility = QuestionBlock1.Visibility;
DescBlock2.Visibility = QuestionBlock2.Visibility;
}
}
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
DialogResult = true;
Close();
}
}
}

View File

@@ -1,4 +1,4 @@
<Window x:Class="Elwig.Dialogs.AreaComDialog" <Window x:Class="Elwig.Dialogs.AreaComTransferDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
@@ -51,7 +51,7 @@
<CheckBox x:Name="CopyYearToInput" Content="Beginn der Laufzeit von Vorgänger übernehmen" Margin="0,80,0,0" <CheckBox x:Name="CopyYearToInput" Content="Beginn der Laufzeit von Vorgänger übernehmen" Margin="0,80,0,0"
HorizontalAlignment="Center" VerticalAlignment="Top" HorizontalAlignment="Center" VerticalAlignment="Top"
Checked="CopyYearToInput_Changed" Unchecked="CopyYearToInput_Changed" Checked="CopyYearToInput_Changed" Unchecked="CopyYearToInput_Changed"
IsChecked="{Binding MaintainYearTo}"/> IsChecked="{Binding MaintainYearFrom}"/>
<TextBlock x:Name="DescBlock1" Margin="0,105,0,0" TextAlignment="Center" <TextBlock x:Name="DescBlock1" Margin="0,105,0,0" TextAlignment="Center"
HorizontalAlignment="Center" VerticalAlignment="Top"> HorizontalAlignment="Center" VerticalAlignment="Top">

View File

@@ -3,16 +3,16 @@ using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
namespace Elwig.Dialogs { namespace Elwig.Dialogs {
public partial class AreaComDialog : Window { public partial class AreaComTransferDialog : Window {
public int CancelSeason { get; set; } public int CancelSeason { get; set; }
public int SuccessorSeason => CancelSeason + 1; public int SuccessorSeason => CancelSeason + 1;
public bool MaintainYearTo { get; set; } public bool MaintainYearFrom { get; set; }
public string AreaComNum { get; set; } public string AreaComNum { get; set; }
public string Area { get; set; } public string Area { get; set; }
public AreaComDialog(string name, int areaComNum, int area) { public AreaComTransferDialog(string name, int areaComNum, int area) {
CancelSeason = Utils.FollowingSeason - 1; CancelSeason = Utils.FollowingSeason - 1;
AreaComNum = $"{areaComNum:N0}"; AreaComNum = $"{areaComNum:N0}";
Area = $"{area:N0}"; Area = $"{area:N0}";
@@ -29,7 +29,7 @@ namespace Elwig.Dialogs {
SeasonLabel.Margin = new(0, 40, 100, 0); SeasonLabel.Margin = new(0, 40, 100, 0);
} }
public AreaComDialog(string name, string successorName, int areaComNum, int area) { public AreaComTransferDialog(string name, string successorName, int areaComNum, int area) {
CancelSeason = Utils.FollowingSeason - 1; CancelSeason = Utils.FollowingSeason - 1;
AreaComNum = $"{areaComNum:N0}"; AreaComNum = $"{areaComNum:N0}";
Area = $"{area:N0}"; Area = $"{area:N0}";
@@ -43,13 +43,13 @@ namespace Elwig.Dialogs {
CancelSeason = (int)SeasonInput.Value!; CancelSeason = (int)SeasonInput.Value!;
CancelSeason1.Text = $"{CancelSeason}"; CancelSeason1.Text = $"{CancelSeason}";
CancelSeason2.Text = $"{CancelSeason}"; CancelSeason2.Text = $"{CancelSeason}";
TransferSeason.Text = MaintainYearTo ? "" : $"{SuccessorSeason}"; TransferSeason.Text = MaintainYearFrom ? "" : $"{SuccessorSeason}";
DescBlock1Season.Text = MaintainYearTo ? "dem originalen Beginn der FB" : "inkl. Saison "; DescBlock1Season.Text = MaintainYearFrom ? "dem originalen Beginn der FB" : "inkl. Saison ";
} }
private void CopyYearToInput_Changed(object sender, RoutedEventArgs evt) { private void CopyYearToInput_Changed(object sender, RoutedEventArgs evt) {
TransferSeason.Text = MaintainYearTo ? "" : $"{SuccessorSeason}"; TransferSeason.Text = MaintainYearFrom ? "" : $"{SuccessorSeason}";
DescBlock1Season.Text = MaintainYearTo ? "dem originalen Beginn der FB" : "inkl. Saison "; DescBlock1Season.Text = MaintainYearFrom ? "dem originalen Beginn der FB" : "inkl. Saison ";
} }
private void ConfirmButton_Click(object sender, RoutedEventArgs evt) { private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {

View File

@@ -2,7 +2,7 @@
@inherits TemplatePage<Elwig.Documents.BusinessDocument> @inherits TemplatePage<Elwig.Documents.BusinessDocument>
@model Elwig.Documents.BusinessDocument @model Elwig.Documents.BusinessDocument
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\BusinessDocument.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\BusinessDocument.css"/>
<div class="info-wrapper"> <div class="info-wrapper">
<div class="address-wrapper"> <div class="address-wrapper">
<div class="sender"> <div class="sender">

View File

@@ -3,7 +3,7 @@
@inherits TemplatePage<Elwig.Documents.CreditNote> @inherits TemplatePage<Elwig.Documents.CreditNote>
@model Elwig.Documents.CreditNote @model Elwig.Documents.CreditNote
@{ Layout = "BusinessDocument"; } @{ Layout = "BusinessDocument"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\CreditNote.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\CreditNote.css" />
<main> <main>
<h1>@Model.Title</h1> <h1>@Model.Title</h1>
<table class="credit"> <table class="credit">
@@ -136,7 +136,10 @@
} }
</tbody> </tbody>
<tbody style="break-inside: avoid;"> <tbody style="break-inside: avoid;">
@{ decimal penalty = 0; } @{
decimal penalty = 0;
string? comment = null;
}
@if (Model.MemberUnderDeliveries != null && Model.MemberUnderDeliveries.Count() > 0) { @if (Model.MemberUnderDeliveries != null && Model.MemberUnderDeliveries.Count() > 0) {
<tr class="small"> <tr class="small">
@@ -158,7 +161,13 @@
penalty += Model.MemberAutoBusinessSharesAmount; penalty += Model.MemberAutoBusinessSharesAmount;
} }
@if (Model.CustomPayment?.Amount != null) { @if (Model.CustomPayment?.Amount != null) {
@Raw(FormatRow(Model.CustomPayment.Comment ?? ((Model.CustomPayment.Amount.Value) < 0 ? "Weitere Abzüge" : "Weitere Zuschläge"), Model.CustomPayment.Amount.Value, add: true)); comment = Model.CustomPayment.Comment;
string text = (Model.CustomPayment.Amount.Value < 0 ? "Weitere Abzüge" : "Weitere Zuschläge") + (comment != null ? "*" : "");
if (comment != null && comment!.Length <= 30) {
text = comment;
comment = null;
}
@Raw(FormatRow(text, Model.CustomPayment.Amount.Value, add: true));
penalty += Model.CustomPayment.Amount.Value; penalty += Model.CustomPayment.Amount.Value;
} }
@@ -176,6 +185,9 @@
} }
</tbody> </tbody>
</table> </table>
@if (comment != null) {
<p>* @comment</p>
}
<p>Überweisung erfolgt auf Konto @(Elwig.Helpers.Utils.FormatIban(Model.Member.Iban ?? "-")).</p> <p>Überweisung erfolgt auf Konto @(Elwig.Helpers.Utils.FormatIban(Model.Member.Iban ?? "-")).</p>
<div style="margin-top: 1em;"> <div style="margin-top: 1em;">
@if (Model.Text != null) { @if (Model.Text != null) {

View File

@@ -2,7 +2,7 @@
@inherits TemplatePage<Elwig.Documents.DeliveryAncmtList> @inherits TemplatePage<Elwig.Documents.DeliveryAncmtList>
@model Elwig.Documents.DeliveryAncmtList @model Elwig.Documents.DeliveryAncmtList
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\DeliveryAncmtList.css" /> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\DeliveryAncmtList.css" />
<main> <main>
<h1>Anmeldeliste</h1> <h1>Anmeldeliste</h1>
<h2>@Model.Filter</h2> <h2>@Model.Filter</h2>
@@ -24,7 +24,7 @@
<th rowspan="2" style="text-align: left;">Ort</th> <th rowspan="2" style="text-align: left;">Ort</th>
<th rowspan="2" style="text-align: left;">Sorte</th> <th rowspan="2" style="text-align: left;">Sorte</th>
<th rowspan="2">Anmldg.</th> <th rowspan="2">Anmldg.</th>
<th>Gewicht</th> <th>Menge</th>
</tr> </tr>
<tr> <tr>
<th class="unit">[kg]</th> <th class="unit">[kg]</th>

View File

@@ -3,7 +3,7 @@
@inherits TemplatePage<Elwig.Documents.DeliveryConfirmation> @inherits TemplatePage<Elwig.Documents.DeliveryConfirmation>
@model Elwig.Documents.DeliveryConfirmation @model Elwig.Documents.DeliveryConfirmation
@{ Layout = "BusinessDocument"; } @{ Layout = "BusinessDocument"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\DeliveryConfirmation.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\DeliveryConfirmation.css" />
<main> <main>
<h1>@Model.Title</h1> <h1>@Model.Title</h1>
<table class="delivery-confirmation"> <table class="delivery-confirmation">
@@ -30,7 +30,7 @@
<th rowspan="2" style="text-align: left;">Qualitätsstufe</th> <th rowspan="2" style="text-align: left;">Qualitätsstufe</th>
<th colspan="2">Gradation</th> <th colspan="2">Gradation</th>
<th colspan="2">Flächenbindung</th> <th colspan="2">Flächenbindung</th>
<th>Gewicht</th> <th>Menge</th>
<th rowspan="3" style="padding: 0;"> <th rowspan="3" style="padding: 0;">
<svg width="10" height="40" xmlns="http://www.w3.org/2000/svg"> <svg width="10" height="40" xmlns="http://www.w3.org/2000/svg">
<text x="-40" y="4" transform="rotate(270)" font-size="8pt" font-style="italic" font-family="Times New Roman" <text x="-40" y="4" transform="rotate(270)" font-size="8pt" font-style="italic" font-family="Times New Roman"

View File

@@ -2,7 +2,7 @@
@inherits TemplatePage<Elwig.Documents.DeliveryDepreciationList> @inherits TemplatePage<Elwig.Documents.DeliveryDepreciationList>
@model Elwig.Documents.DeliveryDepreciationList @model Elwig.Documents.DeliveryDepreciationList
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\DeliveryDepreciationList.css" /> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\DeliveryDepreciationList.css" />
<main> <main>
<h1>Abwertungsliste</h1> <h1>Abwertungsliste</h1>
<h2>@Model.Filter</h2> <h2>@Model.Filter</h2>
@@ -27,7 +27,7 @@
<th rowspan="2" style="text-align: left;">Sorte</th> <th rowspan="2" style="text-align: left;">Sorte</th>
<th rowspan="2" style="text-align: left;">Attr./Bewirt.</th> <th rowspan="2" style="text-align: left;">Attr./Bewirt.</th>
<th colspan="2">Gradation</th> <th colspan="2">Gradation</th>
<th>Gewicht</th> <th>Menge</th>
</tr> </tr>
<tr> <tr>
<th class="unit">[°Oe]</th> <th class="unit">[°Oe]</th>

View File

@@ -2,7 +2,7 @@
@inherits TemplatePage<Elwig.Documents.DeliveryJournal> @inherits TemplatePage<Elwig.Documents.DeliveryJournal>
@model Elwig.Documents.DeliveryJournal @model Elwig.Documents.DeliveryJournal
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\DeliveryJournal.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\DeliveryJournal.css"/>
<main> <main>
<h1>Lieferjournal</h1> <h1>Lieferjournal</h1>
<h2>@Model.Filter</h2> <h2>@Model.Filter</h2>
@@ -29,7 +29,7 @@
<th rowspan="2" style="text-align: left;">Mitglied</th> <th rowspan="2" style="text-align: left;">Mitglied</th>
<th rowspan="2" style="text-align: left;">Sorte</th> <th rowspan="2" style="text-align: left;">Sorte</th>
<th colspan="2">Gradation</th> <th colspan="2">Gradation</th>
<th>Gewicht</th> <th>Menge</th>
</tr> </tr>
<tr> <tr>
<th class="unit">[°Oe]</th> <th class="unit">[°Oe]</th>

View File

@@ -2,7 +2,7 @@
@inherits TemplatePage<Elwig.Documents.DeliveryNote> @inherits TemplatePage<Elwig.Documents.DeliveryNote>
@model Elwig.Documents.DeliveryNote @model Elwig.Documents.DeliveryNote
@{ Layout = "BusinessDocument"; } @{ Layout = "BusinessDocument"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\DeliveryNote.css" /> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\DeliveryNote.css" />
<main> <main>
<h1>@Model.Title</h1> <h1>@Model.Title</h1>
<table class="delivery large"> <table class="delivery large">
@@ -24,7 +24,7 @@
<th class="main" rowspan="2" colspan="2">Attribut</th> <th class="main" rowspan="2" colspan="2">Attribut</th>
<th class="main" rowspan="2">Qualitätsstufe</th> <th class="main" rowspan="2">Qualitätsstufe</th>
<th colspan="2">Gradation</th> <th colspan="2">Gradation</th>
<th>Gewicht</th> <th>Menge</th>
</tr> </tr>
<tr> <tr>
<th class="unit">[°Oe]</th> <th class="unit">[°Oe]</th>

View File

@@ -23,7 +23,7 @@ namespace Elwig.Documents {
public bool ShowFoldMarks = App.Config.Debug; public bool ShowFoldMarks = App.Config.Debug;
public bool DoublePaged = false; public bool DoublePaged = false;
public string DataPath; public string DocumentsPath;
public int CurrentNextSeason; public int CurrentNextSeason;
public string? DocumentId; public string? DocumentId;
public string Title; public string Title;
@@ -34,7 +34,7 @@ namespace Elwig.Documents {
public Document(string title) { public Document(string title) {
var c = App.Client; var c = App.Client;
DataPath = App.DataPath; DocumentsPath = App.DocumentsPath;
CurrentNextSeason = Utils.CurrentNextSeason; CurrentNextSeason = Utils.CurrentNextSeason;
Title = title; Title = title;
Author = c.NameFull; Author = c.NameFull;

View File

@@ -7,9 +7,9 @@
<title>@Model.Title</title> <title>@Model.Title</title>
<meta name="author" value="@Model.Author"/> <meta name="author" value="@Model.Author"/>
<meta charset="UTF-8"/> <meta charset="UTF-8"/>
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\Document.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\Document.css" />
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\Document.Page.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\Document.Page.css" />
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\Document.Table.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\Document.Table.css" />
@if (Model.DoublePaged) { @if (Model.DoublePaged) {
<style> <style>
@@page :left { @@page :left {

View File

@@ -3,7 +3,7 @@
@inherits TemplatePage<Elwig.Documents.MemberDataSheet> @inherits TemplatePage<Elwig.Documents.MemberDataSheet>
@model Elwig.Documents.MemberDataSheet @model Elwig.Documents.MemberDataSheet
@{ Layout = "BusinessDocument"; } @{ Layout = "BusinessDocument"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\MemberDataSheet.css" /> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\MemberDataSheet.css" />
<main> <main>
<h1>@Model.Title</h1> <h1>@Model.Title</h1>
<table class="member border"> <table class="member border">

View File

@@ -2,7 +2,7 @@
@inherits TemplatePage<Elwig.Documents.MemberList> @inherits TemplatePage<Elwig.Documents.MemberList>
@model Elwig.Documents.MemberList @model Elwig.Documents.MemberList
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\MemberList.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\MemberList.css" />
<main> <main>
<h1>Mitgliederliste</h1> <h1>Mitgliederliste</h1>
<h2>@Model.Filter</h2> <h2>@Model.Filter</h2>

View File

@@ -3,7 +3,7 @@
@inherits TemplatePage<Elwig.Documents.PaymentVariantSummary> @inherits TemplatePage<Elwig.Documents.PaymentVariantSummary>
@model Elwig.Documents.PaymentVariantSummary @model Elwig.Documents.PaymentVariantSummary
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\PaymentVariantSummary.css" /> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\PaymentVariantSummary.css" />
<main> <main>
<h1>Auszahlungsvariante Lese @Model.Variant.Year</h1> <h1>Auszahlungsvariante Lese @Model.Variant.Year</h1>
<h2>@Model.Variant.Name</h2> <h2>@Model.Variant.Name</h2>
@@ -111,8 +111,8 @@
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(payed):N2}")</td> <td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(payed):N2}")</td>
@{ @{
var weiRows = Model.Data.Rows.Where(r => r.QualityLevel == "Wein"); var weiRows = Model.Data.Rows.Where(r => r.QualityLevel == "Wein");
var minWei = weiRows.Min(r => r.Ungeb.Price); var minWei = weiRows.Min(r => r.Ungeb.MinPrice);
var maxWei = weiRows.Max(r => r.Ungeb.Price); var maxWei = weiRows.Max(r => r.Ungeb.MaxPrice);
} }
<th class="lborder tborder">Preis (abgewertet):</th> <th class="lborder tborder">Preis (abgewertet):</th>
<td colspan="2" class="center tborder">@(minWei != maxWei ? $"{minWei:N4}{maxWei:N4}" : $"{minWei:N4}") @Model.CurrencySymbol/kg</td> <td colspan="2" class="center tborder">@(minWei != maxWei ? $"{minWei:N4}{maxWei:N4}" : $"{minWei:N4}") @Model.CurrencySymbol/kg</td>
@@ -123,8 +123,8 @@
<td class="number tborder"><span class="fleft">@Model.CurrencySymbol</span>@($"{netSum:N2}")</td> <td class="number tborder"><span class="fleft">@Model.CurrencySymbol</span>@($"{netSum:N2}")</td>
@{ @{
var quwRows = Model.Data.Rows.Where(r => r.QualityLevel != "Wein"); var quwRows = Model.Data.Rows.Where(r => r.QualityLevel != "Wein");
var minPrice = quwRows.Min(r => r.Ungeb.Price); var minPrice = quwRows.Min(r => r.Ungeb.MinPrice);
var maxPrice = quwRows.Max(r => r.Ungeb.Price); var maxPrice = quwRows.Max(r => r.Ungeb.MaxPrice);
} }
<th class="lborder">Preis (ungeb., nicht abgew.):</th> <th class="lborder">Preis (ungeb., nicht abgew.):</th>
<td colspan="2" class="center">@(minPrice != maxPrice ? $"{minPrice:N4}{maxPrice:N4}" : $"{minPrice:N4}") @Model.CurrencySymbol/kg</td> <td colspan="2" class="center">@(minPrice != maxPrice ? $"{minPrice:N4}{maxPrice:N4}" : $"{minPrice:N4}") @Model.CurrencySymbol/kg</td>
@@ -135,8 +135,8 @@
<td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(vat):N2}")</td> <td class="number"><span class="fleft">@Model.CurrencySymbol</span>@($"{Math.Abs(vat):N2}")</td>
@{ @{
var gebRows = Model.Data.Rows var gebRows = Model.Data.Rows
.Where(r => r.Geb.Price != null && r.Ungeb.Price != null) .Where(r => r.Geb.MaxPrice != null && r.Ungeb.MinPrice != null)
.Select(r => r.Geb.Price - r.Ungeb.Price); .Select(r => r.Geb.MaxPrice - r.Ungeb.MinPrice);
var minGeb = gebRows.Min(); var minGeb = gebRows.Min();
var maxGeb = gebRows.Max(); var maxGeb = gebRows.Max();
} }
@@ -219,19 +219,22 @@
</table> </table>
<table class="payment-variant-data"> <table class="payment-variant-data">
<colgroup> <colgroup>
<col style="width: 30mm;"/>
<col style="width: 20mm;"/>
<col style="width: 25mm;"/>
<col style="width: 20mm;"/>
<col style="width: 25mm;"/>
<col style="width: 20mm;"/>
<col style="width: 25mm;"/> <col style="width: 25mm;"/>
<col style="width: 19mm;"/>
<col style="width: 18mm;"/>
<col style="width: 15mm;"/>
<col style="width: 18mm;"/>
<col style="width: 15mm;"/>
<col style="width: 18mm;"/>
<col style="width: 15mm;"/>
<col style="width: 22mm;"/>
</colgroup> </colgroup>
<thead> <thead>
<tr> <tr>
<th rowspan="2" style="text-align: left;">Qualitätsstufe</th> <th rowspan="2" style="text-align: left;">Qualitätsstufe</th>
<th>Gradation</th> <th>Gradation</th>
<th colspan="2">ungebunden</th> <th colspan="2">ungebunden</th>
<th colspan="2">attributlos gebunden</th>
<th colspan="2">gebunden</th> <th colspan="2">gebunden</th>
<th>Gesamt</th> <th>Gesamt</th>
</tr> </tr>
@@ -241,6 +244,8 @@
<th>[@(Model.CurrencySymbol)/kg]</th> <th>[@(Model.CurrencySymbol)/kg]</th>
<th>[kg]</th> <th>[kg]</th>
<th>[@(Model.CurrencySymbol)/kg]</th> <th>[@(Model.CurrencySymbol)/kg]</th>
<th>[kg]</th>
<th>[@(Model.CurrencySymbol)/kg]</th>
<th>[@(Model.CurrencySymbol)]</th> <th>[@(Model.CurrencySymbol)]</th>
</tr> </tr>
</thead> </thead>
@@ -258,6 +263,8 @@
<th colspan="2">@hdr</th> <th colspan="2">@hdr</th>
<td class="number">@($"{rows.Sum(r => r.Ungeb.Weight):N0}")</td> <td class="number">@($"{rows.Sum(r => r.Ungeb.Weight):N0}")</td>
<td></td> <td></td>
<td class="number">@($"{rows.Sum(r => r.LowGeb.Weight):N0}")</td>
<td></td>
<td class="number">@($"{rows.Sum(r => r.Geb.Weight):N0}")</td> <td class="number">@($"{rows.Sum(r => r.Geb.Weight):N0}")</td>
<td></td> <td></td>
<td class="number">@($"{rows.Sum(r => r.Amount):N2}")</td> <td class="number">@($"{rows.Sum(r => r.Amount):N2}")</td>
@@ -267,9 +274,11 @@
<td>@(row.QualityLevel)</td> <td>@(row.QualityLevel)</td>
<td class="center">@($"{row.Oe:N0}")</td> <td class="center">@($"{row.Oe:N0}")</td>
<td class="number">@(row.Ungeb.Weight != 0 ? $"{row.Ungeb.Weight:N0}" : "-")</td> <td class="number">@(row.Ungeb.Weight != 0 ? $"{row.Ungeb.Weight:N0}" : "-")</td>
<td class="number">@(row.Ungeb.Price != null ? $"{row.Ungeb.Price:N4}" : "-")</td> <td class="number">@(row.Ungeb.MaxPrice != null ? $"{row.Ungeb.MaxPrice:N4}" : "-")</td>
<td class="number">@(row.LowGeb.Weight != 0 ? $"{row.LowGeb.Weight:N0}" : "-")</td>
<td class="number">@(row.LowGeb.MaxPrice != null ? $"{row.LowGeb.MaxPrice:N4}" : "-")</td>
<td class="number">@(row.Geb.Weight != 0 ? $"{row.Geb.Weight:N0}" : "-")</td> <td class="number">@(row.Geb.Weight != 0 ? $"{row.Geb.Weight:N0}" : "-")</td>
<td class="number">@(row.Geb.Price != null ? $"{row.Geb.Price:N4}" : "-")</td> <td class="number">@(row.Geb.MaxPrice != null ? $"{row.Geb.MaxPrice:N4}" : "-")</td>
<td class="number">@($"{row.Amount:N2}")</td> <td class="number">@($"{row.Amount:N2}")</td>
</tr> </tr>
lastHdr = hdr; lastHdr = hdr;

View File

@@ -3,7 +3,7 @@
@inherits TemplatePage<Elwig.Documents.WineQualityStatistics> @inherits TemplatePage<Elwig.Documents.WineQualityStatistics>
@model Elwig.Documents.WineQualityStatistics @model Elwig.Documents.WineQualityStatistics
@{ Layout = "Document"; } @{ Layout = "Document"; }
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\WineQualityStatistics.css"/> <link rel="stylesheet" href="file:///@Raw(Model.DocumentsPath)\WineQualityStatistics.css" />
<main> <main>
<h1>Qualitätsstatistik</h1> <h1>Qualitätsstatistik</h1>
<h2>@Model.Filter</h2> <h2>@Model.Filter</h2>

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>0.13.8</Version> <Version>0.13.9</Version>
<SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<ApplicationManifest>app.manifest</ApplicationManifest> <ApplicationManifest>app.manifest</ApplicationManifest>
@@ -20,20 +20,16 @@
<EmbeddedResource Include="Resources\Sql\*" /> <EmbeddedResource Include="Resources\Sql\*" />
</ItemGroup> </ItemGroup>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="call fetch-resources.bat" />
</Target>
<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.8" />
<PackageReference Include="MailKit" Version="4.11.0" /> <PackageReference Include="MailKit" Version="4.12.0" />
<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.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.4" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.4" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.4" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.4" /> <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.4" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3179.45" /> <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3179.45" />
<PackageReference Include="NJsonSchema" Version="11.2.0" /> <PackageReference Include="NJsonSchema" Version="11.3.2" />
<PackageReference Include="PdfiumViewer" Version="2.13.0" /> <PackageReference Include="PdfiumViewer" Version="2.13.0" />
<PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" /> <PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" />
<PackageReference Include="RazorLight" Version="2.3.1" /> <PackageReference Include="RazorLight" Version="2.3.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 = 31; public static readonly int RequiredSchemaVersion = 32;
private static int VersionOffset = 0; private static int VersionOffset = 0;

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows.Media;
namespace Elwig.Helpers.Billing { namespace Elwig.Helpers.Billing {
public class GraphEntry { public class GraphEntry {
@@ -40,6 +41,7 @@ namespace Elwig.Helpers.Billing {
public string VaributeStringSimple => (Abgewertet ? "Abgew.: " : "") + (Vaributes.Count != 0 ? (Vaributes.Count >= 25 ? "Restliche Sorten" : string.Join(", ", Vaributes.Select(c => c.Listing))) : "-"); public string VaributeStringSimple => (Abgewertet ? "Abgew.: " : "") + (Vaributes.Count != 0 ? (Vaributes.Count >= 25 ? "Restliche Sorten" : string.Join(", ", Vaributes.Select(c => c.Listing))) : "-");
public string VaributeString => Vaributes.Count != 0 ? string.Join("\n", Vaributes.Select(c => c.FullName)) : "-"; public string VaributeString => Vaributes.Count != 0 ? string.Join("\n", Vaributes.Select(c => c.FullName)) : "-";
public string VaributeStringChange => (Abgewertet ? "A." : "") + string.Join(",", Vaributes.Select(c => c.Listing)); public string VaributeStringChange => (Abgewertet ? "A." : "") + string.Join(",", Vaributes.Select(c => c.Listing));
public Brush? Color => Vaributes.Select(v => v.Variety?.Color).Distinct().SingleOrDefault();
private readonly int Precision; private readonly int Precision;
public GraphEntry(int id, int precision, BillingData.CurveMode mode) { public GraphEntry(int id, int precision, BillingData.CurveMode mode) {

View File

@@ -1,14 +1,15 @@
using System.IO.Compression;
using System.IO;
using System.Threading.Tasks;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using System.Collections.Generic;
using System;
using System.Text.Json.Nodes;
using System.Linq;
using System.Windows;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text.Json; using System.Text.Json;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using System.Windows;
namespace Elwig.Helpers.Export { namespace Elwig.Helpers.Export {
public static class ElwigData { public static class ElwigData {
@@ -63,7 +64,8 @@ namespace Elwig.Helpers.Export {
List<WbRd> Riede, List<WbRd> Riede,
List<Delivery> Deliveries, List<Delivery> Deliveries,
List<DeliveryPart> DeliveryParts, List<DeliveryPart> DeliveryParts,
List<DeliveryPartModifier> Modifiers)>(); List<DeliveryPartModifier> Modifiers,
Dictionary<string, List<(int Id1, int Id2, DateTime CreatedAt, DateTime ModifiedAt)>> Timestamps)>();
var metaData = new List<(string FileName, string ZwstId, string Device, var metaData = new List<(string FileName, string ZwstId, string Device,
int? MemberNum, string? MemberFilters, int? MemberNum, string? MemberFilters,
@@ -94,7 +96,11 @@ namespace Elwig.Helpers.Export {
areaComCount, areaComFilters != null ? string.Join(" / ", areaComFilters) : null, areaComCount, areaComFilters != null ? string.Join(" / ", areaComFilters) : null,
deliveryCount, deliveryFilters != null ? string.Join(" / ", deliveryFilters) : null)); deliveryCount, deliveryFilters != null ? string.Join(" / ", deliveryFilters) : null));
data.Add(new([], [], [], [], [], [], [], new([], []))); data.Add(new([], [], [], [], [], [], [], new([], [], new() {
["member"] = [],
["area_commitment"] = [],
["delivery"] = [],
})));
var r = data[^1]; var r = data[^1];
var membersJson = zip.GetEntry("members.json"); var membersJson = zip.GetEntry("members.json");
@@ -103,11 +109,13 @@ namespace Elwig.Helpers.Export {
string? line; string? line;
while ((line = await reader.ReadLineAsync()) != null) { while ((line = await reader.ReadLineAsync()) != null) {
var obj = JsonNode.Parse(line)!.AsObject(); var obj = JsonNode.Parse(line)!.AsObject();
var (m, b, telNrs, emailAddrs) = obj.ToMember(kgs); var (m, b, telNrs, emailAddrs, timestamps) = obj.ToMember(kgs);
r.Members.Add(m); r.Members.Add(m);
if (b != null) r.BillingAddresses.Add(b); if (b != null) r.BillingAddresses.Add(b);
r.TelephoneNumbers.AddRange(telNrs); r.TelephoneNumbers.AddRange(telNrs);
r.EmailAddresses.AddRange(emailAddrs); r.EmailAddresses.AddRange(emailAddrs);
if (timestamps.HasValue)
r.Timestamps["member"].Add((m.MgNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
} }
} }
@@ -117,12 +125,14 @@ namespace Elwig.Helpers.Export {
string? line; string? line;
while ((line = await reader.ReadLineAsync()) != null) { while ((line = await reader.ReadLineAsync()) != null) {
var obj = JsonNode.Parse(line)!.AsObject(); var obj = JsonNode.Parse(line)!.AsObject();
var (areaCom, wbrd) = obj.ToAreaCom(kgs, currentWbRde); var (areaCom, wbrd, timestamps) = obj.ToAreaCom(kgs, currentWbRde);
r.AreaCommitments.Add(areaCom); r.AreaCommitments.Add(areaCom);
if (wbrd != null) { if (wbrd != null) {
currentWbRde[wbrd.KgNr].Add(wbrd); currentWbRde[wbrd.KgNr].Add(wbrd);
r.Riede.Add(wbrd); r.Riede.Add(wbrd);
} }
if (timestamps.HasValue)
r.Timestamps["area_commitment"].Add((areaCom.FbNr, 0, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
} }
} }
@@ -132,10 +142,12 @@ namespace Elwig.Helpers.Export {
string? line; string? line;
while ((line = await reader.ReadLineAsync()) != null) { while ((line = await reader.ReadLineAsync()) != null) {
var obj = JsonNode.Parse(line)!.AsObject(); var obj = JsonNode.Parse(line)!.AsObject();
var (d, parts, mods) = obj.ToDelivery(currentLsNrs, currentDids); var (d, parts, mods, timestamps) = obj.ToDelivery(currentLsNrs, currentDids);
r.Deliveries.Add(d); r.Deliveries.Add(d);
r.DeliveryParts.AddRange(parts); r.DeliveryParts.AddRange(parts);
r.Modifiers.AddRange(mods); r.Modifiers.AddRange(mods);
if (timestamps.HasValue)
r.Timestamps["delivery"].Add((d.Year, d.DId, timestamps.Value.CreatedAt, timestamps.Value.ModifiedAt));
} }
} }
} }
@@ -144,7 +156,7 @@ namespace Elwig.Helpers.Export {
var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int Imported, int NotImported, string Filters)>(); var importedAreaComs = new List<(string FileName, string ZwstId, string Device, int Imported, int NotImported, string Filters)>();
var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string Filters)>(); var importedDeliveries = new List<(string FileName, string ZwstId, string Device, int New, int Overwritten, int NotImported, string Filters)>();
foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, areaCommitments, riede, deliveries, deliveryParts, modifiers), meta) in data.Zip(metaData)) { foreach (var ((members, billingAddresses, telephoneNumbers, emailAddresses, areaCommitments, riede, deliveries, deliveryParts, modifiers, timestamps), meta) in data.Zip(metaData)) {
var branch = branches[meta.ZwstId]; var branch = branches[meta.ZwstId];
var device = meta.Device; var device = meta.Device;
@@ -272,6 +284,26 @@ namespace Elwig.Helpers.Export {
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
var primaryKeys = new Dictionary<string, string>() {
["member"] = "mgnr, 0",
["area_commitment"] = "fbnr, 0",
["delivery"] = "year, did",
};
var updateStmts = timestamps
.SelectMany(e => e.Value.Select(m => $"UPDATE {e.Key} " +
$"SET ctime = {((DateTimeOffset)m.CreatedAt.ToUniversalTime()).ToUnixTimeSeconds()}, " +
$"mtime = {((DateTimeOffset)m.ModifiedAt.ToUniversalTime()).ToUnixTimeSeconds()} " +
$"WHERE ({primaryKeys[e.Key]}) = ({m.Id1}, {m.Id2});"));
using var cnx = AppDbContext.Connect();
await AppDbContext.ExecuteBatch(cnx, $"""
BEGIN;
UPDATE client_parameter SET value = '0' WHERE param = 'ENABLE_TIME_TRIGGERS';
{string.Join("\n", updateStmts)}
UPDATE client_parameter SET value = '1' WHERE param = 'ENABLE_TIME_TRIGGERS';
COMMIT;
""");
await AddImportedFiles(Path.GetFileName(meta.FileName)); await AddImportedFiles(Path.GetFileName(meta.FileName));
} }
App.HintContextChange(); App.HintContextChange();
@@ -460,15 +492,19 @@ namespace Elwig.Helpers.Export {
return obj; return obj;
}).ToArray()), }).ToArray()),
["comment"] = m.Comment, ["comment"] = m.Comment,
["created_at"] = $"{m.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
["modified_at"] = $"{m.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
}; };
} }
public static (Member, BillingAddr?, List<MemberTelNr>, List<MemberEmailAddr>) ToMember(this JsonNode json, Dictionary<int, AT_Kg> kgs) { public static (Member, BillingAddr?, List<MemberTelNr>, List<MemberEmailAddr>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToMember(this JsonNode json, Dictionary<int, AT_Kg> kgs) {
var mgnr = json["mgnr"]!.AsValue().GetValue<int>(); var mgnr = json["mgnr"]!.AsValue().GetValue<int>();
var kgnr = json["default_kgnr"]?.AsValue().GetValue<int>(); var kgnr = json["default_kgnr"]?.AsValue().GetValue<int>();
if (kgnr != null && !kgs.Values.Any(k => k.WbKg?.KgNr == kgnr)) { if (kgnr != null && !kgs.Values.Any(k => k.WbKg?.KgNr == kgnr)) {
throw new ArgumentException($"Für KG {(kgs.TryGetValue(kgnr.Value, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten → Herkunftshierarchie)"); throw new ArgumentException($"Für KG {(kgs.TryGetValue(kgnr.Value, out var k) ? k.Name : "?")} ({kgnr:00000}) ist noch keine Großlage festgelegt!\n(Stammdaten → Herkunftshierarchie)");
} }
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
return (new Member { return (new Member {
MgNr = mgnr, MgNr = mgnr,
PredecessorMgNr = json["predecessor_mgnr"]?.AsValue().GetValue<int>(), PredecessorMgNr = json["predecessor_mgnr"]?.AsValue().GetValue<int>(),
@@ -502,6 +538,7 @@ namespace Elwig.Helpers.Export {
ContactViaPost = json["contact_postal"]?.AsValue().GetValue<bool>() ?? false, ContactViaPost = json["contact_postal"]?.AsValue().GetValue<bool>() ?? false,
ContactViaEmail = json["contact_email"]?.AsValue().GetValue<bool>() ?? false, ContactViaEmail = json["contact_email"]?.AsValue().GetValue<bool>() ?? false,
Comment = json["comment"]?.AsValue().GetValue<string>(), Comment = json["comment"]?.AsValue().GetValue<string>(),
ImportedAt = DateTime.Now,
}, json["billing_address"] is JsonObject a ? new BillingAddr { }, json["billing_address"] is JsonObject a ? new BillingAddr {
MgNr = mgnr, MgNr = mgnr,
FullName = a["name"]!.AsValue().GetValue<string>(), FullName = a["name"]!.AsValue().GetValue<string>(),
@@ -519,7 +556,10 @@ namespace Elwig.Helpers.Export {
Nr = i + 1, Nr = i + 1,
Address = a["address"]!.AsValue().GetValue<string>(), Address = a["address"]!.AsValue().GetValue<string>(),
Comment = a["comment"]?.AsValue().GetValue<string>(), Comment = a["comment"]?.AsValue().GetValue<string>(),
}).ToList()); }).ToList(),
createdAt == null || modifiedAt == null ? null :
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
} }
public static JsonObject ToJson(this AreaCom c) { public static JsonObject ToJson(this AreaCom c) {
@@ -535,10 +575,12 @@ namespace Elwig.Helpers.Export {
["year_from"] = c.YearFrom, ["year_from"] = c.YearFrom,
["year_to"] = c.YearTo, ["year_to"] = c.YearTo,
["comment"] = c.Comment, ["comment"] = c.Comment,
["created_at"] = $"{c.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
["modified_at"] = $"{c.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
}; };
} }
public static (AreaCom, WbRd?) ToAreaCom(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, List<WbRd>> riede) { public static (AreaCom, WbRd?, (DateTime CreatedAt, DateTime ModifiedAt)?) ToAreaCom(this JsonNode json, Dictionary<int, AT_Kg> kgs, Dictionary<int, List<WbRd>> riede) {
var kgnr = json["kgnr"]!.AsValue().GetValue<int>(); var kgnr = json["kgnr"]!.AsValue().GetValue<int>();
var ried = json["ried"]?.AsValue().GetValue<string>(); var ried = json["ried"]?.AsValue().GetValue<string>();
WbRd? rd = null; WbRd? rd = null;
@@ -556,6 +598,8 @@ namespace Elwig.Helpers.Export {
rde.Add(rd); rde.Add(rd);
} }
} }
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
return (new AreaCom { return (new AreaCom {
FbNr = json["fbnr"]!.AsValue().GetValue<int>(), FbNr = json["fbnr"]!.AsValue().GetValue<int>(),
MgNr = json["mgnr"]!.AsValue().GetValue<int>(), MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
@@ -568,7 +612,11 @@ namespace Elwig.Helpers.Export {
YearFrom = json["year_from"]?.AsValue().GetValue<int>(), YearFrom = json["year_from"]?.AsValue().GetValue<int>(),
YearTo = json["year_to"]?.AsValue().GetValue<int>(), YearTo = json["year_to"]?.AsValue().GetValue<int>(),
Comment = json["comment"]?.AsValue().GetValue<string>(), Comment = json["comment"]?.AsValue().GetValue<string>(),
}, newRd ? rd : null); ImportedAt = DateTime.Now,
}, newRd ? rd : null,
createdAt == null || modifiedAt == null ? null :
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
} }
public static JsonObject ToJson(this Delivery d) { public static JsonObject ToJson(this Delivery d) {
@@ -596,6 +644,8 @@ namespace Elwig.Helpers.Export {
["manual_weighing"] = p.IsManualWeighing, ["manual_weighing"] = p.IsManualWeighing,
["modids"] = new JsonArray(p.Modifiers.Select(m => (JsonNode)m.ModId).ToArray()), ["modids"] = new JsonArray(p.Modifiers.Select(m => (JsonNode)m.ModId).ToArray()),
["comment"] = p.Comment, ["comment"] = p.Comment,
["created_at"] = $"{p.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
["modified_at"] = $"{p.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
}; };
if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck; if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck;
if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked; if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked;
@@ -609,10 +659,12 @@ namespace Elwig.Helpers.Export {
return obj; return obj;
}).ToArray()), }).ToArray()),
["comment"] = d.Comment, ["comment"] = d.Comment,
["created_at"] = $"{d.CreatedAt:yyyy-MM-ddTHH:mm:ssK}",
["modified_at"] = $"{d.ModifiedAt:yyyy-MM-ddTHH:mm:ssK}",
}; };
} }
public static (Delivery, List<DeliveryPart>, List<DeliveryPartModifier>) ToDelivery(this JsonNode json, Dictionary<string, int> currentLsNrs, Dictionary<int, int> currentDids) { public static (Delivery, List<DeliveryPart>, List<DeliveryPartModifier>, (DateTime CreatedAt, DateTime ModifiedAt)?) ToDelivery(this JsonNode json, Dictionary<string, int> currentLsNrs, Dictionary<int, int> currentDids) {
var year = json["year"]!.AsValue().GetValue<int>(); var year = json["year"]!.AsValue().GetValue<int>();
var lsnr = json["lsnr"]!.AsValue().GetValue<string>(); var lsnr = json["lsnr"]!.AsValue().GetValue<string>();
var did = currentLsNrs.GetValueOrDefault(lsnr, -1); var did = currentLsNrs.GetValueOrDefault(lsnr, -1);
@@ -621,6 +673,8 @@ namespace Elwig.Helpers.Export {
did = ++currentDids[year]; did = ++currentDids[year];
} }
currentLsNrs[lsnr] = did; currentLsNrs[lsnr] = did;
var createdAt = json["created_at"]?.AsValue().GetValue<string>();
var modifiedAt = json["modified_at"]?.AsValue().GetValue<string>();
return (new Delivery { return (new Delivery {
Year = year, Year = year,
DId = did, DId = did,
@@ -631,6 +685,7 @@ namespace Elwig.Helpers.Export {
LsNr = lsnr, LsNr = lsnr,
MgNr = json["mgnr"]!.AsValue().GetValue<int>(), MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
Comment = json["comment"]?.AsValue().GetValue<string>(), Comment = json["comment"]?.AsValue().GetValue<string>(),
ImportedAt = DateTime.Now,
}, json["parts"]!.AsArray().Select(p => p!.AsObject()).Select(p => new DeliveryPart { }, json["parts"]!.AsArray().Select(p => p!.AsObject()).Select(p => new DeliveryPart {
Year = year, Year = year,
DId = did, DId = did,
@@ -661,7 +716,10 @@ namespace Elwig.Helpers.Export {
DId = did, DId = did,
DPNr = p["dpnr"]!.AsValue().GetValue<int>(), DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
ModId = m!.AsValue().GetValue<string>(), ModId = m!.AsValue().GetValue<string>(),
})).ToList()); })).ToList(),
createdAt == null || modifiedAt == null ? null :
(DateTime.ParseExact(createdAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None),
DateTime.ParseExact(modifiedAt, "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None)));
} }
} }
} }

View File

@@ -317,7 +317,7 @@ namespace Elwig.Helpers.Export {
c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}><text:p>{SecurityElement.Escape(data.ToString())}</text:p></{ct}>"; c = $"<{ct} office:value-type=\"string\" calcext:value-type=\"string\"{add}><text:p>{SecurityElement.Escape(data.ToString())}</text:p></{ct}>";
} }
return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-rows-repeated=\"{colSpan - 1}\"/>\r\n" : ""); return $" {c}\r\n" + (colSpan > 1 ? $" <table:covered-table-cell table:number-columns-repeated=\"{colSpan - 1}\"/>\r\n" : "");
} }
} }
} }

View File

@@ -10,7 +10,7 @@ namespace Elwig.Helpers.Printing {
public static async Task Init(Action? evtHandler = null) { public static async Task Init(Action? evtHandler = null) {
var e = new RazorLightEngineBuilder() var e = new RazorLightEngineBuilder()
.UseFileSystemProject(App.DataPath + "resources") .UseFileSystemProject(App.DocumentsPath)
.UseMemoryCachingProvider() .UseMemoryCachingProvider()
.Build(); .Build();

View File

@@ -14,7 +14,7 @@ using System.Drawing.Printing;
namespace Elwig.Helpers.Printing { namespace Elwig.Helpers.Printing {
public static class Pdf { public static class Pdf {
private static readonly string WinziPrint = new string[] { App.ExePath } private static readonly string WinziPrint = new string[] { App.InstallPath }
.Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? []) .Union(Environment.GetEnvironmentVariable("PATH")?.Split(';') ?? [])
.Select(x => Path.Combine(x, "WinziPrint.exe")) .Select(x => Path.Combine(x, "WinziPrint.exe"))
.Where(File.Exists) .Where(File.Exists)

View File

@@ -434,8 +434,7 @@ namespace Elwig.Helpers {
if (accept != null) if (accept != null)
client.DefaultRequestHeaders.Accept.Add(new(accept)); client.DefaultRequestHeaders.Accept.Add(new(accept));
if (username != null || password != null) if (username != null || password != null)
client.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String( client.DefaultRequestHeaders.Authorization = new("Basic", Convert.ToBase64String(Utils.UTF8.GetBytes($"{username}:{password}")));
Utils.UTF8.GetBytes($"{username}:{password}")));
return client; return client;
} }
@@ -454,6 +453,8 @@ namespace Elwig.Helpers {
} }
public static async Task UploadExportData(string zip, string url, string username, string password) { public static async Task UploadExportData(string zip, string url, string username, string password) {
if (url.StartsWith("https://elwig.at/clients/"))
url = "https://sync.elwig.at/" + url[25..];
if (!url.EndsWith('/')) url += "/"; if (!url.EndsWith('/')) url += "/";
using var client = GetHttpClient(username, password, accept: "application/json"); using var client = GetHttpClient(username, password, accept: "application/json");
var content = new StreamContent(new FileStream(zip, FileMode.Open, FileAccess.Read)); var content = new StreamContent(new FileStream(zip, FileMode.Open, FileAccess.Read));
@@ -463,6 +464,8 @@ namespace Elwig.Helpers {
} }
public static async Task<JsonArray> GetExportMetaData(string url, string username, string password) { public static async Task<JsonArray> GetExportMetaData(string url, string username, string password) {
if (url.StartsWith("https://elwig.at/clients/"))
url = "https://sync.elwig.at/" + url[25..];
using var client = GetHttpClient(username, password, accept: "application/json"); using var client = GetHttpClient(username, password, accept: "application/json");
using var res = await client.GetAsync(url); using var res = await client.GetAsync(url);
res.EnsureSuccessStatusCode(); res.EnsureSuccessStatusCode();
@@ -496,9 +499,11 @@ namespace Elwig.Helpers {
if (App.Config.Smtp == null) if (App.Config.Smtp == null)
return false; return false;
Mouse.OverrideCursor = Cursors.Wait;
var success = await Task.Run(async () => {
SmtpClient? client = null; SmtpClient? client = null;
try { try {
Mouse.OverrideCursor = Cursors.AppStarting;
client = await GetSmtpClient(); client = await GetSmtpClient();
using var msg = new MimeMessage(); using var msg = new MimeMessage();
@@ -521,9 +526,12 @@ namespace Elwig.Helpers {
if (client != null) if (client != null)
await client.DisconnectAsync(true); await client.DisconnectAsync(true);
client?.Dispose(); client?.Dispose();
Mouse.OverrideCursor = null;
} }
return true; return true;
});
Mouse.OverrideCursor = null;
return success;
} }
public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member, string, string)? emailData = null) { public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member, string, string)? emailData = null) {

View File

@@ -27,14 +27,14 @@ namespace Elwig.Models.Dtos {
MgNr = mgnr; MgNr = mgnr;
} }
public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<Season> seasons, int year, int avnr) { public static async Task<IDictionary<int, CreditNoteDeliveryData>> ForPaymentVariant(DbSet<CreditNoteDeliveryRowSingle> table, DbSet<PaymentVar> paymentVariants, int year, int avnr) {
var variant = (await seasons.FindAsync(year))?.PaymentVariants.Where(v => v.AvNr == avnr).SingleOrDefault(); var variant = await paymentVariants.FindAsync(year, avnr);
BillingData? varData = null; BillingData? varData = null;
try { varData = variant != null ? BillingData.FromJson(variant.Data) : null; } catch { } try { varData = variant != null ? BillingData.FromJson(variant.Data) : null; } catch { }
return (await FromDbSet(table, year, avnr)) return (await FromDbSet(table, year, avnr))
.GroupBy( .GroupBy(
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr }, r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
(k, g) => new CreditNoteDeliveryRow(g, seasons, varData?.NetWeightModifier ?? 0.0, varData?.GrossWeightModifier ?? 0.0)) (k, g) => new CreditNoteDeliveryRow(g, variant, varData))
.GroupBy( .GroupBy(
r => new { r.Year, r.AvNr, r.MgNr, r.TgNr }, r => new { r.Year, r.AvNr, r.MgNr, r.TgNr },
(k, g) => new CreditNoteDeliveryData(g, k.Year, k.TgNr, mgnr: k.MgNr)) (k, g) => new CreditNoteDeliveryData(g, k.Year, k.TgNr, mgnr: k.MgNr))
@@ -86,13 +86,13 @@ namespace Elwig.Models.Dtos {
public decimal? Amount; public decimal? Amount;
public double WeighingModifier; public double WeighingModifier;
public CreditNoteDeliveryRow(IEnumerable<CreditNoteDeliveryRowSingle> rows, DbSet<Season> seasons, double netWeightModifier, double grossWeightModifier) { public CreditNoteDeliveryRow(IEnumerable<CreditNoteDeliveryRowSingle> rows, PaymentVar paymentVariant, BillingData? varData) {
var f = rows.First(); var f = rows.First();
Year = f.Year; Year = f.Year;
TgNr = f.TgNr; TgNr = f.TgNr;
AvNr = f.AvNr; AvNr = f.AvNr;
MgNr = f.MgNr; MgNr = f.MgNr;
var season = seasons.Find(Year); var season = paymentVariant.Season;
LsNr = f.LsNr; LsNr = f.LsNr;
DPNr = f.DPNr; DPNr = f.DPNr;
@@ -115,7 +115,7 @@ namespace Elwig.Models.Dtos {
b.Price != null ? season?.DecFromDb((long)b.Price) : null, b.Price != null ? season?.DecFromDb((long)b.Price) : null,
b.Amount != null ? season?.DecFromDb((long)b.Amount) : null)) b.Amount != null ? season?.DecFromDb((long)b.Amount) : null))
.ToArray(); .ToArray();
WeighingModifier = f.NetWeight ? netWeightModifier : grossWeightModifier; WeighingModifier = (varData == null || !varData.ConsiderDelieryModifiers) ? 0 : f.NetWeight ? varData.NetWeightModifier : varData.GrossWeightModifier;
Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null; Amount = f.TotalAmount != null ? season?.DecFromDb((long)f.TotalAmount) : null;
var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null; var netAmount = f.NetAmount != null ? season?.DecFromDb((long)f.NetAmount) : null;
var amt = netAmount * (decimal)(1.0 + WeighingModifier); var amt = netAmount * (decimal)(1.0 + WeighingModifier);

View File

@@ -17,9 +17,9 @@ namespace Elwig.Models.Dtos {
("Name2", "Vorname", null, 40), ("Name2", "Vorname", null, 40),
("DefaultKg", "Ort", null, 40), ("DefaultKg", "Ort", null, 40),
("SortId", "Sorte", null, 10), ("SortId", "Sorte", null, 10),
("Weight", "Gewicht", "kg", 20), ("Weight", "Menge", "kg", 20),
("CreatedTimestamp", "Angemeldet", null, 35), ("CreatedAt", "Angemeldet", null, 35),
("ModifiedTimestamp", "Geändert", null, 35), ("ModifiedAt", "Geändert", null, 35),
("Status", "Status", null, 20), ("Status", "Status", null, 20),
]; ];
@@ -47,8 +47,8 @@ namespace Elwig.Models.Dtos {
public string? DefaultKg; public string? DefaultKg;
public string SortId; public string SortId;
public string Variety; public string Variety;
public DateTime CreatedTimestamp; public DateTime CreatedAt;
public DateTime? ModifiedTimestamp; public DateTime? ModifiedAt;
public int Weight; public int Weight;
public string? Status; public string? Status;
@@ -65,10 +65,10 @@ namespace Elwig.Models.Dtos {
DefaultKg = m.DefaultKg?.Name; DefaultKg = m.DefaultKg?.Name;
SortId = a.SortId; SortId = a.SortId;
Variety = a.Variety.Name; Variety = a.Variety.Name;
CreatedTimestamp = a.CreatedTimestamp; CreatedAt = a.CreatedAt;
ModifiedTimestamp = a.ModifiedTimestamp == a.CreatedTimestamp ? null : a.ModifiedTimestamp; ModifiedAt = a.ModifiedAt == a.CreatedAt ? null : a.ModifiedAt;
Weight = a.Weight; Weight = a.Weight;
Status = s.AncmtTo == null ? null : a.CreatedTimestamp >= s.AncmtTo ? "verspät." : "ok"; Status = s.AncmtTo == null ? null : a.CreatedAt >= s.AncmtTo ? "verspät." : "ok";
} }
} }
} }

View File

@@ -16,7 +16,7 @@ namespace Elwig.Models.Dtos {
("QualityLevel", "Qualitätsstufe", null, 25), ("QualityLevel", "Qualitätsstufe", null, 25),
("Gradation", "Gradation", "°Oe|°KMW", 32), ("Gradation", "Gradation", "°Oe|°KMW", 32),
("Buckets", "Flächenbindung", "|kg", 36), ("Buckets", "Flächenbindung", "|kg", 36),
("Weight", "Gewicht", "kg", 16), ("Weight", "Menge", "kg", 16),
]; ];
private readonly int MgNr; private readonly int MgNr;

View File

@@ -24,7 +24,7 @@ namespace Elwig.Models.Dtos {
("CultId", "Bewirt.", null, 15), ("CultId", "Bewirt.", null, 15),
("QualId", "Qualität", null, 15), ("QualId", "Qualität", null, 15),
("Gradation", "Gradation", "°Oe|°KMW", 40), ("Gradation", "Gradation", "°Oe|°KMW", 40),
("Weight", "Gewicht", "kg", 20), ("Weight", "Menge", "kg", 20),
("IsNetWeight", "Gerebelt", null, 20), ("IsNetWeight", "Gerebelt", null, 20),
("HkId", "Herkunft", null, 20), ("HkId", "Herkunft", null, 20),
("Modifiers", "Zu-/Abschläge", null, 40), ("Modifiers", "Zu-/Abschläge", null, 40),

View File

@@ -18,8 +18,9 @@ namespace Elwig.Models.Dtos {
("Cultivation", "Bewirt.", null, 20), ("Cultivation", "Bewirt.", null, 20),
("QualityLevel", "Qualitätsstufe", null, 30), ("QualityLevel", "Qualitätsstufe", null, 30),
("Oe", "Gradation", "°Oe", 20), ("Oe", "Gradation", "°Oe", 20),
("Ungeb", "ungebunden", "kg|€/kg", 40), ("Ungeb", "ungebunden", "kg|€/kg|€/kg", 60),
("Geb", "gebunden", "kg|€/kg", 40), ("LowGeb", "attributlos gebunden", "kg|€/kg|€/kg", 60),
("Geb", "gebunden", "kg|€/kg|€/kg", 60),
("Amount", "Gesamt", "€", 25), ("Amount", "Gesamt", "€", 25),
]; ];
@@ -30,8 +31,9 @@ namespace Elwig.Models.Dtos {
string? Cultivation, string? Cultivation,
string QualityLevel, string QualityLevel,
double Oe, double Oe,
(int Weight, decimal? Price) Ungeb, (int Weight, decimal? MinPrice, decimal? MaxPrice) Ungeb,
(int Weight, decimal? Price) Geb, (int Weight, decimal? MinPrice, decimal? MaxPrice) LowGeb,
(int Weight, decimal? MinPrice, decimal? MaxPrice) Geb,
decimal Amount decimal Amount
); );
@@ -42,8 +44,9 @@ namespace Elwig.Models.Dtos {
public static async Task<PaymentVariantSummaryData> ForPaymentVariant(PaymentVar v, DbSet<PaymentVariantSummaryRow> table) { public static async Task<PaymentVariantSummaryData> ForPaymentVariant(PaymentVar v, DbSet<PaymentVariantSummaryRow> table) {
return new(v, (await FromDbSet(table, v.Year, v.AvNr)) return new(v, (await FromDbSet(table, v.Year, v.AvNr))
.Select(r => new PaymentRow(r.Type, r.Variety, r.Attribute, r.Cultivation, r.QualityLevel, r.Oe, .Select(r => new PaymentRow(r.Type, r.Variety, r.Attribute, r.Cultivation, r.QualityLevel, r.Oe,
(r.WeightUngeb, r.PriceUngeb != null ? Utils.DecFromDb(r.PriceUngeb.Value, v.Season.Precision) : null), (r.WeightUngeb, r.MinPriceUngeb != null ? Utils.DecFromDb(r.MinPriceUngeb.Value, v.Season.Precision) : null, r.MaxPriceUngeb != null ? Utils.DecFromDb(r.MaxPriceUngeb.Value, v.Season.Precision) : null),
(r.WeightGeb, r.PriceGeb != null ? Utils.DecFromDb(r.PriceGeb.Value, v.Season.Precision) : null), (r.WeightLowGeb, r.MinPriceLowGeb != null ? Utils.DecFromDb(r.MinPriceLowGeb.Value, v.Season.Precision) : null, r.MaxPriceLowGeb != null ? Utils.DecFromDb(r.MaxPriceLowGeb.Value, v.Season.Precision) : null),
(r.WeightGeb, r.MinPriceGeb != null ? Utils.DecFromDb(r.MinPriceGeb.Value, v.Season.Precision) : null, r.MaxPriceGeb != null ? Utils.DecFromDb(r.MaxPriceGeb.Value, v.Season.Precision) : null),
Utils.DecFromDb(r.Amount, v.Season.Precision))) Utils.DecFromDb(r.Amount, v.Season.Precision)))
.ToArray()); .ToArray());
} }
@@ -57,19 +60,23 @@ namespace Elwig.Models.Dtos {
q.name AS quality_level, q.name AS quality_level,
ROUND(kmw * (4.54 + 0.022 * kmw)) AS oe, ROUND(kmw * (4.54 + 0.022 * kmw)) AS oe,
SUM(IIF(w.discr = '_', w.value, 0)) AS weight_ungeb, SUM(IIF(w.discr = '_', w.value, 0)) AS weight_ungeb,
MAX(IIF(w.discr = '_', b.price, NULL)) AS price_ungeb, MIN(IIF(w.discr = '_', b.price, NULL)) AS min_price_ungeb,
SUM(IIF(w.discr != '_', w.value, 0)) AS weight_geb, MAX(IIF(w.discr = '_', b.price, NULL)) AS max_price_ungeb,
MAX(IIF(w.discr != '_', b.price, NULL)) AS price_geb, SUM(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), w.value, 0)) AS weight_lowgeb,
MIN(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), b.price, NULL)) AS min_price_lowgeb,
MAX(IIF(w.discr NOT IN (COALESCE(p.attrid, ''), '_'), b.price, NULL)) AS max_price_lowgeb,
SUM(IIF(w.discr = COALESCE(p.attrid, ''), w.value, 0)) AS weight_geb,
MIN(IIF(w.discr = COALESCE(p.attrid, ''), b.price, NULL)) AS min_price_geb,
MAX(IIF(w.discr = COALESCE(p.attrid, ''), b.price, NULL)) AS max_price_geb,
SUM(b.amount) AS amount SUM(b.amount) AS amount
FROM payment_delivery_part_bucket b FROM payment_delivery_part_bucket b
LEFT JOIN delivery_part_bucket w ON (w.year, w.did, w.dpnr, w.bktnr) = (b.year, b.did, b.dpnr, b.bktnr) LEFT JOIN delivery_part_bucket w ON (w.year, w.did, w.dpnr, w.bktnr) = (b.year, b.did, b.dpnr, b.bktnr)
LEFT JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (b.year, b.did, b.dpnr) LEFT JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (b.year, b.did, b.dpnr)
LEFT JOIN delivery d ON (d.year, d.did) = (p.year, p.did)
LEFT JOIN wine_variety v ON v.sortid = p.sortid LEFT JOIN wine_variety v ON v.sortid = p.sortid
LEFT JOIN wine_attribute a ON a.attrid = p.attrid LEFT JOIN wine_attribute a ON a.attrid = p.attrid
LEFT JOIN wine_cultivation c ON c.cultid = p.cultid LEFT JOIN wine_cultivation c ON c.cultid = p.cultid
LEFT JOIN wine_quality_level q ON q.qualid = p.qualid LEFT JOIN wine_quality_level q ON q.qualid = p.qualid
WHERE d.year = {year} AND b.avnr = {avnr} WHERE p.year = {year} AND b.avnr = {avnr}
GROUP BY variety, attribute, cultivation, q.min_kmw, oe GROUP BY variety, attribute, cultivation, q.min_kmw, oe
ORDER BY variety, attribute, cultivation, q.min_kmw, oe ORDER BY variety, attribute, cultivation, q.min_kmw, oe
""").ToListAsync(); """).ToListAsync();
@@ -92,12 +99,22 @@ namespace Elwig.Models.Dtos {
public double Oe { get; set; } public double Oe { get; set; }
[Column("weight_ungeb")] [Column("weight_ungeb")]
public int WeightUngeb { get; set; } public int WeightUngeb { get; set; }
[Column("price_ungeb")] [Column("min_price_ungeb")]
public long? PriceUngeb { get; set; } public long? MinPriceUngeb { get; set; }
[Column("max_price_ungeb")]
public long? MaxPriceUngeb { get; set; }
[Column("weight_lowgeb")]
public int WeightLowGeb { get; set; }
[Column("min_price_lowgeb")]
public long? MinPriceLowGeb { get; set; }
[Column("max_price_lowgeb")]
public long? MaxPriceLowGeb { get; set; }
[Column("weight_geb")] [Column("weight_geb")]
public int WeightGeb { get; set; } public int WeightGeb { get; set; }
[Column("price_geb")] [Column("min_price_geb")]
public long? PriceGeb { get; set; } public long? MinPriceGeb { get; set; }
[Column("max_price_geb")]
public long? MaxPriceGeb { get; set; }
[Column("amount")] [Column("amount")]
public long Amount { get; set; } public long Amount { get; set; }
} }

View File

@@ -14,7 +14,7 @@ namespace Elwig.Models.Dtos {
("CultId", "Bewirt.", null, 15), ("CultId", "Bewirt.", null, 15),
("QualId", "Qual.", null, 15), ("QualId", "Qual.", null, 15),
("Geb", "gebunden", null, 20), ("Geb", "gebunden", null, 20),
("Weight", "Gewicht", "kg", 20), ("Weight", "Menge", "kg", 20),
]; ];
public WeightBreakdownData(IEnumerable<WeightBreakdownRow> rows, int year, string name) : public WeightBreakdownData(IEnumerable<WeightBreakdownRow> rows, int year, string name) :

View File

@@ -17,7 +17,7 @@ namespace Elwig.Models.Dtos {
("Members", "Mitgl.", "#", 15), ("Members", "Mitgl.", "#", 15),
("Deliveries", "Lfrg.", "#", 15), ("Deliveries", "Lfrg.", "#", 15),
("Parts", "Teill.", "#", 15), ("Parts", "Teill.", "#", 15),
("Weight", "Gewicht", "kg", 20), ("Weight", "Menge", "kg", 20),
("Gradation", "Gradation", "°Oe|°KMW", 30), ("Gradation", "Gradation", "°Oe|°KMW", 30),
]; ];

View File

@@ -41,14 +41,36 @@ namespace Elwig.Models.Entities {
public string? Comment { get; set; } public string? Comment { get; set; }
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[ForeignKey("MgNr")] [ForeignKey("MgNr")]
public virtual Member Member { get; private set; } = null!; public virtual Member Member { get; private set; } = null!;

View File

@@ -84,14 +84,36 @@ namespace Elwig.Models.Entities {
} }
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[ForeignKey("Year, AvNr, MgNr")] [ForeignKey("Year, AvNr, MgNr")]
public virtual PaymentMember Payment { get; private set; } = null!; public virtual PaymentMember Payment { get; private set; } = null!;

View File

@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Linq; using System.Linq;
using System.Windows.Media;
using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute; using IndexAttribute = Microsoft.EntityFrameworkCore.IndexAttribute;
namespace Elwig.Models.Entities { namespace Elwig.Models.Entities {
@@ -62,14 +63,36 @@ namespace Elwig.Models.Entities {
public string? Comment { get; set; } public string? Comment { get; set; }
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[ForeignKey("Year")] [ForeignKey("Year")]
public virtual Season Season { get; private set; } = null!; public virtual Season Season { get; private set; } = null!;
@@ -96,6 +119,9 @@ namespace Elwig.Models.Entities {
public string SortIdString => string.Join(", ", SortIds); public string SortIdString => string.Join(", ", SortIds);
public string FilteredSortIdString => string.Join(", ", FilteredSortIds); public string FilteredSortIdString => string.Join(", ", FilteredSortIds);
public Brush? Color => Parts.Select(p => p.Variety.Color).Distinct().SingleOrDefault();
public Brush? FilteredColor => FilteredParts.Select(p => p.Variety.Color).Distinct().SingleOrDefault();
public IEnumerable<string> Modifiers => Parts public IEnumerable<string> Modifiers => Parts
.SelectMany(p => p.Modifiers) .SelectMany(p => p.Modifiers)
.Select(m => m.Name) .Select(m => m.Name)

View File

@@ -27,14 +27,36 @@ namespace Elwig.Models.Entities {
public required string Type { get; set; } public required string Type { get; set; }
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[ForeignKey("Year, DsNr")] [ForeignKey("Year, DsNr")]
public virtual DeliverySchedule Schedule { get; private set; } = null!; public virtual DeliverySchedule Schedule { get; private set; } = null!;

View File

@@ -129,14 +129,36 @@ namespace Elwig.Models.Entities {
public string? Comment { get; set; } public string? Comment { get; set; }
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[InverseProperty(nameof(DeliveryPartModifier.Part))] [InverseProperty(nameof(DeliveryPartModifier.Part))]
public virtual ICollection<DeliveryPartModifier> PartModifiers { get; private set; } = null!; public virtual ICollection<DeliveryPartModifier> PartModifiers { get; private set; } = null!;

View File

@@ -145,14 +145,36 @@ namespace Elwig.Models.Entities {
public AT_Kg? DefaultKg => DefaultWbKg?.AtKg; public AT_Kg? DefaultKg => DefaultWbKg?.AtKg;
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[ForeignKey("ZwstId")] [ForeignKey("ZwstId")]
public virtual Branch? Branch { get; private set; } public virtual Branch? Branch { get; private set; }

View File

@@ -46,14 +46,36 @@ namespace Elwig.Models.Entities {
public required string Data { get; set; } public required string Data { get; set; }
[Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("ctime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long CTime { get; private set; } public long CTime { get; set; }
[NotMapped] [NotMapped]
public DateTime CreatedTimestamp => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime; public DateTime CreatedAt {
get => DateTimeOffset.FromUnixTimeSeconds(CTime).LocalDateTime;
set => CTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)] [Column("mtime"), DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public long MTime { get; private set; } public long MTime { get; set; }
[NotMapped] [NotMapped]
public DateTime ModifiedTimestamp => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime; public DateTime ModifiedAt {
get => DateTimeOffset.FromUnixTimeSeconds(MTime).LocalDateTime;
set => MTime = ((DateTimeOffset)value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("xtime")]
public long? XTime { get; set; }
[NotMapped]
public DateTime? ExportedAt {
get => XTime == null ? null : DateTimeOffset.FromUnixTimeSeconds(XTime.Value).LocalDateTime;
set => XTime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[Column("itime")]
public long? ITime { get; set; }
[NotMapped]
public DateTime? ImportedAt {
get => ITime == null ? null : DateTimeOffset.FromUnixTimeSeconds(ITime.Value).LocalDateTime;
set => ITime = value == null ? null : ((DateTimeOffset)value.Value.ToUniversalTime()).ToUnixTimeSeconds();
}
[ForeignKey("Year")] [ForeignKey("Year")]
public virtual Season Season { get; private set; } = null!; public virtual Season Season { get; private set; } = null!;

View File

@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Windows.Media;
namespace Elwig.Models.Entities { namespace Elwig.Models.Entities {
[Table("wine_variety"), PrimaryKey("SortId")] [Table("wine_variety"), PrimaryKey("SortId")]
@@ -20,6 +21,7 @@ namespace Elwig.Models.Entities {
public bool IsRed => Type == "R"; public bool IsRed => Type == "R";
public bool IsWhite => Type == "W"; public bool IsWhite => Type == "W";
public Brush? Color => IsWhite ? Brushes.DarkGreen : IsRed ? Brushes.DarkRed : null;
public WineVar() { } public WineVar() { }

View File

@@ -0,0 +1,33 @@
-- schema version 31 to 32
INSERT INTO client_parameter (param, value) VALUES ('ENABLE_TIME_TRIGGERS', '1');
ALTER TABLE member ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE member ADD COLUMN itime INTEGER DEFAULT NULL;
ALTER TABLE area_commitment ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE area_commitment ADD COLUMN itime INTEGER DEFAULT NULL;
ALTER TABLE delivery_announcement ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE delivery_announcement ADD COLUMN itime INTEGER DEFAULT NULL;
ALTER TABLE delivery ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE delivery ADD COLUMN itime INTEGER DEFAULT NULL;
ALTER TABLE delivery_part ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE delivery_part ADD COLUMN itime INTEGER DEFAULT NULL;
ALTER TABLE payment_variant ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE payment_variant ADD COLUMN itime INTEGER DEFAULT NULL;
ALTER TABLE credit ADD COLUMN xtime INTEGER DEFAULT NULL;
ALTER TABLE credit ADD COLUMN itime INTEGER DEFAULT NULL;
PRAGMA writable_schema = ON;
UPDATE sqlite_schema SET sql = REPLACE(REPLACE(sql,
' WHEN',
' WHEN (SELECT value FROM client_parameter WHERE param = ''ENABLE_TIME_TRIGGERS'') = 1 AND'),
'FOR EACH ROW' || char(10) ||
'BEGIN',
'FOR EACH ROW' || char(10) ||
' WHEN (SELECT value FROM client_parameter WHERE param = ''ENABLE_TIME_TRIGGERS'') = 1' || char(10) ||
'BEGIN')
WHERE type = 'trigger' AND name LIKE '%time%';
PRAGMA writable_schema = OFF;
PRAGMA schema_version = 3101;

View File

@@ -106,12 +106,13 @@ namespace Elwig.Services {
} }
public static async Task<int> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr) { public static async Task<int> UpdateAreaCommitment(this AreaComAdminViewModel vm, int? oldFbNr) {
int newFbNr = (int)vm.FbNr!; int newFbNr = vm.FbNr!.Value;
using (var ctx = new AppDbContext()) { return await Task.Run(async () => {
using var ctx = new AppDbContext();
var a = new AreaCom { var a = new AreaCom {
FbNr = oldFbNr ?? newFbNr, FbNr = oldFbNr ?? newFbNr,
MgNr = (int)vm.MgNr!, MgNr = vm.MgNr!.Value,
YearFrom = vm.YearFrom, YearFrom = vm.YearFrom,
YearTo = vm.YearTo, YearTo = vm.YearTo,
VtrgId = vm.AreaComType!.VtrgId, VtrgId = vm.AreaComType!.VtrgId,
@@ -119,8 +120,8 @@ namespace Elwig.Services {
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment, Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
KgNr = vm.Kg!.KgNr, KgNr = vm.Kg!.KgNr,
RdNr = vm.Rd?.RdNr, RdNr = vm.Rd?.RdNr,
GstNr = vm.GstNr!.Trim(), GstNr = vm.GstNr?.Trim() ?? "-",
Area = (int)vm.Area!, Area = vm.Area!.Value,
}; };
if (vm.Rd?.RdNr == 0) { if (vm.Rd?.RdNr == 0) {
@@ -140,11 +141,9 @@ namespace Elwig.Services {
if (newFbNr != a.FbNr) { if (newFbNr != a.FbNr) {
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}"); await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}");
} }
}
App.HintContextChange();
return newFbNr; return newFbNr;
});
} }
private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) { private static void AddToolTipCell(Grid grid, string text, int row, int col, int colSpan = 1, bool bold = false, bool alignRight = false, bool alignCenter = false) {
@@ -253,5 +252,14 @@ namespace Elwig.Services {
} }
return grid; return grid;
} }
public static async Task DeleteAreaCom(int fbnr) {
await Task.Run(async () => {
using var ctx = new AppDbContext();
var l = (await ctx.AreaCommitments.FindAsync(fbnr))!;
ctx.Remove(l);
await ctx.SaveChangesAsync();
});
}
} }
} }

View File

@@ -37,8 +37,8 @@ namespace Elwig.Services {
vm.DeliverySchedule = (DeliverySchedule?)ControlUtils.GetItemFromSourceWithPk(vm.DeliveryScheduleSource, a.Year, a.DsNr); vm.DeliverySchedule = (DeliverySchedule?)ControlUtils.GetItemFromSourceWithPk(vm.DeliveryScheduleSource, a.Year, a.DsNr);
vm.SortId = a.SortId; vm.SortId = a.SortId;
vm.Weight = a.Weight; vm.Weight = a.Weight;
vm.StatusAncmtCreated = $"{a.CreatedTimestamp:dd.MM.yyyy, HH:mm} ({a.Type})"; vm.StatusAncmtCreated = $"{a.CreatedAt:dd.MM.yyyy, HH:mm} ({a.Type})";
vm.StatusAncmtModified = a.ModifiedTimestamp != a.CreatedTimestamp ? $"{a.ModifiedTimestamp:dd.MM.yyyy, HH:mm}" : "-"; vm.StatusAncmtModified = a.ModifiedAt != a.CreatedAt ? $"{a.ModifiedAt:dd.MM.yyyy, HH:mm}" : "-";
} }
public static async Task<(List<string>, IQueryable<DeliveryAncmt>, List<string>)> GetFilters(this DeliveryAncmtAdminViewModel vm, AppDbContext ctx) { public static async Task<(List<string>, IQueryable<DeliveryAncmt>, List<string>)> GetFilters(this DeliveryAncmtAdminViewModel vm, AppDbContext ctx) {
@@ -211,7 +211,8 @@ namespace Elwig.Services {
int newMgNr = vm.MgNr!.Value; int newMgNr = vm.MgNr!.Value;
string newSortId = vm.SortId!; string newSortId = vm.SortId!;
using (var ctx = new AppDbContext()) { return await Task.Run(async () => {
using var ctx = new AppDbContext();
var a = new DeliveryAncmt { var a = new DeliveryAncmt {
Year = oldYear ?? year, Year = oldYear ?? year,
DsNr = oldDsNr ?? dsnr, DsNr = oldDsNr ?? dsnr,
@@ -232,11 +233,9 @@ namespace Elwig.Services {
if (oldDsNr != null && (oldYear != year || oldDsNr != dsnr || oldMgNr != newMgNr || oldSortId != newSortId)) { if (oldDsNr != null && (oldYear != year || oldDsNr != dsnr || oldMgNr != newMgNr || oldSortId != newSortId)) {
await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_announcement SET year = {year}, dsnr = {dsnr}, mgnr = {newMgNr}, sortid = {newSortId} WHERE (year, dsnr, mgnr, sortid) = ({a.Year}, {a.DsNr}, {a.MgNr}, {a.SortId})"); await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_announcement SET year = {year}, dsnr = {dsnr}, mgnr = {newMgNr}, sortid = {newSortId} WHERE (year, dsnr, mgnr, sortid) = ({a.Year}, {a.DsNr}, {a.MgNr}, {a.SortId})");
} }
}
App.HintContextChange();
return (year, dsnr, newMgNr, newSortId); return (year, dsnr, newMgNr, newSortId);
});
} }
public static async Task GenerateDeliveryAncmtList(this DeliveryAncmtAdminViewModel vm, ExportSubject subject, ExportMode mode) { public static async Task GenerateDeliveryAncmtList(this DeliveryAncmtAdminViewModel vm, ExportSubject subject, ExportMode mode) {
@@ -269,7 +268,8 @@ namespace Elwig.Services {
Title = $"{DeliveryAncmtList.Name} speichern unter - Elwig" Title = $"{DeliveryAncmtList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await DeliveryAncmtListData.FromQuery(query, filterNames); var data = await DeliveryAncmtListData.FromQuery(query, filterNames);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
@@ -277,10 +277,12 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await DeliveryAncmtListData.FromQuery(query, filterNames); var data = await DeliveryAncmtListData.FromQuery(query, filterNames);
using var doc = new DeliveryAncmtList(string.Join(" / ", filterNames), data); using var doc = new DeliveryAncmtList(string.Join(" / ", filterNames), data);
@@ -288,6 +290,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@@ -326,7 +329,7 @@ namespace Elwig.Services {
var weight = await deliveryAncmts.SumAsync(p => p.Weight); var weight = await deliveryAncmts.SumAsync(p => p.Weight);
text = $"{weight:N0} kg"; text = $"{weight:N0} kg";
AddToolTipRow(grid, 0, "Gewicht", null, weight, null, weight); AddToolTipRow(grid, 0, "Menge", null, weight, null, weight);
if (await deliveryAncmts.AnyAsync()) { if (await deliveryAncmts.AnyAsync()) {
var attrGroups = await deliveryAncmts var attrGroups = await deliveryAncmts

View File

@@ -152,7 +152,8 @@ namespace Elwig.Services {
public static async Task UpdateDeliverySchedule(this DeliveryScheduleAdminViewModel vm, int? oldYear, int? oldDsNr) { public static async Task UpdateDeliverySchedule(this DeliveryScheduleAdminViewModel vm, int? oldYear, int? oldDsNr) {
int year = vm.Date!.Value.Year; int year = vm.Date!.Value.Year;
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var s = new DeliverySchedule { var s = new DeliverySchedule {
Year = oldYear ?? year, Year = oldYear ?? year,
DsNr = oldDsNr ?? await ctx.NextDsNr(year), DsNr = oldDsNr ?? await ctx.NextDsNr(year),
@@ -181,9 +182,7 @@ namespace Elwig.Services {
.ToList(), vm.MainVarieties.Select(v => (v, 1)).Union(vm.OtherVarieties.Select(v => (v, 2))).ToList()); .ToList(), vm.MainVarieties.Select(v => (v, 1)).Union(vm.OtherVarieties.Select(v => (v, 2))).ToList());
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange();
} }
} }
} }

View File

@@ -430,9 +430,10 @@ namespace Elwig.Services {
} }
public static async Task<DeliveryPart> UpdateDeliveryPart(this DeliveryAdminViewModel vm, int? oldYear, int? oldDid, int? oldDpnr, bool dateHasChanged, bool timeHasChanged, bool timeIsDefault) { public static async Task<DeliveryPart> UpdateDeliveryPart(this DeliveryAdminViewModel vm, int? oldYear, int? oldDid, int? oldDpnr, bool dateHasChanged, bool timeHasChanged, bool timeIsDefault) {
return await Task.Run(async () => {
DeliveryPart p; DeliveryPart p;
using (var ctx = new AppDbContext()) { using var ctx = new AppDbContext();
int year = oldYear ?? Utils.CurrentYear; int year = oldYear ?? Utils.CurrentYear;
int did = oldDid ?? await ctx.NextDId(year); int did = oldDid ?? await ctx.NextDId(year);
int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did); int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did);
@@ -524,17 +525,16 @@ namespace Elwig.Services {
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
}
App.HintContextChange();
return p; return p;
});
} }
public static async Task<Delivery> SplitDeliveryToMember(int year, int did, int[] weights, int mgnr) { public static async Task<Delivery> SplitDeliveryToMember(int year, int did, int[] weights, int mgnr) {
return await Task.Run(async () => {
Delivery n; Delivery n;
using (var ctx = new AppDbContext()) { using var ctx = new AppDbContext();
bool anyLeft = false; bool anyLeft = false;
var d = (await ctx.Deliveries.FindAsync(year, did))!; var d = (await ctx.Deliveries.FindAsync(year, did))!;
var lnr = await ctx.NextLNr(d.Date, d.ZwstId); var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
@@ -577,17 +577,15 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
if (!anyLeft) if (!anyLeft)
await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})"); await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
}
App.HintContextChange();
return n; return n;
});
} }
public static async Task<Delivery> SplitDeliveryToLsNr(int year, int did, int[] weights, string lsnr) { public static async Task<Delivery> SplitDeliveryToLsNr(int year, int did, int[] weights, string lsnr) {
return await Task.Run(async () => {
Delivery n; Delivery n;
using var ctx = new AppDbContext();
using (var ctx = new AppDbContext()) {
var anyLeft = false; var anyLeft = false;
n = (await ctx.Deliveries.FirstAsync(d => d.LsNr == lsnr))!; n = (await ctx.Deliveries.FirstAsync(d => d.LsNr == lsnr))!;
var d = (await ctx.Deliveries.FindAsync(year, did))!; var d = (await ctx.Deliveries.FindAsync(year, did))!;
@@ -616,15 +614,14 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
if (!anyLeft && n.LsNr != d.LsNr) if (!anyLeft && n.LsNr != d.LsNr)
await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})"); await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
}
App.HintContextChange();
return n; return n;
});
} }
public static async Task DepreciateDelivery(int year, int did, int[] weights) { public static async Task DepreciateDelivery(int year, int did, int[] weights) {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var d = (await ctx.Deliveries.FindAsync(year, did))!; var d = (await ctx.Deliveries.FindAsync(year, did))!;
var dpnr = await ctx.NextDPNr(year, did); var dpnr = await ctx.NextDPNr(year, did);
foreach (var (p, w) in d.Parts.ToList().Zip(weights)) { foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
@@ -648,13 +645,12 @@ namespace Elwig.Services {
} }
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange();
} }
public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) { public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var d = (await ctx.Deliveries.FindAsync(year, did))!; var d = (await ctx.Deliveries.FindAsync(year, did))!;
@@ -663,6 +659,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -707,7 +704,8 @@ namespace Elwig.Services {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig" Title = $"{DeliveryJournal.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await DeliveryJournalData.FromQuery(query, filterNames); var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
@@ -715,6 +713,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
@@ -725,7 +724,8 @@ namespace Elwig.Services {
Title = $"{DeliveryJournal.Name} speichern unter - Elwig" Title = $"{DeliveryJournal.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
await ElwigData.Export(d.FileName, await query await ElwigData.Export(d.FileName, await query
.Select(p => p.Delivery) .Select(p => p.Delivery)
@@ -737,10 +737,12 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) { } else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip"; var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip";
var path = Path.Combine(App.TempPath, filename); var path = Path.Combine(App.TempPath, filename);
@@ -767,9 +769,11 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await DeliveryJournalData.FromQuery(query, filterNames); var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data); using var doc = new DeliveryJournal(string.Join(" / ", filterNames), data);
@@ -777,6 +781,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@@ -798,7 +803,8 @@ namespace Elwig.Services {
throw new ArgumentException("Invalid value for ExportSubject"); throw new ArgumentException("Invalid value for ExportSubject");
} }
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList); var data = await WineQualityStatisticsData.FromQuery(query, App.Client.OrderingMemberList);
using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data); using var doc = new WineQualityStatistics(string.Join(" / ", filterNames), data);
@@ -806,6 +812,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -829,7 +836,8 @@ namespace Elwig.Services {
Title = $"Lieferstatistik pro Ort speichern unter - Elwig" Title = $"Lieferstatistik pro Ort speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames); var tbl = await WineLocalityStatisticsData.FromQuery(query, filterNames);
@@ -837,6 +845,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@@ -875,7 +884,8 @@ namespace Elwig.Services {
Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig" Title = $"{DeliveryDepreciationList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames); var tblTotal = await DeliveryJournalData.FromQuery(query, filterNames);
@@ -891,10 +901,12 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await DeliveryJournalData.FromQuery(query, filterNames); var data = await DeliveryJournalData.FromQuery(query, filterNames);
using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data); using var doc = new DeliveryDepreciationList(string.Join(" / ", filterNames), data);
@@ -902,6 +914,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
@@ -946,7 +959,7 @@ namespace Elwig.Services {
var weight = await deliveryParts.SumAsync(p => p.Weight); var weight = await deliveryParts.SumAsync(p => p.Weight);
wText = $"{weight:N0} kg"; wText = $"{weight:N0} kg";
wGrid.Add(("Gewicht", null, weight, null, weight)); wGrid.Add(("Menge", null, weight, null, weight));
if (await deliveryParts.AnyAsync()) { if (await deliveryParts.AnyAsync()) {
var kmwMin = await deliveryParts.MinAsync(p => p.Kmw); var kmwMin = await deliveryParts.MinAsync(p => p.Kmw);
@@ -1047,7 +1060,7 @@ namespace Elwig.Services {
wGrid.ColumnDefinitions.Add(new() { Width = new(50) }); wGrid.ColumnDefinitions.Add(new() { Width = new(50) });
int rowNum = 0; int rowNum = 0;
foreach (var row in weightData) { foreach (var row in weightData) {
if (rowNum == 1 || (rowNum != 0 && row.Item1 != null)) rowNum++; if (rowNum != 0 && row.Item2 == null) rowNum++;
AddWeightToolTipRow(wGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5); AddWeightToolTipRow(wGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
} }
@@ -1062,7 +1075,7 @@ namespace Elwig.Services {
AddToolTipCell(gGrid, "Max.", 0, 4, 1, false, false, true); AddToolTipCell(gGrid, "Max.", 0, 4, 1, false, false, true);
rowNum = 1; rowNum = 1;
foreach (var row in gradationData) { foreach (var row in gradationData) {
if (rowNum == 2 || (rowNum != 1 && row.Item1 != null)) rowNum++; if (rowNum != 1 && row.Item2 == null) rowNum++;
AddGradationToolTipRow(gGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5); AddGradationToolTipRow(gGrid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
} }
@@ -1070,11 +1083,11 @@ namespace Elwig.Services {
} }
public static async Task DeleteDelivery(string lsnr) { public static async Task DeleteDelivery(string lsnr) {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
await ctx.Deliveries.Where(d => d.LsNr == lsnr).ExecuteDeleteAsync(); await ctx.Deliveries.Where(d => d.LsNr == lsnr).ExecuteDeleteAsync();
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange();
} }
} }
} }

View File

@@ -1,20 +1,20 @@
using Elwig.Helpers;
using Elwig.Models.Entities;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System;
using Microsoft.EntityFrameworkCore;
using Elwig.Documents; using Elwig.Documents;
using System.Windows.Input; using Elwig.Helpers;
using System.Windows;
using Elwig.Helpers.Billing; using Elwig.Helpers.Billing;
using Elwig.Models.Dtos;
using Elwig.Helpers.Export; using Elwig.Helpers.Export;
using Microsoft.Win32; using Elwig.Models.Dtos;
using Elwig.Models.Entities;
using Elwig.ViewModels; using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Elwig.Services { namespace Elwig.Services {
public static class MemberService { public static class MemberService {
@@ -49,6 +49,11 @@ namespace Elwig.Services {
vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}"; vm.StatusAreaCommitmentInfo = $"{Utils.CurrentLastSeason}";
vm.StatusAreaCommitmentToolTip = null; vm.StatusAreaCommitmentToolTip = null;
vm.Age = "-"; vm.Age = "-";
vm.CreatedAt = "-";
vm.ModifiedAt = "-";
vm.ModifiedAtShort = "-";
vm.ExportedAt = "-";
vm.ImportedAt = "-";
} }
public static void FillInputs(this MemberAdminViewModel vm, Member m) { public static void FillInputs(this MemberAdminViewModel vm, Member m) {
@@ -137,6 +142,12 @@ namespace Elwig.Services {
vm.ContactViaPost = m.ContactViaPost; vm.ContactViaPost = m.ContactViaPost;
vm.ContactViaEmail = m.ContactViaEmail; vm.ContactViaEmail = m.ContactViaEmail;
vm.CreatedAt = $"{m.CreatedAt:dd.MM.yyyy, HH:mm:ss}";
vm.ModifiedAt = $"{m.ModifiedAt:dd.MM.yyyy, HH:mm:ss}";
vm.ModifiedAtShort = $"{m.ModifiedAt:dd.MM.yyyy, HH:mm}";
vm.ExportedAt = m.ExportedAt == null ? "-" : $"{m.ExportedAt:dd.MM.yyyy, HH:mm:ss}";
vm.ImportedAt = m.ImportedAt == null ? "-" : $"{m.ImportedAt:dd.MM.yyyy, HH:mm:ss}";
vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}"; vm.StatusDeliveriesLastSeasonInfo = $"{Utils.CurrentLastSeason - 1}";
vm.StatusDeliveriesLastSeason = "..."; vm.StatusDeliveriesLastSeason = "...";
vm.StatusDeliveriesLastSeasonToolTip = null; vm.StatusDeliveriesLastSeasonToolTip = null;
@@ -357,8 +368,8 @@ namespace Elwig.Services {
if (filterMgNr.Count > 0) memberQuery = memberQuery.Where(m => filterMgNr.Contains(m.MgNr)); if (filterMgNr.Count > 0) memberQuery = memberQuery.Where(m => filterMgNr.Contains(m.MgNr));
if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr)); if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr));
if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId)); if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId));
if (filterAreaCom.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments()).Any(c => filterAreaCom.Contains(c.VtrgId))); if (filterAreaCom.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).Any(c => filterAreaCom.Contains(c.VtrgId)));
if (filterNotAreaCom.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments()).All(c => filterNotAreaCom.Contains(c.VtrgId))); if (filterNotAreaCom.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments(Utils.CurrentLastSeason)).All(c => filterNotAreaCom.Contains(c.VtrgId)));
if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr)); if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr));
if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr)); if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr));
} }
@@ -367,7 +378,8 @@ namespace Elwig.Services {
} }
public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) { public static async Task GenerateMemberDataSheet(Member m, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
using var doc = new MemberDataSheet(m, ctx); using var doc = new MemberDataSheet(m, ctx);
@@ -375,11 +387,13 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) { public static async Task GenerateDeliveryConfirmation(Member m, int year, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var b = new Billing(year); var b = new Billing(year);
await b.FinishSeason(); await b.FinishSeason();
@@ -393,15 +407,17 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) { public static async Task GenerateCreditNote(Member m, int year, int avnr, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!; var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr); var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, year, avnr);
var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!; var p = (await ctx.MemberPayments.FindAsync(year, avnr, m.MgNr))!;
var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data); var b = BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data);
@@ -412,6 +428,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -464,7 +481,8 @@ namespace Elwig.Services {
Title = $"{MemberList.Name} speichern unter - Elwig" Title = $"{MemberList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var ods = new OdsFile(d.FileName); using var ods = new OdsFile(d.FileName);
@@ -472,6 +490,7 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Export) { } else if (mode == ExportMode.Export) {
@@ -482,7 +501,8 @@ namespace Elwig.Services {
Title = $"{MemberList.Name} speichern unter - Elwig" Title = $"{MemberList.Name} speichern unter - Elwig"
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var members = await query var members = await query
.OrderBy(m => m.MgNr) .OrderBy(m => m.MgNr)
@@ -499,10 +519,12 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) { } else if (mode == ExportMode.Upload && App.Config.SyncUrl != null) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip"; var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip";
var path = Path.Combine(App.TempPath, filename); var path = Path.Combine(App.TempPath, filename);
@@ -533,9 +555,11 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} else { } else {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1])); var data = await MemberListData.FromQuery(query, filterNames, filterNames.Where(f => f.StartsWith("Flächenbindung")).Select(f => f.Split(' ')[^1]));
using var doc = new MemberList(string.Join(" / ", filterNames), data); using var doc = new MemberList(string.Join(" / ", filterNames), data);
@@ -543,14 +567,13 @@ namespace Elwig.Services {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }
public static async Task<int> UpdateMember(this MemberAdminViewModel vm, int? oldMgNr) { public static async Task<int> UpdateMember(this MemberAdminViewModel vm, int? oldMgNr) {
var newMgNr = (int)vm.MgNr!; var newMgNr = (int)vm.MgNr!;
using (var ctx = new AppDbContext()) {
var m = new Member { var m = new Member {
MgNr = oldMgNr ?? newMgNr, MgNr = oldMgNr ?? newMgNr,
PredecessorMgNr = vm.PredecessorMgNr, PredecessorMgNr = vm.PredecessorMgNr,
@@ -588,6 +611,8 @@ namespace Elwig.Services {
ContactViaEmail = vm.ContactViaEmail, ContactViaEmail = vm.ContactViaEmail,
}; };
return await Task.Run(async () => {
using var ctx = new AppDbContext();
if (oldMgNr != null) { if (oldMgNr != null) {
ctx.Update(m); ctx.Update(m);
} else { } else {
@@ -644,7 +669,7 @@ namespace Elwig.Services {
KgNr = c.KgNr, KgNr = c.KgNr,
GstNr = c.GstNr, GstNr = c.GstNr,
RdNr = c.RdNr, RdNr = c.RdNr,
YearFrom = vm.MaintainAreaComYearTo ? c.YearFrom : year, YearFrom = vm.MaintainAreaComYearFrom ? c.YearFrom : year,
YearTo = c.YearTo, YearTo = c.YearTo,
})); }));
@@ -670,15 +695,14 @@ namespace Elwig.Services {
if (newMgNr != m.MgNr) { if (newMgNr != m.MgNr) {
await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}"); await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}");
} }
}
App.HintContextChange();
return newMgNr; return newMgNr;
});
} }
public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) { public static async Task DeleteMember(int mgnr, bool deletePaymentData, bool deleteDeliveries, bool deleteAreaComs) {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var l = (await ctx.Members.FindAsync(mgnr))!; var l = (await ctx.Members.FindAsync(mgnr))!;
if (deletePaymentData) { if (deletePaymentData) {
ctx.RemoveRange(l.Credits); ctx.RemoveRange(l.Credits);
@@ -691,8 +715,7 @@ namespace Elwig.Services {
} }
ctx.Remove(l); ctx.Remove(l);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange();
} }
} }
} }

View File

@@ -0,0 +1,387 @@
using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Helpers.Billing;
using Elwig.Helpers.Export;
using Elwig.Models.Dtos;
using Elwig.Models.Entities;
using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
namespace Elwig.Services {
public static class PaymentVariantService {
private static readonly JsonSerializerOptions JsonOpt = new() { WriteIndented = true };
public static void ClearInputs(this PaymentVariantsViewModel vm) {
vm.IsPaymentVariantSelected = false;
vm.EditText = "Bearbeiten";
vm.SaveIsEnabled = false;
vm.DeleteIsEnabled = false;
vm.CalculateIsEnabled = false;
vm.CommitIsEnabled = false;
vm.CommitVisibility = Visibility.Visible;
vm.RevertIsEnabled = false;
vm.RevertVisibility = Visibility.Hidden;
vm.Arrow = "\xF0AF";
vm.ExportIsEnabled = false;
vm.IsReadOnly = true;
vm.DataIsReadOnly = true;
vm.BillingData = null;
vm.Name = "";
vm.Comment = "";
vm.Date = null;
vm.TransferDate = null;
vm.WeightModifier = null;
vm.ConsiderModifiers = false;
vm.ConsiderPenalties = false;
vm.ConsiderPenalty = false;
vm.ConsiderAuto = false;
vm.ConsiderCustom = false;
vm.IsEnabled = false;
vm.Data = "";
vm.StatusModifierSum = "-";
vm.StatusTotalSum = "-";
vm.StatusVatSum = "-";
vm.StatusDeductionSum = "-";
vm.StatusPaymentSum = "-";
}
public static void FillInputs(this PaymentVariantsViewModel vm, PaymentVar v) {
var locked = !v.TestVariant;
vm.IsPaymentVariantSelected = true;
vm.SaveIsEnabled = !locked;
vm.DeleteIsEnabled = !locked;
vm.CalculateIsEnabled = !locked;
vm.CommitIsEnabled = !locked && !vm.SeasonLocked;
vm.CommitVisibility = !locked ? Visibility.Visible : Visibility.Hidden;
vm.RevertIsEnabled = locked && !vm.SeasonLocked;
vm.RevertVisibility = locked ? Visibility.Visible : Visibility.Hidden;
vm.Arrow = locked ? "\xF0B0" : "\xF0AF";
vm.EditText = locked ? "Ansehen" : "Bearbeiten";
vm.ExportIsEnabled = locked;
vm.IsReadOnly = false;
vm.DataIsReadOnly = locked;
vm.Name = v.Name;
vm.Comment = v.Comment ?? "";
vm.Date = v.Date;
vm.TransferDate = v.TransferDate;
try {
vm.BillingData = BillingData.FromJson(v.Data);
vm.ConsiderModifiers = vm.BillingData.ConsiderDelieryModifiers;
vm.ConsiderPenalties = vm.BillingData.ConsiderContractPenalties;
vm.ConsiderPenalty = vm.BillingData.ConsiderTotalPenalty;
vm.ConsiderAuto = vm.BillingData.ConsiderAutoBusinessShares;
vm.ConsiderCustom = vm.BillingData.ConsiderCustomModifiers;
if (vm.BillingData.NetWeightModifier != 0) {
vm.WeightModifier = Math.Round(vm.BillingData.NetWeightModifier * 100.0, 8);
} else if (vm.BillingData.GrossWeightModifier != 0) {
vm.WeightModifier = Math.Round(vm.BillingData.GrossWeightModifier * 100.0, 8);
} else {
vm.WeightModifier = null;
}
vm.Data = JsonSerializer.Serialize(vm.BillingData.Data, JsonOpt);
} catch {
vm.BillingData = null;
vm.ConsiderModifiers = false;
vm.ConsiderPenalties = false;
vm.ConsiderPenalty = false;
vm.ConsiderAuto = false;
vm.ConsiderCustom = false;
vm.WeightModifier = null;
vm.Data = v.Data;
}
vm.IsEnabled = !locked;
vm.StatusModifierSum = "...";
vm.StatusTotalSum = "...";
vm.StatusVatSum = "...";
vm.StatusDeductionSum = "...";
vm.StatusPaymentSum = "...";
Utils.RunBackground("Variantendaten laden", async () => {
await vm.UpdateSums(v);
});
}
private static async Task UpdateSums(this PaymentVariantsViewModel vm, PaymentVar v) {
if (App.MainDispatcher == null)
return;
var modText = "-";
var totalText = "-";
var vatText = "-";
var deductionText = "-";
var paymentText = "-";
using var ctx = new AppDbContext();
var sym = v.Season.Currency.Symbol ?? v.Season.Currency.Code;
var modSum = await ctx.PaymentDeliveryParts
.Where(p => p.Year == v.Year && p.AvNr == v.AvNr)
.SumAsync(p => p.AmountValue - p.NetAmountValue);
modText = $"{v.Season.DecFromDb(modSum):N2} {sym}";
var totalSum = await ctx.MemberPayments
.Where(p => p.Year == v.Year && p.AvNr == v.AvNr)
.SumAsync(p => p.AmountValue);
totalText = $"{v.Season.DecFromDb(totalSum):N2} {sym}";
await App.MainDispatcher.BeginInvoke(() => {
if (vm.SelectedPaymentVariant != v)
return;
vm.StatusModifierSum = modText;
vm.StatusTotalSum = totalText;
});
var credits = ctx.Credits.Where(c => c.Year == v.Year && c.AvNr == v.AvNr);
if (!credits.Any()) {
long lastTotalSum = 0;
decimal vatSum = 0;
var currentPayments = await ctx.MemberPayments
.Where(p => p.Year == v.Year && p.AvNr == v.AvNr)
.ToDictionaryAsync(p => p.MgNr);
var lastV = await ctx.PaymentVariants
.Where(l => l.Year == v.Year && !l.TestVariant)
.OrderByDescending(l => l.TransferDateString ?? l.DateString)
.ThenByDescending(l => l.AvNr)
.FirstOrDefaultAsync();
if (lastV != null) {
var lastPayments = await ctx.MemberPayments
.Where(p => p.Year == v.Year && p.AvNr == lastV.AvNr)
.ToDictionaryAsync(p => p.MgNr);
lastTotalSum = lastPayments.Sum(e => e.Value.AmountValue);
foreach (int mgnr in currentPayments.Keys) {
var c = currentPayments[mgnr];
var l = lastPayments[mgnr];
vatSum += (c.Amount - l.Amount) * (decimal)(c.Member.IsBuchführend ? v.Season.VatNormal : v.Season.VatFlatrate);
}
} else {
vatSum = currentPayments.Sum(e => e.Value.Amount * (decimal)(e.Value.Member.IsBuchführend ? v.Season.VatNormal : v.Season.VatFlatrate));
}
vatText = $"~{vatSum:N2} {sym}";
deductionText = $"- {sym}";
paymentText = $"~{v.Season.DecFromDb(totalSum - lastTotalSum) + vatSum:N2} {sym}";
} else {
// all values in the credit table are stored with precision 2!
totalText = $"{Utils.DecFromDb(await credits.SumAsync(c => c.NetAmountValue), 2):N2} {sym}";
vatText = $"{Utils.DecFromDb(await credits.SumAsync(c => c.VatAmountValue), 2):N2} {sym}";
deductionText = $"{-Utils.DecFromDb(await credits.SumAsync(c => c.ModifiersValue ?? 0), 2):N2} {sym}";
paymentText = $"{Utils.DecFromDb(await credits.SumAsync(c => c.AmountValue), 2):N2} {sym}";
}
await App.MainDispatcher.BeginInvoke(() => {
if (vm.SelectedPaymentVariant != v)
return;
vm.StatusModifierSum = modText;
vm.StatusTotalSum = totalText;
vm.StatusVatSum = vatText;
vm.StatusDeductionSum = deductionText;
vm.StatusPaymentSum = paymentText;
});
}
public static async Task GenerateSummary(PaymentVar v, ExportMode mode) {
if (mode == ExportMode.SaveList) {
var d = new SaveFileDialog() {
FileName = $"Variantendaten-{v.Name.Trim().Replace(' ', '-')}.ods",
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Variantendaten {v.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return;
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
} else {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var doc = new PaymentVariantSummary((await ctx.PaymentVariants.FindAsync(v.Year, v.AvNr))!, data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
public static async Task GenerateEbics(int year, int avnr) {
using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
var withoutIban = v.Credits.Count(c => c.Member.Iban == null);
if (withoutIban > 0) {
var r = MessageBox.Show($"Achtung: Für {withoutIban:N0} Mitglieder ist kein IBAN hinterlegt.\n\nDiese werden NICHT exportiert.",
"Mitglieder ohne IBAN", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r != MessageBoxResult.OK) return;
}
var withNegAmount = v.Credits.Count(c => c.Amount <= 0);
if (withNegAmount > 0) {
var r = MessageBox.Show($"Achtung: Es gibt {withNegAmount:N0} Traubengutschriften mit negativem Betrag.\n\nDiese werden NICHT exportiert.",
"Traubengutschriften mit negativem Betrag", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.OK);
if (r != MessageBoxResult.OK) return;
}
var d = new SaveFileDialog() {
FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}",
DefaultExt = Ebics.FileExtension,
Filter = "EBICS-Datei (*.xml)|*.xml",
Title = $"Überweisungsdaten speichern unter - Elwig",
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var e = new Ebics(v, d.FileName, App.Client.ExportEbicsVersion, (Ebics.AddressMode)App.Client.ExportEbicsAddress);
await e.ExportAsync(Transaction.FromPaymentVariant(v));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
public static async Task GenerateAccountingList(int year, int avnr, string name) {
var d = new SaveFileDialog() {
FileName = $"{App.Client.NameToken}-Buchungsliste-{year}-{name.Trim().Replace(' ', '-')}.ods",
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Buchungsliste speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try {
using var ctx = new AppDbContext();
var tbl = await CreditNoteData.ForPaymentVariant(ctx, year, avnr);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(tbl);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
});
Mouse.OverrideCursor = null;
}
}
public static async Task<PaymentVar> CreatePaymentVariant(int year) {
return await Task.Run(async () => {
using var ctx = new AppDbContext();
var v = new PaymentVar {
Year = year,
AvNr = await ctx.NextAvNr(year),
Name = "Neue Auszahlungsvariante",
TestVariant = true,
DateString = $"{DateTime.Today:yyyy-MM-dd}",
Data = "{\"mode\": \"elwig\", \"version\": 1, \"payment\": {}, \"curves\": []}",
};
ctx.Add(v);
await ctx.SaveChangesAsync();
return v;
});
}
public static async Task<PaymentVar> Duplicate(this PaymentVar orig) {
return await Task.Run(async () => {
using var ctx = new AppDbContext();
var n = new PaymentVar {
Year = orig.Year,
AvNr = await ctx.NextAvNr(orig.Year),
Name = $"{orig.Name} (Kopie)",
TestVariant = true,
DateString = $"{DateTime.Today:yyyy-MM-dd}",
Data = orig.Data,
};
ctx.Add(n);
await ctx.SaveChangesAsync();
return n;
});
}
public static async Task<(int, int)> UpdatePaymentVariant(this PaymentVariantsViewModel vm, int? oldYear, int? oldAvNr) {
var year = oldYear ?? Utils.CurrentYear;
int avnr = 0;
await Task.Run(async () => {
var d = App.Config.Debug ? BillingData.FromJson(vm.Data ?? "{}") : vm.BillingData!;
d.ConsiderDelieryModifiers = vm.ConsiderModifiers;
d.ConsiderContractPenalties = vm.ConsiderPenalties;
d.ConsiderTotalPenalty = vm.ConsiderPenalty;
d.ConsiderAutoBusinessShares = vm.ConsiderAuto;
d.ConsiderCustomModifiers = vm.ConsiderCustom;
var modVal = vm.WeightModifier ?? 0;
d.NetWeightModifier = modVal > 0 ? modVal / 100.0 : 0;
d.GrossWeightModifier = modVal < 0 ? modVal / 100.0 : 0;
using var ctx = new AppDbContext();
var v = new PaymentVar {
Year = year,
AvNr = oldAvNr ?? await ctx.NextAvNr(year),
Name = vm.Name!,
DateString = $"{vm.Date!.Value:yyyy-MM-dd}",
TransferDate = vm.TransferDate,
TestVariant = vm.SelectedPaymentVariant?.TestVariant ?? true,
CalcTimeUnix = vm.SelectedPaymentVariant?.CalcTimeUnix,
Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
Data = JsonSerializer.Serialize(d.Data),
};
avnr = v.AvNr;
ctx.Update(v);
await ctx.SaveChangesAsync();
});
vm.WeightModifierChanged = false;
return (year, avnr);
}
public static async Task DeletePaymentVariant(int year, int avnr) {
await Task.Run(async () => {
using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(year, avnr))!;
ctx.Remove(v);
await ctx.SaveChangesAsync();
});
}
public static async Task Calculate(int year, int avnr) {
await Task.Run(async () => {
var b = new BillingVariant(year, avnr);
await b.Calculate();
});
}
public static async Task Commit(int year, int avnr) {
await Task.Run(async () => {
var b = new BillingVariant(year, avnr);
await b.Commit();
});
}
public static async Task Revert(int year, int avnr) {
await Task.Run(async () => {
var b = new BillingVariant(year, avnr);
await b.Revert();
});
}
}
}

View File

@@ -15,7 +15,7 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private string? _searchQuery = ""; private string? _searchQuery = "";
public List<string> TextFilter { public List<string> TextFilter {
get => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0)]; get => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
set => SearchQuery = string.Join(' ', value.Where(e => e.Length > 0)); set => SearchQuery = string.Join(' ', value.Where(e => e.Length > 0));
} }

View File

@@ -18,7 +18,7 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private string? _searchQuery = ""; private string? _searchQuery = "";
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0)]; public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
[ObservableProperty] [ObservableProperty]
private string? _lastScaleError; private string? _lastScaleError;

View File

@@ -10,7 +10,7 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private string? _searchQuery = ""; private string? _searchQuery = "";
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0)]; public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
[ObservableProperty] [ObservableProperty]
private bool _filterOnlyUpcoming; private bool _filterOnlyUpcoming;

View File

@@ -11,7 +11,7 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private string? _searchQuery = ""; private string? _searchQuery = "";
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0)]; public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
[ObservableProperty] [ObservableProperty]
private bool _filterOnlyUpcoming; private bool _filterOnlyUpcoming;

View File

@@ -11,14 +11,14 @@ namespace Elwig.ViewModels {
public partial class MemberAdminViewModel : ObservableObject { public partial class MemberAdminViewModel : ObservableObject {
public int? TransferPredecessorAreaComs = null; public int? TransferPredecessorAreaComs = null;
public bool MaintainAreaComYearTo = false; public bool MaintainAreaComYearFrom = false;
public int? CancelAreaComs = null; public int? CancelAreaComs = null;
public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes); public ObservableCollection<KeyValuePair<string, string>> PhoneNrTypes { get; set; } = new(Utils.PhoneNrTypes);
[ObservableProperty] [ObservableProperty]
private string? _searchQuery = ""; private string? _searchQuery = "";
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0)]; public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0) ?? []];
[ObservableProperty] [ObservableProperty]
private bool _showOnlyActiveMembers; private bool _showOnlyActiveMembers;
@@ -153,6 +153,17 @@ namespace Elwig.ViewModels {
[ObservableProperty] [ObservableProperty]
private bool _contactViaEmail; private bool _contactViaEmail;
[ObservableProperty]
private string _createdAt = "-";
[ObservableProperty]
private string _modifiedAt = "-";
[ObservableProperty]
private string _modifiedAtShort = "-";
[ObservableProperty]
private string _exportedAt = "-";
[ObservableProperty]
private string _importedAt = "-";
public ObservableCollection<string?> EmailAddresses { get; private set; } = [null, null, null, null, null, null, null, null, null]; public ObservableCollection<string?> EmailAddresses { get; private set; } = [null, null, null, null, null, null, null, null, null];
public partial class PhoneNr(int? type = null, string? number = null, string? comment = null) : ObservableObject { public partial class PhoneNr(int? type = null, string? number = null, string? comment = null) : ObservableObject {

View File

@@ -0,0 +1,95 @@
using CommunityToolkit.Mvvm.ComponentModel;
using Elwig.Helpers.Billing;
using Elwig.Models.Entities;
using System;
using System.Collections.Generic;
using System.Windows;
namespace Elwig.ViewModels {
public partial class PaymentVariantsViewModel : ObservableObject {
[ObservableProperty]
private PaymentVar? _selectedPaymentVariant;
[ObservableProperty]
private IEnumerable<PaymentVar> _paymentVariants = [];
public BillingData? BillingData;
public bool SeasonLocked;
public bool WeightModifierChanged;
[ObservableProperty]
private string _name = "";
[ObservableProperty]
private string _comment = "";
[ObservableProperty]
private string _dateString = "";
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 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 double? WeightModifier {
get => double.TryParse(WeightModifierString, out var d) ? d : null;
set => WeightModifierString = $"{value}";
}
[ObservableProperty]
private string _data = "";
[ObservableProperty]
private bool _considerModifiers;
[ObservableProperty]
private bool _considerPenalties;
[ObservableProperty]
private bool _considerPenalty;
[ObservableProperty]
private bool _considerAuto;
[ObservableProperty]
private bool _considerCustom;
[ObservableProperty]
private bool _isPaymentVariantSelected;
[ObservableProperty]
private bool _isReadOnly = true;
[ObservableProperty]
private bool _dataIsReadOnly = true;
[ObservableProperty]
private bool _isEnabled = false;
[ObservableProperty]
private bool _saveIsEnabled = false;
[ObservableProperty]
private bool _deleteIsEnabled = false;
[ObservableProperty]
private bool _calculateIsEnabled = false;
[ObservableProperty]
private bool _exportIsEnabled = false;
[ObservableProperty]
private bool _commitIsEnabled = false;
[ObservableProperty]
private Visibility _commitVisibility = Visibility.Visible;
[ObservableProperty]
private bool _revertIsEnabled = false;
[ObservableProperty]
private Visibility _revertVisibility = Visibility.Hidden;
[ObservableProperty]
private string _arrow = "\xF0AF";
[ObservableProperty]
private string _editText = "Bearbeiten";
[ObservableProperty]
private string _statusModifierSum = "-";
[ObservableProperty]
private string _statusTotalSum = "-";
[ObservableProperty]
private string _statusVatSum = "-";
[ObservableProperty]
private string _statusDeductionSum = "-";
[ObservableProperty]
private string _statusPaymentSum = "-";
}
}

View File

@@ -7,7 +7,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"
xmlns:vm="clr-namespace:Elwig.ViewModels" xmlns:vm="clr-namespace:Elwig.ViewModels"
Title="{Binding Title}" Height="550" MinHeight="450" Width="920" MinWidth="860" Title="{Binding Title}" Height="600" MinHeight="450" Width="1000" MinWidth="860"
Loaded="Window_Loaded"> Loaded="Window_Loaded">
<Window.DataContext> <Window.DataContext>
<vm:AreaComAdminViewModel/> <vm:AreaComAdminViewModel/>
@@ -57,7 +57,7 @@
<RowDefinition Height="24"/> <RowDefinition Height="24"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" MinWidth="555"/> <ColumnDefinition Width="3*" MinWidth="500"/>
<ColumnDefinition Width="5"/> <ColumnDefinition Width="5"/>
<ColumnDefinition Width="*" MinWidth="280"/> <ColumnDefinition Width="*" MinWidth="280"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
@@ -102,25 +102,35 @@
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" SelectionChanged="AreaCommitmentList_SelectionChanged" Grid.Column="0" Grid.Row="1" CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" SelectionChanged="AreaCommitmentList_SelectionChanged" Grid.Column="0" Grid.Row="1"
Margin="5,0,5,0" FontSize="14" Grid.ColumnSpan="3" Background="#e2e2e2"> Margin="5,0,5,0" FontSize="14" Grid.ColumnSpan="3" Background="#e2e2e2">
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="FbNr." Binding="{Binding FbNr}" Width="50"/> <DataGridTextColumn Header="FbNr." Binding="{Binding FbNr, StringFormat='{}{0} '}" Width="50">
<DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="150"/>
<DataGridTextColumn Header="Ried" Binding="{Binding Rd.Name}" Width="130"/>
<DataGridTextColumn Header="Parzelle" Binding="{Binding GstNr}" Width="120"/>
<DataGridTextColumn Header="Fläche" Binding="{Binding Area, StringFormat='{}{0:N0} m²'}" Width="80">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Sorte" Binding="{Binding AreaComType.WineVar.SortId}" Width="70"> <DataGridTextColumn Header="Katastralgemeinde" Binding="{Binding Kg.AtKg.Name}" Width="130"/>
<DataGridTextColumn Header="Sorte" Binding="{Binding AreaComType.WineVar.SortId}" Width="50">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.Foreground" Value="{Binding AreaComType.WineVar.Color}"/>
<Setter Property="TextBlock.TextAlignment" Value="Center"/> <Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Attribut" Binding="{Binding AreaComType.WineAttr.Name}" Width="120"/> <DataGridTextColumn Header="Fläche" Binding="{Binding Area, StringFormat='{}{0:N0} m² '}" Width="80">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="Attribut" Binding="{Binding AreaComType.WineAttr.Name}" Width="100"/>
<DataGridTextColumn Header="Ried" Binding="{Binding Rd.Name}" Width="130"/>
<DataGridTextColumn Header="Parzelle" Binding="{Binding GstNr}" Width="130"/>
<DataGridTextColumn Header="Bewirt." Binding="{Binding WineCult.Name}" Width="60"/>
<DataGridTextColumn Header="Von" Binding="{Binding YearFrom}" Width="48"/>
<DataGridTextColumn Header="Bis" Binding="{Binding YearTo}" Width="48"/>
</DataGrid.Columns> </DataGrid.Columns>
</DataGrid> </DataGrid>
@@ -143,19 +153,19 @@
</Button.ToolTip> </Button.ToolTip>
</Button> </Button>
<Button x:Name="AreaCommitmentSaveButton" Content="Speichern" Click="AreaCommitmentSaveButton_Click" IsEnabled="False" Visibility="Hidden" <Button x:Name="SaveButton" Content="Speichern" Click="SaveButton_Click" IsEnabled="False" Visibility="Hidden"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2"> HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2">
<Button.ToolTip> <Button.ToolTip>
<TextBlock FontWeight="Bold">Strg+S</TextBlock> <TextBlock FontWeight="Bold">Strg+S</TextBlock>
</Button.ToolTip> </Button.ToolTip>
</Button> </Button>
<Button x:Name="AreaCommitmentResetButton" Content="Zurücksetzen" Click="AreaCommitmentResetButton_Click" IsEnabled="False" Visibility="Hidden" <Button x:Name="ResetButton" Content="Zurücksetzen" Click="ResetButton_Click" IsEnabled="False" Visibility="Hidden"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2"> HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2">
<Button.ToolTip> <Button.ToolTip>
<TextBlock FontWeight="Bold">Strg+Z</TextBlock> <TextBlock FontWeight="Bold">Strg+Z</TextBlock>
</Button.ToolTip> </Button.ToolTip>
</Button> </Button>
<Button x:Name="AreaCommitmentCancelButton" Content="Abbrechen" Click="AreaCommitmentCancelButton_Click" IsEnabled="False" Visibility="Hidden" IsCancel="True" <Button x:Name="CancelButton" Content="Abbrechen" Click="CancelButton_Click" IsEnabled="False" Visibility="Hidden" IsCancel="True"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2"> HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="2">
<Button.ToolTip> <Button.ToolTip>
<TextBlock FontWeight="Bold">Esc</TextBlock> <TextBlock FontWeight="Bold">Esc</TextBlock>
@@ -175,28 +185,27 @@
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="80"/> <ColumnDefinition Width="80"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="48"/>
<ColumnDefinition Width="50"/> <ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Content="FbNr.:" Margin="10,10,0,0" Grid.Column="0"/> <Label Content="MgNr.:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="False"
Margin="0,10,0,0" Width="48" HorizontalAlignment="Left" Grid.Column="1" TextAlignment="Right"/>
<Label Content="FbNr.:" Margin="10,10,0,0" Grid.Column="2"/>
<TextBox x:Name="FbNrInput" Text="{Binding FbNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="FbNrInput" Text="{Binding FbNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,10,10,0" Grid.Column="1" TextAlignment="Right" Margin="0,10,10,0" Width="56" HorizontalAlignment="Left" Grid.Column="3" TextAlignment="Right"
TextChanged="FbNrInput_TextChanged" LostFocus="FbNrInput_LostFocus"/> TextChanged="FbNrInput_TextChanged" LostFocus="FbNrInput_LostFocus"/>
<Label Content="MgNr.:" Margin="10,40,0,0" Grid.Column="0"/> <Label Content="Zeitraum:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="False"
Margin="0,40,10,0" Grid.Column="1" TextAlignment="Right"/>
<Label Content="Von:" Margin="10,10,0,0" Grid.Column="2"/>
<TextBox x:Name="YearFromInput" Text="{Binding YearFromString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="YearFromInput" Text="{Binding YearFromString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,10,10,0" Grid.Column="3" TextAlignment="Right" Margin="0,40,10,0" Width="40" HorizontalAlignment="Left" Grid.Column="1" Grid.ColumnSpan="2" TextAlignment="Right"
TextChanged="IntegerInput_TextChanged"/> TextChanged="IntegerInput_TextChanged"/>
<Label Content="" Grid.Column="1" Grid.ColumnSpan="3" Margin="45,40,0,0"/>
<Label Content="Bis:" Margin="10,40,0,0" Grid.Column="2"/>
<TextBox x:Name="YearToInput" Text="{Binding YearToString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="YearToInput" Text="{Binding YearToString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,40,10,0" Grid.Column="3" TextAlignment="Right" Margin="60,40,10,0" Width="40" HorizontalAlignment="Left" Grid.Column="1" Grid.ColumnSpan="3" TextAlignment="Right"
TextChanged="IntegerInput_TextChanged"/> TextChanged="IntegerInput_TextChanged"/>
<Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0" Grid.ColumnSpan="2"/> <Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>

View File

@@ -1,13 +1,14 @@
using Microsoft.EntityFrameworkCore; using Elwig.Dialogs;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using System;
using System.Threading.Tasks;
using Elwig.ViewModels;
using Elwig.Services; using Elwig.Services;
using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore;
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
namespace Elwig.Windows { namespace Elwig.Windows {
@@ -25,8 +26,8 @@ namespace Elwig.Windows {
ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig"; ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
ExemptInputs = [ ExemptInputs = [
MgNrInput, AreaCommitmentList, NewAreaCommitmentButton, MgNrInput, AreaCommitmentList, NewAreaCommitmentButton,
EditAreaCommitmentButton, DeleteAreaCommitmentButton, AreaCommitmentSaveButton, EditAreaCommitmentButton, DeleteAreaCommitmentButton, SaveButton,
AreaCommitmentResetButton, AreaCommitmentCancelButton, SearchInput, ActiveAreaCommitmentInput ResetButton, CancelButton, SearchInput, ActiveAreaCommitmentInput
]; ];
RequiredInputs = [ RequiredInputs = [
FbNrInput, YearFromInput, KgInput, RdInput, FbNrInput, YearFromInput, KgInput, RdInput,
@@ -163,8 +164,8 @@ namespace Elwig.Windows {
IsCreating = true; IsCreating = true;
AreaCommitmentList.IsEnabled = false; AreaCommitmentList.IsEnabled = false;
AreaCommitmentList.SelectedItem = null; AreaCommitmentList.SelectedItem = null;
HideAreaCommitmentNewEditDeleteButtons(); HideNewEditDeleteButtons();
ShowAreaCommitmentSaveResetCancelButtons(); ShowSaveResetCancelButtons();
UnlockInputs(); UnlockInputs();
await InitInputs(); await InitInputs();
LockSearchInputs(); LockSearchInputs();
@@ -184,8 +185,8 @@ namespace Elwig.Windows {
IsEditing = true; IsEditing = true;
AreaCommitmentList.IsEnabled = false; AreaCommitmentList.IsEnabled = false;
HideAreaCommitmentNewEditDeleteButtons(); HideNewEditDeleteButtons();
ShowAreaCommitmentSaveResetCancelButtons(); ShowSaveResetCancelButtons();
UnlockInputs(); UnlockInputs();
LockSearchInputs(); LockSearchInputs();
} }
@@ -199,15 +200,18 @@ namespace Elwig.Windows {
private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) { private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) {
if (AreaCommitmentList.SelectedItem is not AreaCom a) if (AreaCommitmentList.SelectedItem is not AreaCom a)
return; return;
var r = MessageBox.Show(
$"Soll die Flächenbindung {a.GstNr} ({a.Area} m²) wirklich unwiderruflich gelöscht werden?", var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, true);
"Flächenbindung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); if (d.ShowDialog() != true)
if (r == MessageBoxResult.OK) { return;
Mouse.OverrideCursor = Cursors.AppStarting;
Mouse.OverrideCursor = Cursors.Wait;
try { try {
using (var ctx = new AppDbContext()) { if (d.YearTo is int yearTo) {
ctx.Remove(a); ViewModel.YearTo = yearTo;
await ctx.SaveChangesAsync(); await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr);
} else {
await AreaComService.DeleteAreaCom(a.FbNr);
} }
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
@@ -217,52 +221,86 @@ namespace Elwig.Windows {
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
}
protected override void ShortcutSave() { protected override void ShortcutSave() {
if (!AreaCommitmentSaveButton.IsEnabled || AreaCommitmentSaveButton.Visibility != Visibility.Visible) if (!SaveButton.IsEnabled || SaveButton.Visibility != Visibility.Visible)
return; return;
AreaCommitmentSaveButton_Click(null, null); SaveButton_Click(null, null);
} }
private async void AreaCommitmentSaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
AreaCommitmentSaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
int? yearTo = null;
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput)) {
var a = (AreaCommitmentList.SelectedItem as AreaCom)!;
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false);
if (d.ShowDialog() != true)
return;
yearTo = d.YearTo;
}
int fbnr; int fbnr;
Mouse.OverrideCursor = Cursors.Wait;
try { try {
AreaCom? temp = null;
if (yearTo != null && (!ViewModel.YearTo.HasValue || yearTo < ViewModel.YearTo)) {
temp = new AreaCom {
FbNr = ViewModel.FbNr!.Value,
MgNr = ViewModel.MgNr!.Value,
YearFrom = ViewModel.YearFrom,
YearTo = ViewModel.YearTo,
VtrgId = ViewModel.AreaComType!.VtrgId,
CultId = ViewModel.WineCult?.CultId,
Comment = ViewModel.Comment,
KgNr = ViewModel.Kg!.KgNr,
RdNr = ViewModel.Rd?.RdNr,
GstNr = ViewModel.GstNr?.Trim() ?? "-",
Area = ViewModel.Area!.Value,
};
RefreshInputs();
ViewModel.YearTo = yearTo;
}
fbnr = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr); fbnr = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr);
if (temp is AreaCom t) {
await ViewModel.InitInputs();
t.FbNr = ViewModel.FbNr!.Value;
t.YearFrom = yearTo + 1;
ViewModel.FillInputs(t);
fbnr = await ViewModel.UpdateAreaCommitment(null);
}
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
AreaCommitmentSaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
IsCreating = false; IsCreating = false;
AreaCommitmentList.IsEnabled = true; AreaCommitmentList.IsEnabled = true;
HideAreaCommitmentSaveResetCancelButtons(); HideSaveResetCancelButtons();
ShowAreaCommitmentNewEditDeleteButtons(); ShowNewEditDeleteButtons();
LockInputs(); LockInputs();
UnlockSearchInputs(); UnlockSearchInputs();
FinishInputFilling(); FinishInputFilling();
await RefreshList(); await RefreshList();
RefreshInputs(); RefreshInputs();
Mouse.OverrideCursor = null;
ViewModel.SearchQuery = ""; ViewModel.SearchQuery = "";
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault()); ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault());
} }
protected override void ShortcutReset() { protected override void ShortcutReset() {
if (!AreaCommitmentResetButton.IsEnabled || AreaCommitmentResetButton.Visibility != Visibility.Visible) if (!ResetButton.IsEnabled || ResetButton.Visibility != Visibility.Visible)
return; return;
AreaCommitmentResetButton_Click(null, null); ResetButton_Click(null, null);
} }
private async void AreaCommitmentResetButton_Click(object? sender, RoutedEventArgs? evt) { private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) {
if (IsEditing) { if (IsEditing) {
RefreshInputs(); RefreshInputs();
} else if (IsCreating) { } else if (IsCreating) {
@@ -271,12 +309,12 @@ namespace Elwig.Windows {
UpdateButtons(); UpdateButtons();
} }
private void AreaCommitmentCancelButton_Click(object sender, RoutedEventArgs evt) { private void CancelButton_Click(object sender, RoutedEventArgs evt) {
IsEditing = false; IsEditing = false;
IsCreating = false; IsCreating = false;
AreaCommitmentList.IsEnabled = true; AreaCommitmentList.IsEnabled = true;
HideAreaCommitmentSaveResetCancelButtons(); HideSaveResetCancelButtons();
ShowAreaCommitmentNewEditDeleteButtons(); ShowNewEditDeleteButtons();
RefreshInputs(); RefreshInputs();
ClearInputStates(); ClearInputStates();
LockInputs(); LockInputs();
@@ -286,49 +324,49 @@ namespace Elwig.Windows {
override protected void UpdateButtons() { override protected void UpdateButtons() {
if (!IsEditing && !IsCreating) return; if (!IsEditing && !IsCreating) return;
bool ch = HasChanged, v = IsValid; bool ch = HasChanged, v = IsValid;
AreaCommitmentResetButton.IsEnabled = (ch); ResetButton.IsEnabled = (ch);
AreaCommitmentSaveButton.IsEnabled = (ch && v); SaveButton.IsEnabled = (ch && v);
} }
private void DisableAreaCommitmentNewEditDeleteButtons() { private void DisableNewEditDeleteButtons() {
NewAreaCommitmentButton.IsEnabled = false; NewAreaCommitmentButton.IsEnabled = false;
EditAreaCommitmentButton.IsEnabled = false; EditAreaCommitmentButton.IsEnabled = false;
DeleteAreaCommitmentButton.IsEnabled = false; DeleteAreaCommitmentButton.IsEnabled = false;
} }
private void EnableAreaCommitmentNewEditDeleteButtons() { private void EnableNewEditDeleteButtons() {
NewAreaCommitmentButton.IsEnabled = true; NewAreaCommitmentButton.IsEnabled = true;
EditAreaCommitmentButton.IsEnabled = AreaCommitmentList.SelectedItem != null; EditAreaCommitmentButton.IsEnabled = AreaCommitmentList.SelectedItem != null;
DeleteAreaCommitmentButton.IsEnabled = AreaCommitmentList.SelectedItem != null; DeleteAreaCommitmentButton.IsEnabled = AreaCommitmentList.SelectedItem != null;
} }
private void ShowAreaCommitmentSaveResetCancelButtons() { private void ShowSaveResetCancelButtons() {
AreaCommitmentSaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
AreaCommitmentResetButton.IsEnabled = false; ResetButton.IsEnabled = false;
AreaCommitmentCancelButton.IsEnabled = true; CancelButton.IsEnabled = true;
AreaCommitmentSaveButton.Visibility = Visibility.Visible; SaveButton.Visibility = Visibility.Visible;
AreaCommitmentResetButton.Visibility = Visibility.Visible; ResetButton.Visibility = Visibility.Visible;
AreaCommitmentCancelButton.Visibility = Visibility.Visible; CancelButton.Visibility = Visibility.Visible;
} }
private void HideAreaCommitmentSaveResetCancelButtons() { private void HideSaveResetCancelButtons() {
AreaCommitmentSaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
AreaCommitmentResetButton.IsEnabled = false; ResetButton.IsEnabled = false;
AreaCommitmentCancelButton.IsEnabled = false; CancelButton.IsEnabled = false;
AreaCommitmentSaveButton.Visibility = Visibility.Hidden; SaveButton.Visibility = Visibility.Hidden;
AreaCommitmentResetButton.Visibility = Visibility.Hidden; ResetButton.Visibility = Visibility.Hidden;
AreaCommitmentCancelButton.Visibility = Visibility.Hidden; CancelButton.Visibility = Visibility.Hidden;
} }
private void ShowAreaCommitmentNewEditDeleteButtons() { private void ShowNewEditDeleteButtons() {
EnableAreaCommitmentNewEditDeleteButtons(); EnableNewEditDeleteButtons();
NewAreaCommitmentButton.Visibility = Visibility.Visible; NewAreaCommitmentButton.Visibility = Visibility.Visible;
EditAreaCommitmentButton.Visibility = Visibility.Visible; EditAreaCommitmentButton.Visibility = Visibility.Visible;
DeleteAreaCommitmentButton.Visibility = Visibility.Visible; DeleteAreaCommitmentButton.Visibility = Visibility.Visible;
} }
private void HideAreaCommitmentNewEditDeleteButtons() { private void HideNewEditDeleteButtons() {
DisableAreaCommitmentNewEditDeleteButtons(); DisableNewEditDeleteButtons();
NewAreaCommitmentButton.Visibility = Visibility.Hidden; NewAreaCommitmentButton.Visibility = Visibility.Hidden;
EditAreaCommitmentButton.Visibility = Visibility.Hidden; EditAreaCommitmentButton.Visibility = Visibility.Hidden;
DeleteAreaCommitmentButton.Visibility = Visibility.Hidden; DeleteAreaCommitmentButton.Visibility = Visibility.Hidden;
@@ -345,6 +383,8 @@ namespace Elwig.Windows {
} }
private void AreaCommitmentList_SelectionChanged(object sender, SelectionChangedEventArgs evt) { private void AreaCommitmentList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
if (AreaCommitmentList.SelectedItem != null)
AreaCommitmentList.ScrollIntoView(AreaCommitmentList.SelectedItem);
RefreshInputs(); RefreshInputs();
} }

View File

@@ -157,7 +157,7 @@ namespace Elwig.Windows {
} }
var d = new NewSeasonDialog(s, currencies); var d = new NewSeasonDialog(s, currencies);
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
ctx.Add(new Season { ctx.Add(new Season {
@@ -209,7 +209,7 @@ namespace Elwig.Windows {
$"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?", $"Soll die Saison {s.Year} wirklich unwiderruflich gelöscht werden?",
"Saison löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Saison löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
ctx.Remove(s); ctx.Remove(s);

View File

@@ -318,8 +318,7 @@ namespace Elwig.Windows {
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Save(); await Save();
} catch (Exception exc) { } catch (Exception exc) {
@@ -327,9 +326,8 @@ namespace Elwig.Windows {
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Stammdaten aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Stammdaten aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@@ -349,6 +347,7 @@ namespace Elwig.Windows {
} }
App.HintContextChange(); App.HintContextChange();
Mouse.OverrideCursor = null;
} }
private void FillInputs(ClientParameters p, Season? s) { private void FillInputs(ClientParameters p, Season? s) {

View File

@@ -75,8 +75,8 @@
<ctrl:CheckComboBox.ItemTemplate> <ctrl:CheckComboBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Variety.Name}" Width="150"/> <TextBlock Text="{Binding Variety.Name}" Foreground="{Binding Variety.Color}" Width="150"/>
<TextBlock Text="{Binding Variety.Type}" Width="30"/> <TextBlock Text="{Binding Variety.Type}" Foreground="{Binding Variety.Color}" Width="30"/>
<TextBlock Text="{Binding Attribute.Name}" Width="80"/> <TextBlock Text="{Binding Attribute.Name}" Width="80"/>
<TextBlock Text="{Binding Cultivation.Name}" Width="80"/> <TextBlock Text="{Binding Cultivation.Name}" Width="80"/>
<TextBlock Text="{Binding AssignedGraphId}" Width="30"/> <TextBlock Text="{Binding AssignedGraphId}" Width="30"/>
@@ -94,14 +94,14 @@
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" Width="30"/> <TextBlock Text="{Binding Id}" Foreground="{Binding Color}" Width="30"/>
<TextBlock Text="{Binding VaributeStringSimple}" ToolTip="{Binding VaributeString}"/> <TextBlock Text="{Binding VaributeStringSimple}" Foreground="{Binding Color}" ToolTip="{Binding VaributeString}"/>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>
<Button x:Name="SaveButton" Content="Speichern" IsEnabled="False" <Button x:Name="SaveButton" Content="Speichern &amp; Berechnen" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="10,5,35,10" Grid.Column="0" Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="10,5,35,10" Grid.Column="0" Grid.Row="2"
Click="SaveButton_Click"/> Click="SaveButton_Click"/>

View File

@@ -639,10 +639,11 @@ namespace Elwig.Windows {
private async void SaveButton_Click(object sender, RoutedEventArgs e) { private async void SaveButton_Click(object sender, RoutedEventArgs e) {
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
var origData = BillingData.FromJson(PaymentVar.Data); var origData = BillingData.FromJson(PaymentVar.Data);
var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(ctx, Year), var data = BillingData.FromGraphEntries(GraphEntries, origData, Utils.GetVaributes(ctx, Year),
AllVaributesAssigned, AllVaributesAssignedAbgew); AllVaributesAssigned, AllVaributesAssignedAbgew);
@@ -650,21 +651,31 @@ namespace Elwig.Windows {
PaymentVar.Data = data.ToJsonString(); PaymentVar.Data = data.ToJsonString();
ctx.Update(PaymentVar); ctx.Update(PaymentVar);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
LockContext = false;
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
Mouse.OverrideCursor = null;
var str = "Der Eintrag konnte nicht in der Datenbank gespeichert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank gespeichert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante speichern", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Auszahlungsvariante speichern", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return; return;
} finally {
Mouse.OverrideCursor = null;
} }
try {
await Task.Run(async () => {
var b = new BillingVariant(PaymentVar.Year, PaymentVar.AvNr);
await b.Calculate();
});
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Berechnungsfehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
LockContext = false;
App.HintContextChange();
LockContext = true; LockContext = true;
SetHasChanged(false); SetHasChanged(false);
Mouse.OverrideCursor = null;
} }
private void EnableTextBox(TextBox u) { private void EnableTextBox(TextBox u) {

View File

@@ -217,7 +217,7 @@
<Bold>Zweigstelle</Bold>: z.B. musterort, ...<LineBreak/> <Bold>Zweigstelle</Bold>: z.B. musterort, ...<LineBreak/>
<Bold>Attribut</Bold>: z.B. kabinett, !kabinett (alle außer kabinett), ...<LineBreak/> <Bold>Attribut</Bold>: z.B. kabinett, !kabinett (alle außer kabinett), ...<LineBreak/>
<Bold>Bewirtschaftung</Bold>: z.B. bio, !kip (alle außer KIP), ...<LineBreak/> <Bold>Bewirtschaftung</Bold>: z.B. bio, !kip (alle außer KIP), ...<LineBreak/>
<Bold>Gewicht</Bold>: z.B. &lt;500kg, &gt;6000kg, ... (gilt für Gewicht der gesamten Lieferung)<LineBreak/> <Bold>Gewicht</Bold>: z.B. &lt;500kg, &gt;6000kg, ... (gilt für Menge der gesamten Lieferung)<LineBreak/>
<Bold>Datum</Bold>: z.B. 1.9., 15.9.-10.10., -15.10.2020, ...<LineBreak/> <Bold>Datum</Bold>: z.B. 1.9., 15.9.-10.10., -15.10.2020, ...<LineBreak/>
<Bold>Uhrzeit</Bold>: z.B. 06:00-08:00, 18:00-, ...<LineBreak/> <Bold>Uhrzeit</Bold>: z.B. 06:00-08:00, 18:00-, ...<LineBreak/>
<Bold>Handwiegung</Bold>: handw[iegung], !Handw[iegung] (alle ohne Handwiegung)<LineBreak/> <Bold>Handwiegung</Bold>: handw[iegung], !Handw[iegung] (alle ohne Handwiegung)<LineBreak/>
@@ -268,11 +268,12 @@
<DataGridTextColumn Header="Sorte" Binding="{Binding FilteredSortIdString}" Width="50"> <DataGridTextColumn Header="Sorte" Binding="{Binding FilteredSortIdString}" Width="50">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.Foreground" Value="{Binding FilteredColor}"/>
<Setter Property="TextBlock.TextAlignment" Value="Center"/> <Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Gewicht" Binding="{Binding FilteredWeight, StringFormat='{}{0:N0} kg '}" Width="75"> <DataGridTextColumn Header="Menge" Binding="{Binding FilteredWeight, StringFormat='{}{0:N0} kg '}" Width="75">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
@@ -438,7 +439,7 @@
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DPNr}" Width="13" TextAlignment="Right" Margin="0,0,7,0"/> <TextBlock Text="{Binding DPNr}" Width="13" TextAlignment="Right" Margin="0,0,7,0"/>
<TextBlock Text="{Binding SortId}" Width="30"/> <TextBlock Text="{Binding SortId}" Foreground="{Binding Variety.Color}" TextAlignment="Center" Width="30"/>
<TextBlock Text="{Binding Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"/> <TextBlock Text="{Binding Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"/>
<TextBlock Text="{Binding QualId}" Width="30"/> <TextBlock Text="{Binding QualId}" Width="30"/>
<TextBlock Text="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/> <TextBlock Text="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/>
@@ -460,7 +461,7 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Content="Sorte:" Margin="10,10,0,0" Grid.Column="0"/> <Label Content="Sorte:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="SortIdInput" Text="{Binding SortId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="SortIdInput" Text="{Binding SortId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="{Binding WineVar.Color}"
Width="36" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" Width="36" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left"
TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/> TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/>
<ComboBox x:Name="WineVarietyInput" SelectedItem="{Binding WineVar, Mode=TwoWay}" ItemsSource="{Binding WineVarSource, Mode=TwoWay}" <ComboBox x:Name="WineVarietyInput" SelectedItem="{Binding WineVar, Mode=TwoWay}" ItemsSource="{Binding WineVarSource, Mode=TwoWay}"
@@ -516,7 +517,7 @@
</Grid> </Grid>
</GroupBox> </GroupBox>
<GroupBox Header="Gewicht" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5"> <GroupBox Header="Menge" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/> <ColumnDefinition Width="70"/>
@@ -669,7 +670,7 @@
<Separator Grid.Column="5"/> <Separator Grid.Column="5"/>
<StatusBarItem Grid.Column="6"> <StatusBarItem Grid.Column="6">
<TextBlock ToolTip="{Binding StatusWeightToolTip}"> <TextBlock ToolTip="{Binding StatusWeightToolTip}">
Gewicht: <Run Text="{Binding StatusWeight}"/> Menge: <Run Text="{Binding StatusWeight}"/>
</TextBlock> </TextBlock>
</StatusBarItem> </StatusBarItem>
<Separator Grid.Column="7"/> <Separator Grid.Column="7"/>

View File

@@ -719,7 +719,7 @@ namespace Elwig.Windows {
private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
FinishButton.IsEnabled = false; FinishButton.IsEnabled = false;
NewDeliveryPartButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
DeliveryPartList.IsEnabled = false; DeliveryPartList.IsEnabled = false;
DeliveryPart? p; DeliveryPart? p;
@@ -732,6 +732,7 @@ namespace Elwig.Windows {
InputHasChanged(TimeInput), InputHasChanged(TimeInput),
!InputIsNotDefault(TimeInput) !InputIsNotDefault(TimeInput)
); );
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@@ -757,7 +758,7 @@ namespace Elwig.Windows {
private async void FinishButton_Click(object sender, RoutedEventArgs evt) { private async void FinishButton_Click(object sender, RoutedEventArgs evt) {
FinishButton.IsEnabled = false; FinishButton.IsEnabled = false;
NewDeliveryPartButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
DeliveryPartList.IsEnabled = false; DeliveryPartList.IsEnabled = false;
DeliveryPart? p; DeliveryPart? p;
@@ -770,6 +771,7 @@ namespace Elwig.Windows {
InputHasChanged(TimeInput), InputHasChanged(TimeInput),
!InputIsNotDefault(TimeInput) !InputIsNotDefault(TimeInput)
); );
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@@ -888,7 +890,7 @@ namespace Elwig.Windows {
if (res == null) if (res == null)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
var id = res.Value.Item1; var id = res.Value.Item1;
var weights = res.Value.Item2; var weights = res.Value.Item2;
@@ -905,6 +907,7 @@ namespace Elwig.Windows {
var n = await DeliveryService.SplitDeliveryToLsNr(d.Year, d.DId, weights, id); var n = await DeliveryService.SplitDeliveryToLsNr(d.Year, d.DId, weights, id);
ControlUtils.SelectItemWithPk(DeliveryList, n.Year, n.DId); ControlUtils.SelectItemWithPk(DeliveryList, n.Year, n.DId);
} }
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@@ -959,9 +962,10 @@ namespace Elwig.Windows {
$"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?", $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?",
"Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await DeliveryService.DeleteDelivery(d.LsNr); await DeliveryService.DeleteDelivery(d.LsNr);
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@@ -979,7 +983,7 @@ namespace Elwig.Windows {
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
DeliveryPart? p; DeliveryPart? p;
try { try {
@@ -991,14 +995,14 @@ namespace Elwig.Windows {
InputHasChanged(TimeInput), InputHasChanged(TimeInput),
!InputIsNotDefault(TimeInput) !InputIsNotDefault(TimeInput)
); );
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@@ -1015,6 +1019,7 @@ namespace Elwig.Windows {
await RefreshDeliveryParts(); await RefreshDeliveryParts();
RefreshInputs(); RefreshInputs();
Mouse.OverrideCursor = null;
DepreciateButton.IsEnabled = true; DepreciateButton.IsEnabled = true;
} }

View File

@@ -125,7 +125,7 @@
<Bold>Zweigstelle</Bold>: z.B. musterort, ...<LineBreak/> <Bold>Zweigstelle</Bold>: z.B. musterort, ...<LineBreak/>
<Bold>Attribut</Bold>: z.B. kabinett, !kabinett (alle außer kabinett), ...<LineBreak/> <Bold>Attribut</Bold>: z.B. kabinett, !kabinett (alle außer kabinett), ...<LineBreak/>
<Bold>Bewirtschaftung</Bold>: z.B. bio, !kip (alle außer KIP), ...<LineBreak/> <Bold>Bewirtschaftung</Bold>: z.B. bio, !kip (alle außer KIP), ...<LineBreak/>
<Bold>Gewicht</Bold>: z.B. &lt;500kg, &gt;6000kg, ...<LineBreak/> <Bold>Menge</Bold>: z.B. &lt;500kg, &gt;6000kg, ...<LineBreak/>
<Bold>Datum</Bold>: z.B. 1.9., 15.9.-10.10., -15.10.2020, ... <Bold>Datum</Bold>: z.B. 1.9., 15.9.-10.10., -15.10.2020, ...
</TextBlock> </TextBlock>
</TextBox.ToolTip> </TextBox.ToolTip>
@@ -187,18 +187,19 @@
<DataGridTextColumn Header="Sorte" Binding="{Binding SortId}" Width="50"> <DataGridTextColumn Header="Sorte" Binding="{Binding SortId}" Width="50">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.Foreground" Value="{Binding Variety.Color}"/>
<Setter Property="TextBlock.TextAlignment" Value="Center"/> <Setter Property="TextBlock.TextAlignment" Value="Center"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="75"> <DataGridTextColumn Header="Menge" Binding="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="75">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
</Style> </Style>
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Angemeldet" Binding="{Binding CreatedTimestamp, StringFormat='{}{0:HH:mm, dd.MM.}'}" Width="100"> <DataGridTextColumn Header="Angemeldet" Binding="{Binding CreatedAt, StringFormat='{}{0:HH:mm, dd.MM.}'}" Width="100">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Center"/> <Setter Property="TextBlock.TextAlignment" Value="Center"/>
@@ -316,7 +317,7 @@
</ComboBox> </ComboBox>
<Label Content="Sorte:" Margin="10,40,0,0" Grid.Column="0"/> <Label Content="Sorte:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="SortIdInput" Text="{Binding SortId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <TextBox x:Name="SortIdInput" Text="{Binding SortId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="{Binding WineVariety.Color}"
Width="36" Grid.Row="1" Grid.Column="1" Margin="0,40,0,0" HorizontalAlignment="Left" Width="36" Grid.Row="1" Grid.Column="1" Margin="0,40,0,0" HorizontalAlignment="Left"
TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/> TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/>
<ComboBox x:Name="WineVarietyInput" SelectedItem="{Binding WineVariety, Mode=TwoWay}" ItemsSource="{Binding WineVarietySource, Mode=TwoWay}" <ComboBox x:Name="WineVarietyInput" SelectedItem="{Binding WineVariety, Mode=TwoWay}" ItemsSource="{Binding WineVarietySource, Mode=TwoWay}"
@@ -328,7 +329,7 @@
</ComboBox.ItemTemplateSelector> </ComboBox.ItemTemplateSelector>
</ComboBox> </ComboBox>
<Label Content="Gewicht:" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="Menge:" Margin="10,70,0,0" Grid.Column="0"/>
<ctrl:UnitTextBox x:Name="WeightInput" Unit="kg" Text="{Binding WeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <ctrl:UnitTextBox x:Name="WeightInput" Unit="kg" Text="{Binding WeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="1" Margin="0,70,10,10" Width="61" HorizontalAlignment="Left" Grid.Column="1" Margin="0,70,10,10" Width="61" HorizontalAlignment="Left"
TextChanged="WeightInput_TextChanged" KeyUp="Input_KeyUp"/> TextChanged="WeightInput_TextChanged" KeyUp="Input_KeyUp"/>
@@ -364,7 +365,7 @@
<Separator Grid.Column="1"/> <Separator Grid.Column="1"/>
<StatusBarItem Grid.Column="2"> <StatusBarItem Grid.Column="2">
<TextBlock ToolTip="{Binding StatusWeightToolTip}"> <TextBlock ToolTip="{Binding StatusWeightToolTip}">
Gewicht: <Run Text="{Binding StatusWeight}"/> Menge: <Run Text="{Binding StatusWeight}"/>
</TextBlock> </TextBlock>
</StatusBarItem> </StatusBarItem>
<Separator Grid.Column="3"/> <Separator Grid.Column="3"/>

View File

@@ -103,6 +103,7 @@ namespace Elwig.Windows {
var deliveryAncmts = await deliveryAncmtQuery var deliveryAncmts = await deliveryAncmtQuery
.Include(a => a.Member.BillingAddress) .Include(a => a.Member.BillingAddress)
.Include(a => a.Schedule) .Include(a => a.Schedule)
.Include(a => a.Variety)
.AsSplitQuery() .AsSplitQuery()
.ToListAsync(); .ToListAsync();
@@ -317,12 +318,13 @@ namespace Elwig.Windows {
$"Soll die Anmeldung wirklich unwiderruflich gelöscht werden?", $"Soll die Anmeldung wirklich unwiderruflich gelöscht werden?",
"Anmeldung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Anmeldung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
ctx.Remove(a); ctx.Remove(a);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
@@ -340,7 +342,7 @@ namespace Elwig.Windows {
} }
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
int year = -1, dsnr = -1, mgnr = -1; int year = -1, dsnr = -1, mgnr = -1;
@@ -348,6 +350,7 @@ namespace Elwig.Windows {
try { try {
var s = ViewModel.SelectedDeliveryAncmt; var s = ViewModel.SelectedDeliveryAncmt;
(year, dsnr, mgnr, sortid) = await ViewModel.UpdateDeliveryAncmt(s?.Year, s?.DsNr, s?.MgNr, s?.SortId, s?.Type); (year, dsnr, mgnr, sortid) = await ViewModel.UpdateDeliveryAncmt(s?.Year, s?.DsNr, s?.MgNr, s?.SortId, s?.Type);
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;

View File

@@ -127,7 +127,7 @@
</DataGridTextColumn.CellStyle> </DataGridTextColumn.CellStyle>
</DataGridTextColumn> </DataGridTextColumn>
<DataGridTextColumn Header="Beschreibung" Binding="{Binding Description}" Width="200"/> <DataGridTextColumn Header="Beschreibung" Binding="{Binding Description}" Width="200"/>
<DataGridTextColumn Header="Max. Gew." Binding="{Binding MaxWeight, StringFormat='{}{0:N0} kg'}" Width="80"> <DataGridTextColumn Header="Max. Mg." Binding="{Binding MaxWeight, StringFormat='{}{0:N0} kg'}" Width="80">
<DataGridTextColumn.CellStyle> <DataGridTextColumn.CellStyle>
<Style> <Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/> <Setter Property="TextBlock.TextAlignment" Value="Right"/>
@@ -211,7 +211,7 @@
Margin="0,40,10,10" Grid.Column="1" Grid.ColumnSpan="2" Margin="0,40,10,10" Grid.Column="1" Grid.ColumnSpan="2"
TextChanged="TextBox_TextChanged"/> TextChanged="TextBox_TextChanged"/>
<Label Content="Max. Gewicht:" Margin="10,70,0,10"/> <Label Content="Max. Menge:" Margin="10,70,0,10"/>
<ctrl:UnitTextBox x:Name="MaxWeightInput" Unit="kg" Text="{Binding MaxWeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" <ctrl:UnitTextBox x:Name="MaxWeightInput" Unit="kg" Text="{Binding MaxWeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,70,10,10" Grid.Column="1" Grid.ColumnSpan="2" Width="68" HorizontalAlignment="Left" Margin="0,70,10,10" Grid.Column="1" Grid.ColumnSpan="2" Width="68" HorizontalAlignment="Left"
TextChanged="MaxWeightInput_TextChanged"/> TextChanged="MaxWeightInput_TextChanged"/>

View File

@@ -177,12 +177,13 @@ namespace Elwig.Windows {
$"Soll der Leseplan \"{s.Description}\" vom {s.Date:dd.MM.yyyy} wirklich unwiderruflich gelöscht werden?", $"Soll der Leseplan \"{s.Description}\" vom {s.Date:dd.MM.yyyy} wirklich unwiderruflich gelöscht werden?",
"Leseplan löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); "Leseplan löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r == MessageBoxResult.OK) { if (r == MessageBoxResult.OK) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using (var ctx = new AppDbContext()) { await Task.Run(async () => {
using var ctx = new AppDbContext();
ctx.Remove(s); ctx.Remove(s);
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
} });
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
@@ -200,11 +201,12 @@ namespace Elwig.Windows {
} }
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
try { try {
await ViewModel.UpdateDeliverySchedule(ViewModel.SelectedDeliverySchedule?.Year, ViewModel.SelectedDeliverySchedule?.DsNr); await ViewModel.UpdateDeliverySchedule(ViewModel.SelectedDeliverySchedule?.Year, ViewModel.SelectedDeliverySchedule?.DsNr);
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;

View File

@@ -3,7 +3,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Elwig.Windows" xmlns:local="clr-namespace:Elwig.Windows"
Title="Ausgangs-Protokoll - Rundschreiben - Elwig" Height="600" Width="1000"> Title="Ausgangs-Protokoll - Rundschreiben - Elwig" Height="600" Width="1000"
Loaded="Window_Loaded">
<Grid> <Grid>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/> <ColumnDefinition Width="3*"/>

View File

@@ -2,6 +2,7 @@ using Elwig.Helpers;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
namespace Elwig.Windows { namespace Elwig.Windows {
@@ -18,8 +19,16 @@ namespace Elwig.Windows {
FilterInput.TextChanged -= FilterInput_TextChanged; FilterInput.TextChanged -= FilterInput_TextChanged;
} }
private async void Window_Loaded(object sender, RoutedEventArgs evt) {
await Load();
}
private async void TimeSpanInput_SelectionChanged(object sender, RoutedEventArgs evt) { private async void TimeSpanInput_SelectionChanged(object sender, RoutedEventArgs evt) {
if (!IsLoaded) return; if (!IsLoaded) return;
await Load();
}
private async Task Load() {
DateTime? fromDate = DateTime.Now; DateTime? fromDate = DateTime.Now;
if (TimeSpanInput.SelectedIndex == 0) { if (TimeSpanInput.SelectedIndex == 0) {
fromDate = fromDate.Value.AddDays(-7); fromDate = fromDate.Value.AddDays(-7);

View File

@@ -602,7 +602,7 @@ namespace Elwig.Windows {
PreviewButton.IsEnabled = false; PreviewButton.IsEnabled = false;
PrintButton.IsEnabled = false; PrintButton.IsEnabled = false;
EmailButton.IsEnabled = false; EmailButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
GenerateButton.IsEnabled = false; GenerateButton.IsEnabled = false;
DisposeDocs(); DisposeDocs();
@@ -671,7 +671,7 @@ namespace Elwig.Windows {
var avnr = details.Item2; var avnr = details.Item2;
try { try {
cnData[(year, avnr)] = ( cnData[(year, avnr)] = (
await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, year, avnr), await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, year, avnr),
await ctx.MemberPayments.Where(p => p.Year == year && p.AvNr == avnr).ToDictionaryAsync(c => c.MgNr), await ctx.MemberPayments.Where(p => p.Year == year && p.AvNr == avnr).ToDictionaryAsync(c => c.MgNr),
BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data) BillingData.FromJson((await ctx.PaymentVariants.FindAsync(year, avnr))!.Data)
); );
@@ -828,12 +828,13 @@ namespace Elwig.Windows {
EmailButton.IsEnabled = EmailDocuments != null && App.Config.Smtp != null; EmailButton.IsEnabled = EmailDocuments != null && App.Config.Smtp != null;
} }
private void PreviewButton_Click(object sender, RoutedEventArgs evt) { private async void PreviewButton_Click(object sender, RoutedEventArgs evt) {
var d = new OpenFolderDialog() { var d = new OpenFolderDialog() {
Title = "Ordner auswählen - Elwig", Title = "Ordner auswählen - Elwig",
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(() => {
PrintDocument?.SaveTo($"{d.FolderName}/Print.pdf"); PrintDocument?.SaveTo($"{d.FolderName}/Print.pdf");
if (EmailDocuments != null) { if (EmailDocuments != null) {
foreach (var (m, docs) in EmailDocuments) { foreach (var (m, docs) in EmailDocuments) {
@@ -847,6 +848,7 @@ namespace Elwig.Windows {
} }
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
Process.Start("explorer.exe", d.FolderName); Process.Start("explorer.exe", d.FolderName);
} }
@@ -862,7 +864,8 @@ namespace Elwig.Windows {
var res = MessageBox.Show($"Sollen {PrintDocument.Pages} Blätter ({PrintDocument.TotalPages} Seiten) gedruckt werden?", var res = MessageBox.Show($"Sollen {PrintDocument.Pages} Blätter ({PrintDocument.TotalPages} Seiten) gedruckt werden?",
"Rundschreiben drucken", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No); "Rundschreiben drucken", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No);
if (res == MessageBoxResult.Yes) { if (res == MessageBoxResult.Yes) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
if (App.Config.Debug) { if (App.Config.Debug) {
PrintDocument.Show(); PrintDocument.Show();
} else { } else {
@@ -876,6 +879,7 @@ namespace Elwig.Windows {
)) ))
); );
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -893,8 +897,8 @@ namespace Elwig.Windows {
SmtpClient? client = null; SmtpClient? client = null;
try { try {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
client = await Utils.GetSmtpClient(); client = await Task.Run(Utils.GetSmtpClient);
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
var res = MessageBox.Show($"Sollen {EmailDocuments.Count:N0} E-Mails verschickt werden?", var res = MessageBox.Show($"Sollen {EmailDocuments.Count:N0} E-Mails verschickt werden?",
@@ -903,9 +907,10 @@ namespace Elwig.Windows {
return; return;
} }
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
var subject = EmailSubjectInput.Text; var subject = EmailSubjectInput.Text;
var text = EmailBodyInput.Text; var text = EmailBodyInput.Text;
await Task.Run(async () => {
await Utils.AddSentMailBody(subject, text, EmailDocuments.Count); await Utils.AddSentMailBody(subject, text, EmailDocuments.Count);
foreach (var (m, docs) in EmailDocuments) { foreach (var (m, docs) in EmailDocuments) {
using var msg = new MimeMessage(); using var msg = new MimeMessage();
@@ -928,6 +933,7 @@ namespace Elwig.Windows {
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!", "Rundschreiben verschicken", MessageBoxButton.OK, MessageBoxImage.Information);
} catch (Exception exc) { } catch (Exception exc) {

View File

@@ -207,7 +207,7 @@
<Button x:Name="BreakdownButton" <Button x:Name="BreakdownButton"
Click="BreakdownButton_Click" Click="BreakdownButton_Click"
Margin="195,90,0,10" Width="190" Padding="3,5,5,5" Margin="195,90,0,10" Width="190" Padding="3,5,5,5"
ToolTip="Aufschlüsselung des Gewichts nach Zweigstelle, Mitglied, Sorte, Attribut/Bewirt., Qualitätsstufe, gebunden/ungebunden"> ToolTip="Aufschlüsselung der Menge nach Zweigstelle, Mitglied, Sorte, Attribut/Bewirt., Qualitätsstufe, gebunden/ungebunden">
<Grid> <Grid>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE9F9;" <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE9F9;"
TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,0.5,0,0"/> TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,0.5,0,0"/>
@@ -252,7 +252,7 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" TextAlignment="Right"><Bold>Mitglieder</Bold></TextBlock> <TextBlock Grid.Row="0" Grid.Column="1" TextAlignment="Right"><Bold>Mitglieder</Bold></TextBlock>
<TextBlock Grid.Row="0" Grid.Column="2" TextAlignment="Right"><Bold>Gewicht</Bold></TextBlock> <TextBlock Grid.Row="0" Grid.Column="2" TextAlignment="Right"><Bold>Menge</Bold></TextBlock>
<TextBlock Grid.Row="0" Grid.Column="3" TextAlignment="Right"><Bold>Fläche</Bold></TextBlock> <TextBlock Grid.Row="0" Grid.Column="3" TextAlignment="Right"><Bold>Fläche</Bold></TextBlock>
<TextBlock Grid.Row="1" Grid.Column="0">Gesamt:</TextBlock> <TextBlock Grid.Row="1" Grid.Column="0">Gesamt:</TextBlock>

View File

@@ -62,7 +62,7 @@ namespace Elwig.Windows {
} }
private async void Menu_Help_Smtp_Click(object sender, RoutedEventArgs evt) { private async void Menu_Help_Smtp_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var client = await Utils.GetSmtpClient(); using var client = await Utils.GetSmtpClient();
await client!.DisconnectAsync(true); await client!.DisconnectAsync(true);
@@ -133,8 +133,10 @@ namespace Elwig.Windows {
Multiselect = true, Multiselect = true,
}; };
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
await ElwigData.Import(d.FileNames, ElwigData.ImportMode.Interactively); await ElwigData.Import(d.FileNames, ElwigData.ImportMode.Interactively);
});
} }
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
@@ -145,7 +147,8 @@ namespace Elwig.Windows {
private async void DownloadButton_Click(object sender, RoutedEventArgs evt) { private async void DownloadButton_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) if (App.Config.SyncUrl == null)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword);
var files = data var files = data
@@ -181,13 +184,15 @@ namespace Elwig.Windows {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
private async void UploadButton_Click(object sender, RoutedEventArgs evt) { private async void UploadButton_Click(object sender, RoutedEventArgs evt) {
if (App.Config.SyncUrl == null) if (App.Config.SyncUrl == null)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip"); var path = Path.Combine(App.TempPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.elwig.zip");
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
@@ -212,10 +217,11 @@ namespace Elwig.Windows {
} catch (HttpRequestException exc) { } catch (HttpRequestException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (TaskCanceledException exc) { } catch (TaskCanceledException exc) {
MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("Eventuell Internetverbindung prüfen!\n\n" + exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Lieferungen hochladen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -270,24 +276,31 @@ namespace Elwig.Windows {
AreaCommitmentsButton.IsEnabled = valid; AreaCommitmentsButton.IsEnabled = valid;
BreakdownMemberVarietyButton.IsEnabled = valid; BreakdownMemberVarietyButton.IsEnabled = valid;
if (valid) {
var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value);
var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight);
var gebWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value);
SeasonStatMembersTotal.Text = $"{await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync():N0}";
SeasonStatMembersGeb.Text = $"{await areaComs.Select(c => c.Member).Distinct().CountAsync():N0}";
SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg";
SeasonStatWeightGeb.Text = $"{gebWeight:N0} kg";
SeasonStatWeightUngeb.Text = $"{weightTotal - gebWeight:N0} kg";
SeasonStatArea.Text = $"{await areaComs.SumAsync(c => c.Area):N0} m²";
} else {
SeasonStatMembersTotal.Text = "-"; SeasonStatMembersTotal.Text = "-";
SeasonStatMembersGeb.Text = "-"; SeasonStatMembersGeb.Text = "-";
SeasonStatWeightTotal.Text = "-"; SeasonStatWeightTotal.Text = "-";
SeasonStatWeightGeb.Text = "-"; SeasonStatWeightGeb.Text = "-";
SeasonStatWeightUngeb.Text = "-"; SeasonStatWeightUngeb.Text = "-";
SeasonStatArea.Text = "-"; SeasonStatArea.Text = "-";
} if (valid) {
await Task.Run(async () => {
var membersTotal = await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync();
var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value);
var membersGeb = await areaComs.Select(c => c.Member).Distinct().CountAsync();
var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight);
var gebWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value);
var area = await areaComs.SumAsync(c => c.Area);
await App.MainDispatcher.BeginInvoke(() => {
if (year != SeasonInput.Value) return;
SeasonStatMembersTotal.Text = $"{membersTotal:N0}";
SeasonStatMembersGeb.Text = $"{membersGeb:N0}";
SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg";
SeasonStatWeightGeb.Text = $"{gebWeight:N0} kg";
SeasonStatWeightUngeb.Text = $"{weightTotal - gebWeight:N0} kg";
SeasonStatArea.Text = $"{area:N0} m²";
});
});
};
} }
private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) { private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) {
@@ -315,7 +328,8 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var b = new Billing(year); var b = new Billing(year);
await b.FinishSeason(); await b.FinishSeason();
@@ -331,6 +345,7 @@ namespace Elwig.Windows {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -346,7 +361,8 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var b = new Billing(year); var b = new Billing(year);
await b.FinishSeason(); await b.FinishSeason();
@@ -364,6 +380,7 @@ namespace Elwig.Windows {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -379,7 +396,8 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var b = new Billing(year); var b = new Billing(year);
await b.FinishSeason(); await b.FinishSeason();
@@ -393,6 +411,7 @@ namespace Elwig.Windows {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
@@ -408,7 +427,8 @@ namespace Elwig.Windows {
if (d.ShowDialog() == false) if (d.ShowDialog() == false)
return; return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
await Task.Run(async () => {
try { try {
var b = new Billing(year); var b = new Billing(year);
await b.FinishSeason(); await b.FinishSeason();
@@ -422,6 +442,7 @@ namespace Elwig.Windows {
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
});
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }

View File

@@ -653,13 +653,40 @@
TextChanged="TextBox_TextChanged" TextChanged="TextBox_TextChanged"
VerticalAlignment="Stretch" Height="auto" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/> VerticalAlignment="Stretch" Height="auto" AcceptsReturn="True" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible"/>
<Label Content="Kontaktart:" Margin="10,10,0,10" Grid.Column="0" VerticalAlignment="Bottom"/> <Label Content="Kontaktart:" Margin="10,10,0,40" Grid.Column="0" VerticalAlignment="Bottom"/>
<CheckBox x:Name="ContactPostalInput" Content="Post" IsChecked="{Binding ContactViaPost, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="ContactPostalInput" Content="Post" IsChecked="{Binding ContactViaPost, Mode=TwoWay}" IsEnabled="False"
Checked="CheckBox_Changed" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
HorizontalAlignment="Left" Margin="0,0,0,15" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="2"/> HorizontalAlignment="Left" Margin="0,0,0,45" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="2"/>
<CheckBox x:Name="ContactEmailInput" Content="E-Mail" IsChecked="{Binding ContactViaEmail, Mode=TwoWay}" IsEnabled="False" <CheckBox x:Name="ContactEmailInput" Content="E-Mail" IsChecked="{Binding ContactViaEmail, Mode=TwoWay}" IsEnabled="False"
Checked="ContactEmailInput_Changed" Unchecked="ContactEmailInput_Changed" Checked="ContactEmailInput_Changed" Unchecked="ContactEmailInput_Changed"
HorizontalAlignment="Left" Margin="60,0,0,15" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="2"/> HorizontalAlignment="Left" Margin="60,0,0,45" VerticalAlignment="Bottom" Grid.Column="1" Grid.ColumnSpan="2"/>
<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">
<TextBlock.ToolTip>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="110"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Erstellt:"/>
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding CreatedAt}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Zuletzt geändert:"/>
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding ModifiedAt}"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Zuletzt von diesem Gerät exportiert:"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding ExportedAt}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Zuletzt auf dieses Gerät importiert:"/>
<TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding ImportedAt}"/>
</Grid>
</TextBlock.ToolTip>
</TextBlock>
<Button x:Name="DeliveryButton" Content="Lieferungen" IsEnabled="{Binding IsMemberSelected}" <Button x:Name="DeliveryButton" Content="Lieferungen" IsEnabled="{Binding IsMemberSelected}"
Click="DeliveryButton_Click" Click="DeliveryButton_Click"

View File

@@ -389,9 +389,10 @@ namespace Elwig.Windows {
} }
var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits); var d = new DeleteMemberDialog(m.MgNr, m.AdministrativeName, areaComs, deliveries, credits);
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs); await MemberService.DeleteMember(m.MgNr, d.DeletePaymentData, d.DeleteDeliveries, d.DeleteAreaComs);
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
@@ -408,20 +409,20 @@ namespace Elwig.Windows {
} }
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
SaveButton.IsEnabled = false; SaveButton.IsEnabled = false;
int mgnr; int mgnr;
try { try {
mgnr = await ViewModel.UpdateMember(ViewModel.SelectedMember?.MgNr); mgnr = await ViewModel.UpdateMember(ViewModel.SelectedMember?.MgNr);
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Mitglied aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Mitglied aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
SaveButton.IsEnabled = true; SaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
return;
} }
IsEditing = false; IsEditing = false;
@@ -436,6 +437,7 @@ namespace Elwig.Windows {
await RefreshList(); await RefreshList();
RefreshInputs(); RefreshInputs();
ViewModel.SearchQuery = ""; ViewModel.SearchQuery = "";
Mouse.OverrideCursor = null;
if (mgnr is int m) if (mgnr is int m)
FocusMember(m); FocusMember(m);
} }
@@ -491,8 +493,9 @@ namespace Elwig.Windows {
private async void Menu_Contact_Letterhead_Click(object sender, RoutedEventArgs evt) { private async void Menu_Contact_Letterhead_Click(object sender, RoutedEventArgs evt) {
if (ViewModel.SelectedMember is not Member m) return; if (ViewModel.SelectedMember is not Member m) return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Task.Run(async () => {
using var doc = new Letterhead(m); using var doc = new Letterhead(m);
await doc.Generate(); await doc.Generate();
if (!App.Config.Debug) { if (!App.Config.Debug) {
@@ -500,6 +503,7 @@ namespace Elwig.Windows {
} else { } else {
doc.Show(); doc.Show();
} }
});
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
@@ -780,11 +784,11 @@ namespace Elwig.Windows {
$"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" + $"{ViewModel.Prefix}{(!string.IsNullOrEmpty(ViewModel.Prefix) ? " " : "")}" +
$"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" + $"{ViewModel.GivenName}{(!string.IsNullOrEmpty(ViewModel.GivenName) ? " " : "")}" +
$"{ViewModel.Suffix}{(!string.IsNullOrEmpty(ViewModel.Suffix) ? " " : "")}"; $"{ViewModel.Suffix}{(!string.IsNullOrEmpty(ViewModel.Suffix) ? " " : "")}";
var d = new AreaComDialog(oldMember.AdministrativeName, newName, areaComs.Count, areaComs.Sum(c => c.Area)); var d = new AreaComTransferDialog(oldMember.AdministrativeName, newName, areaComs.Count, areaComs.Sum(c => c.Area));
if (d.ShowDialog() != true) if (d.ShowDialog() != true)
return; return;
ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason; ViewModel.TransferPredecessorAreaComs = d.SuccessorSeason;
ViewModel.MaintainAreaComYearTo = d.MaintainYearTo; ViewModel.MaintainAreaComYearFrom = d.MaintainYearFrom;
if (IsEditing) if (IsEditing)
SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save SetOriginalValue(PredecessorMgNrInput, -1); // hack to allow user to save
UpdateButtons(); UpdateButtons();
@@ -843,7 +847,7 @@ namespace Elwig.Windows {
.Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason)) .Where(c => c.MgNr == mgnr && (c.YearTo == null || c.YearTo >= Utils.FollowingSeason))
.ToListAsync(); .ToListAsync();
if (areaComs.Count > 0) { if (areaComs.Count > 0) {
var d = new AreaComDialog(m.AdministrativeName, areaComs.Count, areaComs.Sum(c => c.Area)); var d = new AreaComTransferDialog(m.AdministrativeName, areaComs.Count, areaComs.Sum(c => c.Area));
if (d.ShowDialog() == true) { if (d.ShowDialog() == true) {
ViewModel.CancelAreaComs = d.CancelSeason; ViewModel.CancelAreaComs = d.CancelSeason;
} }

View File

@@ -156,7 +156,7 @@ namespace Elwig.Windows {
} }
private async void AutoAdjustBsButton_Click(object sender, RoutedEventArgs evt) { private async void AutoAdjustBsButton_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
int? kg = AllowanceKgInput.Text == "" ? null : int.Parse(AllowanceKgInput.Text); int? kg = AllowanceKgInput.Text == "" ? null : int.Parse(AllowanceKgInput.Text);
double? bs = AllowanceBsInput.Text == "" ? null : double.Parse(AllowanceBsInput.Text); double? bs = AllowanceBsInput.Text == "" ? null : double.Parse(AllowanceBsInput.Text);
@@ -169,10 +169,12 @@ namespace Elwig.Windows {
App.Client.AutoAdjustBs.AllowanceKgPerBs = kgPerBs; App.Client.AutoAdjustBs.AllowanceKgPerBs = kgPerBs;
App.Client.AutoAdjustBs.AllowancePercent = percent; App.Client.AutoAdjustBs.AllowancePercent = percent;
App.Client.AutoAdjustBs.MinBs = minBs; App.Client.AutoAdjustBs.MinBs = minBs;
await App.Client.UpdateValues();
await Task.Run(async () => {
await App.Client.UpdateValues();
var b = new Billing(Year); var b = new Billing(Year);
await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, bs ?? default, kgPerBs ?? default, percent / 100.0 ?? default, minBs ?? default); await b.AutoAdjustBusinessShares(new DateOnly(Year, 11, 30), kg ?? default, bs ?? default, kgPerBs ?? default, percent / 100.0 ?? default, minBs ?? default);
});
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
@@ -183,10 +185,12 @@ namespace Elwig.Windows {
} }
private async void UnAdjustBsButton_Click(object sender, RoutedEventArgs evt) { private async void UnAdjustBsButton_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
await Task.Run(async () => {
var b = new Billing(Year); var b = new Billing(Year);
await b.UnAdjustBusinessShares(); await b.UnAdjustBusinessShares();
});
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
@@ -281,18 +285,19 @@ namespace Elwig.Windows {
private async void CustomButton_Click(object sender, RoutedEventArgs evt) { private async void CustomButton_Click(object sender, RoutedEventArgs evt) {
if (MemberInput.SelectedItem is not Member m) return; if (MemberInput.SelectedItem is not Member m) return;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
using var ctx = new AppDbContext();
if (CustomPayments?.TryGetValue(m.MgNr, out var p) == true) {
ctx.Remove(p);
}
if (sender == SaveCustomButton) {
var modAbs = decimal.TryParse(CustomModAbsInput.Text, out var n1) ? (decimal?)n1 : null; var modAbs = decimal.TryParse(CustomModAbsInput.Text, out var n1) ? (decimal?)n1 : null;
var modRel = decimal.TryParse(CustomModRelInput.Text, out var n2) ? (decimal?)n2 / 100 : null; var modRel = decimal.TryParse(CustomModRelInput.Text, out var n2) ? (decimal?)n2 / 100 : null;
var amount = decimal.TryParse(CustomAmountInput.Text, out var n3) ? (decimal?)n3 : null; var amount = decimal.TryParse(CustomAmountInput.Text, out var n3) ? (decimal?)n3 : null;
var modText = CustomModCommentInput.Text.Trim(); var modText = CustomModCommentInput.Text.Trim();
var text = CustomCommentInput.Text.Trim(); var text = CustomCommentInput.Text.Trim();
await Task.Run(async () => {
using var ctx = new AppDbContext();
if (CustomPayments?.TryGetValue(m.MgNr, out var p) == true) {
ctx.Remove(p);
}
if (sender == SaveCustomButton) {
ctx.Add(new PaymentCustom { ctx.Add(new PaymentCustom {
MgNr = m.MgNr, MgNr = m.MgNr,
Year = Year, Year = Year,
@@ -304,12 +309,13 @@ namespace Elwig.Windows {
}); });
} }
await ctx.SaveChangesAsync(); await ctx.SaveChangesAsync();
});
App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Benutzerdefinierten Zu-/Abschlag speichern", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Benutzerdefinierten Zu-/Abschlag speichern", MessageBoxButton.OK, MessageBoxImage.Error);
} }
App.HintContextChange();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
} }
} }

View File

@@ -5,8 +5,12 @@
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"
xmlns:vm="clr-namespace:Elwig.ViewModels"
xmlns:ctrl="clr-namespace:Elwig.Controls" xmlns:ctrl="clr-namespace:Elwig.Controls"
Title="Auszahlungsvarianten - Elwig" Height="480" Width="850" MinHeight="400" MinWidth="830"> Title="Auszahlungsvarianten - Elwig" Height="480" Width="850" MinHeight="400" MinWidth="850">
<Window.DataContext>
<vm:PaymentVariantsViewModel/>
</Window.DataContext>
<Window.Resources> <Window.Resources>
<Style TargetType="Label"> <Style TargetType="Label">
<Setter Property="HorizontalAlignment" Value="Left"/> <Setter Property="HorizontalAlignment" Value="Left"/>
@@ -55,25 +59,25 @@
<Menu Grid.ColumnSpan="2" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> <Menu Grid.ColumnSpan="2" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White">
<MenuItem Header="Variantendaten"> <MenuItem Header="Variantendaten">
<MenuItem x:Name="Menu_SummaryShow" Header="...anzeigen (PDF)" IsEnabled="False" <MenuItem x:Name="Menu_SummaryShow" Header="...anzeigen (PDF)" IsEnabled="{Binding IsPaymentVariantSelected}"
Click="Menu_SummaryShow_Click" InputGestureText="Strg+P"> Click="Menu_SummaryShow_Click" InputGestureText="Strg+P">
<MenuItem.Icon> <MenuItem.Icon>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE8FF;"/> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE8FF;"/>
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem x:Name="Menu_SummarySave" Header="...speichern... (PDF)" IsEnabled="False" <MenuItem x:Name="Menu_SummarySave" Header="...speichern... (PDF)" IsEnabled="{Binding IsPaymentVariantSelected}"
Click="Menu_SummarySave_Click"> Click="Menu_SummarySave_Click">
<MenuItem.Icon> <MenuItem.Icon>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xEA90;"/> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xEA90;"/>
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem x:Name="Menu_SummaryExport" Header="...speichern... (Excel)" IsEnabled="False" <MenuItem x:Name="Menu_SummaryExport" Header="...speichern... (Excel)" IsEnabled="{Binding IsPaymentVariantSelected}"
Click="Menu_SummaryExport_Click"> Click="Menu_SummaryExport_Click">
<MenuItem.Icon> <MenuItem.Icon>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE9F9;"/> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE9F9;"/>
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem x:Name="Menu_SummaryPrint" Header="...drucken" IsEnabled="False" <MenuItem x:Name="Menu_SummaryPrint" Header="...drucken" IsEnabled="{Binding IsPaymentVariantSelected}"
Click="Menu_SummaryPrint_Click" InputGestureText="Strg+Shift+P"> Click="Menu_SummaryPrint_Click" InputGestureText="Strg+Shift+P">
<MenuItem.Icon> <MenuItem.Icon>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE749;"/> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE749;"/>
@@ -81,7 +85,7 @@
</MenuItem> </MenuItem>
</MenuItem> </MenuItem>
<MenuItem Header="Buchungsliste"> <MenuItem Header="Buchungsliste">
<MenuItem x:Name="Menu_ExportSave" Header="...speichern... (Excel)" IsEnabled="False" <MenuItem x:Name="Menu_ExportSave" Header="...speichern... (Excel)" IsEnabled="{Binding ExportIsEnabled}"
Click="Menu_ExportSave_Click" InputGestureText="Strg+L"> Click="Menu_ExportSave_Click" InputGestureText="Strg+L">
<MenuItem.Icon> <MenuItem.Icon>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE9F9;"/> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE9F9;"/>
@@ -89,7 +93,7 @@
</MenuItem> </MenuItem>
</MenuItem> </MenuItem>
<MenuItem Header="Überweisungsdaten"> <MenuItem Header="Überweisungsdaten">
<MenuItem x:Name="Menu_EbicsSave" Header="...exportieren... (EBICS)" IsEnabled="False" <MenuItem x:Name="Menu_EbicsSave" Header="...exportieren... (EBICS)" IsEnabled="{Binding ExportIsEnabled}"
Click="Menu_EbicsSave_Click" InputGestureText="Strg+Ü"> Click="Menu_EbicsSave_Click" InputGestureText="Strg+Ü">
<MenuItem.Icon> <MenuItem.Icon>
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE792;"/> <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="&#xE792;"/>
@@ -99,7 +103,9 @@
</Menu> </Menu>
<Grid Grid.Row="1"> <Grid Grid.Row="1">
<ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2" SelectionChanged="PaymentVariantList_SelectionChanged"> <ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2"
SelectionChanged="PaymentVariantList_SelectionChanged"
ItemsSource="{Binding PaymentVariants, Mode=TwoWay}" SelectedItem="{Binding SelectedPaymentVariant, Mode=TwoWay}">
<ListBox.ItemTemplate> <ListBox.ItemTemplate>
<DataTemplate> <DataTemplate>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -109,17 +115,21 @@
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox> </ListBox>
<Button x:Name="AddButton" Content="&#xF8AA;" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" ToolTip="Neue Auszahlungsvariante hinzufügen" <Button x:Name="AddButton"
Content="&#xF8AA;" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" ToolTip="Neue Auszahlungsvariante hinzufügen"
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,60" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,60" Grid.RowSpan="2"
Click="AddButton_Click"/> Click="AddButton_Click"/>
<Button x:Name="CopyButton" Content="&#xE8C8;" FontFamily="Segoe MDL2 Assets" FontSize="12" Padding="0,0,0,0" IsEnabled="False" ToolTip="Ausgewählte Auszahlungsvariante duplizieren" <Button x:Name="CopyButton" IsEnabled="{Binding IsPaymentVariantSelected}"
Content="&#xE8C8;" FontFamily="Segoe MDL2 Assets" FontSize="12" Padding="0,0,0,0" ToolTip="Ausgewählte Auszahlungsvariante duplizieren"
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,0" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,0" Grid.RowSpan="2"
Click="CopyButton_Click"/> Click="CopyButton_Click"/>
<Button x:Name="DeleteButton" Content="&#xF8AB;" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" IsEnabled="False" ToolTip="Ausgewählte Auszahlungsvariante löschen" <Button x:Name="DeleteButton" IsEnabled="{Binding DeleteIsEnabled}"
Content="&#xF8AB;" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" ToolTip="Ausgewählte Auszahlungsvariante löschen"
VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,60,5,0" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,60,5,0" Grid.RowSpan="2"
Click="DeleteButton_Click"/> Click="DeleteButton_Click"/>
<TextBox x:Name="DataInput" Margin="10,200,35,10" <TextBox x:Name="DataInput" Text="{Binding Data, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding DataIsReadOnly}"
Margin="10,200,35,10"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="auto"
AcceptsReturn="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
FontFamily="Cascadia Code Light" FontSize="13" FontFamily="Cascadia Code Light" FontSize="13"
@@ -133,23 +143,28 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Content="Name:" Margin="10,10,0,0" Grid.Column="0"/> <Label Content="Name:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="NameInput" Width="200" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0" <TextBox x:Name="NameInput" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}"
Width="200" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0"
TextChanged="NameInput_TextChanged"/> TextChanged="NameInput_TextChanged"/>
<Label Content="Beschreibung:" Margin="10,40,0,0" Grid.Column="0"/> <Label Content="Beschreibung:" Margin="10,40,0,0" Grid.Column="0"/>
<TextBox x:Name="CommentInput" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,40,10,0" <TextBox x:Name="CommentInput" Text="{Binding Comment, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}"
Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,40,10,0"
TextChanged="CommentInput_TextChanged"/> TextChanged="CommentInput_TextChanged"/>
<Label Content="Datum:" Margin="10,70,0,0" Grid.Column="0"/> <Label Content="Datum:" Margin="10,70,0,0" Grid.Column="0"/>
<TextBox x:Name="DateInput" Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,70,10,0" <TextBox x:Name="DateInput" Text="{Binding DateString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}"
Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,70,10,0"
TextChanged="DateInput_TextChanged"/> TextChanged="DateInput_TextChanged"/>
<Label Content="Überwiesen am:" Margin="10,100,0,0" Grid.Column="0"/> <Label Content="Überwiesen am:" Margin="10,100,0,0" Grid.Column="0"/>
<TextBox x:Name="TransferDateInput" Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,100,10,0" <TextBox x:Name="TransferDateInput" Text="{Binding TransferDateString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}"
Grid.Column="1" Width="77" HorizontalAlignment="Left" Margin="0,100,10,0"
TextChanged="TransferDateInput_TextChanged"/> TextChanged="TransferDateInput_TextChanged"/>
<Label Content="Rebelzuschlag:" Margin="10,130,0,0" Grid.Column="0"/> <Label Content="Rebelzuschlag:" Margin="10,130,0,0" Grid.Column="0"/>
<ctrl:UnitTextBox x:Name="WeightModifierInput" Grid.Column="1" Width="60" Margin="0,130,10,0" Unit="%" <ctrl:UnitTextBox x:Name="WeightModifierInput" Text="{Binding WeightModifierString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsReadOnly="{Binding IsReadOnly}"
Grid.Column="1" Width="60" Margin="0,130,10,0" Unit="%"
HorizontalAlignment="Left" VerticalAlignment="Top" HorizontalAlignment="Left" VerticalAlignment="Top"
TextChanged="WeightModifierInput_TextChanged" LostFocus="WeightModifierInput_LostFocus"/> TextChanged="WeightModifierInput_TextChanged" LostFocus="WeightModifierInput_LostFocus"/>
@@ -160,19 +175,24 @@
</TextBlock> </TextBlock>
<Label Content="Berücksichtigen:" Margin="90,70,10,10" Grid.Column="1"/> <Label Content="Berücksichtigen:" Margin="90,70,10,10" Grid.Column="1"/>
<CheckBox x:Name="ConsiderModifiersInput" Content="Zu-/Abschläge bei Lieferungen" <CheckBox x:Name="ConsiderModifiersInput" IsChecked="{Binding ConsiderModifiers, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}"
Content="Zu-/Abschläge bei Lieferungen (inkl. Rebelzuschl.)"
Margin="110,95,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="110,95,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="ConsiderModifiersInput_Changed" Unchecked="ConsiderModifiersInput_Changed"/> Checked="ConsiderModifiersInput_Changed" Unchecked="ConsiderModifiersInput_Changed"/>
<CheckBox x:Name="ConsiderPenaltiesInput" Content="Pönalen bei Unterlieferungen (FB)" <CheckBox x:Name="ConsiderPenaltiesInput" IsChecked="{Binding ConsiderPenalties, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}"
Content="Pönalen bei Unterlieferungen (FB)"
Margin="110,115,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="110,115,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="ConsiderPenaltiesInput_Changed" Unchecked="ConsiderPenaltiesInput_Changed"/> Checked="ConsiderPenaltiesInput_Changed" Unchecked="ConsiderPenaltiesInput_Changed"/>
<CheckBox x:Name="ConsiderPenaltyInput" Content="Strafen bei Unterlieferungen (GA)" <CheckBox x:Name="ConsiderPenaltyInput" IsChecked="{Binding ConsiderPenalty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}"
Content="Strafen bei Unterlieferungen (GA)"
Margin="110,135,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="110,135,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="ConsiderPenaltyInput_Changed" Unchecked="ConsiderPenaltyInput_Changed"/> Checked="ConsiderPenaltyInput_Changed" Unchecked="ConsiderPenaltyInput_Changed"/>
<CheckBox x:Name="ConsiderAutoInput" Content="Automatische Nachzeichnungen der GA" <CheckBox x:Name="ConsiderAutoInput" IsChecked="{Binding ConsiderAuto, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}"
Content="Automatische Nachzeichnungen der GA"
Margin="110,155,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="110,155,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="ConsiderAutoInput_Changed" Unchecked="ConsiderAutoInput_Changed"/> Checked="ConsiderAutoInput_Changed" Unchecked="ConsiderAutoInput_Changed"/>
<CheckBox x:Name="ConsiderCustomInput" Content="Benutzerdefinierte Zu-/Abschläge pro Mitglied" <CheckBox x:Name="ConsiderCustomInput" IsChecked="{Binding ConsiderCustom, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}"
Content="Benutzerdefinierte Zu-/Abschläge pro Mitglied"
Margin="110,175,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="110,175,10,10" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Top"
Checked="ConsiderCustomInput_Changed" Unchecked="ConsiderCustomInput_Changed"/> Checked="ConsiderCustomInput_Changed" Unchecked="ConsiderCustomInput_Changed"/>
<Label Content="&#xF0AE;" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="0" Grid.Column="1" Margin="108,195,10,10"/> <Label Content="&#xF0AE;" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="0" Grid.Column="1" Margin="108,195,10,10"/>
@@ -206,7 +226,8 @@
</Style> </Style>
</Grid.Resources> </Grid.Resources>
<Button x:Name="EditButton" Content="Bearbeiten" Grid.Column="0" Grid.Row="2" <Button x:Name="EditButton" IsEnabled="{Binding IsPaymentVariantSelected}"
Content="{Binding EditText}" Grid.Column="0" Grid.Row="2"
Click="EditButton_Click"/> Click="EditButton_Click"/>
<Label Content="&#xF0AF;" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="2" Grid.Column="1"/> <Label Content="&#xF0AF;" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="2" Grid.Column="1"/>
<Button x:Name="ModifierButton" Content="Zu-/Abschläge" Grid.Column="0" Grid.Row="4" <Button x:Name="ModifierButton" Content="Zu-/Abschläge" Grid.Column="0" Grid.Row="4"
@@ -219,12 +240,13 @@
</TransformGroup> </TransformGroup>
</Label.RenderTransform> </Label.RenderTransform>
</Label> </Label>
<Button x:Name="CalculateButton" Content="Berechnen" Grid.Column="2" Grid.Row="2" <Button x:Name="CalculateButton" IsEnabled="{Binding CalculateIsEnabled}"
Content="Berechnen" Grid.Column="2" Grid.Row="2"
Click="CalculateButton_Click"/> Click="CalculateButton_Click"/>
<Label Content="&#xF0AF;" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="2" Grid.Column="3" x:Name="Arrow3"/> <Label Content="{Binding Arrow}" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="2" Grid.Column="3"/>
<Button x:Name="PaymentAdjustmentButton" Content="Anpassen" Grid.Column="2" Grid.Row="4" <Button x:Name="PaymentAdjustmentButton" Content="Anpassen" Grid.Column="2" Grid.Row="4"
Click="PaymentAdjustmentButton_Click"/> Click="PaymentAdjustmentButton_Click"/>
<Label Content="&#xF0AF;" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="4" Grid.Column="3" x:Name="Arrow4" RenderTransformOrigin="0.5,0.5" > <Label Content="{Binding Arrow}" FontFamily="Segoe MDL2 Assets" FontSize="16" Grid.Row="4" Grid.Column="3" RenderTransformOrigin="0.5,0.5" >
<Label.RenderTransform> <Label.RenderTransform>
<TransformGroup> <TransformGroup>
<RotateTransform Angle="-45"/> <RotateTransform Angle="-45"/>
@@ -232,16 +254,19 @@
</TransformGroup> </TransformGroup>
</Label.RenderTransform> </Label.RenderTransform>
</Label> </Label>
<Button x:Name="CommitButton" Content="Festsetzen" Grid.Column="4" Grid.Row="2" <Button x:Name="CommitButton" IsEnabled="{Binding CommitIsEnabled}" Visibility="{Binding CommitVisibility}"
Content="Festsetzen" Grid.Column="4" Grid.Row="2"
Click="CommitButton_Click"/> Click="CommitButton_Click"/>
<Button x:Name="RevertButton" Content="Freigeben" Grid.Column="4" Grid.Row="2" <Button x:Name="RevertButton" IsEnabled="{Binding RevertIsEnabled}" Visibility="{Binding RevertVisibility}"
Content="Freigeben" Grid.Column="4" Grid.Row="2"
Click="RevertButton_Click"/> Click="RevertButton_Click"/>
<Button x:Name="SaveButton" Content="Speichern" Grid.Column="4" Grid.Row="0" <Button x:Name="SaveButton" IsEnabled="{Binding SaveIsEnabled}"
Content="Speichern" Grid.Column="4" Grid.Row="0"
Click="SaveButton_Click"/> Click="SaveButton_Click"/>
</Grid> </Grid>
<Button x:Name="MailButton" <Button x:Name="MailButton" IsEnabled="{Binding IsPaymentVariantSelected}"
FontSize="14" Width="180" Margin="10,10,10,10" Height="30" IsEnabled="False" FontSize="14" Width="180" Margin="10,10,10,10" Height="30"
Click="MailButton_Click" Click="MailButton_Click"
VerticalAlignment="Bottom" HorizontalAlignment="Right" HorizontalContentAlignment="Stretch" Grid.Column="1"> VerticalAlignment="Bottom" HorizontalAlignment="Right" HorizontalContentAlignment="Stretch" Grid.Column="1">
<Grid> <Grid>
@@ -273,35 +298,35 @@
<StatusBarItem Grid.Column="0" HorizontalContentAlignment="Stretch"> <StatusBarItem Grid.Column="0" HorizontalContentAlignment="Stretch">
<DockPanel> <DockPanel>
<TextBlock Text="Zu-/Abschl.:"/> <TextBlock Text="Zu-/Abschl.:"/>
<TextBlock x:Name="ModifierSum" Text="-" TextAlignment="Right"/> <TextBlock Text="{Binding StatusModifierSum}" TextAlignment="Right"/>
</DockPanel> </DockPanel>
</StatusBarItem> </StatusBarItem>
<Separator Grid.Column="1"/> <Separator Grid.Column="1"/>
<StatusBarItem Grid.Column="2" HorizontalContentAlignment="Stretch"> <StatusBarItem Grid.Column="2" HorizontalContentAlignment="Stretch">
<DockPanel> <DockPanel>
<TextBlock Text="Gesamt:"/> <TextBlock Text="Gesamt:"/>
<TextBlock x:Name="TotalSum" Text="-" TextAlignment="Right"/> <TextBlock Text="{Binding StatusTotalSum}" TextAlignment="Right"/>
</DockPanel> </DockPanel>
</StatusBarItem> </StatusBarItem>
<Separator Grid.Column="3"/> <Separator Grid.Column="3"/>
<StatusBarItem Grid.Column="4" HorizontalContentAlignment="Stretch"> <StatusBarItem Grid.Column="4" HorizontalContentAlignment="Stretch">
<DockPanel> <DockPanel>
<TextBlock Text="MwSt.:"/> <TextBlock Text="MwSt.:"/>
<TextBlock x:Name="VatSum" Text="-" TextAlignment="Right"/> <TextBlock Text="{Binding StatusVatSum}" TextAlignment="Right"/>
</DockPanel> </DockPanel>
</StatusBarItem> </StatusBarItem>
<Separator Grid.Column="5"/> <Separator Grid.Column="5"/>
<StatusBarItem Grid.Column="6" HorizontalContentAlignment="Stretch"> <StatusBarItem Grid.Column="6" HorizontalContentAlignment="Stretch">
<DockPanel> <DockPanel>
<TextBlock Text="Abzüge:"/> <TextBlock Text="Abzüge:"/>
<TextBlock x:Name="DeductionSum" Text="-" TextAlignment="Right"/> <TextBlock Text="{Binding StatusDeductionSum}" TextAlignment="Right"/>
</DockPanel> </DockPanel>
</StatusBarItem> </StatusBarItem>
<Separator Grid.Column="7"/> <Separator Grid.Column="7"/>
<StatusBarItem Grid.Column="8" HorizontalContentAlignment="Stretch"> <StatusBarItem Grid.Column="8" HorizontalContentAlignment="Stretch">
<DockPanel> <DockPanel>
<TextBlock Text="Auszahl.:"/> <TextBlock Text="Auszahl.:"/>
<TextBlock x:Name="PaymentSum" Text="-" TextAlignment="Right"/> <TextBlock Text="{Binding StatusPaymentSum}" TextAlignment="Right"/>
</DockPanel> </DockPanel>
</StatusBarItem> </StatusBarItem>
</StatusBar> </StatusBar>

View File

@@ -1,29 +1,27 @@
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Helpers.Billing;
using Elwig.Helpers.Export;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Elwig.Models.Entities; using Elwig.Models.Entities;
using Elwig.Services;
using Elwig.ViewModels;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using System; using System;
using System.Linq; using System.Linq;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input; using System.Windows.Input;
using Elwig.Helpers.Billing;
using Elwig.Helpers.Export;
using Microsoft.Win32;
using System.Text.Json;
using Elwig.Documents;
namespace Elwig.Windows { namespace Elwig.Windows {
public partial class PaymentVariantsWindow : ContextWindow { public partial class PaymentVariantsWindow : ContextWindow {
public readonly int Year; public PaymentVariantsViewModel ViewModel => (PaymentVariantsViewModel)DataContext;
public readonly bool SeasonLocked;
private bool DataValid, DataChanged, NameChanged, CommentChanged, DateValid, DateChanged, TransferDateValid, TransferDateChanged;
private BillingData? BillingData;
private bool WeightModifierChanged = false;
private static readonly JsonSerializerOptions JsonOpt = new() { WriteIndented = true }; public readonly int Year;
private bool DataValid, DataChanged, NameChanged, CommentChanged, DateValid, DateChanged, TransferDateValid, TransferDateChanged;
private readonly RoutedCommand CtrlL = new("CtrlL", typeof(MemberAdminWindow), [new KeyGesture(Key.L, ModifierKeys.Control)]); private readonly RoutedCommand CtrlL = new("CtrlL", typeof(MemberAdminWindow), [new KeyGesture(Key.L, ModifierKeys.Control)]);
private readonly RoutedCommand CtrlP = new("CtrlP", typeof(MemberAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control)]); private readonly RoutedCommand CtrlP = new("CtrlP", typeof(MemberAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control)]);
@@ -38,7 +36,7 @@ namespace Elwig.Windows {
CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_SummaryPrint_Click)); CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_SummaryPrint_Click));
Year = year; Year = year;
using (var ctx = new AppDbContext()) { using (var ctx = new AppDbContext()) {
SeasonLocked = ctx.Seasons.Find(Year + 1) != null; ViewModel.SeasonLocked = ctx.Seasons.Find(Year + 1) != null;
} }
Title = $"Auszahlungsvarianten - Lese {Year} - Elwig"; Title = $"Auszahlungsvarianten - Lese {Year} - Elwig";
if (!App.Config.Debug) { if (!App.Config.Debug) {
@@ -57,257 +55,95 @@ namespace Elwig.Windows {
.OrderBy(v => v.AvNr) .OrderBy(v => v.AvNr)
.Include(v => v.Season.Currency) .Include(v => v.Season.Currency)
.ToListAsync()); .ToListAsync());
await Update(); Update();
} }
private async Task Update() { private void Update() {
if (PaymentVariantList.SelectedItem is PaymentVar v) { if (PaymentVariantList.SelectedItem is PaymentVar v) {
var locked = !v.TestVariant; ViewModel.FillInputs(v);
DeleteButton.IsEnabled = !locked;
CalculateButton.IsEnabled = !locked;
CommitButton.IsEnabled = !locked && !SeasonLocked;
CommitButton.Visibility = !locked ? Visibility.Visible : Visibility.Hidden;
RevertButton.IsEnabled = locked && !SeasonLocked;
RevertButton.Visibility = locked ? Visibility.Visible : Visibility.Hidden;
Arrow3.Content = locked ? "\xF0B0" : "\xF0AF";
Arrow4.Content = locked ? "\xF0B0" : "\xF0AF";
CopyButton.IsEnabled = true;
EditButton.Content = locked ? "Ansehen" : "Bearbeiten";
EditButton.IsEnabled = true;
SaveButton.IsEnabled = !locked;
MailButton.IsEnabled = true;
Menu_ExportSave.IsEnabled = locked;
Menu_EbicsSave.IsEnabled = locked;
Menu_SummaryExport.IsEnabled = true;
Menu_SummaryShow.IsEnabled = true;
Menu_SummarySave.IsEnabled = true;
Menu_SummaryPrint.IsEnabled = true;
NameInput.Text = v.Name;
NameInput.IsReadOnly = false;
CommentInput.Text = v.Comment;
CommentInput.IsReadOnly = false;
DateInput.Text = $"{v.Date:dd.MM.yyyy}";
DateInput.IsReadOnly = false;
TransferDateInput.Text = $"{v.TransferDate:dd.MM.yyyy}";
TransferDateInput.IsReadOnly = false;
try {
BillingData = BillingData.FromJson(v.Data);
ConsiderModifiersInput.IsChecked = BillingData.ConsiderDelieryModifiers;
ConsiderPenaltiesInput.IsChecked = BillingData.ConsiderContractPenalties;
ConsiderPenaltyInput.IsChecked = BillingData.ConsiderTotalPenalty;
ConsiderAutoInput.IsChecked = BillingData.ConsiderAutoBusinessShares;
ConsiderCustomInput.IsChecked = BillingData.ConsiderCustomModifiers;
if (BillingData.NetWeightModifier != 0) {
WeightModifierInput.Text = $"{Math.Round(BillingData.NetWeightModifier * 100.0, 8)}";
} else if (BillingData.GrossWeightModifier != 0) {
WeightModifierInput.Text = $"{Math.Round(BillingData.GrossWeightModifier * 100.0, 8)}";
} else { } else {
WeightModifierInput.Text = ""; ViewModel.ClearInputs();
} }
DataInput.Text = JsonSerializer.Serialize(BillingData.Data, JsonOpt); UpdateButtons();
} catch {
BillingData = null;
ConsiderModifiersInput.IsChecked = false;
ConsiderPenaltiesInput.IsChecked = false;
ConsiderPenaltyInput.IsChecked = false;
ConsiderAutoInput.IsChecked = false;
ConsiderCustomInput.IsChecked = false;
WeightModifierInput.Text = "";
DataInput.Text = v.Data;
}
WeightModifierInput.IsReadOnly = false;
ConsiderModifiersInput.IsEnabled = !locked;
ConsiderPenaltiesInput.IsEnabled = !locked;
ConsiderPenaltyInput.IsEnabled = !locked;
ConsiderAutoInput.IsEnabled = !locked;
ConsiderCustomInput.IsEnabled = !locked;
DataInput.IsReadOnly = locked;
} else {
EditButton.Content = "Bearbeiten";
EditButton.IsEnabled = false;
SaveButton.IsEnabled = false;
CopyButton.IsEnabled = false;
CalculateButton.IsEnabled = false;
CommitButton.IsEnabled = false;
CommitButton.Visibility = Visibility.Visible;
RevertButton.IsEnabled = false;
RevertButton.Visibility = Visibility.Hidden;
Arrow3.Content = "\xF0AF";
Arrow4.Content = "\xF0AF";
DeleteButton.IsEnabled = false;
MailButton.IsEnabled = false;
Menu_ExportSave.IsEnabled = false;
Menu_EbicsSave.IsEnabled = false;
Menu_SummaryExport.IsEnabled = false;
Menu_SummaryShow.IsEnabled = false;
Menu_SummarySave.IsEnabled = false;
Menu_SummaryPrint.IsEnabled = false;
BillingData = null;
NameInput.Text = "";
NameInput.IsReadOnly = true;
CommentInput.Text = "";
CommentInput.IsReadOnly = true;
DateInput.Text = "";
DateInput.IsReadOnly = true;
TransferDateInput.Text = "";
TransferDateInput.IsReadOnly = true;
WeightModifierInput.Text = "";
WeightModifierInput.IsReadOnly = true;
ConsiderModifiersInput.IsChecked = false;
ConsiderModifiersInput.IsEnabled = false;
ConsiderPenaltiesInput.IsChecked = false;
ConsiderPenaltiesInput.IsEnabled = false;
ConsiderPenaltyInput.IsChecked = false;
ConsiderPenaltyInput.IsEnabled = false;
ConsiderAutoInput.IsChecked = false;
ConsiderAutoInput.IsEnabled = false;
ConsiderCustomInput.IsChecked = false;
ConsiderCustomInput.IsEnabled = false;
DataInput.Text = "";
DataInput.IsReadOnly = true;
}
await UpdateSums();
UpdateSaveButton();
} }
private void UpdateSaveButton() { private void UpdateButtons() {
SaveButton.IsEnabled = PaymentVariantList.SelectedItem != null && ViewModel.SaveIsEnabled = PaymentVariantList.SelectedItem != null &&
((DataChanged && DataValid) || NameChanged || CommentChanged || ((DataChanged && DataValid) || NameChanged || CommentChanged ||
(DateChanged && DateValid) || (DateChanged && DateValid) ||
(TransferDateChanged && TransferDateValid) || (TransferDateChanged && TransferDateValid) ||
(ConsiderModifiersInput.IsChecked != BillingData?.ConsiderDelieryModifiers) || (ViewModel.ConsiderModifiers != ViewModel.BillingData?.ConsiderDelieryModifiers) ||
(ConsiderPenaltiesInput.IsChecked != BillingData?.ConsiderContractPenalties) || (ViewModel.ConsiderPenalties != ViewModel.BillingData?.ConsiderContractPenalties) ||
(ConsiderPenaltyInput.IsChecked != BillingData?.ConsiderTotalPenalty) || (ViewModel.ConsiderPenalty != ViewModel.BillingData?.ConsiderTotalPenalty) ||
(ConsiderAutoInput.IsChecked != BillingData?.ConsiderAutoBusinessShares) || (ViewModel.ConsiderAuto != ViewModel.BillingData?.ConsiderAutoBusinessShares) ||
(ConsiderCustomInput.IsChecked != BillingData?.ConsiderCustomModifiers) || (ViewModel.ConsiderCustom != ViewModel.BillingData?.ConsiderCustomModifiers) ||
WeightModifierChanged); ViewModel.WeightModifierChanged);
CalculateButton.IsEnabled = !SaveButton.IsEnabled && PaymentVariantList.SelectedItem is PaymentVar { TestVariant: true }; ViewModel.CalculateIsEnabled = !ViewModel.SaveIsEnabled && PaymentVariantList.SelectedItem is PaymentVar { TestVariant: true };
CommitButton.IsEnabled = CalculateButton.IsEnabled; ViewModel.CommitIsEnabled = ViewModel.CalculateIsEnabled;
} }
private async Task UpdateSums() { private void PaymentVariantList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
if (PaymentVariantList.SelectedItem is PaymentVar v) { Update();
using var ctx = new AppDbContext();
var sym = v.Season.Currency.Symbol ?? v.Season.Currency.Code;
var modSum = await ctx.PaymentDeliveryParts
.Where(p => p.Year == v.Year && p.AvNr == v.AvNr)
.SumAsync(p => p.AmountValue - p.NetAmountValue);
ModifierSum.Text = $"{v.Season.DecFromDb(modSum):N2} {sym}";
var totalSum = await ctx.MemberPayments
.Where(p => p.Year == v.Year && p.AvNr == v.AvNr)
.SumAsync(p => p.AmountValue);
TotalSum.Text = $"{v.Season.DecFromDb(totalSum):N2} {sym}";
var credits = ctx.Credits.Where(c => c.Year == v.Year && c.AvNr == v.AvNr);
if (!credits.Any()) {
VatSum.Text = $"- {sym}";
DeductionSum.Text = $"- {sym}";
PaymentSum.Text = $"- {sym}";
} else {
// all values in the credit table are stored with precision 2!
TotalSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.NetAmountValue), 2):N2} {sym}";
VatSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.VatAmountValue), 2):N2} {sym}";
DeductionSum.Text = $"{-Utils.DecFromDb(await credits.SumAsync(c => c.ModifiersValue ?? 0), 2):N2} {sym}";
PaymentSum.Text = $"{Utils.DecFromDb(await credits.SumAsync(c => c.AmountValue), 2):N2} {sym}";
}
} else {
ModifierSum.Text = "-";
TotalSum.Text = "-";
VatSum.Text = "-";
DeductionSum.Text = "-";
PaymentSum.Text = "-";
}
}
private async void PaymentVariantList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
await Update();
} }
private async void AddButton_Click(object sender, RoutedEventArgs evt) { private async void AddButton_Click(object sender, RoutedEventArgs evt) {
Mouse.OverrideCursor = Cursors.Wait;
try { try {
PaymentVar? v; var v = await PaymentVariantService.CreatePaymentVariant(Year);
using (var ctx = new AppDbContext()) {
v = new PaymentVar {
Year = Year,
AvNr = await ctx.NextAvNr(Year),
Name = "Neue Auszahlungsvariante",
TestVariant = true,
DateString = $"{DateTime.Today:yyyy-MM-dd}",
Data = "{\"mode\": \"elwig\", \"version\": 1, \"payment\": {}, \"curves\": []}",
};
ctx.Add(v);
await ctx.SaveChangesAsync();
}
App.HintContextChange(); App.HintContextChange();
ControlUtils.SelectItem(PaymentVariantList, v); ControlUtils.SelectItem(PaymentVariantList, v);
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante erstellen", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Auszahlungsvariante erstellen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null;
} }
private async void CopyButton_Click(object sender, RoutedEventArgs evt) { private async void CopyButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar orig) return; if (PaymentVariantList.SelectedItem is not PaymentVar orig)
return;
Mouse.OverrideCursor = Cursors.Wait;
try { try {
PaymentVar? n; PaymentVar n = await orig.Duplicate();
using (var ctx = new AppDbContext()) {
n = new PaymentVar {
Year = orig.Year,
AvNr = await ctx.NextAvNr(Year),
Name = $"{orig.Name} (Kopie)",
TestVariant = true,
DateString = $"{DateTime.Today:yyyy-MM-dd}",
Data = orig.Data,
};
ctx.Add(n);
await ctx.SaveChangesAsync();
}
App.HintContextChange(); App.HintContextChange();
ControlUtils.SelectItem(PaymentVariantList, n); ControlUtils.SelectItem(PaymentVariantList, n);
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante kopieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Auszahlungsvariante kopieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null;
} }
private async void DeleteButton_Click(object sender, RoutedEventArgs evt) { private async void DeleteButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v || !v.TestVariant) return; if (PaymentVariantList.SelectedItem is not PaymentVar v || !v.TestVariant)
return;
Mouse.OverrideCursor = Cursors.Wait;
try { try {
using (var ctx = new AppDbContext()) { await PaymentVariantService.DeletePaymentVariant(v.Year, v.AvNr);
ctx.Remove(v);
await ctx.SaveChangesAsync();
}
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante löschen", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Auszahlungsvariante löschen", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null;
} }
private async void CalculateButton_Click(object sender, RoutedEventArgs evt) { private async void CalculateButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
CalculateButton.IsEnabled = false; ViewModel.CalculateIsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
var b = new BillingVariant(v.Year, v.AvNr); await PaymentVariantService.Calculate(v.Year, v.AvNr);
await b.Calculate(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Berechnungsfehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Berechnungsfehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
App.HintContextChange();
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
CalculateButton.IsEnabled = true; ViewModel.CalculateIsEnabled = true;
} }
private void EditButton_Click(object sender, RoutedEventArgs evt) { private void EditButton_Click(object sender, RoutedEventArgs evt) {
@@ -336,71 +172,40 @@ namespace Elwig.Windows {
private async void Menu_SummaryExport_Click(object sender, RoutedEventArgs evt) { private async void Menu_SummaryExport_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
var d = new SaveFileDialog() { await PaymentVariantService.GenerateSummary(v, ExportMode.SaveList);
FileName = $"Variantendaten-{v.Name.Trim().Replace(' ', '-')}.ods",
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Variantendaten {v.Name} speichern unter - Elwig"
};
if (d.ShowDialog() == false)
return;
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ctx = new AppDbContext();
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(data);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
} }
private async void Menu_SummaryShow_Click(object sender, RoutedEventArgs evt) { private async void Menu_SummaryShow_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
await GenerateSummary(v, ExportMode.Show); await PaymentVariantService.GenerateSummary(v, ExportMode.Show);
} }
private async void Menu_SummarySave_Click(object sender, RoutedEventArgs evt) { private async void Menu_SummarySave_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
await GenerateSummary(v, ExportMode.SavePdf); await PaymentVariantService.GenerateSummary(v, ExportMode.SavePdf);
} }
private async void Menu_SummaryPrint_Click(object sender, RoutedEventArgs evt) { private async void Menu_SummaryPrint_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
await GenerateSummary(v, ExportMode.Print); await PaymentVariantService.GenerateSummary(v, ExportMode.Print);
}
private static async Task GenerateSummary(PaymentVar v, ExportMode mode) {
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ctx = new AppDbContext();
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var doc = new PaymentVariantSummary((await ctx.PaymentVariants.FindAsync(v.Year, v.AvNr))!, data);
await Utils.ExportDocument(doc, mode);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
} }
private async void CommitButton_Click(object sender, RoutedEventArgs evt) { private async void CommitButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
CommitButton.IsEnabled = false; ViewModel.CommitIsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
try { try {
var b = new BillingVariant(v.Year, v.AvNr); await PaymentVariantService.Commit(v.Year, v.AvNr);
await b.Commit(); App.HintContextChange();
} catch (Exception exc) { } catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
RevertButton.IsEnabled = true; ViewModel.RevertIsEnabled = true;
App.HintContextChange();
} }
private async void RevertButton_Click(object sender, RoutedEventArgs evt) { private async void RevertButton_Click(object sender, RoutedEventArgs evt) {
@@ -412,13 +217,16 @@ namespace Elwig.Windows {
"Traubengutschriften löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); "Traubengutschriften löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
if (res != MessageBoxResult.Yes) if (res != MessageBoxResult.Yes)
return; return;
RevertButton.IsEnabled = false; ViewModel.RevertIsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting; Mouse.OverrideCursor = Cursors.Wait;
var b = new BillingVariant(v.Year, v.AvNr); try {
await b.Revert(); await PaymentVariantService.Revert(v.Year, v.AvNr);
App.HintContextChange(); App.HintContextChange();
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null; Mouse.OverrideCursor = null;
CommitButton.IsEnabled = true; ViewModel.CommitIsEnabled = true;
} }
private async void Menu_EbicsSave_Click(object sender, RoutedEventArgs evt) { private async void Menu_EbicsSave_Click(object sender, RoutedEventArgs evt) {
@@ -428,107 +236,39 @@ namespace Elwig.Windows {
MessageBox.Show("Überweisungsdatum muss gesetzt sein!", "Exportieren nicht möglich", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show("Überweisungsdatum muss gesetzt sein!", "Exportieren nicht möglich", MessageBoxButton.OK, MessageBoxImage.Error);
return; return;
} }
await PaymentVariantService.GenerateEbics(v.Year, v.AvNr);
using var ctx = new AppDbContext();
v = (await ctx.PaymentVariants.FindAsync(v.Year, v.AvNr))!;
var withoutIban = v.Credits.Count(c => c.Member.Iban == null);
if (withoutIban > 0) {
var r = MessageBox.Show($"Achtung: Für {withoutIban:N0} Mitglieder ist kein IBAN hinterlegt.\n\nDiese werden NICHT exportiert.",
"Mitglieder ohne IBAN", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
if (r != MessageBoxResult.OK) return;
}
var withNegAmount = v.Credits.Count(c => c.Amount <= 0);
if (withNegAmount > 0) {
var r = MessageBox.Show($"Achtung: Es gibt {withNegAmount:N0} Traubengutschriften mit negativem Betrag.\n\nDiese werden NICHT exportiert.",
"Traubengutschriften mit negativem Betrag", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.OK);
if (r != MessageBoxResult.OK) return;
}
var d = new SaveFileDialog() {
FileName = $"{App.Client.NameToken}-Überweisungsdaten-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.{Ebics.FileExtension}",
DefaultExt = Ebics.FileExtension,
Filter = "EBICS-Datei (*.xml)|*.xml",
Title = $"Überweisungsdaten speichern unter - Elwig",
};
if (d.ShowDialog() == true) {
Menu_EbicsSave.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var e = new Ebics(v, d.FileName, App.Client.ExportEbicsVersion, (Ebics.AddressMode)App.Client.ExportEbicsAddress);
await e.ExportAsync(Transaction.FromPaymentVariant(v));
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
Menu_EbicsSave.IsEnabled = true;
}
} }
private async void Menu_ExportSave_Click(object sender, RoutedEventArgs evt) { private async void Menu_ExportSave_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) { if (PaymentVariantList.SelectedItem is not PaymentVar v)
return; return;
} await PaymentVariantService.GenerateAccountingList(v.Year, v.AvNr, v.Name);
var d = new SaveFileDialog() {
FileName = $"{App.Client.NameToken}-Buchungsliste-{v.Year}-{v.Name.Trim().Replace(' ', '-')}.ods",
DefaultExt = "ods",
Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods",
Title = $"Buchungsliste speichern unter - Elwig"
};
if (d.ShowDialog() == true) {
Menu_ExportSave.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
try {
using var ctx = new AppDbContext();
var tbl = await CreditNoteData.ForPaymentVariant(ctx, v.Year, v.AvNr);
using var ods = new OdsFile(d.FileName);
await ods.AddTable(tbl);
} catch (Exception exc) {
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
}
Mouse.OverrideCursor = null;
Menu_ExportSave.IsEnabled = true;
}
} }
private async void SaveButton_Click(object sender, RoutedEventArgs evt) { private async void SaveButton_Click(object sender, RoutedEventArgs evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v || BillingData == null) return; if (PaymentVariantList.SelectedItem is not PaymentVar v || ViewModel.BillingData == null)
return;
Mouse.OverrideCursor = Cursors.Wait;
try { try {
v.Name = NameInput.Text; await ViewModel.UpdatePaymentVariant(v.Year, v.AvNr);
v.Comment = (CommentInput.Text != "") ? CommentInput.Text : null;
v.DateString = string.Join("-", DateInput.Text.Split(".").Reverse());
v.TransferDateString = (TransferDateInput.Text != "") ? string.Join("-", TransferDateInput.Text.Split(".").Reverse()) : null;
var d = App.Config.Debug ? BillingData.FromJson(DataInput.Text) : BillingData;
d.ConsiderDelieryModifiers = ConsiderModifiersInput.IsChecked ?? false;
d.ConsiderContractPenalties = ConsiderPenaltiesInput.IsChecked ?? false;
d.ConsiderTotalPenalty = ConsiderPenaltyInput.IsChecked ?? false;
d.ConsiderAutoBusinessShares = ConsiderAutoInput.IsChecked ?? false;
d.ConsiderCustomModifiers = ConsiderCustomInput.IsChecked ?? false;
var modVal = WeightModifierInput.Text.Length > 0 ? double.Parse(WeightModifierInput.Text) : 0;
d.NetWeightModifier = modVal > 0 ? modVal / 100.0 : 0;
d.GrossWeightModifier = modVal < 0 ? modVal / 100.0 : 0;
WeightModifierChanged = false;
v.Data = JsonSerializer.Serialize(d.Data);
using (var ctx = new AppDbContext()) {
ctx.Update(v);
await ctx.SaveChangesAsync();
}
App.HintContextChange(); App.HintContextChange();
CommentInput_TextChanged(null, null);
ConsiderModifiersInput_Changed(null, null);
ConsiderPenaltiesInput_Changed(null, null);
ConsiderPenaltyInput_Changed(null, null);
ConsiderAutoInput_Changed(null, null);
ConsiderCustomInput_Changed(null, null);
WeightModifierInput_TextChanged(null, null);
} catch (Exception exc) { } catch (Exception exc) {
await HintContextChange(); await HintContextChange();
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
MessageBox.Show(str, "Auszahlungsvariante aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show(str, "Auszahlungsvariante aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
} }
Mouse.OverrideCursor = null;
await HintContextChange();
CommentInput_TextChanged(null, null);
DateInput_TextChanged(null, null);
TransferDateInput_TextChanged(null, null);
ConsiderModifiersInput_Changed(null, null);
ConsiderPenaltiesInput_Changed(null, null);
ConsiderPenaltyInput_Changed(null, null);
ConsiderAutoInput_Changed(null, null);
ConsiderCustomInput_Changed(null, null);
WeightModifierInput_TextChanged(null, null);
} }
private void ModifierButton_Click(object sender, RoutedEventArgs evt) { private void ModifierButton_Click(object sender, RoutedEventArgs evt) {
@@ -547,7 +287,7 @@ namespace Elwig.Windows {
ControlUtils.ClearInputState(NameInput); ControlUtils.ClearInputState(NameInput);
NameChanged = false; NameChanged = false;
} }
UpdateSaveButton(); UpdateButtons();
} }
private void CommentInput_TextChanged(object? sender, TextChangedEventArgs? evt) { private void CommentInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
@@ -562,10 +302,10 @@ namespace Elwig.Windows {
ControlUtils.ClearInputState(CommentInput); ControlUtils.ClearInputState(CommentInput);
CommentChanged = false; CommentChanged = false;
} }
UpdateSaveButton(); UpdateButtons();
} }
private void DateInput_TextChanged(object sender, TextChangedEventArgs evt) { private void DateInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) { if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(DateInput); ControlUtils.ClearInputState(DateInput);
return; return;
@@ -583,10 +323,10 @@ namespace Elwig.Windows {
DateValid = true; DateValid = true;
DateChanged = false; DateChanged = false;
} }
UpdateSaveButton(); UpdateButtons();
} }
private void TransferDateInput_TextChanged(object sender, TextChangedEventArgs evt) { private void TransferDateInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
if (PaymentVariantList.SelectedItem is not PaymentVar v) { if (PaymentVariantList.SelectedItem is not PaymentVar v) {
ControlUtils.ClearInputState(TransferDateInput); ControlUtils.ClearInputState(TransferDateInput);
return; return;
@@ -604,7 +344,7 @@ namespace Elwig.Windows {
TransferDateValid = true; TransferDateValid = true;
TransferDateChanged = false; TransferDateChanged = false;
} }
UpdateSaveButton(); UpdateButtons();
} }
private void DataInput_TextChanged(object sender, TextChangedEventArgs evt) { private void DataInput_TextChanged(object sender, TextChangedEventArgs evt) {
@@ -630,89 +370,89 @@ namespace Elwig.Windows {
ControlUtils.SetInputInvalid(DataInput); ControlUtils.SetInputInvalid(DataInput);
DataValid = false; DataValid = false;
} }
UpdateSaveButton(); UpdateButtons();
} }
private void ConsiderModifiersInput_Changed(object? sender, RoutedEventArgs? evt) { private void ConsiderModifiersInput_Changed(object? sender, RoutedEventArgs? evt) {
if (BillingData == null) { if (ViewModel.BillingData == null) {
ControlUtils.ClearInputState(ConsiderModifiersInput); ControlUtils.ClearInputState(ConsiderModifiersInput);
return; return;
} }
if (BillingData.ConsiderDelieryModifiers != ConsiderModifiersInput.IsChecked) { if (ViewModel.BillingData.ConsiderDelieryModifiers != ConsiderModifiersInput.IsChecked) {
ControlUtils.SetInputChanged(ConsiderModifiersInput); ControlUtils.SetInputChanged(ConsiderModifiersInput);
} else { } else {
ControlUtils.ClearInputState(ConsiderModifiersInput); ControlUtils.ClearInputState(ConsiderModifiersInput);
} }
UpdateSaveButton(); UpdateButtons();
} }
private void ConsiderPenaltiesInput_Changed(object? sender, RoutedEventArgs? evt) { private void ConsiderPenaltiesInput_Changed(object? sender, RoutedEventArgs? evt) {
if (BillingData == null) { if (ViewModel.BillingData == null) {
ControlUtils.ClearInputState(ConsiderPenaltiesInput); ControlUtils.ClearInputState(ConsiderPenaltiesInput);
return; return;
} }
if (BillingData.ConsiderContractPenalties != ConsiderPenaltiesInput.IsChecked) { if (ViewModel.BillingData.ConsiderContractPenalties != ConsiderPenaltiesInput.IsChecked) {
ControlUtils.SetInputChanged(ConsiderPenaltiesInput); ControlUtils.SetInputChanged(ConsiderPenaltiesInput);
} else { } else {
ControlUtils.ClearInputState(ConsiderPenaltiesInput); ControlUtils.ClearInputState(ConsiderPenaltiesInput);
} }
UpdateSaveButton(); UpdateButtons();
} }
private void ConsiderPenaltyInput_Changed(object? sender, RoutedEventArgs? evt) { private void ConsiderPenaltyInput_Changed(object? sender, RoutedEventArgs? evt) {
if (BillingData == null) { if (ViewModel.BillingData == null) {
ControlUtils.ClearInputState(ConsiderPenaltyInput); ControlUtils.ClearInputState(ConsiderPenaltyInput);
return; return;
} }
if (BillingData.ConsiderTotalPenalty != ConsiderPenaltyInput.IsChecked) { if (ViewModel.BillingData.ConsiderTotalPenalty != ConsiderPenaltyInput.IsChecked) {
ControlUtils.SetInputChanged(ConsiderPenaltyInput); ControlUtils.SetInputChanged(ConsiderPenaltyInput);
} else { } else {
ControlUtils.ClearInputState(ConsiderPenaltyInput); ControlUtils.ClearInputState(ConsiderPenaltyInput);
} }
UpdateSaveButton(); UpdateButtons();
} }
private void ConsiderAutoInput_Changed(object? sender, RoutedEventArgs? evt) { private void ConsiderAutoInput_Changed(object? sender, RoutedEventArgs? evt) {
if (BillingData == null) { if (ViewModel.BillingData == null) {
ControlUtils.ClearInputState(ConsiderAutoInput); ControlUtils.ClearInputState(ConsiderAutoInput);
return; return;
} }
if (BillingData.ConsiderAutoBusinessShares != ConsiderAutoInput.IsChecked) { if (ViewModel.BillingData.ConsiderAutoBusinessShares != ConsiderAutoInput.IsChecked) {
ControlUtils.SetInputChanged(ConsiderAutoInput); ControlUtils.SetInputChanged(ConsiderAutoInput);
} else { } else {
ControlUtils.ClearInputState(ConsiderAutoInput); ControlUtils.ClearInputState(ConsiderAutoInput);
} }
UpdateSaveButton(); UpdateButtons();
} }
private void ConsiderCustomInput_Changed(object? sender, RoutedEventArgs? evt) { private void ConsiderCustomInput_Changed(object? sender, RoutedEventArgs? evt) {
if (BillingData == null) { if (ViewModel.BillingData == null) {
ControlUtils.ClearInputState(ConsiderCustomInput); ControlUtils.ClearInputState(ConsiderCustomInput);
return; return;
} }
if (BillingData.ConsiderCustomModifiers != ConsiderCustomInput.IsChecked) { if (ViewModel.BillingData.ConsiderCustomModifiers != ConsiderCustomInput.IsChecked) {
ControlUtils.SetInputChanged(ConsiderCustomInput); ControlUtils.SetInputChanged(ConsiderCustomInput);
} else { } else {
ControlUtils.ClearInputState(ConsiderCustomInput); ControlUtils.ClearInputState(ConsiderCustomInput);
} }
UpdateSaveButton(); UpdateButtons();
} }
private void WeightModifierInput_TextChanged(object? sender, TextChangedEventArgs? evt) { private void WeightModifierInput_TextChanged(object? sender, TextChangedEventArgs? evt) {
var res = Validator.CheckDecimal(WeightModifierInput, false, 3, 2, true); var res = Validator.CheckDecimal(WeightModifierInput, false, 3, 2, true);
if (BillingData == null) { if (ViewModel.BillingData == null) {
ControlUtils.ClearInputState(WeightModifierInput); ControlUtils.ClearInputState(WeightModifierInput);
return; return;
} }
var val = WeightModifierInput.Text.Length > 0 && res.IsValid ? double.Parse(WeightModifierInput.Text) : 0; var val = WeightModifierInput.Text.Length > 0 && res.IsValid ? double.Parse(WeightModifierInput.Text) : 0;
WeightModifierChanged = (val != Math.Round(BillingData.NetWeightModifier * 100.0, 8) && val != Math.Round(BillingData.GrossWeightModifier * 100.0, 8)) || ViewModel.WeightModifierChanged = (val != Math.Round(ViewModel.BillingData.NetWeightModifier * 100.0, 8) && val != Math.Round(ViewModel.BillingData.GrossWeightModifier * 100.0, 8)) ||
(val == 0 && (BillingData.NetWeightModifier != 0 || BillingData.GrossWeightModifier != 0)); (val == 0 && (ViewModel.BillingData.NetWeightModifier != 0 || ViewModel.BillingData.GrossWeightModifier != 0));
if (WeightModifierChanged) { if (ViewModel.WeightModifierChanged) {
ControlUtils.SetInputChanged(WeightModifierInput); ControlUtils.SetInputChanged(WeightModifierInput);
} else { } else {
ControlUtils.ClearInputState(WeightModifierInput); ControlUtils.ClearInputState(WeightModifierInput);
} }
UpdateSaveButton(); UpdateButtons();
} }
private void WeightModifierInput_LostFocus(object sender, RoutedEventArgs evt) { private void WeightModifierInput_LostFocus(object sender, RoutedEventArgs evt) {

View File

@@ -1,5 +0,0 @@
::mkdir "C:\Program Files\Elwig"
mkdir "C:\ProgramData\Elwig\resources"
copy /b /y Documents\*.css "C:\ProgramData\Elwig\resources"
copy /b /y Documents\*.cshtml "C:\ProgramData\Elwig\resources"
::copy /b /y ..\Installer\Files\*.exe "C:\Program Files\Elwig\"

View File

@@ -1,15 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
<Fragment> <Fragment>
<!-- C:\Program Files (x86)\Elwig oder C:\Program Files\Elwig --> <!-- C:\Program Files (x86)\Elwig oder C:\Program Files\Elwig -->
<StandardDirectory Id="ProgramFiles64Folder"> <StandardDirectory Id="ProgramFiles64Folder">
<Directory Id="InstallFolder" Name="!(bind.Property.ProductName)" /> <Directory Id="InstallFolder" Name="!(bind.Property.ProductName)">
<Directory Id="InstallFolderResources" Name="resources">
<Directory Id="InstallFolderDocuments" Name="Documents" />
</Directory>
</Directory>
</StandardDirectory> </StandardDirectory>
<!-- C:\ProgramData\Elwig --> <!-- C:\ProgramData\Elwig -->
<StandardDirectory Id="CommonAppDataFolder"> <StandardDirectory Id="CommonAppDataFolder">
<Directory Id="ConfigFolder" Name="!(bind.Property.ProductName)"> <Directory Id="ConfigFolder" Name="!(bind.Property.ProductName)" />
<Directory Id="ConfigFolderResources" Name="resources" />
</Directory>
</StandardDirectory> </StandardDirectory>
<!-- C:\ProgramData\Microsoft\Windows\Start Menu\Programs --> <!-- C:\ProgramData\Microsoft\Windows\Start Menu\Programs -->
@@ -17,7 +20,7 @@
<Directory Id="StartMenuProgramsFolder" Name="!(bind.Property.ProductName)" /> <Directory Id="StartMenuProgramsFolder" Name="!(bind.Property.ProductName)" />
</StandardDirectory> </StandardDirectory>
<!-- C:\Users{USERNAME}\Desktop --> <!-- C:\Users\{USERNAME}\Desktop -->
<StandardDirectory Id="DesktopFolder" /> <StandardDirectory Id="DesktopFolder" />
</Fragment> </Fragment>
</Wix> </Wix>

View File

@@ -6,7 +6,7 @@
<Exclude Files="..\Elwig\bin\Publish\**.exe" /> <Exclude Files="..\Elwig\bin\Publish\**.exe" />
<Exclude Files="..\Elwig\bin\Publish\**.pdb" /> <Exclude Files="..\Elwig\bin\Publish\**.pdb" />
</Files> </Files>
<Files Directory="ConfigFolderResources" Include="..\Elwig\Documents\**"> <Files Directory="InstallFolderDocuments" Include="..\Elwig\Documents\**">
<Exclude Files="..\Elwig\Documents\**.cs" /> <Exclude Files="..\Elwig\Documents\**.cs" />
</Files> </Files>
</ComponentGroup> </ComponentGroup>

View File

@@ -1,28 +0,0 @@
using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Models.Dtos;
namespace Tests.DocumentTests {
[TestFixture]
public class PaymentVariantSummaryTest {
[Test]
public async Task Test_01_PaymentVariant2020() {
using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(2020, 1))!;
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var doc = new PaymentVariantSummary(v, data);
var text = await Utils.GeneratePdfText(doc);
Assert.Multiple(() => {
Assert.That(text, Contains.Substring("Auszahlungsvariante"));
Assert.That(text, Contains.Substring(v.Name));
Assert.That(text, Contains.Substring("""
Gradation ungebunden gebunden Gesamt
[°Oe] [kg] [/kg] [kg] [/kg] []
Grüner Veltliner 3 219 0 1 609,50
Qualitätswein 73 3 219 0,5000 - - 1 609,50
"""));
});
}
}
}

View File

@@ -1,6 +1,6 @@
using OpenQA.Selenium; using OpenQA.Selenium;
using OpenQA.Selenium.Appium.Windows; using OpenQA.Selenium.Appium.Windows;
using Tests.WeighingTests; using Tests.UnitTests.WeighingTests;
namespace Tests.E2ETests { namespace Tests.E2ETests {
[TestFixture, Order(2)] [TestFixture, Order(2)]

View File

@@ -3,7 +3,7 @@ using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class CreditNoteTest { public class CreditNoteTest {
@@ -12,7 +12,7 @@ namespace Tests.DocumentTests {
using var ctx = new AppDbContext(); using var ctx = new AppDbContext();
var m = await ctx.Members.FindAsync(101); var m = await ctx.Members.FindAsync(101);
var p = await ctx.MemberPayments.Where(p => p.Year == 2020 && p.AvNr == 1).SingleAsync(); var p = await ctx.MemberPayments.Where(p => p.Year == 2020 && p.AvNr == 1).SingleAsync();
var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.Seasons, 2020, 1); var data = await CreditNoteDeliveryData.ForPaymentVariant(ctx.CreditNoteDeliveryRows, ctx.PaymentVariants, 2020, 1);
using var doc = new CreditNote(ctx, p, data[m!.MgNr], false, false, false, false, using var doc = new CreditNote(ctx, p, data[m!.MgNr], false, false, false, false,
ctx.GetMemberUnderDelivery(2020, m!.MgNr).GetAwaiter().GetResult()); ctx.GetMemberUnderDelivery(2020, m!.MgNr).GetAwaiter().GetResult());
var text = await Utils.GeneratePdfText(doc); var text = await Utils.GeneratePdfText(doc);

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class DeliveryAncmtListTest { public class DeliveryAncmtListTest {

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class DeliveryConfirmationTest { public class DeliveryConfirmationTest {

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class DeliveryDepreciationListTest { public class DeliveryDepreciationListTest {

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class DeliveryJournalTest { public class DeliveryJournalTest {

View File

@@ -1,7 +1,7 @@
using Elwig.Documents; using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class DeliveryNoteTest { public class DeliveryNoteTest {

View File

@@ -1,7 +1,7 @@
using Elwig.Documents; using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class LetterheadTest { public class LetterheadTest {

View File

@@ -1,7 +1,7 @@
using Elwig.Documents; using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class MemberDataSheetTest { public class MemberDataSheetTest {

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class MemberListTest { public class MemberListTest {

View File

@@ -0,0 +1,29 @@
using Elwig.Documents;
using Elwig.Helpers;
using Elwig.Models.Dtos;
namespace Tests.UnitTests.DocumentTests {
[TestFixture]
public class PaymentVariantSummaryTest {
[Test]
public async Task Test_01_PaymentVariant2020() {
using var ctx = new AppDbContext();
var v = (await ctx.PaymentVariants.FindAsync(2020, 1))!;
var data = await PaymentVariantSummaryData.ForPaymentVariant(v, ctx.PaymentVariantSummaryRows);
using var doc = new PaymentVariantSummary(v, data);
var text = await Utils.GeneratePdfText(doc, true);
var table = Utils.ExtractTable(text);
Assert.Multiple(() => {
Assert.That(text, Contains.Substring("Auszahlungsvariante"));
Assert.That(text, Contains.Substring(v.Name));
Assert.That(table.Skip(17).ToArray(), Is.EqualTo(new string[][] {
[ "Gradation", "ungebunden", "attributlos gebunden", "gebunden", "Gesamt" ],
[ "[°Oe]", "[kg]", "[/kg]", "[kg]", "[/kg]", "[kg]", "[/kg]", "[]" ],
["Grüner Veltliner", "3 219", "0", "0", "1 609,50"],
["Qualitätswein", "73", "3 219", "0,5000", "-", "-", "-", "-", "1 609,50"]
}));
});
}
}
}

View File

@@ -3,7 +3,7 @@ using System.Reflection;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using Elwig.Helpers.Printing; using Elwig.Helpers.Printing;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[SetUpFixture] [SetUpFixture]
public class Setup { public class Setup {

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using NReco.PdfRenderer; using NReco.PdfRenderer;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
public static class Utils { public static class Utils {
private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf"); private static readonly string FileName = Path.Combine(Path.GetTempPath(), "test_document.pdf");

View File

@@ -2,7 +2,7 @@ using Elwig.Documents;
using Elwig.Helpers; using Elwig.Helpers;
using Elwig.Models.Dtos; using Elwig.Models.Dtos;
namespace Tests.DocumentTests { namespace Tests.UnitTests.DocumentTests {
[TestFixture] [TestFixture]
public class WineQualityStatisticsTest { public class WineQualityStatisticsTest {

View File

@@ -2,7 +2,7 @@ using Elwig.Helpers;
using Elwig.Helpers.Billing; using Elwig.Helpers.Billing;
using System.Text.Json; using System.Text.Json;
namespace Tests.HelperTests { namespace Tests.UnitTests.HelperTests {
[TestFixture] [TestFixture]
public class BillingDataTest { public class BillingDataTest {

View File

@@ -3,7 +3,7 @@ using Elwig.Helpers.Billing;
using Microsoft.Data.Sqlite; using Microsoft.Data.Sqlite;
using System.Reflection; using System.Reflection;
namespace Tests.HelperTests { namespace Tests.UnitTests.HelperTests {
[TestFixture] [TestFixture]
public class BillingTest { public class BillingTest {

View File

@@ -5,7 +5,7 @@ using Elwig.Models.Entities;
using System.Reflection; using System.Reflection;
using System.Xml; using System.Xml;
namespace Tests.HelperTests { namespace Tests.UnitTests.HelperTests {
// see https://www.iso20022.org/iso-20022-message-definitions // see https://www.iso20022.org/iso-20022-message-definitions
// and https://www.iso20022.org/catalogue-messages/iso-20022-messages-archive?search=pain // and https://www.iso20022.org/catalogue-messages/iso-20022-messages-archive?search=pain
[TestFixture] [TestFixture]

View File

@@ -1,6 +1,6 @@
using Elwig.Helpers; using Elwig.Helpers;
namespace Tests.HelperTests { namespace Tests.UnitTests.HelperTests {
[TestFixture] [TestFixture]
public class UtilsTest { public class UtilsTest {

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