Compare commits
	
		
			8 Commits
		
	
	
		
			v0.13.0
			...
			86f7f693a0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 86f7f693a0 | |||
| 8680e51052 | |||
| 1d97f3c422 | |||
| b6ae1f5675 | |||
| c185437b9a | |||
| a2315e84bd | |||
| 6ba1973087 | |||
| c62947dacd | 
							
								
								
									
										20
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -3,6 +3,26 @@ Changelog
 | 
			
		||||
=========
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[v0.13.1][v0.13.1] (2024-09-29) {#v0.13.1}
 | 
			
		||||
------------------------------------------
 | 
			
		||||
 | 
			
		||||
### Neue Funktionen {#0.13.1-features}
 | 
			
		||||
 | 
			
		||||
* Das Extrahieren/Abwerten/Aufteilen von (Teil-)Lieferungen wurde grundlegend überarbeitet und funktioniert ab jetzt in einem einzigen, übersichtlicheren Dialog. (c62947dacd, c185437b9a)
 | 
			
		||||
 | 
			
		||||
### Behobene Fehler {#0.13.1-bugfixes}
 | 
			
		||||
 | 
			
		||||
* Im Mitglieder-Fenster (`MemberAdminWinodw`) wurden bei `Anlieferungsbestätigung -> speichern (PDF)` und `Traubengutschrift -> speichern (PDF)` E-Mails verschickt, anstatt ein PDF gespeichert. (6ba1973087, a2315e84bd)
 | 
			
		||||
 | 
			
		||||
### Sonstiges {#0.13.1-misc}
 | 
			
		||||
 | 
			
		||||
* Abhängigkeiten aktualisiert. (b6ae1f5675)
 | 
			
		||||
 | 
			
		||||
[v0.13.1]: https://git.necronda.net/winzer/elwig/releases/tag/v0.13.1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[v0.13.0][v0.13.0] (2024-09-25) {#v0.13.0}
 | 
			
		||||
------------------------------------------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -183,6 +183,9 @@ namespace Elwig {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Application_Exit(object sender, ExitEventArgs evt) {
 | 
			
		||||
            foreach (var s in EventScales) {
 | 
			
		||||
                s.Dispose();
 | 
			
		||||
            }
 | 
			
		||||
            await Pdf.Cleanup();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
                            BorderThickness="{Binding Path=BorderThickness, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
 | 
			
		||||
                            BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
 | 
			
		||||
                            SnapsToDevicePixels="True">
 | 
			
		||||
                        <Grid>
 | 
			
		||||
                        <Grid Background="{Binding Path=Background, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}">
 | 
			
		||||
                            <ScrollViewer x:Name="PART_ContentHost" VerticalAlignment="Bottom">
 | 
			
		||||
                                <ScrollViewer.Margin>
 | 
			
		||||
                                    <Binding ElementName="UnitBlock" Path="ActualWidth">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,56 +0,0 @@
 | 
			
		||||
<Window x:Class="Elwig.Dialogs.AbwertenDialog"
 | 
			
		||||
        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"
 | 
			
		||||
        ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
 | 
			
		||||
        WindowStartupLocation="CenterOwner"
 | 
			
		||||
        FocusManager.FocusedElement="{Binding ElementName=WeightInput}"
 | 
			
		||||
        Title="Teillieferung abwerten" Height="190" Width="400">
 | 
			
		||||
    <Window.Resources>
 | 
			
		||||
        <Style TargetType="Label">
 | 
			
		||||
            <Setter Property="HorizontalAlignment" Value="Left"/>
 | 
			
		||||
            <Setter Property="VerticalAlignment" Value="Top"/>
 | 
			
		||||
            <Setter Property="Padding" Value="2,4,2,4"/>
 | 
			
		||||
            <Setter Property="Height" Value="25"/>
 | 
			
		||||
        </Style>
 | 
			
		||||
        <Style TargetType="TextBox">
 | 
			
		||||
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
 | 
			
		||||
            <Setter Property="VerticalAlignment" Value="Top"/>
 | 
			
		||||
            <Setter Property="FontSize" Value="14"/>
 | 
			
		||||
            <Setter Property="Padding" Value="2"/>
 | 
			
		||||
            <Setter Property="Height" Value="25"/>
 | 
			
		||||
            <Setter Property="TextWrapping" Value="NoWrap"/>
 | 
			
		||||
        </Style>
 | 
			
		||||
        <Style TargetType="Button">
 | 
			
		||||
            <Setter Property="HorizontalAlignment" Value="Right"/>
 | 
			
		||||
            <Setter Property="VerticalAlignment" Value="Bottom"/>
 | 
			
		||||
            <Setter Property="Width" Value="100"/>
 | 
			
		||||
            <Setter Property="Height" Value="25"/>
 | 
			
		||||
        </Style>
 | 
			
		||||
    </Window.Resources>
 | 
			
		||||
    <Grid>
 | 
			
		||||
        <Grid.ColumnDefinitions>
 | 
			
		||||
            <ColumnDefinition Width="70"/>
 | 
			
		||||
            <ColumnDefinition/>
 | 
			
		||||
        </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
        <TextBlock Margin="10,10,10,10" Grid.ColumnSpan="2" TextWrapping="Wrap" TextAlignment="Center">
 | 
			
		||||
            Welche Menge der Teillieferung <Run x:Name="TextLsNr" FontWeight="Bold" Text="20201010A000/1"/><LineBreak/>
 | 
			
		||||
            von <Run x:Name="TextMember" FontWeight="Bold" Text="Max Mustermann"/><LineBreak/>
 | 
			
		||||
            mit <Run x:Name="TextWeight" FontWeight="Bold" Text="1 000 kg"/> soll abgewertet werden?
 | 
			
		||||
        </TextBlock>
 | 
			
		||||
 | 
			
		||||
        <Label Content="Gewicht:" Margin="10,70,10,10"/>
 | 
			
		||||
        <Grid Grid.Column="1" Width="70" Height="25" Margin="0,70,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
            <TextBox x:Name="WeightInput" TextAlignment="Right" Padding="2,2,17,2"
 | 
			
		||||
                     TextChanged="WeightInput_TextChanged"/>
 | 
			
		||||
            <Label Content="kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10" Padding="2,4,2,4"/>
 | 
			
		||||
        </Grid>
 | 
			
		||||
 | 
			
		||||
        <Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" Grid.Column="1" IsEnabled="False" IsDefault="True"
 | 
			
		||||
                Click="ConfirmButton_Click"/>
 | 
			
		||||
        <Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" Grid.Column="1" IsCancel="True"/>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</Window>
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
using Elwig.Helpers;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Dialogs {
 | 
			
		||||
    public partial class AbwertenDialog : Window {
 | 
			
		||||
 | 
			
		||||
        public int Weight;
 | 
			
		||||
 | 
			
		||||
        public AbwertenDialog(string lsnr, string name, int weight) {
 | 
			
		||||
            Weight = weight;
 | 
			
		||||
            InitializeComponent();
 | 
			
		||||
            TextLsNr.Text = lsnr;
 | 
			
		||||
            TextMember.Text = name;
 | 
			
		||||
            TextWeight.Text = $"{weight:N0}{Utils.UnitSeparator}kg";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            DialogResult = true;
 | 
			
		||||
            Weight = int.Parse(WeightInput.Text);
 | 
			
		||||
            Close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void UpdateButtons() {
 | 
			
		||||
            ConfirmButton.IsEnabled = int.TryParse(WeightInput.Text, out var w) && w > 0 && w <= Weight;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
            Validator.CheckInteger(WeightInput, true, 5);
 | 
			
		||||
            UpdateButtons();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -57,8 +57,8 @@
 | 
			
		||||
                  Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"
 | 
			
		||||
                  IsChecked="{Binding DeletePaymentData}"/>
 | 
			
		||||
 | 
			
		||||
        <Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" Grid.Column="1" IsEnabled="False"
 | 
			
		||||
        <Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" IsEnabled="False"
 | 
			
		||||
                Click="ConfirmButton_Click"/>
 | 
			
		||||
        <Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" Grid.Column="1" IsCancel="True"/>
 | 
			
		||||
        <Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" IsCancel="True"/>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</Window>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,57 +0,0 @@
 | 
			
		||||
<Window x:Class="Elwig.Dialogs.DeliveryExtractionDialog"
 | 
			
		||||
        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"
 | 
			
		||||
        ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
 | 
			
		||||
        WindowStartupLocation="CenterOwner"
 | 
			
		||||
        FocusManager.FocusedElement="{Binding ElementName=WeightInput}"
 | 
			
		||||
        Title="Teillieferung extrahieren" Height="210" Width="380">
 | 
			
		||||
    <Window.Resources>
 | 
			
		||||
        <Style TargetType="Label">
 | 
			
		||||
            <Setter Property="HorizontalAlignment" Value="Left"/>
 | 
			
		||||
            <Setter Property="VerticalAlignment" Value="Top"/>
 | 
			
		||||
            <Setter Property="Padding" Value="2,4,2,4"/>
 | 
			
		||||
            <Setter Property="Height" Value="25"/>
 | 
			
		||||
        </Style>
 | 
			
		||||
        <Style TargetType="TextBox">
 | 
			
		||||
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
 | 
			
		||||
            <Setter Property="VerticalAlignment" Value="Top"/>
 | 
			
		||||
            <Setter Property="FontSize" Value="14"/>
 | 
			
		||||
            <Setter Property="Padding" Value="2"/>
 | 
			
		||||
            <Setter Property="Height" Value="25"/>
 | 
			
		||||
            <Setter Property="TextWrapping" Value="NoWrap"/>
 | 
			
		||||
        </Style>
 | 
			
		||||
        <Style TargetType="Button">
 | 
			
		||||
            <Setter Property="HorizontalAlignment" Value="Right"/>
 | 
			
		||||
            <Setter Property="VerticalAlignment" Value="Bottom"/>
 | 
			
		||||
            <Setter Property="Width" Value="100"/>
 | 
			
		||||
            <Setter Property="Height" Value="25"/>
 | 
			
		||||
        </Style>
 | 
			
		||||
    </Window.Resources>
 | 
			
		||||
    <Grid>
 | 
			
		||||
        <Grid.ColumnDefinitions>
 | 
			
		||||
            <ColumnDefinition Width="200"/>
 | 
			
		||||
            <ColumnDefinition/>
 | 
			
		||||
        </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
        <TextBlock Margin="10,10,0,10" TextWrapping="Wrap">
 | 
			
		||||
            Was soll mit der Teillieferung <Run x:Name="TextLsNr" FontWeight="Bold" Text="20201010A000/1"/><LineBreak/>
 | 
			
		||||
            von <Run x:Name="TextMember" FontWeight="Bold" Text="Max Mustermann"/> geschehen?
 | 
			
		||||
        </TextBlock>
 | 
			
		||||
        <RadioButton x:Name="NewDeliveryButton" Content="Neue Lieferung erstellen"
 | 
			
		||||
                     Margin="10,80,0,10" HorizontalAlignment="Left" VerticalAlignment="Top"
 | 
			
		||||
                     Checked="Selection_Changed" Unchecked="Selection_Changed"/>
 | 
			
		||||
        <RadioButton x:Name="AddToDeliveryButton" Content="Zu Lieferung hinzufügen"
 | 
			
		||||
                     Margin="10,100,0,10" HorizontalAlignment="Left" VerticalAlignment="Top"
 | 
			
		||||
                     Checked="Selection_Changed" Unchecked="Selection_Changed"/>
 | 
			
		||||
 | 
			
		||||
        <ListBox x:Name="DeliveryList" Grid.Column="1" Margin="10,10,10,45"
 | 
			
		||||
                 SelectionChanged="DeliveryList_SelectionChanged"/>
 | 
			
		||||
 | 
			
		||||
        <Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" Grid.ColumnSpan="2" IsEnabled="False" IsDefault="True"
 | 
			
		||||
                Click="ConfirmButton_Click"/>
 | 
			
		||||
        <Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" Grid.ColumnSpan="2" IsCancel="True"/>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</Window>
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Dialogs {
 | 
			
		||||
    public partial class DeliveryExtractionDialog : Window {
 | 
			
		||||
 | 
			
		||||
        public string? AddTo;
 | 
			
		||||
 | 
			
		||||
        public DeliveryExtractionDialog(string lsnr, string name, bool single, IEnumerable<string> lsnrs) {
 | 
			
		||||
            InitializeComponent();
 | 
			
		||||
            TextLsNr.Text = lsnr;
 | 
			
		||||
            TextMember.Text = name;
 | 
			
		||||
            NewDeliveryButton.IsEnabled = !single;
 | 
			
		||||
            DeliveryList.IsEnabled = false;
 | 
			
		||||
            DeliveryList.ItemsSource = lsnrs;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            DialogResult = true;
 | 
			
		||||
            AddTo = NewDeliveryButton.IsChecked == true ? "new" : DeliveryList.SelectedItem as string;
 | 
			
		||||
            Close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void UpdateButtons() {
 | 
			
		||||
            ConfirmButton.IsEnabled = NewDeliveryButton.IsChecked == true || (AddToDeliveryButton.IsChecked == true && DeliveryList.SelectedItem != null);
 | 
			
		||||
            DeliveryList.IsEnabled = AddToDeliveryButton.IsChecked == true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Selection_Changed(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            UpdateButtons();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DeliveryList_SelectionChanged(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            UpdateButtons();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										104
									
								
								Elwig/Dialogs/DeliverySplittingDialog.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								Elwig/Dialogs/DeliverySplittingDialog.xaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
			
		||||
<local:ContextWindow
 | 
			
		||||
        x:Class="Elwig.Dialogs.DeliverySplittingDialog"
 | 
			
		||||
        AutomationProperties.AutomationId="DeliverySplittingDialog"
 | 
			
		||||
        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:local="clr-namespace:Elwig.Windows"
 | 
			
		||||
        xmlns:ctrl="clr-namespace:Elwig.Controls"
 | 
			
		||||
        ResizeMode="NoResize" ShowInTaskbar="False" Topmost="True"
 | 
			
		||||
        WindowStartupLocation="CenterOwner"
 | 
			
		||||
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
 | 
			
		||||
        Title="Lieferung abwerten oder aufteilen" Height="400" Width="600">
 | 
			
		||||
    <Window.Resources>
 | 
			
		||||
        <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>
 | 
			
		||||
 | 
			
		||||
        <RadioButton x:Name="DepreciateModeInput" GroupName="ModeInput" Content="Abwerten" Margin="15,10,10,10" IsChecked="True"
 | 
			
		||||
                     VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                     Checked="ModeInput_Changed"/>
 | 
			
		||||
        <RadioButton x:Name="MemberModeInput" GroupName="ModeInput" Content="Auf Mitglied übertragen" Margin="15,30,10,10"
 | 
			
		||||
                     VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                     Checked="ModeInput_Changed"/>
 | 
			
		||||
        <RadioButton x:Name="DeliveryModeInput" GroupName="ModeInput" Content="Zu anderer Lieferung hinzufügen" Margin="15,50,10,10"
 | 
			
		||||
                     VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                     Checked="ModeInput_Changed"/>
 | 
			
		||||
 | 
			
		||||
        <TextBox x:Name="MgNrInput" FontSize="14" Padding="2" Visibility="Hidden"
 | 
			
		||||
                 Width="48" Margin="220,10,0,0" Height="25" TextAlignment="Right"
 | 
			
		||||
                 TextChanged="MgNrInput_TextChanged"
 | 
			
		||||
                 VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
			
		||||
        <ComboBox x:Name="MemberInput" FontSize="14" Visibility="Hidden"
 | 
			
		||||
                  Margin="273,10,40,10" IsEditable="True" Height="25"
 | 
			
		||||
                  ItemTemplate="{StaticResource MemberAdminNameTemplate}" TextSearch.TextPath="AdministrativeName"
 | 
			
		||||
                  SelectionChanged="MemberInput_SelectionChanged"
 | 
			
		||||
                  VerticalAlignment="Top" HorizontalAlignment="Stretch"/>
 | 
			
		||||
        <Button x:Name="MemberReferenceButton" Height="25" Width="25" FontFamily="Segoe MDL2 Assets" Content="" Padding="0"
 | 
			
		||||
                Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Right" ToolTip="Zu Mitglied springen" FontSize="14" Visibility="Hidden"
 | 
			
		||||
                Click="MemberReferenceButton_Click"/>
 | 
			
		||||
 | 
			
		||||
        <ComboBox x:Name="DeliveryInput" FontSize="14" Visibility="Hidden"
 | 
			
		||||
                  Margin="220,10,10,10" Height="25"
 | 
			
		||||
                  TextSearch.TextPath="LsNr"
 | 
			
		||||
                  SelectionChanged="DeliveryInput_SelectionChanged"
 | 
			
		||||
                  VerticalAlignment="Top" HorizontalAlignment="Stretch">
 | 
			
		||||
            <ComboBox.ItemTemplate>
 | 
			
		||||
                <DataTemplate>
 | 
			
		||||
                    <StackPanel Orientation="Horizontal">
 | 
			
		||||
                        <TextBlock Text="{Binding LsNr}" Width="100"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="80" TextAlignment="Right" Margin="0,0,10,0"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Member.AdministrativeName}"/>
 | 
			
		||||
                    </StackPanel>
 | 
			
		||||
                </DataTemplate>
 | 
			
		||||
            </ComboBox.ItemTemplate>
 | 
			
		||||
        </ComboBox>
 | 
			
		||||
 | 
			
		||||
        <TextBlock x:Name="InfoBlock" Margin="230,45,10,10" FontSize="14" TextAlignment="Right"
 | 
			
		||||
                   VerticalAlignment="Top" HorizontalAlignment="Stretch"
 | 
			
		||||
                   Text="Insgesamt 0 kg / 0 kg ausgewählt."/>
 | 
			
		||||
 | 
			
		||||
        <ListBox x:Name="DeliveryPartList" Margin="10,75,10,40" ItemsSource="{Binding DeliveryParts, Mode=TwoWay}">
 | 
			
		||||
            <ListBox.ItemContainerStyle>
 | 
			
		||||
                <Style TargetType="{x:Type ListBoxItem}">
 | 
			
		||||
                    <Setter Property="Focusable" Value="False"/>
 | 
			
		||||
                </Style>
 | 
			
		||||
            </ListBox.ItemContainerStyle>
 | 
			
		||||
            <ListBox.ItemTemplate>
 | 
			
		||||
                <DataTemplate>
 | 
			
		||||
                    <StackPanel Orientation="Horizontal">
 | 
			
		||||
                        <TextBlock Text="{Binding Part.DPNr}" Width="20" TextAlignment="Right"
 | 
			
		||||
                                   VerticalAlignment="Center"  Margin="0,0,5,0" FontSize="14"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Part.SortId}" Width="40" TextAlignment="Center"
 | 
			
		||||
                                   VerticalAlignment="Center" Margin="0,0,0,0" FontSize="14"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Part.Kmw, StringFormat='{}{0:N1}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"
 | 
			
		||||
                                   VerticalAlignment="Center"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Part.QualId}" Width="30"
 | 
			
		||||
                                   VerticalAlignment="Center"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Part.Weight, StringFormat='{}{0:N0} kg'}" Width="70" TextAlignment="Right"
 | 
			
		||||
                                   VerticalAlignment="Center" Margin="0,0,10,0" FontSize="14"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Part.Attribute.Name}" Width="60"
 | 
			
		||||
                                   VerticalAlignment="Center"/>
 | 
			
		||||
                        <TextBlock Text="{Binding Part.Cultivation.Name}" Width="50"
 | 
			
		||||
                                   VerticalAlignment="Center"/>
 | 
			
		||||
                        <CheckBox IsChecked="{Binding SplitCompletely, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Content="Vollständig" Tag="{Binding Part.DPNr}"
 | 
			
		||||
                                  VerticalAlignment="Center" Margin="20,0,5,0"
 | 
			
		||||
                                  Checked="SplitCompletelyInput_Changed" Unchecked="SplitCompletelyInput_Changed"/>
 | 
			
		||||
                        <ctrl:UnitTextBox Text="{Binding SplitWeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Unit="kg" Width="70" Height="25" IsEnabled="{Binding SplitWeightEnabled}" Tag="{Binding Part.DPNr}"
 | 
			
		||||
                                          VerticalAlignment="Center" Margin="5,0,5,0" FontSize="14" Padding="2" Background="White"
 | 
			
		||||
                                          TextChanged="SplitWeightInput_TextChanged"/>
 | 
			
		||||
                    </StackPanel>
 | 
			
		||||
                </DataTemplate>
 | 
			
		||||
            </ListBox.ItemTemplate>
 | 
			
		||||
        </ListBox>
 | 
			
		||||
 | 
			
		||||
        <Button x:Name="ConfirmButton" Content="Bestätigen" Margin="10,10,115,10" IsEnabled="False"
 | 
			
		||||
                Click="ConfirmButton_Click"/>
 | 
			
		||||
        <Button x:Name="CancelButton" Content="Abbrechen" Margin="10,10,10,10" IsCancel="True"/>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</local:ContextWindow>
 | 
			
		||||
							
								
								
									
										163
									
								
								Elwig/Dialogs/DeliverySplittingDialog.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										163
									
								
								Elwig/Dialogs/DeliverySplittingDialog.xaml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,163 @@
 | 
			
		||||
using Elwig.Helpers;
 | 
			
		||||
using Elwig.Models.Entities;
 | 
			
		||||
using Elwig.Windows;
 | 
			
		||||
using Microsoft.EntityFrameworkCore;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.ObjectModel;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.Windows;
 | 
			
		||||
using System.Windows.Controls;
 | 
			
		||||
using System.Windows.Data;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Dialogs {
 | 
			
		||||
    public partial class DeliverySplittingDialog : ContextWindow {
 | 
			
		||||
 | 
			
		||||
        public class Row {
 | 
			
		||||
            public DeliveryPart Part { get; set; }
 | 
			
		||||
            public bool SplitCompletely { get; set; }
 | 
			
		||||
            public string? SplitWeightString { get; set; }
 | 
			
		||||
            public int? SplitWeight {
 | 
			
		||||
                get => int.TryParse(SplitWeightString, out var v) ? v : null;
 | 
			
		||||
                set => SplitWeightString = $"{value}";
 | 
			
		||||
            }
 | 
			
		||||
            public bool SplitWeightEnabled { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private readonly Delivery _delivery;
 | 
			
		||||
 | 
			
		||||
        public int? MgNr { get; set; }
 | 
			
		||||
        public string? LsNr { get; set; }
 | 
			
		||||
        public int[]? Weights => DeliveryParts.Select(r => r.SplitCompletely ? r.Part.Weight : r.SplitWeight ?? 0).ToArray();
 | 
			
		||||
 | 
			
		||||
        public ObservableCollection<Row> DeliveryParts { get; set; }
 | 
			
		||||
 | 
			
		||||
        public DeliverySplittingDialog(Delivery d) {
 | 
			
		||||
            _delivery = d;
 | 
			
		||||
            DeliveryParts = new(d.Parts.Select(p => new Row {
 | 
			
		||||
                Part = p,
 | 
			
		||||
                SplitCompletely = false,
 | 
			
		||||
                SplitWeight = null,
 | 
			
		||||
                SplitWeightEnabled = true,
 | 
			
		||||
            }).ToList());
 | 
			
		||||
            InitializeComponent();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override async Task OnRenewContext(AppDbContext ctx) {
 | 
			
		||||
            ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
 | 
			
		||||
                .Where(m => m.IsActive)
 | 
			
		||||
                .OrderBy(m => m.Name)
 | 
			
		||||
                .ThenBy(m => m.GivenName)
 | 
			
		||||
                .ToListAsync());
 | 
			
		||||
            ControlUtils.RenewItemsSource(DeliveryInput, await ctx.Deliveries
 | 
			
		||||
                .Where(d => d.DateString == $"{_delivery.Date:yyyy-MM-dd}" && d.ZwstId == _delivery.ZwstId)
 | 
			
		||||
                .OrderBy(d => d.LsNr)
 | 
			
		||||
                .Include(d => d.Member)
 | 
			
		||||
                .Include(d => d.Parts)
 | 
			
		||||
                .ToListAsync());
 | 
			
		||||
            if (DeliveryInput.SelectedItem == null)
 | 
			
		||||
                ControlUtils.SelectItem(DeliveryInput, _delivery);
 | 
			
		||||
            CheckValidity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ConfirmButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DepreciateModeInput.IsChecked == true) {
 | 
			
		||||
                MgNr = null;
 | 
			
		||||
                LsNr = null;
 | 
			
		||||
            } else if (MemberModeInput.IsChecked == true) {
 | 
			
		||||
                MgNr = ((Member)MemberInput.SelectedItem).MgNr;
 | 
			
		||||
                LsNr = null;
 | 
			
		||||
            } else if (DeliveryModeInput.IsChecked == true) {
 | 
			
		||||
                MgNr = null;
 | 
			
		||||
                LsNr = ((Delivery)DeliveryInput.SelectedItem).LsNr;
 | 
			
		||||
            }
 | 
			
		||||
            DialogResult = true;
 | 
			
		||||
            Close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ModeInput_Changed(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (!IsLoaded) return;
 | 
			
		||||
            CheckValidity();
 | 
			
		||||
            if (DepreciateModeInput.IsChecked == true) {
 | 
			
		||||
                MgNrInput.Visibility = Visibility.Hidden;
 | 
			
		||||
                MemberInput.Visibility = Visibility.Hidden;
 | 
			
		||||
                MemberReferenceButton.Visibility = Visibility.Hidden;
 | 
			
		||||
                DeliveryInput.Visibility = Visibility.Hidden;
 | 
			
		||||
            } else if (MemberModeInput.IsChecked == true) {
 | 
			
		||||
                MgNrInput.Visibility = Visibility.Visible;
 | 
			
		||||
                MemberInput.Visibility = Visibility.Visible;
 | 
			
		||||
                MemberReferenceButton.Visibility = Visibility.Visible;
 | 
			
		||||
                DeliveryInput.Visibility = Visibility.Hidden;
 | 
			
		||||
            } else if (DeliveryModeInput.IsChecked == true) {
 | 
			
		||||
                MgNrInput.Visibility = Visibility.Hidden;
 | 
			
		||||
                MemberInput.Visibility = Visibility.Hidden;
 | 
			
		||||
                MemberReferenceButton.Visibility = Visibility.Hidden;
 | 
			
		||||
                DeliveryInput.Visibility = Visibility.Visible;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckValidity() {
 | 
			
		||||
            var weight = DeliveryParts.Sum(r => r.SplitCompletely ? r.Part.Weight : r.SplitWeight ?? 0);
 | 
			
		||||
            var total = DeliveryParts.Sum(r => r.Part.Weight);
 | 
			
		||||
            InfoBlock.Text = $"Insgesamt {weight:N0} kg / {total:N0} kg ausgewählt.";
 | 
			
		||||
            ConfirmButton.IsEnabled = DeliveryParts.Any(r => r.SplitCompletely || r.SplitWeight > 0) && (
 | 
			
		||||
                DepreciateModeInput.IsChecked == true ||
 | 
			
		||||
                (MemberModeInput.IsChecked == true && MemberInput.SelectedItem != null && !DeliveryParts.All(r => r.SplitCompletely)) ||
 | 
			
		||||
                (DeliveryModeInput.IsChecked == true && DeliveryInput.SelectedItem != null));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void MgNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
            var res = Validator.CheckMgNr((TextBox)sender, true);
 | 
			
		||||
            var text = MgNrInput.Text;
 | 
			
		||||
            var caret = MgNrInput.CaretIndex;
 | 
			
		||||
            ControlUtils.SelectItemWithPk(MemberInput, res.IsValid ? int.Parse(MgNrInput.Text) : null);
 | 
			
		||||
            MgNrInput.Text = text;
 | 
			
		||||
            MgNrInput.CaretIndex = caret;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void MemberInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
 | 
			
		||||
            var m = MemberInput.SelectedItem as Member;
 | 
			
		||||
            MgNrInput.Text = m?.MgNr.ToString();
 | 
			
		||||
            CheckValidity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (MemberInput.SelectedItem is not Member m) return;
 | 
			
		||||
            App.FocusMember(m.MgNr);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DeliveryInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
 | 
			
		||||
            CheckValidity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SplitCompletelyInput_Changed(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            var checkbox = (CheckBox)sender;
 | 
			
		||||
            var dpnr = int.Parse(checkbox.Tag.ToString()!);
 | 
			
		||||
            var row = DeliveryParts.First(d => d.Part.DPNr == dpnr);
 | 
			
		||||
            if (checkbox.IsChecked == true) {
 | 
			
		||||
                row.SplitWeightEnabled = false;
 | 
			
		||||
                row.SplitWeight = row.Part.Weight;
 | 
			
		||||
            } else if (checkbox.IsChecked == false) {
 | 
			
		||||
                row.SplitWeightEnabled = true;
 | 
			
		||||
                row.SplitWeight = null;
 | 
			
		||||
            }
 | 
			
		||||
            CollectionViewSource.GetDefaultView(DeliveryParts).Refresh();
 | 
			
		||||
            CheckValidity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void SplitWeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
            var textbox = (TextBox)sender;
 | 
			
		||||
            Validator.CheckInteger(textbox, false, 6);
 | 
			
		||||
            var dpnr = int.Parse(textbox.Tag.ToString()!);
 | 
			
		||||
            var row = DeliveryParts.First(d => d.Part.DPNr == dpnr);
 | 
			
		||||
            var w = int.TryParse(textbox.Text, out var v) ? v : (int?)null;
 | 
			
		||||
            if (w >= row.Part.Weight) {
 | 
			
		||||
                row.SplitCompletely = true;
 | 
			
		||||
                row.SplitWeightEnabled = false;
 | 
			
		||||
                row.SplitWeight = row.Part.Weight;
 | 
			
		||||
                CollectionViewSource.GetDefaultView(DeliveryParts).Refresh();
 | 
			
		||||
            }
 | 
			
		||||
            CheckValidity();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <UseWPF>true</UseWPF>
 | 
			
		||||
    <PreserveCompilationContext>true</PreserveCompilationContext>
 | 
			
		||||
    <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
 | 
			
		||||
    <Version>0.13.0</Version>
 | 
			
		||||
    <Version>0.13.1</Version>
 | 
			
		||||
    <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
 | 
			
		||||
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
 | 
			
		||||
    <ApplicationManifest>app.manifest</ApplicationManifest>
 | 
			
		||||
@@ -25,14 +25,14 @@
 | 
			
		||||
  </Target>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.1" />
 | 
			
		||||
    <PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
 | 
			
		||||
    <PackageReference Include="LinqKit" Version="1.3.0" />
 | 
			
		||||
    <PackageReference Include="MailKit" Version="4.7.1.1" />
 | 
			
		||||
    <PackageReference Include="MailKit" Version="4.8.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.33" />
 | 
			
		||||
    <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.8" />
 | 
			
		||||
    <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.8" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2739.15" />
 | 
			
		||||
    <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2792.45" />
 | 
			
		||||
    <PackageReference Include="NJsonSchema" Version="11.0.2" />
 | 
			
		||||
    <PackageReference Include="PdfiumViewer" Version="2.13.0" />
 | 
			
		||||
    <PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" />
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,7 @@ namespace Elwig.Helpers.Export {
 | 
			
		||||
                """;
 | 
			
		||||
            var c = App.Client;
 | 
			
		||||
            var (a1, a2) = Utils.SplitAddress(c.Address);
 | 
			
		||||
            _clientData = $"{c.LfbisNr};{c.NameFull};;{a1};{a2};{c.Plz};{c.Ort}";
 | 
			
		||||
            _clientData = $"{c.LfbisNr};{c.NameFull};;{a1};\t{a2};{c.Plz};{c.Ort}";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task ExportAsync(int year) {
 | 
			
		||||
@@ -35,7 +35,7 @@ namespace Elwig.Helpers.Export {
 | 
			
		||||
                WHERE year = {year}
 | 
			
		||||
                """;
 | 
			
		||||
            var r = await cmd.ExecuteReaderAsync();
 | 
			
		||||
            List<Row> rows = new();
 | 
			
		||||
            List<Row> rows = [];
 | 
			
		||||
            while (await r.ReadAsync()) {
 | 
			
		||||
                rows.Add(new(
 | 
			
		||||
                    (r.IsDBNull(0) ? null : r.GetString(0), r.IsDBNull(1) ? null : r.GetString(1), r.IsDBNull(2) ? null : r.GetString(2), r.IsDBNull(3) ? null : r.GetString(3), r.GetString(4), r.GetInt32(5), r.GetString(6), r.GetInt32(7)),
 | 
			
		||||
@@ -57,7 +57,7 @@ namespace Elwig.Helpers.Export {
 | 
			
		||||
 | 
			
		||||
            var (n1, n2) = billingName == null ? (familyName, name) : Utils.SplitName(billingName, familyName);
 | 
			
		||||
            var (a1, a2) = Utils.SplitAddress(address);
 | 
			
		||||
            var memberData = $"{lfBisNr};{n1};{n2};{a1};{a2};{plz};{ort}";
 | 
			
		||||
            var memberData = $"{lfBisNr};{n1};{n2};{a1};\t{a2};{plz};{ort}";
 | 
			
		||||
            var deliveryData = $"{string.Join(".", date.Split("-").Reverse())};{weight};TB;{(type == "W" ? "J" : "")};{(type == "R" ? "J" : "")};{sortid};;;{qualid};{year};{hkid};{kmw:0.0};{oe:0}";
 | 
			
		||||
            var vollData = $"N;;;{area / 10_000.0}";
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,7 @@ namespace Elwig.Helpers {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string? ReadUntil(this StreamReader reader, char delimiter) {
 | 
			
		||||
            return ReadUntil(reader, new char[] { delimiter });
 | 
			
		||||
            return ReadUntil(reader, [ delimiter ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string? ReadUntil(this StreamReader reader, char[] delimiter) {
 | 
			
		||||
@@ -45,7 +45,7 @@ namespace Elwig.Helpers {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Task<string?> ReadUntilAsync(this StreamReader reader, char delimiter) {
 | 
			
		||||
            return ReadUntilAsync(reader, new char[] { delimiter });
 | 
			
		||||
            return ReadUntilAsync(reader, [ delimiter ]);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<string?> ReadUntilAsync(this StreamReader reader, char[] delimiter) {
 | 
			
		||||
 
 | 
			
		||||
@@ -267,9 +267,9 @@ namespace Elwig.Helpers {
 | 
			
		||||
            return d.ShowDialog() == true ? (d.Weight, d.Reason) : null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static int? ShowAbwertenDialog(string lsnr, string name, int weight) {
 | 
			
		||||
            var d = new AbwertenDialog(lsnr, name, weight);
 | 
			
		||||
            return d.ShowDialog() == true ? d.Weight : null;
 | 
			
		||||
        public static (string?, int[])? ShowDeliverySplittingDialog(Delivery delivery) {
 | 
			
		||||
            var d = new DeliverySplittingDialog(delivery);
 | 
			
		||||
            return d.ShowDialog() == true ? (d.MgNr?.ToString() ?? d.LsNr, d.Weights ?? []) : null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static double? ShowLinearPriceIncreaseDialog() {
 | 
			
		||||
@@ -277,11 +277,6 @@ namespace Elwig.Helpers {
 | 
			
		||||
            return d.ShowDialog() == true ? d.Price : null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static string? ShowDeliveryExtractionDialog(string lsnr, string name, bool single, IEnumerable<string> lsnrs) {
 | 
			
		||||
            var d = new DeliveryExtractionDialog(lsnr, name, single, lsnrs);
 | 
			
		||||
            return d.ShowDialog() == true ? d.AddTo : null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static Footer GenerateFooter(string lineBreak, string seperator) {
 | 
			
		||||
            return new Footer(lineBreak, seperator);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -58,11 +58,19 @@ namespace Elwig.Helpers.Weighing {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected async Task<WeighingResult?> Receive() {
 | 
			
		||||
            var line = await Reader.ReadUntilAsync("\r\n");
 | 
			
		||||
            var line = "";
 | 
			
		||||
            while (line.Length < 33) {
 | 
			
		||||
                var ch = Reader.Read();
 | 
			
		||||
                if (ch == -1) {
 | 
			
		||||
                    return null;
 | 
			
		||||
                } else if (line.Length > 0 || ch == ' ') {
 | 
			
		||||
                    line += char.ToString((char)ch);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if (LogPath != null) await File.AppendAllTextAsync(LogPath, line);
 | 
			
		||||
            if (line == null || line == "") {
 | 
			
		||||
                return null;
 | 
			
		||||
            } else if (line.Length != 35 || line[0] != ' ' || line[9] != ' ' || line[15] != ' ' || line[20] != ' ' || line[32] != ' ') {
 | 
			
		||||
            } else if (line.Length != 33 || line[0] != ' ' || line[9] != ' ' || line[15] != ' ' || line[20] != ' ' || line[32] != ' ') {
 | 
			
		||||
                throw new IOException($"Invalid event from scale: '{line}'");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -430,8 +430,9 @@ namespace Elwig.Services {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<DeliveryPart> UpdateDeliveryPart(this DeliveryAdminViewModel vm, int? oldYear, int? oldDid, int? oldDpnr, bool dateHasChanged, bool timeHasChanged, bool timeIsDefault) {
 | 
			
		||||
            using var ctx = new AppDbContext();
 | 
			
		||||
            DeliveryPart p;
 | 
			
		||||
 | 
			
		||||
            using (var ctx = new AppDbContext()) {
 | 
			
		||||
                int year = oldYear ?? Utils.CurrentYear;
 | 
			
		||||
                int did = oldDid ?? await ctx.NextDId(year);
 | 
			
		||||
                int dpnr = oldDpnr ?? await ctx.NextDPNr(year, did);
 | 
			
		||||
@@ -465,7 +466,7 @@ namespace Elwig.Services {
 | 
			
		||||
                    Comment = string.IsNullOrEmpty(vm.Comment) ? null : vm.Comment,
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            var p = new DeliveryPart {
 | 
			
		||||
                p = new DeliveryPart {
 | 
			
		||||
                    Year = year,
 | 
			
		||||
                    DId = did,
 | 
			
		||||
                    DPNr = dpnr,
 | 
			
		||||
@@ -523,10 +524,135 @@ namespace Elwig.Services {
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            App.HintContextChange();
 | 
			
		||||
 | 
			
		||||
            return p;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<Delivery> SplitDeliveryToMember(int year, int did, int[] weights, int mgnr) {
 | 
			
		||||
            Delivery n;
 | 
			
		||||
 | 
			
		||||
            using (var ctx = new AppDbContext()) {
 | 
			
		||||
                bool anyLeft = false;
 | 
			
		||||
                var d = (await ctx.Deliveries.FindAsync(year, did))!;
 | 
			
		||||
                var lnr = await ctx.NextLNr(d.Date, d.ZwstId);
 | 
			
		||||
                n = new Delivery {
 | 
			
		||||
                    Year = year,
 | 
			
		||||
                    DId = await ctx.NextDId(d.Year),
 | 
			
		||||
                    DateString = d.DateString,
 | 
			
		||||
                    TimeString = d.TimeString,
 | 
			
		||||
                    ZwstId = d.ZwstId,
 | 
			
		||||
                    LNr = lnr,
 | 
			
		||||
                    LsNr = Utils.GenerateLsNr(d.Date, d.ZwstId, lnr),
 | 
			
		||||
                    MgNr = mgnr,
 | 
			
		||||
                    Comment = d.Comment,
 | 
			
		||||
                };
 | 
			
		||||
                ctx.Add(n);
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
                var dpnr = 1;
 | 
			
		||||
                foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
 | 
			
		||||
                    if (w <= 0) {
 | 
			
		||||
                        anyLeft = true;
 | 
			
		||||
                        continue;
 | 
			
		||||
                    } else if (w >= p.Weight) {
 | 
			
		||||
                        await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_part SET year = {n.Year}, did = {n.DId}, dpnr = {dpnr++} WHERE (year, did, dpnr) = ({p.Year}, {p.DId}, {p.DPNr})");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        anyLeft = true;
 | 
			
		||||
                        p.Weight -= w;
 | 
			
		||||
                        ctx.Update(p);
 | 
			
		||||
                        var s = ctx.CreateProxy<DeliveryPart>();
 | 
			
		||||
                        var values = ctx.Entry(p).CurrentValues;
 | 
			
		||||
                        ctx.Entry(s).CurrentValues.SetValues(values);
 | 
			
		||||
                        s.Year = n.Year;
 | 
			
		||||
                        s.DId = n.DId;
 | 
			
		||||
                        s.DPNr = dpnr++;
 | 
			
		||||
                        s.Weight = w;
 | 
			
		||||
                        ctx.Add(s);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
                if (!anyLeft)
 | 
			
		||||
                    await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            App.HintContextChange();
 | 
			
		||||
 | 
			
		||||
            return n;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task<Delivery> SplitDeliveryToLsNr(int year, int did, int[] weights, string lsnr) {
 | 
			
		||||
            Delivery n;
 | 
			
		||||
 | 
			
		||||
            using (var ctx = new AppDbContext()) {
 | 
			
		||||
                var anyLeft = false;
 | 
			
		||||
                n = (await ctx.Deliveries.FirstAsync(d => d.LsNr == lsnr))!;
 | 
			
		||||
                var d = (await ctx.Deliveries.FindAsync(year, did))!;
 | 
			
		||||
                var dpnr = await ctx.NextDPNr(n.Year, n.DId);
 | 
			
		||||
                foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
 | 
			
		||||
                    if (w <= 0) {
 | 
			
		||||
                        anyLeft = true;
 | 
			
		||||
                        continue;
 | 
			
		||||
                    } else if (w >= p.Weight) {
 | 
			
		||||
                        await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_part SET year = {n.Year}, did = {n.DId}, dpnr = {dpnr++} WHERE (year, did, dpnr) = ({p.Year}, {p.DId}, {p.DPNr})");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        anyLeft = true;
 | 
			
		||||
                        p.Weight -= w;
 | 
			
		||||
                        ctx.Update(p);
 | 
			
		||||
                        var s = ctx.CreateProxy<DeliveryPart>();
 | 
			
		||||
                        var values = ctx.Entry(p).CurrentValues;
 | 
			
		||||
                        ctx.Entry(s).CurrentValues.SetValues(values);
 | 
			
		||||
                        s.Year = n.Year;
 | 
			
		||||
                        s.DId = n.DId;
 | 
			
		||||
                        s.DPNr = dpnr++;
 | 
			
		||||
                        s.Weight = w;
 | 
			
		||||
                        ctx.Add(s);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
                if (!anyLeft && n.LsNr != d.LsNr)
 | 
			
		||||
                    await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({d.Year}, {d.DId})");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            App.HintContextChange();
 | 
			
		||||
 | 
			
		||||
            return n;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task DepreciateDelivery(int year, int did, int[] weights) {
 | 
			
		||||
            using (var ctx = new AppDbContext()) {
 | 
			
		||||
                var d = (await ctx.Deliveries.FindAsync(year, did))!;
 | 
			
		||||
                var dpnr = await ctx.NextDPNr(year, did);
 | 
			
		||||
                foreach (var (p, w) in d.Parts.ToList().Zip(weights)) {
 | 
			
		||||
                    if (w <= 0) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    } else if (w >= p.Weight) {
 | 
			
		||||
                        p.QualId = "WEI";
 | 
			
		||||
                        p.HkId = "OEST";
 | 
			
		||||
                        ctx.Update(p);
 | 
			
		||||
                    } else {
 | 
			
		||||
                        p.Weight -= w;
 | 
			
		||||
                        ctx.Update(p);
 | 
			
		||||
                        var n = ctx.CreateProxy<DeliveryPart>();
 | 
			
		||||
                        var values = ctx.Entry(p).CurrentValues;
 | 
			
		||||
                        ctx.Entry(n).CurrentValues.SetValues(values);
 | 
			
		||||
                        n.DPNr = dpnr++;
 | 
			
		||||
                        n.Weight = w;
 | 
			
		||||
                        n.QualId = "WEI";
 | 
			
		||||
                        n.HkId = "OEST";
 | 
			
		||||
                        ctx.Add(n);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            App.HintContextChange();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static async Task GenerateDeliveryNote(int year, int did, ExportMode mode) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            try {
 | 
			
		||||
 
 | 
			
		||||
@@ -274,10 +274,10 @@
 | 
			
		||||
                    <TextBlock FontWeight="Bold">Alt+Einfg</TextBlock>
 | 
			
		||||
                </Button.ToolTip>
 | 
			
		||||
            </Button>
 | 
			
		||||
            <Button x:Name="AbwertenButton" Content="Abwerten" IsEnabled="False" 
 | 
			
		||||
                    ToolTip="Ausgewählte Teillieferung vollständig oder teilweise abwerten"
 | 
			
		||||
            <Button x:Name="DepreciateButton" Content="Abwert./Aufteil." IsEnabled="False"
 | 
			
		||||
                    ToolTip="Lieferung vollständig oder teilweise abwerten bzw. auf anderes Mitglied aufteilen"
 | 
			
		||||
                    HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="2"
 | 
			
		||||
                    Click="AbwertenButton_Click"/>
 | 
			
		||||
                    Click="DepreciateButton_Click"/>
 | 
			
		||||
            <Button x:Name="EditDeliveryButton" Content="Bearbeiten" IsEnabled="False"
 | 
			
		||||
                    HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="2"
 | 
			
		||||
                    Click="EditDeliveryButton_Click">
 | 
			
		||||
@@ -391,19 +391,14 @@
 | 
			
		||||
                             Grid.Column="1" Margin="0,100,10,10"
 | 
			
		||||
                             TextChanged="TextBox_TextChanged"/>
 | 
			
		||||
 | 
			
		||||
                    <Grid Grid.ColumnSpan="2" Margin="0,130,0,0">
 | 
			
		||||
                        <Grid.ColumnDefinitions>
 | 
			
		||||
                            <ColumnDefinition/>
 | 
			
		||||
                            <ColumnDefinition/>
 | 
			
		||||
                        </Grid.ColumnDefinitions>
 | 
			
		||||
                        <ListBox x:Name="DeliveryPartList" Margin="5,5,5,38" Grid.ColumnSpan="2"
 | 
			
		||||
                    <ListBox x:Name="DeliveryPartList" Margin="5,135,5,5" Grid.ColumnSpan="2"
 | 
			
		||||
                                SelectionChanged="DeliveryPartList_SelectionChanged">
 | 
			
		||||
                        <ListBox.ItemTemplate>
 | 
			
		||||
                            <DataTemplate>
 | 
			
		||||
                                <StackPanel Orientation="Horizontal">
 | 
			
		||||
                                        <TextBlock Text="{Binding DPNr}" Width="20"/>
 | 
			
		||||
                                    <TextBlock Text="{Binding DPNr}" Width="13" TextAlignment="Right" Margin="0,0,7,0"/>
 | 
			
		||||
                                    <TextBlock Text="{Binding SortId}" Width="30"/>
 | 
			
		||||
                                        <TextBlock Text="{Binding Kmw, StringFormat='{}{0:0.0}°'}" 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 Weight, StringFormat='{}{0:N0} kg'}" Width="60" TextAlignment="Right" Padding="0,0,10,0"/>
 | 
			
		||||
                                    <TextBlock Text="{Binding Attribute.Name}" Width="60"/>
 | 
			
		||||
@@ -412,15 +407,6 @@
 | 
			
		||||
                            </DataTemplate>
 | 
			
		||||
                        </ListBox.ItemTemplate>
 | 
			
		||||
                    </ListBox>
 | 
			
		||||
 | 
			
		||||
                        <Button x:Name="ExtractDeliveryPartButton" Content="Extrahieren" IsEnabled="False"
 | 
			
		||||
                                ToolTip="Ausgewählte Teillieferung aus aktueller Lieferung entfernen und entweder anderer oder neuer Lieferung zuordnen"
 | 
			
		||||
                                HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,2.5,5" Grid.Column="0" Grid.Row="2"
 | 
			
		||||
                                Click="ExtractDeliveryPartButton_Click"/>
 | 
			
		||||
                        <Button x:Name="DeleteDeliveryPartButton" Content="Löschen" IsEnabled="False"
 | 
			
		||||
                                HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,10,5,5" Grid.Column="1" Grid.Row="2"
 | 
			
		||||
                                Click="DeleteDeliveryPartButton_Click"/>
 | 
			
		||||
                    </Grid>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -155,6 +155,10 @@ namespace Elwig.Windows {
 | 
			
		||||
        private async void Menu_DeliveryNote_Email_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryList.SelectedItem is not Delivery d)
 | 
			
		||||
                return;
 | 
			
		||||
            var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Lieferschein verschicken",
 | 
			
		||||
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
 | 
			
		||||
            if (res != MessageBoxResult.Yes)
 | 
			
		||||
                return;
 | 
			
		||||
            await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.Email);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -638,15 +642,11 @@ namespace Elwig.Windows {
 | 
			
		||||
        private void DeliveryPartList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
 | 
			
		||||
            RefreshInputs();
 | 
			
		||||
            if (DeliveryPartList.SelectedItem is DeliveryPart p) {
 | 
			
		||||
                AbwertenButton.IsEnabled = p.QualId != "WEI";
 | 
			
		||||
                DepreciateButton.IsEnabled = true;
 | 
			
		||||
                EditDeliveryButton.IsEnabled = true;
 | 
			
		||||
                ExtractDeliveryPartButton.IsEnabled = !IsCreating;
 | 
			
		||||
                DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating;
 | 
			
		||||
            } else {
 | 
			
		||||
                AbwertenButton.IsEnabled = false;
 | 
			
		||||
                DepreciateButton.IsEnabled = false;
 | 
			
		||||
                EditDeliveryButton.IsEnabled = false;
 | 
			
		||||
                ExtractDeliveryPartButton.IsEnabled = false;
 | 
			
		||||
                DeleteDeliveryPartButton.IsEnabled = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -855,43 +855,29 @@ namespace Elwig.Windows {
 | 
			
		||||
            LockSearchInputs();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void AbwertenButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryPartList.SelectedItem is not DeliveryPart p) return;
 | 
			
		||||
            var res = Utils.ShowAbwertenDialog($"{p.Delivery.LsNr}/{p.DPNr}", p.Delivery.Member.AdministrativeName, p.Weight);
 | 
			
		||||
            if (res == null || res <= 0)
 | 
			
		||||
        private async void DepreciateButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
			
		||||
            var res = Utils.ShowDeliverySplittingDialog(d);
 | 
			
		||||
            if (res == null)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            try {
 | 
			
		||||
                using var ctx = new AppDbContext();
 | 
			
		||||
                ClearOriginalValues();
 | 
			
		||||
                if (res >= p.Weight) {
 | 
			
		||||
                    ControlUtils.SelectItemWithPk(WineQualityLevelInput, "WEI");
 | 
			
		||||
                    ControlUtils.SelectItemWithPk(WineOriginInput, "OEST");
 | 
			
		||||
                    p.QualId = "WEI";
 | 
			
		||||
                    p.HkId = "OEST";
 | 
			
		||||
                    ctx.Update(p);
 | 
			
		||||
                var id = res.Value.Item1;
 | 
			
		||||
                var weights = res.Value.Item2;
 | 
			
		||||
                if (id == null) {
 | 
			
		||||
                    // abwerten
 | 
			
		||||
                    await DeliveryService.DepreciateDelivery(d.Year, d.DId, weights);
 | 
			
		||||
                } else if (id.All(char.IsAsciiDigit)) {
 | 
			
		||||
                    // auf Mitglied übertragen
 | 
			
		||||
                    var n = await DeliveryService.SplitDeliveryToMember(d.Year, d.DId, weights, int.Parse(id));
 | 
			
		||||
                    await Task.Delay(500);
 | 
			
		||||
                    ControlUtils.SelectItemWithPk(DeliveryList, n.Year, n.DId);
 | 
			
		||||
                } else {
 | 
			
		||||
                    var w = p.Weight - res.Value;
 | 
			
		||||
                    ViewModel.Weight = w;
 | 
			
		||||
                    p.Weight = w;
 | 
			
		||||
                    ctx.Update(p);
 | 
			
		||||
 | 
			
		||||
                    var d = p.Delivery;
 | 
			
		||||
                    var p2 = ctx.CreateProxy<DeliveryPart>();
 | 
			
		||||
                    var values = ctx.Entry(p).CurrentValues;
 | 
			
		||||
                    ctx.Entry(p2).CurrentValues.SetValues(values);
 | 
			
		||||
                    p2.DPNr = await ctx.NextDPNr(d.Year, d.DId);
 | 
			
		||||
                    p2.Weight = res.Value;
 | 
			
		||||
                    p2.QualId = "WEI";
 | 
			
		||||
                    p2.HkId = "OEST";
 | 
			
		||||
                    ctx.Add(p2);
 | 
			
		||||
 | 
			
		||||
                    ctx.UpdateDeliveryPartModifiers(p2, [], p.Modifiers);
 | 
			
		||||
                    // zu existierender Lieferung hinzufügen
 | 
			
		||||
                    var n = await DeliveryService.SplitDeliveryToLsNr(d.Year, d.DId, weights, id);
 | 
			
		||||
                    ControlUtils.SelectItemWithPk(DeliveryList, n.Year, n.DId);
 | 
			
		||||
                }
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
                await RefreshDeliveryParts();
 | 
			
		||||
                FinishInputFilling();
 | 
			
		||||
            } catch (Exception exc) {
 | 
			
		||||
                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;
 | 
			
		||||
@@ -929,9 +915,7 @@ namespace Elwig.Windows {
 | 
			
		||||
            UnlockInputs();
 | 
			
		||||
            LockSearchInputs();
 | 
			
		||||
 | 
			
		||||
            AbwertenButton.IsEnabled = false;
 | 
			
		||||
            ExtractDeliveryPartButton.IsEnabled = false;
 | 
			
		||||
            DeleteDeliveryPartButton.IsEnabled = false;
 | 
			
		||||
            DepreciateButton.IsEnabled = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void ShortcutDelete() {
 | 
			
		||||
@@ -1003,9 +987,7 @@ namespace Elwig.Windows {
 | 
			
		||||
            await RefreshDeliveryParts();
 | 
			
		||||
            RefreshInputs();
 | 
			
		||||
 | 
			
		||||
            AbwertenButton.IsEnabled = p.QualId != "WEI";
 | 
			
		||||
            ExtractDeliveryPartButton.IsEnabled = DeliveryPartList.SelectedItem != null && !IsCreating;
 | 
			
		||||
            DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating;
 | 
			
		||||
            DepreciateButton.IsEnabled = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override void ShortcutReset() {
 | 
			
		||||
@@ -1036,93 +1018,7 @@ namespace Elwig.Windows {
 | 
			
		||||
            LockInputs();
 | 
			
		||||
            UnlockSearchInputs();
 | 
			
		||||
 | 
			
		||||
            AbwertenButton.IsEnabled = DeliveryPartList.SelectedItem is DeliveryPart p && p.QualId != "WEI";
 | 
			
		||||
            ExtractDeliveryPartButton.IsEnabled = DeliveryPartList.SelectedItem != null && !IsCreating;
 | 
			
		||||
            DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void ExtractDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryPartList.SelectedItem is not DeliveryPart p)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            var delivery = p.Delivery;
 | 
			
		||||
            var day = delivery.Date;
 | 
			
		||||
            var count = delivery.Parts.Count;
 | 
			
		||||
 | 
			
		||||
            if (delivery.Time <= new TimeOnly(3, 0))
 | 
			
		||||
                day = day.AddDays(-1);
 | 
			
		||||
 | 
			
		||||
            string? res;
 | 
			
		||||
            using (var ctx = new AppDbContext()) {
 | 
			
		||||
                var lsnrs = await ctx.Deliveries
 | 
			
		||||
                    .Where(d => d.ZwstId == delivery.ZwstId)
 | 
			
		||||
                    .Where(d => (d.DateString == day.ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") > 0)) ||
 | 
			
		||||
                                (d.DateString == day.AddDays(1).ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") <= 0)))
 | 
			
		||||
                    .Where(d => d.LsNr != delivery.LsNr)
 | 
			
		||||
                    .OrderBy(d => d.LsNr)
 | 
			
		||||
                    .Select(d => d.LsNr)
 | 
			
		||||
                    .ToListAsync();
 | 
			
		||||
 | 
			
		||||
                res = Utils.ShowDeliveryExtractionDialog($"{delivery.LsNr}/{p.DPNr}", delivery.Member.AdministrativeName, count == 1, lsnrs);
 | 
			
		||||
                if (res == null)
 | 
			
		||||
                    return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            try {
 | 
			
		||||
                using var ctx = new AppDbContext();
 | 
			
		||||
                if (res == "new") {
 | 
			
		||||
                    var lnr = await ctx.NextLNr(delivery.Date, delivery.ZwstId);
 | 
			
		||||
                    var lsnr = Utils.GenerateLsNr(delivery.Date, delivery.ZwstId, lnr);
 | 
			
		||||
                    ctx.Add(new Delivery {
 | 
			
		||||
                        Year = p.Year,
 | 
			
		||||
                        DId = await ctx.NextDId(p.Year),
 | 
			
		||||
                        LNr = lnr,
 | 
			
		||||
                        DateString = $"{delivery.Date:yyyy-MM-dd}",
 | 
			
		||||
                        TimeString = $"{delivery.Time:HH:mm:ss}",
 | 
			
		||||
                        ZwstId = delivery.ZwstId,
 | 
			
		||||
                        MgNr = delivery.MgNr,
 | 
			
		||||
                        Comment = delivery.Comment,
 | 
			
		||||
                        LsNr = lsnr,
 | 
			
		||||
                    });
 | 
			
		||||
                    await ctx.SaveChangesAsync();
 | 
			
		||||
                    res = lsnr;
 | 
			
		||||
                }
 | 
			
		||||
                Delivery? d = await ctx.Deliveries.Where(d => d.LsNr == res).FirstOrDefaultAsync();
 | 
			
		||||
                if (d == null) return;
 | 
			
		||||
 | 
			
		||||
                await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_part SET year = {d.Year}, did = {d.DId}, dpnr = {await ctx.NextDPNr(d.Year, d.DId)} WHERE (year, did, dpnr) = ({p.Year}, {p.DId}, {p.DPNr})");
 | 
			
		||||
                if (count == 1) {
 | 
			
		||||
                    await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({delivery.Year}, {delivery.DId})");
 | 
			
		||||
                }
 | 
			
		||||
                await ctx.SaveChangesAsync();
 | 
			
		||||
 | 
			
		||||
                await RefreshList();
 | 
			
		||||
                ControlUtils.SelectItem(DeliveryList, d);
 | 
			
		||||
            } catch (Exception exc) {
 | 
			
		||||
                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;
 | 
			
		||||
                MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
			
		||||
            }
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void DeleteDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryPartList.SelectedItem is not DeliveryPart p)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            var r = MessageBox.Show(
 | 
			
		||||
                $"Soll die Teillieferung Nr. {p.DPNr} wirklich unwiderruflich gelöscht werden?",
 | 
			
		||||
                "Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
 | 
			
		||||
            if (r == MessageBoxResult.OK) {
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                using (var ctx = new AppDbContext()) {
 | 
			
		||||
                    ctx.Remove(p);
 | 
			
		||||
                    await ctx.SaveChangesAsync();
 | 
			
		||||
                }
 | 
			
		||||
                await RefreshDeliveryParts();
 | 
			
		||||
                Mouse.OverrideCursor = null;
 | 
			
		||||
            }
 | 
			
		||||
            DepreciateButton.IsEnabled = DeliveryPartList.SelectedItem != null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ShowSaveResetCancelButtons() {
 | 
			
		||||
@@ -1145,22 +1041,22 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
        private void ShowNewEditDeleteButtons() {
 | 
			
		||||
            NewDeliveryButton.IsEnabled = ViewModel.IsReceipt;
 | 
			
		||||
            AbwertenButton.IsEnabled = DeliveryPartList.SelectedItem is DeliveryPart p && p.QualId == "WEI";
 | 
			
		||||
            DepreciateButton.IsEnabled = DeliveryList.SelectedItem != null;
 | 
			
		||||
            EditDeliveryButton.IsEnabled = DeliveryPartList.SelectedItem != null;
 | 
			
		||||
            DeleteDeliveryButton.IsEnabled = DeliveryList.SelectedItem != null;
 | 
			
		||||
            NewDeliveryButton.Visibility = ViewModel.IsReceipt ? Visibility.Visible : Visibility.Hidden;
 | 
			
		||||
            AbwertenButton.Visibility = !ViewModel.IsReceipt ? Visibility.Visible : Visibility.Hidden;
 | 
			
		||||
            DepreciateButton.Visibility = !ViewModel.IsReceipt ? Visibility.Visible : Visibility.Hidden;
 | 
			
		||||
            EditDeliveryButton.Visibility = Visibility.Visible;
 | 
			
		||||
            DeleteDeliveryButton.Visibility = Visibility.Visible;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void HideNewEditDeleteButtons() {
 | 
			
		||||
            NewDeliveryButton.IsEnabled = false;
 | 
			
		||||
            AbwertenButton.IsEnabled = false;
 | 
			
		||||
            DepreciateButton.IsEnabled = false;
 | 
			
		||||
            EditDeliveryButton.IsEnabled = false;
 | 
			
		||||
            DeleteDeliveryButton.IsEnabled = false;
 | 
			
		||||
            NewDeliveryButton.Visibility = Visibility.Hidden;
 | 
			
		||||
            AbwertenButton.Visibility = Visibility.Hidden;
 | 
			
		||||
            DepreciateButton.Visibility = Visibility.Hidden;
 | 
			
		||||
            EditDeliveryButton.Visibility = Visibility.Hidden;
 | 
			
		||||
            DeleteDeliveryButton.Visibility = Visibility.Hidden;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -196,7 +196,7 @@ namespace Elwig.Windows {
 | 
			
		||||
                show.Click += Menu_DeliveryConfirmation_Show_Click;
 | 
			
		||||
                i.Items.Add(show);
 | 
			
		||||
                var pdf = new MenuItem { Header = "...speichern... (PDF)" };
 | 
			
		||||
                pdf.Click += Menu_DeliveryConfirmation_Email_Click;
 | 
			
		||||
                pdf.Click += Menu_DeliveryConfirmation_SavePdf_Click;
 | 
			
		||||
                i.Items.Add(pdf);
 | 
			
		||||
                var print = new MenuItem { Header = "...drucken" };
 | 
			
		||||
                print.Click += Menu_DeliveryConfirmation_Print_Click;
 | 
			
		||||
@@ -217,7 +217,7 @@ namespace Elwig.Windows {
 | 
			
		||||
                    show.Click += Menu_CreditNote_Show_Click;
 | 
			
		||||
                    i2.Items.Add(show);
 | 
			
		||||
                    var pdf = new MenuItem { Header = "...speichern... (PDF)" };
 | 
			
		||||
                    pdf.Click += Menu_CreditNote_Email_Click;
 | 
			
		||||
                    pdf.Click += Menu_CreditNote_SavePdf_Click;
 | 
			
		||||
                    i2.Items.Add(pdf);
 | 
			
		||||
                    var print = new MenuItem { Header = "...drucken" };
 | 
			
		||||
                    print.Click += Menu_CreditNote_Print_Click;
 | 
			
		||||
@@ -506,6 +506,10 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
        private async void Menu_MemberDataSheet_Email_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (ViewModel.SelectedMember is not Member m) return;
 | 
			
		||||
            var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Stammdatenblatt verschicken",
 | 
			
		||||
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
 | 
			
		||||
            if (res != MessageBoxResult.Yes)
 | 
			
		||||
                return;
 | 
			
		||||
            await MemberService.GenerateMemberDataSheet(m, ExportMode.Email);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -534,6 +538,10 @@ namespace Elwig.Windows {
 | 
			
		||||
            var year = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
 | 
			
		||||
            if (ViewModel.SelectedMember is not Member m || year == null)
 | 
			
		||||
                return;
 | 
			
		||||
            var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Anlieferungsbestätigung verschicken",
 | 
			
		||||
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
 | 
			
		||||
            if (res != MessageBoxResult.Yes)
 | 
			
		||||
                return;
 | 
			
		||||
            await MemberService.GenerateDeliveryConfirmation(m, (int)year, ExportMode.Email);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -566,6 +574,10 @@ namespace Elwig.Windows {
 | 
			
		||||
            var avnr = (int?)((sender as MenuItem)?.Parent as MenuItem)?.Tag;
 | 
			
		||||
            if (ViewModel.SelectedMember is not Member m || year == null || avnr == null)
 | 
			
		||||
                return;
 | 
			
		||||
            var res = MessageBox.Show("Soll eine E-Mail verschickt werden?", "Traubengutschrift verschicken",
 | 
			
		||||
                MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
 | 
			
		||||
            if (res != MessageBoxResult.Yes)
 | 
			
		||||
                return;
 | 
			
		||||
            await MemberService.GenerateCreditNote(m, (int)year, (int)avnr, ExportMode.Email);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -171,11 +171,11 @@ namespace Tests.WeighingTests {
 | 
			
		||||
            Thread.Sleep(100);
 | 
			
		||||
 | 
			
		||||
            if (invalid) {
 | 
			
		||||
                return ("abcd\r\n", false);
 | 
			
		||||
                return ("abcd", false);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            bool incr = true;
 | 
			
		||||
            return ($" {new DateTime(2020, 9, 28, 9, 8, 0):dd.MM.yy HH:mm} {identNr,4} {weight,9}{(unit ? "lb" : "kg")} \r\n", incr);
 | 
			
		||||
            return ($" {new DateTime(2020, 9, 28, 9, 8, 0):dd.MM.yy HH:mm} {identNr,4} {weight,9}{(unit ? "lb" : "kg")} ", incr);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user