Compare commits
	
		
			19 Commits
		
	
	
		
			v0.3.2
			...
			00e7eeb774
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 00e7eeb774 | |||
| 47d51ded51 | |||
| 532bb826e1 | |||
| 8193bf483c | |||
| 34dcaf26d9 | |||
| 7411f570ee | |||
| 52702f3fa2 | |||
| 7f3573cede | |||
| 72359dc8be | |||
| 0e17aa5408 | |||
| 2bf850bc55 | |||
| aadf536d13 | |||
| 3be6371be1 | |||
| ca1b68aa4f | |||
| d4e5ac6753 | |||
| c9f49927a8 | |||
| 1794b5b8ca | |||
| 7347439034 | |||
| 51ad8f99fd | 
@@ -157,9 +157,12 @@ namespace Elwig {
 | 
			
		||||
 | 
			
		||||
        protected void OnPrintingReadyChanged(EventArgs evt) {
 | 
			
		||||
            foreach (Window w in Windows) {
 | 
			
		||||
                foreach (var b in ControlUtils.FindAllChildren<Button>(w).Where(b => "Print".Equals(b.Tag))) {
 | 
			
		||||
                foreach (var b in ControlUtils.FindAllChildren<Button>(w).Where(b => b.Tag?.ToString() == "Print")) {
 | 
			
		||||
                    b.IsEnabled = IsPrintingReady;
 | 
			
		||||
                }
 | 
			
		||||
                foreach (var i in ControlUtils.FindAllChildren<MenuItem>(w).Where(i => i.Tag?.ToString() == "Print")) {
 | 
			
		||||
                    i.IsEnabled = IsPrintingReady;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
using Elwig.Helpers;
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Documents {
 | 
			
		||||
@@ -26,14 +27,9 @@ namespace Elwig.Documents {
 | 
			
		||||
 | 
			
		||||
        public string Address {
 | 
			
		||||
            get {
 | 
			
		||||
                var b = Member.BillingAddress;
 | 
			
		||||
                if (b != null && UseBillingAddress) {
 | 
			
		||||
                    var plz = b.PostalDest.AtPlz;
 | 
			
		||||
                    return $"{b.Name}\n{Member.AdministrativeName}\n{b.Address}\n{plz.Plz} {plz.Dest}\nÖsterreich";
 | 
			
		||||
                } else {
 | 
			
		||||
                    var plz = Member.PostalDest.AtPlz;
 | 
			
		||||
                    return $"{Member.AdministrativeName}\n{Member.Address}\n{plz.Plz} {plz.Dest}\nÖsterreich";
 | 
			
		||||
                }
 | 
			
		||||
                IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member;
 | 
			
		||||
                var plz = addr.PostalDest.AtPlz;
 | 
			
		||||
                return (addr is BillingAddr ? $"{addr.Name}\n" : "") + $"{Member.AdministrativeName}\n{addr.Address}\n{plz?.Plz} {plz?.Ort.Name.Split(",")[0]}\n{addr.PostalDest.Country.Name}";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,11 +2,15 @@ using System;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using Elwig.Helpers;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Documents {
 | 
			
		||||
    public abstract class Document : IDisposable {
 | 
			
		||||
    public abstract partial class Document : IDisposable {
 | 
			
		||||
 | 
			
		||||
        private TempFile? PdfFile = null;
 | 
			
		||||
        private TempFile? _pdfFile = null;
 | 
			
		||||
        private string? _renderedHtml = null;
 | 
			
		||||
 | 
			
		||||
        public bool ShowFoldMarks = App.Config.Debug;
 | 
			
		||||
 | 
			
		||||
@@ -35,17 +39,56 @@ namespace Elwig.Documents {
 | 
			
		||||
            Date = DateTime.Today;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [GeneratedRegex(@"</body>.*?</footer>\s*</div>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled)]
 | 
			
		||||
        private static partial Regex GeneratedDocumentHeaderRegex();
 | 
			
		||||
        private static readonly Regex DocumentHeaderRegex = GeneratedDocumentHeaderRegex();
 | 
			
		||||
 | 
			
		||||
        [GeneratedRegex(@"<style>.*?/style>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled)]
 | 
			
		||||
        private static partial Regex GeneratedHtmlStyleRegex();
 | 
			
		||||
        private static readonly Regex HtmlStyleRegex = GeneratedHtmlStyleRegex();
 | 
			
		||||
 | 
			
		||||
        [GeneratedRegex(@"<link[^>]*>", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled)]
 | 
			
		||||
        private static partial Regex GeneratedHtmlLinkRegex();
 | 
			
		||||
        private static readonly Regex HtmlLinkRegex = GeneratedHtmlLinkRegex();
 | 
			
		||||
 | 
			
		||||
        ~Document() {
 | 
			
		||||
            Dispose();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose() {
 | 
			
		||||
            PdfFile?.Dispose();
 | 
			
		||||
            PdfFile = null;
 | 
			
		||||
            _pdfFile?.Dispose();
 | 
			
		||||
            _pdfFile = null;
 | 
			
		||||
            GC.SuppressFinalize(this);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Task<string> Render() {
 | 
			
		||||
        public static async Task<Document> Merge(IEnumerable<Document> docs) {
 | 
			
		||||
            string html = "";
 | 
			
		||||
            var styles = new List<string>();
 | 
			
		||||
            foreach (var d in docs) {
 | 
			
		||||
                var h = await d.Render();
 | 
			
		||||
                var s = HtmlStyleRegex.Matches(h).Select(m => m.Value).ToList();
 | 
			
		||||
                var l = HtmlLinkRegex.Matches(h).Select(m => m.Value).ToList();
 | 
			
		||||
                if (s.All(styles.Contains)) {
 | 
			
		||||
                    h = HtmlStyleRegex.Replace(h, "");
 | 
			
		||||
                } else {
 | 
			
		||||
                    styles.AddRange(s);
 | 
			
		||||
                }
 | 
			
		||||
                if (l.All(styles.Contains)) {
 | 
			
		||||
                    h = HtmlLinkRegex.Replace(h, "");
 | 
			
		||||
                } else {
 | 
			
		||||
                    styles.AddRange(l);
 | 
			
		||||
                }
 | 
			
		||||
                html += h;
 | 
			
		||||
            }
 | 
			
		||||
            html = DocumentHeaderRegex.Replace(html, "<div class='document-break'/>");
 | 
			
		||||
            return new InternalDocument("Mehrere Dokumente") {
 | 
			
		||||
                _renderedHtml = html,
 | 
			
		||||
            };
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task<string> Render() {
 | 
			
		||||
            if (_renderedHtml != null)
 | 
			
		||||
                return _renderedHtml;
 | 
			
		||||
            string name;
 | 
			
		||||
            if (this is BusinessLetter) {
 | 
			
		||||
                name = "BusinessLetter";
 | 
			
		||||
@@ -55,14 +98,17 @@ namespace Elwig.Documents {
 | 
			
		||||
                name = "CreditNote";
 | 
			
		||||
            } else if (this is DeliveryJournal) {
 | 
			
		||||
                name = "DeliveryJournal";
 | 
			
		||||
            } else if (this is Letterhead) {
 | 
			
		||||
                name = "Letterhead";
 | 
			
		||||
            } else {
 | 
			
		||||
                throw new InvalidOperationException("Invalid document object");
 | 
			
		||||
            }
 | 
			
		||||
            return Render(name);
 | 
			
		||||
            return await Render(name);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private Task<string> Render(string name) {
 | 
			
		||||
            return Html.CompileRenderAsync(name, this);
 | 
			
		||||
        private async Task<string> Render(string name) {
 | 
			
		||||
            _renderedHtml = await Html.CompileRenderAsync(name, this);
 | 
			
		||||
            return _renderedHtml;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Generate() {
 | 
			
		||||
@@ -71,22 +117,26 @@ namespace Elwig.Documents {
 | 
			
		||||
                await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
 | 
			
		||||
                await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath);
 | 
			
		||||
            }
 | 
			
		||||
            PdfFile = pdf;
 | 
			
		||||
            _pdfFile = pdf;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void SaveTo(string pdfPath) {
 | 
			
		||||
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
			
		||||
            File.Copy(PdfFile.FilePath, pdfPath);
 | 
			
		||||
            if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
			
		||||
            File.Copy(_pdfFile.FilePath, pdfPath);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public async Task Print(int copies = 1) {
 | 
			
		||||
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
			
		||||
            await Pdf.Print(PdfFile.FilePath, copies);
 | 
			
		||||
            if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
			
		||||
            await Pdf.Print(_pdfFile.FilePath, copies);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Show() {
 | 
			
		||||
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
			
		||||
            Pdf.Show(PdfFile.NewReference(), Title);
 | 
			
		||||
            if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
			
		||||
            Pdf.Show(_pdfFile.NewReference(), Title);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private class InternalDocument : Document {
 | 
			
		||||
            public InternalDocument(string title) : base(title) { }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ namespace Elwig.Documents {
 | 
			
		||||
            await e.CompileTemplateAsync("DeliveryNote");
 | 
			
		||||
            await e.CompileTemplateAsync("CreditNote");
 | 
			
		||||
            await e.CompileTemplateAsync("DeliveryJournal");
 | 
			
		||||
            await e.CompileTemplateAsync("Letterhead");
 | 
			
		||||
 | 
			
		||||
            Engine = e;
 | 
			
		||||
            evtHandler();
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								Elwig/Documents/Letterhead.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Elwig/Documents/Letterhead.cshtml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
@using RazorLight
 | 
			
		||||
@inherits TemplatePage<Elwig.Documents.Letterhead>
 | 
			
		||||
@model Elwig.Documents.Letterhead
 | 
			
		||||
@{ Layout = "BusinessDocument"; }
 | 
			
		||||
<style>
 | 
			
		||||
    header, .footer-wrapper {
 | 
			
		||||
        visibility: hidden;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										9
									
								
								Elwig/Documents/Letterhead.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Elwig/Documents/Letterhead.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
using Elwig.Models;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Documents {
 | 
			
		||||
    public class Letterhead : BusinessDocument {
 | 
			
		||||
        public Letterhead(Member m) : base($"Briefkopf {m.Name}", m, true) {
 | 
			
		||||
            Aside = "";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -59,6 +59,7 @@ namespace Elwig.Documents {
 | 
			
		||||
        public static async Task Print(string path, int copies = 1) {
 | 
			
		||||
            var p = new Process() { StartInfo = new() { FileName = PdfToPrinter } };
 | 
			
		||||
            p.StartInfo.ArgumentList.Add(path);
 | 
			
		||||
            p.StartInfo.ArgumentList.Add("/s");
 | 
			
		||||
            p.StartInfo.ArgumentList.Add($"copies={copies}");
 | 
			
		||||
            p.Start();
 | 
			
		||||
            await p.WaitForExitAsync();
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,9 @@
 | 
			
		||||
hr.page-break {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
.document-break {
 | 
			
		||||
    break-before: page;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@page {
 | 
			
		||||
    size: A4;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
    <UseWPF>true</UseWPF>
 | 
			
		||||
    <PreserveCompilationContext>true</PreserveCompilationContext>
 | 
			
		||||
    <ApplicationIcon>elwig.ico</ApplicationIcon>
 | 
			
		||||
    <Version>0.3.2</Version>
 | 
			
		||||
    <Version>0.3.3</Version>
 | 
			
		||||
    <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,8 @@ namespace Elwig.Helpers {
 | 
			
		||||
                    continue;
 | 
			
		||||
                } else if (child is T t) {
 | 
			
		||||
                    yield return t;
 | 
			
		||||
                } else if (child is DependencyObject childDepOpj) {
 | 
			
		||||
                }
 | 
			
		||||
                if (child is DependencyObject childDepOpj) {
 | 
			
		||||
                    foreach (T childOfChild in FindAllChildren<T>(childDepOpj)) {
 | 
			
		||||
                        yield return childOfChild;
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -157,8 +157,12 @@ namespace Elwig.Helpers {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void MailTo(string emailAddress) {
 | 
			
		||||
            MailTo(new string[] { emailAddress });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void MailTo(IEnumerable<string> emailAddresses) {
 | 
			
		||||
            Process.Start(new ProcessStartInfo() {
 | 
			
		||||
                FileName = $"mailto:{emailAddress}",
 | 
			
		||||
                FileName = $"mailto:{string.Join(",%20", emailAddresses)}",
 | 
			
		||||
                UseShellExecute = true,
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -521,6 +521,36 @@ namespace Elwig.Helpers {
 | 
			
		||||
            return new(true, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static ValidationResult CheckTime(TextBox input, bool required) {
 | 
			
		||||
            string text = "";
 | 
			
		||||
            int pos = input.CaretIndex;
 | 
			
		||||
            int v = 0;
 | 
			
		||||
            for (int i = 0; i < input.Text.Length; i++) {
 | 
			
		||||
                char ch = input.Text[i];
 | 
			
		||||
                if (v >= 0 && v < 5 && v != 2 && char.IsAsciiDigit(ch)) {
 | 
			
		||||
                    if ((v == 0 && ch <= '2') || (v == 1 && (text[0] < '2' || ch <= '3')) || (v == 3 && ch <= '5') || v == 4) {
 | 
			
		||||
                        text += ch;
 | 
			
		||||
                        v++;
 | 
			
		||||
                    }
 | 
			
		||||
                } else if (v == 2 && ch == ':') {
 | 
			
		||||
                    text += ch;
 | 
			
		||||
                    v++;
 | 
			
		||||
                }
 | 
			
		||||
                if (i == input.CaretIndex - 1)
 | 
			
		||||
                    pos = text.Length;
 | 
			
		||||
            }
 | 
			
		||||
            input.Text = text;
 | 
			
		||||
            input.CaretIndex = pos;
 | 
			
		||||
 | 
			
		||||
            if (text.Length == 0) {
 | 
			
		||||
                return required ? new(false, "Wert ist nicht optional") : new(true, null);
 | 
			
		||||
            } else if (v != 5) {
 | 
			
		||||
                return new(false, "Zeit ist ungültig");
 | 
			
		||||
            } else {
 | 
			
		||||
                return new(true, null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static ValidationResult CheckFbNr(TextBox input, bool required, AppDbContext ctx, AreaCom? c) {
 | 
			
		||||
            var res = CheckInteger(input, required);
 | 
			
		||||
            if (!res.IsValid) {
 | 
			
		||||
 
 | 
			
		||||
@@ -482,6 +482,14 @@ namespace Elwig.Windows {
 | 
			
		||||
            InputLostFocus((TextBox)sender, Validator.CheckDate);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void TimeInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            InputTextChanged((TextBox)sender, Validator.CheckTime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void TimeInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            InputLostFocus((TextBox)sender, Validator.CheckTime);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void PlzInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            var plz = (TextBox)sender;
 | 
			
		||||
            InputTextChanged(plz, Validator.CheckPlz);
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@
 | 
			
		||||
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
			
		||||
        xmlns:local="clr-namespace:Elwig.Windows"
 | 
			
		||||
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
			
		||||
        Title="Lieferungen - Elwig" Height="720" Width="1100" MinHeight="700" MinWidth="1000"
 | 
			
		||||
        Title="Lieferungen - Elwig" Height="720" Width="1100" MinHeight="720" MinWidth="1000"
 | 
			
		||||
        Loaded="Window_Loaded">
 | 
			
		||||
    <Window.Resources>
 | 
			
		||||
        <Style TargetType="Label">
 | 
			
		||||
@@ -43,40 +43,42 @@
 | 
			
		||||
    <Grid>
 | 
			
		||||
        <Grid.RowDefinitions>
 | 
			
		||||
            <RowDefinition Height="19"/>
 | 
			
		||||
            <RowDefinition Height="0.625*"/>
 | 
			
		||||
            <RowDefinition Height="*"/>
 | 
			
		||||
            <RowDefinition Height="*"/>
 | 
			
		||||
            <RowDefinition Height="*"/>
 | 
			
		||||
            <RowDefinition Height="24"/>
 | 
			
		||||
        </Grid.RowDefinitions>
 | 
			
		||||
        <Grid.ColumnDefinitions>
 | 
			
		||||
            <ColumnDefinition Width="1*" MinWidth="400"/>
 | 
			
		||||
            <ColumnDefinition Width="1*"/>
 | 
			
		||||
            <ColumnDefinition Width="1*"/>
 | 
			
		||||
            <ColumnDefinition Width="5"/>
 | 
			
		||||
            <ColumnDefinition Width="2*" MinWidth="560"/>
 | 
			
		||||
        </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
        <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White">
 | 
			
		||||
            <MenuItem Header="Lieferung">
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
            <MenuItem Header="Drucken">
 | 
			
		||||
                <MenuItem x:Name="Menu_Print_ShowDeliveryNote" Header="Lieferschein anzeigen" IsEnabled="False"
 | 
			
		||||
                          Click="Menu_Print_ShowDeliveryNote_Click"/>
 | 
			
		||||
                <MenuItem x:Name="Menu_Print_PrintDeliveryNote" Header="Lieferschein drucken" IsEnabled="False"
 | 
			
		||||
                          Click="Menu_Print_PrintDeliveryNote_Click"/>
 | 
			
		||||
                <MenuItem x:Name="Menu_Print_ShowDeliveryJournalToday" Header="Lieferjournal anzeigen (heute)"
 | 
			
		||||
                          Click="Menu_Print_ShowDeliveryJournalToday_Click"/>
 | 
			
		||||
                <MenuItem x:Name="Menu_Print_ShowDeliveryJournalYesterday" Header="Lieferjournal anzeigen (gestern)"
 | 
			
		||||
                          Click="Menu_Print_ShowDeliveryJournalYesterday_Click"/>
 | 
			
		||||
                <MenuItem x:Name="Menu_Print_DeliveryJournal" Header="Lieferjournal">
 | 
			
		||||
                    <MenuItem x:Name="Menu_Print_DeliveryJournal_ShowToday" Header="von heute anzeigen" IsEnabled="False" Tag="Print"
 | 
			
		||||
                              Click="Menu_Print_DeliveryJournal_ShowToday_Click"/>
 | 
			
		||||
                    <MenuItem x:Name="Menu_Print_DeliveryJournal_PrintToday" Header="von heute drucken" IsEnabled="False" Tag="Print"
 | 
			
		||||
                              Click="Menu_Print_DeliveryJournal_PrintToday_Click"/>
 | 
			
		||||
                    <MenuItem x:Name="Menu_Print_DeliveryJournal_ShowFilter" Header="aus Filtern anzeigen" IsEnabled="False" Tag="Print"
 | 
			
		||||
                              Click="Menu_Print_DeliveryJournal_ShowFilter_Click"/>
 | 
			
		||||
                    <MenuItem x:Name="Menu_Print_DeliveryJournal_PrintFilter" Header="aus Filtern drucken" IsEnabled="False" Tag="Print"
 | 
			
		||||
                              Click="Menu_Print_DeliveryJournal_PrintFilter_Click"/>
 | 
			
		||||
                </MenuItem>
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
            <MenuItem Header="Exportieren">
 | 
			
		||||
                <MenuItem x:Name="Menu_Export_Bki" Header="Traubentransportscheinliste (BKI)"/>
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
            <MenuItem Header="Werkzeuge">
 | 
			
		||||
                <MenuItem Header="Alle Lieferscheine überprüfen"/>
 | 
			
		||||
            <MenuItem Header="Einstellungen">
 | 
			
		||||
                <MenuItem x:Name="Menu_Settings_EnableFreeEditing" Header="Freie Bearbeitung aktivieren"
 | 
			
		||||
                          IsCheckable="True" Checked="Menu_Settings_EnableFreeEditing_Checked" Unchecked="Menu_Settings_EnableFreeEditing_Unchecked"/>
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
        </Menu>
 | 
			
		||||
 | 
			
		||||
        <Grid Grid.RowSpan="4" Grid.Row="1" Margin="5,0,5,0">
 | 
			
		||||
        <Grid Grid.Row="1" Margin="5,0,0,0">
 | 
			
		||||
            <Grid.RowDefinitions>
 | 
			
		||||
                <RowDefinition Height="42"/>
 | 
			
		||||
                <RowDefinition Height="*"/>
 | 
			
		||||
@@ -104,17 +106,49 @@
 | 
			
		||||
                      CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False"
 | 
			
		||||
                      Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
 | 
			
		||||
                <DataGrid.Columns>
 | 
			
		||||
                    <DataGridTextColumn Header="MgNr."   Binding="{Binding MgNr}" Width="70"/>
 | 
			
		||||
                    <DataGridTextColumn Header="Datum"   Binding="{Binding Date, StringFormat='dd.MM.yy'}" Width="70"/>
 | 
			
		||||
                    <DataGridTextColumn Header="Zeit"    Binding="{Binding Time, StringFormat='HH:mm'}" Width="70"/>
 | 
			
		||||
                    <DataGridTextColumn Header="Sorte"   Binding="{Binding SortIdString}" Width="60"/>
 | 
			
		||||
                    <DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg'}"  Width="70">
 | 
			
		||||
                    <DataGridTextColumn Header="MgNr." Binding="{Binding MgNr, StringFormat='{}{0} '}" Width="50">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Right"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="Datum" Binding="{Binding Date, StringFormat='dd.MM.yy'}" Width="70">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Center"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="Zeit" Binding="{Binding Time, StringFormat='HH:mm'}" Width="50">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Center"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="Sorte" Binding="{Binding SortIdString}" Width="50">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Center"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg '}" Width="75">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Right"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="Gradation" Binding="{Binding Kmw, StringFormat='{}{0:N1}° '}" Width="50">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Right"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="LsNr." Binding="{Binding LsNr}" Width="120"/>
 | 
			
		||||
                </DataGrid.Columns>
 | 
			
		||||
            </DataGrid>
 | 
			
		||||
 | 
			
		||||
@@ -155,237 +189,255 @@
 | 
			
		||||
                    Click="CancelButton_Click"/>
 | 
			
		||||
        </Grid>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Mitglied" Grid.Column="1" Grid.Row="1" Margin="5,5,5,5">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="70"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
        <GridSplitter Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Mitglied:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
			
		||||
                <TextBox x:Name="MgNrInput" Width="48" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" TextAlignment="Right"
 | 
			
		||||
                         TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                <ComboBox x:Name="MemberInput" Grid.Column="1" Margin="53,10,10,10" IsEditable="True"
 | 
			
		||||
                          ItemTemplate="{StaticResource MemberAdminNameTemplate}" TextSearch.TextPath="AdministrativeName"
 | 
			
		||||
                          SelectionChanged="MemberInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
        <Grid Grid.Row="1" Grid.Column="2">
 | 
			
		||||
            <Grid.RowDefinitions>
 | 
			
		||||
                <RowDefinition Height="0.625*"/>
 | 
			
		||||
                <RowDefinition Height="*"/>
 | 
			
		||||
                <RowDefinition Height="*"/>
 | 
			
		||||
                <RowDefinition Height="*"/>
 | 
			
		||||
            </Grid.RowDefinitions>
 | 
			
		||||
            <Grid.ColumnDefinitions>
 | 
			
		||||
                <ColumnDefinition Width="*"/>
 | 
			
		||||
                <ColumnDefinition Width="*"/>
 | 
			
		||||
            </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Wohnort:" Margin="10,38,0,0" Grid.Column="0"/>
 | 
			
		||||
                <TextBox x:Name="MemberAddressField" Grid.Column="1" Margin="0,40,10,10" FontSize="12" Height="22"
 | 
			
		||||
                         IsReadOnly="True" IsTabStop="False"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
            <GroupBox Header="Mitglied" Grid.Column="0" Grid.Row="0" Margin="5,5,5,5">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="70"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Lieferung" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="100"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
                    <Label Content="Mitglied:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <TextBox x:Name="MgNrInput" Width="48" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" TextAlignment="Right"
 | 
			
		||||
                             TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                    <ComboBox x:Name="MemberInput" Grid.Column="1" Margin="53,10,10,10" IsEditable="True"
 | 
			
		||||
                              ItemTemplate="{StaticResource MemberAdminNameTemplate}" TextSearch.TextPath="AdministrativeName"
 | 
			
		||||
                              SelectionChanged="MemberInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="LieferscheinNr.:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
			
		||||
                <TextBox x:Name="LsNrInput" Width="126" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0"
 | 
			
		||||
                         IsReadOnly="True" IsTabStop="False"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Datum/Uhrzeit:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
			
		||||
                <TextBox x:Name="DateInput" Width="77" Grid.Column="1" HorizontalAlignment="Left" Margin="0,40,0,0"
 | 
			
		||||
                         IsReadOnly="True" IsTabStop="False"
 | 
			
		||||
                         TextChanged="DateInput_TextChanged"/>
 | 
			
		||||
                <TextBox x:Name="TimeInput" Width="44" Grid.Column="1" HorizontalAlignment="Left" Margin="82,40,0,0"
 | 
			
		||||
                         IsReadOnly="True" IsTabStop="False"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Zweigstelle:" Margin="10,70,0,0" Grid.Column="0"/>
 | 
			
		||||
                <ComboBox x:Name="BranchInput" Width="126" Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Left"
 | 
			
		||||
                          IsEnabled="False"
 | 
			
		||||
                          DisplayMemberPath="Name" TextSearch.TextPath="Name"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Anmerkung:" Margin="10,100,0,10"/>
 | 
			
		||||
                <TextBox x:Name="CommentInput" Grid.Column="1" Margin="0,100,10,10"
 | 
			
		||||
                         TextChanged="TextBox_TextChanged"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Sorte" Grid.Column="2" Grid.Row="1" Margin="5,5,5,5">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="70"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Sorte:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
			
		||||
                <TextBox x:Name="SortIdInput" Width="36" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left"
 | 
			
		||||
                         TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                <ComboBox x:Name="WineVarietyInput" Grid.Row="1" Grid.Column="1" Margin="41,10,10,10"
 | 
			
		||||
                          ItemTemplate="{StaticResource WineVarietyTemplate}" TextSearch.TextPath="Name" 
 | 
			
		||||
                          SelectionChanged="WineVarietyInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Attribute:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
			
		||||
                <xctk:CheckComboBox x:Name="AttributesInput" Grid.Row="1" Grid.Column="1" Margin="0,40,10,10"
 | 
			
		||||
                                    DisplayMemberPath="Name" Delimiter=", " AllItemsSelectedContent="Alle"
 | 
			
		||||
                                    ItemSelectionChanged="AttributesInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Gradation" Grid.Column="2" Grid.Row="2" Margin="5,5,5,5">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="100"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
                <Label Content="Gradation:" Margin="10,10,10,10"/>
 | 
			
		||||
                <Grid Grid.Column="1" Width="54" Height="25" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
                    <TextBox x:Name="GradationOeInput"  TextAlignment="Right" Padding="2,2,23,2"
 | 
			
		||||
                             TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                    <Label Content="°Oe" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    <Label Content="Wohnort:" Margin="10,38,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <TextBox x:Name="MemberAddressField" Grid.Column="1" Margin="0,40,10,10" FontSize="12" Height="22"
 | 
			
		||||
                             IsReadOnly="True" IsTabStop="False"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
                <Label Content="=" Margin="60,10,10,10" Grid.Column="1"/>
 | 
			
		||||
                <Grid Grid.Column="1" Width="68" Height="25" Margin="78,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
                    <TextBox x:Name="GradationKmwInput" TextAlignment="Right" Padding="2,2,34,2" SnapsToDevicePixels="True"
 | 
			
		||||
                             TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                    <Label Content="°KMW" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
            <GroupBox Header="Lieferung" Grid.Column="0" Grid.Row="1" Margin="5,5,5,5">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="100"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="LieferscheinNr.:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <TextBox x:Name="LsNrInput" Width="126" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0"
 | 
			
		||||
                             IsReadOnly="True" IsTabStop="False"
 | 
			
		||||
                             TextChanged="TextBox_TextChanged"/>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Datum/Uhrzeit:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <TextBox x:Name="DateInput" Width="77" Grid.Column="1" HorizontalAlignment="Left" Margin="0,40,0,0"
 | 
			
		||||
                             IsReadOnly="True"
 | 
			
		||||
                             TextChanged="DateInput_TextChanged" LostFocus="DateInput_LostFocus"/>
 | 
			
		||||
                    <TextBox x:Name="TimeInput" Width="44" Grid.Column="1" HorizontalAlignment="Left" Margin="82,40,0,0"
 | 
			
		||||
                             IsReadOnly="True"
 | 
			
		||||
                             TextChanged="TimeInput_TextChanged" LostFocus="TimeInput_LostFocus"/>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Zweigstelle:" Margin="10,70,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <ComboBox x:Name="BranchInput" Width="126" Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Left"
 | 
			
		||||
                              IsEnabled="False"
 | 
			
		||||
                              SelectionChanged="BranchInput_SelectionChanged"
 | 
			
		||||
                              DisplayMemberPath="Name" TextSearch.TextPath="Name"/>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Anmerkung:" Margin="10,100,0,10"/>
 | 
			
		||||
                    <TextBox x:Name="CommentInput" Grid.Column="1" Margin="0,100,10,10"
 | 
			
		||||
                             TextChanged="TextBox_TextChanged"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Qualitätsstufe:" Margin="10,40,10,10"/>
 | 
			
		||||
                <ComboBox x:Name="WineQualityLevelInput" Width="146" Margin="0,40,10,10" Grid.Column="1" HorizontalAlignment="Left"
 | 
			
		||||
                          ItemTemplate="{StaticResource WineQualityLevelTemplate}"
 | 
			
		||||
                          SelectionChanged="WineQualityLevelInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
            <GroupBox Header="Sorte" Grid.Column="1" Grid.Row="0" Margin="5,5,5,5">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="70"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                <CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False"
 | 
			
		||||
                          VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
                    <Label Content="Sorte:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <TextBox x:Name="SortIdInput" Width="36" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left"
 | 
			
		||||
                             TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                    <ComboBox x:Name="WineVarietyInput" Grid.Row="1" Grid.Column="1" Margin="41,10,10,10"
 | 
			
		||||
                              ItemTemplate="{StaticResource WineVarietyTemplate}" TextSearch.TextPath="Name" 
 | 
			
		||||
                              SelectionChanged="WineVarietyInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Gewicht" Grid.Column="2" Grid.Row="3" Margin="5,5,5,5">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="70"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Gewicht:" Margin="10,10,10,10"/>
 | 
			
		||||
                <Grid Grid.Column="1" Width="70" Height="25" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
                    <TextBox x:Name="WeightInput" TextAlignment="Right" Padding="2,2,17,2" IsReadOnly="True"
 | 
			
		||||
                             TextChanged="WeightInput_TextChanged"/>
 | 
			
		||||
                    <Label Content="kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    <Label Content="Attribute:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
			
		||||
                    <xctk:CheckComboBox x:Name="AttributesInput" Grid.Row="1" Grid.Column="1" Margin="0,40,10,10"
 | 
			
		||||
                                        DisplayMemberPath="Name" Delimiter=", " AllItemsSelectedContent="Alle"
 | 
			
		||||
                                        ItemSelectionChanged="AttributesInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
                <CheckBox x:Name="ManualWeighingInput" Content="Handwiegung" IsEnabled="False"
 | 
			
		||||
                          VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,45,10,10" Grid.Column="0" Grid.ColumnSpan="2"
 | 
			
		||||
                          Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
 | 
			
		||||
            <GroupBox Header="Gradation" Grid.Column="1" Grid.Row="1" Margin="5,5,5,5">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="100"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
                    <Label Content="Gradation:" Margin="10,10,10,10"/>
 | 
			
		||||
                    <Grid Grid.Column="1" Width="54" Height="25" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
                        <TextBox x:Name="GradationOeInput"  TextAlignment="Right" Padding="2,2,23,2"
 | 
			
		||||
                                 TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                        <Label Content="°Oe" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    </Grid>
 | 
			
		||||
                    <Label Content="=" Margin="60,10,10,10" Grid.Column="1"/>
 | 
			
		||||
                    <Grid Grid.Column="1" Width="68" Height="25" Margin="78,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
                        <TextBox x:Name="GradationKmwInput" TextAlignment="Right" Padding="2,2,34,2" SnapsToDevicePixels="True"
 | 
			
		||||
                                 TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
			
		||||
                        <Label Content="°KMW" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    </Grid>
 | 
			
		||||
 | 
			
		||||
                <CheckBox x:Name="GerebeltGewogenInput" Content="Gerebelt gewogen"
 | 
			
		||||
                          VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"
 | 
			
		||||
                          Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
 | 
			
		||||
                    <Label Content="Qualitätsstufe:" Margin="10,40,10,10"/>
 | 
			
		||||
                    <ComboBox x:Name="WineQualityLevelInput" Width="146" Margin="0,40,10,10" Grid.Column="1" HorizontalAlignment="Left"
 | 
			
		||||
                              ItemTemplate="{StaticResource WineQualityLevelTemplate}"
 | 
			
		||||
                              SelectionChanged="WineQualityLevelInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
			
		||||
 | 
			
		||||
                <Button x:Name="WeighingAButton" Content="Wiegen A" Width="120"
 | 
			
		||||
                        Click="WeighingButton_Click"
 | 
			
		||||
                        VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
 | 
			
		||||
                <Button x:Name="WeighingBButton" Content="Wiegen B" Width="120"
 | 
			
		||||
                        Click="WeighingButton_Click"
 | 
			
		||||
                        VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,42,10,10" Grid.Column="2"/>
 | 
			
		||||
                <Button x:Name="WeighingCButton" Content="Wiegen C" Width="120"
 | 
			
		||||
                        Click="WeighingButton_Click"
 | 
			
		||||
                        VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,74,10,10" Grid.Column="2"/>
 | 
			
		||||
                <Button x:Name="WeighingDButton" Content="Wiegen D" Width="120"
 | 
			
		||||
                        Click="WeighingButton_Click"
 | 
			
		||||
                        VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,106,10,10" Grid.Column="2"/>
 | 
			
		||||
                <Button x:Name="WeighingManualButton" Content="Handwiegung" Width="120"
 | 
			
		||||
                        Click="WeighingManualButton_Click"
 | 
			
		||||
                        VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,138,10,10" Grid.Column="2"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Sonstiges" Grid.Column="2" Grid.Row="4" Margin="5,5,5,10">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="100"/>
 | 
			
		||||
                    <ColumnDefinition Width="65"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Zu-/Abschläge:" Margin="10,10,0,10"/>
 | 
			
		||||
                <xctk:CheckComboBox x:Name="ModifiersInput" Margin="0,10,10,10" Grid.Column="1" Grid.ColumnSpan="2"
 | 
			
		||||
                                    ItemTemplate="{StaticResource ModifierTemplate}" Delimiter=", " AllItemsSelectedContent="Alle"
 | 
			
		||||
                                    ItemSelectionChanged="ModifiersInput_SelectionChanged"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Anmerkung:" Margin="10,40,0,10"/>
 | 
			
		||||
                <TextBox x:Name="PartCommentInput" Grid.Column="1" Margin="0,40,10,10" Grid.ColumnSpan="2"
 | 
			
		||||
                         TextChanged="TextBox_TextChanged"/>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Temperatur:" Margin="10,70,0,10"/>
 | 
			
		||||
                <Grid Grid.Column="1" Height="25" Margin="0,70,10,10" VerticalAlignment="Top">
 | 
			
		||||
                    <TextBox x:Name="TemperatureInput" TextAlignment="Right" Padding="2,2,16,2"
 | 
			
		||||
                             TextChanged="TemperatureAcidInput_TextChanged" LostFocus="TemperatureAcidInput_LostFocus"/>
 | 
			
		||||
                    <Label Content="°C" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    <CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False"
 | 
			
		||||
                              VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Säure:" Margin="10,100,0,10"/>
 | 
			
		||||
                <Grid Grid.Column="1" Height="25" Margin="0,100,10,10" VerticalAlignment="Top">
 | 
			
		||||
                    <TextBox x:Name="AcidInput" TextAlignment="Right" Padding="2,2,19,2"
 | 
			
		||||
                             TextChanged="TemperatureAcidInput_TextChanged" LostFocus="TemperatureAcidInput_LostFocus"/>
 | 
			
		||||
                    <Label Content="g/l" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
            <GroupBox Header="Gewicht" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="70"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Gewicht:" Margin="10,10,10,10"/>
 | 
			
		||||
                    <Grid Grid.Column="1" Width="70" Height="25" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
 | 
			
		||||
                        <TextBox x:Name="WeightInput" TextAlignment="Right" Padding="2,2,17,2" IsReadOnly="True"
 | 
			
		||||
                                 TextChanged="WeightInput_TextChanged"/>
 | 
			
		||||
                        <Label Content="kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    </Grid>
 | 
			
		||||
 | 
			
		||||
                    <CheckBox x:Name="ManualWeighingInput" Content="Handwiegung" IsEnabled="False"
 | 
			
		||||
                              VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,45,10,10" Grid.Column="0" Grid.ColumnSpan="2"
 | 
			
		||||
                              Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
 | 
			
		||||
 | 
			
		||||
                    <CheckBox x:Name="GerebeltGewogenInput" Content="Gerebelt gewogen"
 | 
			
		||||
                              VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"
 | 
			
		||||
                              Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
 | 
			
		||||
 | 
			
		||||
                    <Button x:Name="WeighingAButton" Content="Wiegen A" Width="120"
 | 
			
		||||
                            Click="WeighingButton_Click"
 | 
			
		||||
                            VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
 | 
			
		||||
                    <Button x:Name="WeighingBButton" Content="Wiegen B" Width="120"
 | 
			
		||||
                            Click="WeighingButton_Click"
 | 
			
		||||
                            VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,42,10,10" Grid.Column="2"/>
 | 
			
		||||
                    <Button x:Name="WeighingCButton" Content="Wiegen C" Width="120"
 | 
			
		||||
                            Click="WeighingButton_Click"
 | 
			
		||||
                            VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,74,10,10" Grid.Column="2"/>
 | 
			
		||||
                    <Button x:Name="WeighingDButton" Content="Wiegen D" Width="120"
 | 
			
		||||
                            Click="WeighingButton_Click"
 | 
			
		||||
                            VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,106,10,10" Grid.Column="2"/>
 | 
			
		||||
                    <Button x:Name="WeighingManualButton" Content="Handwiegung" Width="120"
 | 
			
		||||
                            Click="WeighingManualButton_Click"
 | 
			
		||||
                            VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,138,10,10" Grid.Column="2"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
                <CheckBox x:Name="LesewagenInput" Content="Lesewagen" Margin="10,75,0,0" Grid.Column="2"
 | 
			
		||||
                          VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                          Checked="LesewagenInput_Changed" Unchecked="LesewagenInput_Changed"/>
 | 
			
		||||
                <CheckBox x:Name="HandPickedInput" Content="Handlese" Margin="10,105,0,0" Grid.Column="2" IsThreeState="True"
 | 
			
		||||
                          VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                          Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
            <GroupBox Header="Sonstiges" Grid.Column="1" Grid.Row="3" Margin="5,5,5,10">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="100"/>
 | 
			
		||||
                        <ColumnDefinition Width="65"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Teillieferungen" Grid.Column="1" Grid.Row="3" Margin="5,5,5,5">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
                <ListBox x:Name="DeliveryPartList" Margin="5,5,5,38" Grid.ColumnSpan="2"
 | 
			
		||||
                         SelectionChanged="DeliveryPartList_SelectionChanged">
 | 
			
		||||
                    <ListBox.ItemTemplate>
 | 
			
		||||
                        <DataTemplate>
 | 
			
		||||
                            <StackPanel Orientation="Horizontal">
 | 
			
		||||
                                <TextBlock Text="{Binding DPNr}" Width="20"/>
 | 
			
		||||
                                <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 QualId}" Width="30"/>
 | 
			
		||||
                                <TextBlock Text="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="60" TextAlignment="Right"/>
 | 
			
		||||
                            </StackPanel>
 | 
			
		||||
                        </DataTemplate>
 | 
			
		||||
                    </ListBox.ItemTemplate>
 | 
			
		||||
                </ListBox>
 | 
			
		||||
                    <Label Content="Zu-/Abschläge:" Margin="10,10,0,10"/>
 | 
			
		||||
                    <xctk:CheckComboBox x:Name="ModifiersInput" Margin="0,10,10,10" Grid.Column="1" Grid.ColumnSpan="2"
 | 
			
		||||
                                        ItemTemplate="{StaticResource ModifierTemplate}" Delimiter=", " AllItemsSelectedContent="Alle"
 | 
			
		||||
                                        ItemSelectionChanged="ModifiersInput_SelectionChanged"/>
 | 
			
		||||
 | 
			
		||||
                <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>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
                    <Label Content="Anmerkung:" Margin="10,40,0,10"/>
 | 
			
		||||
                    <TextBox x:Name="PartCommentInput" Grid.Column="1" Margin="0,40,10,10" Grid.ColumnSpan="2"
 | 
			
		||||
                             TextChanged="TextBox_TextChanged"/>
 | 
			
		||||
 | 
			
		||||
        <GroupBox Header="Herkunft" Grid.Column="1" Grid.Row="4" Margin="5,5,5,10">
 | 
			
		||||
            <Grid>
 | 
			
		||||
                <Grid.ColumnDefinitions>
 | 
			
		||||
                    <ColumnDefinition Width="100"/>
 | 
			
		||||
                    <ColumnDefinition/>
 | 
			
		||||
                </Grid.ColumnDefinitions>
 | 
			
		||||
                    <Label Content="Temperatur:" Margin="10,70,0,10"/>
 | 
			
		||||
                    <Grid Grid.Column="1" Height="25" Margin="0,70,10,10" VerticalAlignment="Top">
 | 
			
		||||
                        <TextBox x:Name="TemperatureInput" TextAlignment="Right" Padding="2,2,16,2"
 | 
			
		||||
                                 TextChanged="TemperatureAcidInput_TextChanged" LostFocus="TemperatureAcidInput_LostFocus"/>
 | 
			
		||||
                        <Label Content="°C" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    </Grid>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Weinbaugebiet:" Margin="10,10,0,10" Grid.Column="0"/>
 | 
			
		||||
                <ComboBox x:Name="WineOriginInput" Margin="0,10,10,10" Grid.Column="1"
 | 
			
		||||
                          ItemTemplate="{StaticResource WineOriginTemplate}"/>
 | 
			
		||||
                    <Label Content="Säure:" Margin="10,100,0,10"/>
 | 
			
		||||
                    <Grid Grid.Column="1" Height="25" Margin="0,100,10,10" VerticalAlignment="Top">
 | 
			
		||||
                        <TextBox x:Name="AcidInput" TextAlignment="Right" Padding="2,2,19,2"
 | 
			
		||||
                                 TextChanged="TemperatureAcidInput_TextChanged" LostFocus="TemperatureAcidInput_LostFocus"/>
 | 
			
		||||
                        <Label Content="g/l" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
			
		||||
                    </Grid>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Weinbau-KG:" Margin="10,40,0,10" Grid.Column="0"/>
 | 
			
		||||
                <ComboBox x:Name="WineKgInput" Margin="0,40,10,10" Grid.Column="1"
 | 
			
		||||
                          DisplayMemberPath="Name"
 | 
			
		||||
                          SelectionChanged="WineKgInput_SelectionChanged"/>
 | 
			
		||||
                    <CheckBox x:Name="LesewagenInput" Content="Lesewagen" Margin="10,75,0,0" Grid.Column="2"
 | 
			
		||||
                              VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                              Checked="LesewagenInput_Changed" Unchecked="LesewagenInput_Changed"/>
 | 
			
		||||
                    <CheckBox x:Name="HandPickedInput" Content="Handlese" Margin="10,105,0,0" Grid.Column="2" IsThreeState="True"
 | 
			
		||||
                              VerticalAlignment="Top" HorizontalAlignment="Left"
 | 
			
		||||
                              Checked="CheckBox_Changed" Unchecked="CheckBox_Changed"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
                <Label Content="Ried:" Margin="10,70,0,10" Grid.Column="0"/>
 | 
			
		||||
                <ComboBox x:Name="WineRdInput" Margin="0,70,10,10" Grid.Column="1"
 | 
			
		||||
                          DisplayMemberPath="Name"/>
 | 
			
		||||
            </Grid>
 | 
			
		||||
        </GroupBox>
 | 
			
		||||
            <GroupBox Header="Teillieferungen" Grid.Column="0" Grid.Row="2" Margin="5,5,5,5">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
                    <ListBox x:Name="DeliveryPartList" Margin="5,5,5,38" Grid.ColumnSpan="2"
 | 
			
		||||
                             SelectionChanged="DeliveryPartList_SelectionChanged">
 | 
			
		||||
                        <ListBox.ItemTemplate>
 | 
			
		||||
                            <DataTemplate>
 | 
			
		||||
                                <StackPanel Orientation="Horizontal">
 | 
			
		||||
                                    <TextBlock Text="{Binding DPNr}" Width="20"/>
 | 
			
		||||
                                    <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 QualId}" Width="30"/>
 | 
			
		||||
                                    <TextBlock Text="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="60" TextAlignment="Right"/>
 | 
			
		||||
                                </StackPanel>
 | 
			
		||||
                            </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>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
 | 
			
		||||
            <GroupBox Header="Herkunft" Grid.Column="0" Grid.Row="3" Margin="5,5,5,10">
 | 
			
		||||
                <Grid>
 | 
			
		||||
                    <Grid.ColumnDefinitions>
 | 
			
		||||
                        <ColumnDefinition Width="100"/>
 | 
			
		||||
                        <ColumnDefinition/>
 | 
			
		||||
                    </Grid.ColumnDefinitions>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Weinbaugebiet:" Margin="10,10,0,10" Grid.Column="0"/>
 | 
			
		||||
                    <ComboBox x:Name="WineOriginInput" Margin="0,10,10,10" Grid.Column="1"
 | 
			
		||||
                              ItemTemplate="{StaticResource WineOriginTemplate}"/>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Weinbau-KG:" Margin="10,40,0,10" Grid.Column="0"/>
 | 
			
		||||
                    <ComboBox x:Name="WineKgInput" Margin="0,40,10,10" Grid.Column="1"
 | 
			
		||||
                              DisplayMemberPath="Name"
 | 
			
		||||
                              SelectionChanged="WineKgInput_SelectionChanged"/>
 | 
			
		||||
 | 
			
		||||
                    <Label Content="Ried:" Margin="10,70,0,10" Grid.Column="0"/>
 | 
			
		||||
                    <ComboBox x:Name="WineRdInput" Margin="0,70,10,10" Grid.Column="1"
 | 
			
		||||
                              DisplayMemberPath="Name"/>
 | 
			
		||||
                </Grid>
 | 
			
		||||
            </GroupBox>
 | 
			
		||||
        </Grid>
 | 
			
		||||
 | 
			
		||||
        <StatusBar Grid.Row="5" Grid.ColumnSpan="3" BorderThickness="0,1,0,0" BorderBrush="Gray">
 | 
			
		||||
            <StatusBar.ItemsPanel>
 | 
			
		||||
 
 | 
			
		||||
@@ -94,6 +94,11 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Menu_Print_DeliveryJournal_ShowToday.IsEnabled = App.IsPrintingReady;
 | 
			
		||||
            Menu_Print_DeliveryJournal_PrintToday.IsEnabled = App.IsPrintingReady;
 | 
			
		||||
            Menu_Print_DeliveryJournal_ShowFilter.IsEnabled = App.IsPrintingReady;
 | 
			
		||||
            Menu_Print_DeliveryJournal_PrintFilter.IsEnabled = App.IsPrintingReady;
 | 
			
		||||
 | 
			
		||||
            OnSecondPassed(null, null);
 | 
			
		||||
            Timer.Start();
 | 
			
		||||
            LockInputs();
 | 
			
		||||
@@ -108,16 +113,16 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_ShowDeliveryNote_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            using var doc = new DeliveryNote(d, Context);
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            doc.Show();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            doc.Show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            using var doc = new DeliveryNote(d, Context);
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
@@ -134,34 +139,71 @@ namespace Elwig.Windows {
 | 
			
		||||
                Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig"
 | 
			
		||||
            };
 | 
			
		||||
            if (d.ShowDialog() == true) {
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                using var file = new Bki(d.FileName);
 | 
			
		||||
                await file.ExportAsync(year);
 | 
			
		||||
                Mouse.OverrideCursor = null;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_ShowDeliveryJournalToday_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
        private async void Menu_Print_DeliveryJournal_ShowToday_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today));
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            doc.Show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_ShowDeliveryJournalYesterday_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
            var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today.AddDays(-1)));
 | 
			
		||||
        private async void Menu_Print_DeliveryJournal_PrintToday_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today));
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            await doc.Print();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_DeliveryJournal_ShowFilter_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            var (f, _, d, _) = await GetFilters();
 | 
			
		||||
            var doc = new DeliveryJournal(string.Join(" / ", f), d);
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            doc.Show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_DeliveryJournal_PrintFilter_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            var (f, _, d, _) = await GetFilters();
 | 
			
		||||
            var doc = new DeliveryJournal(string.Join(" / ", f), d);
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            doc.Show();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            if (IsEditing || IsCreating) {
 | 
			
		||||
                DateInput.IsReadOnly = false;
 | 
			
		||||
                TimeInput.IsReadOnly = false;
 | 
			
		||||
                BranchInput.IsEnabled = true;
 | 
			
		||||
                if (IsCreating) TimeInput.Text = "";
 | 
			
		||||
                OnSecondPassed(null, null);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Menu_Settings_EnableFreeEditing_Unchecked(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            DateInput.IsReadOnly = true;
 | 
			
		||||
            TimeInput.IsReadOnly = true;
 | 
			
		||||
            BranchInput.IsEnabled = false;
 | 
			
		||||
            OnSecondPassed(null, null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void OnSecondPassed(object? sender, EventArgs? evt) {
 | 
			
		||||
            if (IsReceipt && IsCreating) {
 | 
			
		||||
            if (IsReceipt && IsCreating && !Menu_Settings_EnableFreeEditing.IsChecked) {
 | 
			
		||||
                var now = DateTime.Now;
 | 
			
		||||
                TimeInput.Text = now.ToString("HH:mm");
 | 
			
		||||
                DateInput.Text = now.ToString("dd.MM.yyyy");
 | 
			
		||||
                SetDefaultValue(TimeInput);
 | 
			
		||||
                SetDefaultValue(DateInput);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -227,19 +269,27 @@ namespace Elwig.Windows {
 | 
			
		||||
            await RefreshDeliveryListQuery();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task RefreshDeliveryListQuery(bool updateSort = false) {
 | 
			
		||||
        private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, List<string>)> GetFilters() {
 | 
			
		||||
            List<string> filterNames = new();
 | 
			
		||||
            IQueryable<Delivery> deliveryQuery = Context.Deliveries;
 | 
			
		||||
            if (Member != null) {
 | 
			
		||||
                deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr);
 | 
			
		||||
                filterNames.Add(Member.AdministrativeName);
 | 
			
		||||
            }
 | 
			
		||||
            if (TodayOnlyInput.IsChecked == true) {
 | 
			
		||||
                deliveryQuery = deliveryQuery
 | 
			
		||||
                    .Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) || 
 | 
			
		||||
                                (d.DateString == Utils.Today.AddDays(1).ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") <= 0));
 | 
			
		||||
                    .Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") > 0)) ||
 | 
			
		||||
                                (d.DateString == Utils.Today.AddDays(1).ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") <= 0)));
 | 
			
		||||
                filterNames.Add(Utils.Today.ToString("dd.MM.yyyy"));
 | 
			
		||||
            } else if (AllSeasonsInput.IsChecked == false) {
 | 
			
		||||
                deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value);
 | 
			
		||||
                filterNames.Add(SeasonInput.Value.ToString() ?? "");
 | 
			
		||||
            }
 | 
			
		||||
            IQueryable<DeliveryPart> dpq = deliveryQuery.SelectMany(d => d.Parts).OrderBy(p => p.Delivery.DateString).ThenBy(p => p.Delivery.TimeString);
 | 
			
		||||
 | 
			
		||||
            // TODO add filter for:
 | 
			
		||||
            //      attributes
 | 
			
		||||
            //      branches
 | 
			
		||||
            var filterVar = new List<string>();
 | 
			
		||||
            var filterQual = new List<string>();
 | 
			
		||||
            var filterMgNr = new List<int>();
 | 
			
		||||
@@ -256,21 +306,24 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
            var filter = TextFilter.ToList();
 | 
			
		||||
            if (filter.Count > 0) {
 | 
			
		||||
                var var = await Context.WineVarieties.Select(v => v.SortId).ToListAsync();
 | 
			
		||||
                var qual = await Context.WineQualityLevels.Select(q => q.QualId).ToListAsync();
 | 
			
		||||
                var mgnr = await Context.Members.Select(m => m.MgNr.ToString()).ToListAsync();
 | 
			
		||||
                var var = await Context.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
 | 
			
		||||
                var qual = await Context.WineQualityLevels.ToDictionaryAsync(q => q.QualId, q => q);
 | 
			
		||||
                var mgnr = await Context.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
 | 
			
		||||
 | 
			
		||||
                for (int i = 0; i < filter.Count; i++) {
 | 
			
		||||
                    var e = filter[i];
 | 
			
		||||
                    if (e.Length == 2 && var.Contains(e.ToUpper())) {
 | 
			
		||||
                    if (e.Length == 2 && var.ContainsKey(e.ToUpper())) {
 | 
			
		||||
                        filterVar.Add(e.ToUpper());
 | 
			
		||||
                        filter.RemoveAt(i--);
 | 
			
		||||
                    } else if (e.Length == 3 && qual.Contains(e.ToUpper())) {
 | 
			
		||||
                        filterNames.Add(var[e.ToUpper()].Name);
 | 
			
		||||
                    } else if (e.Length == 3 && qual.ContainsKey(e.ToUpper())) {
 | 
			
		||||
                        filterQual.Add(e.ToUpper());
 | 
			
		||||
                        filter.RemoveAt(i--);
 | 
			
		||||
                    } else if (e.All(char.IsAsciiDigit) && mgnr.Contains(e)) {
 | 
			
		||||
                        filterNames.Add(qual[e.ToUpper()].Name);
 | 
			
		||||
                    } else if (e.All(char.IsAsciiDigit) && mgnr.ContainsKey(e)) {
 | 
			
		||||
                        filterMgNr.Add(int.Parse(e));
 | 
			
		||||
                        filter.RemoveAt(i--);
 | 
			
		||||
                        filterNames.Add(mgnr[e].AdministrativeName);
 | 
			
		||||
                    } else if (e.StartsWith(">") || e.StartsWith("<")) {
 | 
			
		||||
                        if (double.TryParse(e[1..], out var num)) {
 | 
			
		||||
                            switch ((e[0], num)) {
 | 
			
		||||
@@ -319,12 +372,23 @@ namespace Elwig.Windows {
 | 
			
		||||
                        filterTimeLt = TimeOnly.TryParse(parts[1], out var to) ? $"{to:HH:mm}" : null;
 | 
			
		||||
                        filter.RemoveAt(i--);
 | 
			
		||||
                    } else if (DateOnly.TryParse(e, out var date)) {
 | 
			
		||||
                        filterDate.Add($"{date:yyyy-MM-dd}");
 | 
			
		||||
                        // TODO allow date ranges
 | 
			
		||||
                        filterDate.Add(date.ToString("yyyy-MM-dd"));
 | 
			
		||||
                        filter.RemoveAt(i--);
 | 
			
		||||
                        filterNames.Add(date.ToString("dd.MM.yyyy"));
 | 
			
		||||
                    } else if (Utils.PartialDateRegex.IsMatch(e)) {
 | 
			
		||||
                        // TODO allow date ranges
 | 
			
		||||
                        var parts = e.Split(".");
 | 
			
		||||
                        filterPartDate.Add($"-{int.Parse(parts[1]):00}-{int.Parse(parts[0]):00}");
 | 
			
		||||
                        var p0 = int.Parse(parts[0]);
 | 
			
		||||
                        var p1 = int.Parse(parts[1]);
 | 
			
		||||
                        filterPartDate.Add($"-{p1:00}-{p0:00}");
 | 
			
		||||
                        filter.RemoveAt(i--);
 | 
			
		||||
                        if (filterNames.Contains(SeasonInput.Value.ToString())) {
 | 
			
		||||
                            filterNames.Remove(SeasonInput.Value.ToString());
 | 
			
		||||
                            filterNames.Add($"{p0:00}.{p1:00}.{SeasonInput.Value:0000}");
 | 
			
		||||
                        } else {
 | 
			
		||||
                            filterNames.Add($"{p0:00}.{p1:00}.");
 | 
			
		||||
                        }
 | 
			
		||||
                    } else if (e.Length > 2 && e.StartsWith("\"") && e.EndsWith("\"")) {
 | 
			
		||||
                        filter[i] = e[1..^1];
 | 
			
		||||
                    } else if (e.Length <= 2) {
 | 
			
		||||
@@ -332,22 +396,58 @@ namespace Elwig.Windows {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (filterMgNr.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterMgNr.Contains(d.MgNr));
 | 
			
		||||
                if (filterDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterDate.Contains(d.DateString));
 | 
			
		||||
                if (filterPartDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterPartDate.Contains(d.DateString.Substring(4)));
 | 
			
		||||
                if (filterYearGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year >= filterYearGt);
 | 
			
		||||
                if (filterYearLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year < filterYearLt);
 | 
			
		||||
                if (filterTimeGt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeGt.CompareTo(d.TimeString) <= 0);
 | 
			
		||||
                if (filterTimeLt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeLt.CompareTo(d.TimeString) > 0);
 | 
			
		||||
                if (filterVar.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterVar.Contains(p.SortId)));
 | 
			
		||||
                if (filterQual.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterQual.Contains(p.QualId)));
 | 
			
		||||
                if (filterKmwGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw >= filterKmwGt));
 | 
			
		||||
                if (filterKmwLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw < filterKmwLt));
 | 
			
		||||
                if (filterOeGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt));
 | 
			
		||||
                if (filterOeLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt));
 | 
			
		||||
                if (filterMgNr.Count > 0) dpq = dpq.Where(p => filterMgNr.Contains(p.Delivery.MgNr));
 | 
			
		||||
                if (filterDate.Count > 0) dpq = dpq.Where(p => filterDate.Contains(p.Delivery.DateString));
 | 
			
		||||
                if (filterPartDate.Count > 0) dpq = dpq.Where(p => filterPartDate.Contains(p.Delivery.DateString.Substring(4)));
 | 
			
		||||
                if (filterYearGt > 0) dpq = dpq.Where(p => p.Year >= filterYearGt);
 | 
			
		||||
                if (filterYearLt > 0) dpq = dpq.Where(p => p.Year < filterYearLt);
 | 
			
		||||
                if (filterTimeGt != null) dpq = dpq.Where(p => p.Delivery.TimeString != null && filterTimeGt.CompareTo(p.Delivery.TimeString) <= 0);
 | 
			
		||||
                if (filterTimeLt != null) dpq = dpq.Where(p => p.Delivery.TimeString != null && filterTimeLt.CompareTo(p.Delivery.TimeString) > 0);
 | 
			
		||||
                if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId));
 | 
			
		||||
                if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId));
 | 
			
		||||
                if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt);
 | 
			
		||||
                if (filterKmwLt > 0) dpq = dpq.Where(p => p.Kmw < filterKmwLt);
 | 
			
		||||
                if (filterOeGt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt);
 | 
			
		||||
                if (filterOeLt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt);
 | 
			
		||||
 | 
			
		||||
                if (filterYearGt > 0 && filterYearLt > 0) {
 | 
			
		||||
                    filterNames.Insert(0, $"{filterYearGt}–{filterYearLt - 1}");
 | 
			
		||||
                } else if (filterYearGt > 0) {
 | 
			
		||||
                    filterNames.Insert(0, $"ab {filterYearGt}");
 | 
			
		||||
                } else if (filterYearLt > 0) {
 | 
			
		||||
                    filterNames.Insert(0, $"bis {filterYearLt - 1}");
 | 
			
		||||
                }
 | 
			
		||||
                if (filterKmwGt > 0 && filterKmwLt > 0) {
 | 
			
		||||
                    filterNames.Add($"{filterKmwGt:N1}–{filterKmwLt:N1} °KMW");
 | 
			
		||||
                } else if (filterKmwGt > 0) {
 | 
			
		||||
                    filterNames.Add($"ab {filterKmwGt:N1} °KMW");
 | 
			
		||||
                } else if (filterKmwLt > 0) {
 | 
			
		||||
                    filterNames.Add($"bis {filterKmwLt:N1} °KMW");
 | 
			
		||||
                }
 | 
			
		||||
                if (filterOeGt > 0 && filterOeLt > 0) {
 | 
			
		||||
                    filterNames.Add($"{filterOeGt:N1}–{filterOeLt:N1} °Oe");
 | 
			
		||||
                } else if (filterOeGt > 0) {
 | 
			
		||||
                    filterNames.Add($"ab {filterOeGt:N1} °Oe");
 | 
			
		||||
                } else if (filterOeLt > 0) {
 | 
			
		||||
                    filterNames.Add($"bis {filterOeLt:N1} °Oe");
 | 
			
		||||
                }
 | 
			
		||||
                if (filterTimeGt != null && filterTimeLt != null) {
 | 
			
		||||
                    filterNames.Add($"{filterTimeGt}–{filterTimeLt}");
 | 
			
		||||
                } else if (filterTimeGt != null) {
 | 
			
		||||
                    filterNames.Add($"ab {filterTimeGt}");
 | 
			
		||||
                } else if (filterTimeLt != null) {
 | 
			
		||||
                    filterNames.Add($"bis {filterTimeLt}");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            List<Delivery> deliveries = await deliveryQuery.OrderByDescending(d => d.DateString).ThenByDescending(d => d.TimeString).ToListAsync();
 | 
			
		||||
            return (filterNames, dpq.Select(p => p.Delivery).Distinct().OrderBy(d => d.DateString).ThenBy(d => d.TimeString), dpq, filter);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task RefreshDeliveryListQuery(bool updateSort = false) {
 | 
			
		||||
            var (_, deliveryQuery, deliveryPartsQuery, filter) = await GetFilters();
 | 
			
		||||
            var deliveries = await deliveryQuery.ToListAsync();
 | 
			
		||||
            deliveries.Reverse();
 | 
			
		||||
 | 
			
		||||
            if (filter.Count > 0 && deliveries.Count > 0) {
 | 
			
		||||
                var dict = deliveries.AsParallel()
 | 
			
		||||
                    .ToDictionary(d => d, d => d.SearchScore(TextFilter))
 | 
			
		||||
@@ -365,18 +465,11 @@ namespace Elwig.Windows {
 | 
			
		||||
 | 
			
		||||
            var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList();
 | 
			
		||||
            StatusMembers.Text = $"Mitglieder: {members.Count}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
 | 
			
		||||
            StatusMembers.ToolTip = StatusMembers.Text;
 | 
			
		||||
            StatusDeliveries.Text = $"Lieferungen: {deliveries.Count}";
 | 
			
		||||
 | 
			
		||||
            if (filter.Count == 0) {
 | 
			
		||||
                var partsQuery = deliveryQuery.SelectMany(d => d.Parts);
 | 
			
		||||
                if (filterVar.Count > 0) partsQuery = partsQuery.Where(p => filterVar.Contains(p.SortId));
 | 
			
		||||
                if (filterQual.Count > 0) partsQuery = partsQuery.Where(p => filterQual.Contains(p.QualId));
 | 
			
		||||
                if (filterKmwGt > 0) partsQuery = partsQuery.Where(p => p.Kmw >= filterKmwGt);
 | 
			
		||||
                if (filterKmwLt > 0) partsQuery = partsQuery.Where(p => p.Kmw < filterKmwLt);
 | 
			
		||||
                if (filterOeGt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt);
 | 
			
		||||
                if (filterOeLt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt);
 | 
			
		||||
                var deliveryParts = partsQuery;
 | 
			
		||||
 | 
			
		||||
                var deliveryParts = deliveryPartsQuery;
 | 
			
		||||
                var n = await deliveryParts.CountAsync();
 | 
			
		||||
                StatusDeliveries.Text = $"Lieferungen: {deliveries.Count} ({n})";
 | 
			
		||||
                var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync();
 | 
			
		||||
@@ -394,9 +487,8 @@ namespace Elwig.Windows {
 | 
			
		||||
                    StatusGradation.Text = "Gradation: -";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                if (n > 0 && (n <= 200 || TodayOnlyInput.IsChecked == true)) {
 | 
			
		||||
                    var parts = (await deliveryParts.ToListAsync());
 | 
			
		||||
                    var parts = await deliveryParts.ToListAsync();
 | 
			
		||||
                    var groups = parts
 | 
			
		||||
                        .GroupBy(p => string.Join("/", p.Attributes.Select(a => a.Name)))
 | 
			
		||||
                        .Select(g => (g.Key, g.Sum(p => p.Weight), g.Min(p => p.Kmw), Utils.AggregateDeliveryPartsKmw(g), g.Max(p => p.Kmw)))
 | 
			
		||||
@@ -430,6 +522,10 @@ namespace Elwig.Windows {
 | 
			
		||||
                StatusWeight.Text = "Gewicht: -";
 | 
			
		||||
                StatusGradation.Text = "Gradation: -";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            StatusVarieties.ToolTip = StatusVarieties.Text;
 | 
			
		||||
            StatusWeight.ToolTip = StatusWeight.Text;
 | 
			
		||||
            StatusGradation.ToolTip = StatusGradation.Text;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override async Task OnRenewContext() {
 | 
			
		||||
@@ -585,10 +681,10 @@ namespace Elwig.Windows {
 | 
			
		||||
            if (deliveryNew || InputHasChanged(DateInput)) {
 | 
			
		||||
                d.LNr = await Context.NextLNr(d.Date);
 | 
			
		||||
            }
 | 
			
		||||
            if (IsCreating) {
 | 
			
		||||
            if (IsCreating && !InputIsNotDefault(TimeInput)) {
 | 
			
		||||
                d.TimeString = DateTime.Now.ToString("HH:mm:ss");
 | 
			
		||||
            } else if (InputHasChanged(TimeInput)) {
 | 
			
		||||
                d.TimeString = TimeInput.Text + ":00";
 | 
			
		||||
            } else if (IsCreating || InputHasChanged(TimeInput)) {
 | 
			
		||||
                d.TimeString = (TimeInput.Text != "") ? TimeInput.Text + ":00" : null;
 | 
			
		||||
            }
 | 
			
		||||
            d.ZwstId = (BranchInput.SelectedItem as Branch)?.ZwstId;
 | 
			
		||||
            d.LsNr = LsNrInput.Text;
 | 
			
		||||
@@ -790,7 +886,7 @@ namespace Elwig.Windows {
 | 
			
		||||
            NewDeliveryPartButton.Cursor = Cursors.Wait;
 | 
			
		||||
            DeliveryPartList.IsEnabled = false;
 | 
			
		||||
            var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
 | 
			
		||||
			EmptyScale();
 | 
			
		||||
            EmptyScale();
 | 
			
		||||
            await RefreshDeliveryList();
 | 
			
		||||
            await RefreshDeliveryParts();
 | 
			
		||||
            NewDeliveryPartButton.Cursor = null;
 | 
			
		||||
@@ -806,19 +902,18 @@ namespace Elwig.Windows {
 | 
			
		||||
            FinishButton.Cursor = Cursors.Wait;
 | 
			
		||||
            DeliveryPartList.IsEnabled = false;
 | 
			
		||||
            var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
 | 
			
		||||
			EmptyScale();
 | 
			
		||||
			await RefreshDeliveryList();
 | 
			
		||||
            EmptyScale();
 | 
			
		||||
            await RefreshDeliveryList();
 | 
			
		||||
            await RefreshDeliveryParts();
 | 
			
		||||
            if (p?.Delivery != null) {
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                using var doc = new DeliveryNote(p.Delivery, Context);
 | 
			
		||||
                await doc.Generate();
 | 
			
		||||
                Mouse.OverrideCursor = null;
 | 
			
		||||
                if (App.Config.Debug) {
 | 
			
		||||
                    doc.Show();
 | 
			
		||||
                } else {
 | 
			
		||||
                    await doc.Print(2);
 | 
			
		||||
                    Activate();
 | 
			
		||||
                    doc.Print(2);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            FinishButton.Cursor = null;
 | 
			
		||||
@@ -882,7 +977,7 @@ namespace Elwig.Windows {
 | 
			
		||||
            try {
 | 
			
		||||
                if (res == null || res <= 0)
 | 
			
		||||
                    return;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                ClearOriginalValues();
 | 
			
		||||
                if (res >= p.Weight) {
 | 
			
		||||
                    ControlUtils.SelectComboBoxItem(WineQualityLevelInput, q => (q as WineQualLevel)?.QualId, "WEI");
 | 
			
		||||
@@ -964,7 +1059,7 @@ namespace Elwig.Windows {
 | 
			
		||||
                $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?",
 | 
			
		||||
                "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
			
		||||
            if (r == MessageBoxResult.Yes) {
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                Context.Remove(d);
 | 
			
		||||
                await Context.SaveChangesAsync();
 | 
			
		||||
                await RefreshDeliveryList();
 | 
			
		||||
@@ -1039,8 +1134,8 @@ namespace Elwig.Windows {
 | 
			
		||||
                day = day.AddDays(-1);
 | 
			
		||||
            var lsnrs = await Context.Deliveries
 | 
			
		||||
                .Where(d => d.ZwstId == delivery.ZwstId)
 | 
			
		||||
                .Where(d => (d.DateString == day.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) ||
 | 
			
		||||
                            (d.DateString == day.AddDays(1).ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") <= 0))
 | 
			
		||||
                .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)
 | 
			
		||||
@@ -1051,7 +1146,7 @@ namespace Elwig.Windows {
 | 
			
		||||
            EntityEntry<Delivery>? entry = null;
 | 
			
		||||
            try {
 | 
			
		||||
                Delivery? d = null;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                if (res == "new") {
 | 
			
		||||
                    d = Context.CreateProxy<Delivery>();
 | 
			
		||||
                    d.Date = delivery.Date;
 | 
			
		||||
@@ -1102,7 +1197,7 @@ namespace Elwig.Windows {
 | 
			
		||||
                $"Soll die Teillieferung Nr. {p.DPNr} wirklich unwiderruflich gelöscht werden?",
 | 
			
		||||
                "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
			
		||||
            if (r == MessageBoxResult.Yes) {
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
                Context.Remove(p);
 | 
			
		||||
                await Context.SaveChangesAsync();
 | 
			
		||||
                await RefreshDeliveryParts();
 | 
			
		||||
@@ -1192,9 +1287,9 @@ namespace Elwig.Windows {
 | 
			
		||||
            AbgewertetInput.IsEnabled = false;
 | 
			
		||||
            ManualWeighingInput.IsEnabled = false;
 | 
			
		||||
            LsNrInput.IsReadOnly = true;
 | 
			
		||||
            DateInput.IsReadOnly = true;
 | 
			
		||||
            TimeInput.IsReadOnly = true;
 | 
			
		||||
            BranchInput.IsEnabled = false;
 | 
			
		||||
            DateInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked;
 | 
			
		||||
            TimeInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked;
 | 
			
		||||
            BranchInput.IsEnabled = Menu_Settings_EnableFreeEditing.IsChecked;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DisableWeighingButtons() {
 | 
			
		||||
@@ -1218,15 +1313,25 @@ namespace Elwig.Windows {
 | 
			
		||||
            if (DateInput.Text == "" || BranchInput.SelectedItem == null) {
 | 
			
		||||
                LsNrInput.Text = "";
 | 
			
		||||
            } else {
 | 
			
		||||
                var branch = (Branch)BranchInput.SelectedItem;
 | 
			
		||||
                var date = DateOnly.ParseExact(DateInput.Text, "dd.MM.yyyy");
 | 
			
		||||
                var lnr = await Context.NextLNr(date);
 | 
			
		||||
                LsNrInput.Text = Utils.GenerateLsNr(date, branch.ZwstId, lnr);
 | 
			
		||||
                try {
 | 
			
		||||
                    var branch = (Branch)BranchInput.SelectedItem;
 | 
			
		||||
                    var date = DateOnly.ParseExact(DateInput.Text, "dd.MM.yyyy");
 | 
			
		||||
                    var lnr = await Context.NextLNr(date);
 | 
			
		||||
                    LsNrInput.Text = Utils.GenerateLsNr(date, branch.ZwstId, lnr);
 | 
			
		||||
                } catch {
 | 
			
		||||
                    LsNrInput.Text = "";
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DateInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
			
		||||
            if (IsCreating) UpdateLsNr().GetAwaiter().GetResult();
 | 
			
		||||
            base.DateInput_TextChanged(sender, evt);
 | 
			
		||||
            if (IsEditing ||  IsCreating) UpdateLsNr().GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void BranchInput_SelectionChanged(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            base.ComboBox_SelectionChanged(sender, evt);
 | 
			
		||||
            if (IsEditing || IsCreating) UpdateLsNr().GetAwaiter().GetResult();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void UpdateWineVariety(bool valid) {
 | 
			
		||||
 
 | 
			
		||||
@@ -55,7 +55,12 @@
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
            <MenuItem Header="Drucken">
 | 
			
		||||
                <MenuItem Header="Stammdatenblatt drucken"/>
 | 
			
		||||
                <MenuItem Header="Mitgliederliste drucken"/>
 | 
			
		||||
                <MenuItem Header="Briefköpfe drucken">
 | 
			
		||||
                    <MenuItem x:Name="Menu_Print_Letterheads_MgNr" Header="nach MgNr. sortiert" IsEnabled="False" Tag="Print"
 | 
			
		||||
                              Click="Menu_Print_Letterheads_MgNr_Click"/>
 | 
			
		||||
                    <MenuItem x:Name="Menu_Print_Letterheads_Name" Header="nach Name sortiert" IsEnabled="False" Tag="Print"
 | 
			
		||||
                              Click="Menu_Print_Letterheads_Name_Click"/>
 | 
			
		||||
                </MenuItem>
 | 
			
		||||
            </MenuItem>
 | 
			
		||||
            <MenuItem Header="Rundschreiben">
 | 
			
		||||
                <MenuItem Header="Runschreiben ausschicken"/>
 | 
			
		||||
@@ -88,9 +93,15 @@
 | 
			
		||||
                      SelectionChanged="MemberList_SelectionChanged"
 | 
			
		||||
                      Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
 | 
			
		||||
                <DataGrid.Columns>
 | 
			
		||||
                    <DataGridTextColumn Header="MgNr."    Binding="{Binding MgNr}"       Width="70"/>
 | 
			
		||||
                    <DataGridTextColumn Header="MgNr."    Binding="{Binding MgNr, StringFormat='{}{0} '}" Width="50">
 | 
			
		||||
                        <DataGridTextColumn.CellStyle>
 | 
			
		||||
                            <Style>
 | 
			
		||||
                                <Setter Property="TextBlock.TextAlignment" Value="Right"/>
 | 
			
		||||
                            </Style>
 | 
			
		||||
                        </DataGridTextColumn.CellStyle>
 | 
			
		||||
                    </DataGridTextColumn>
 | 
			
		||||
                    <DataGridTextColumn Header="Nachname" Binding="{Binding FamilyName}" Width="4*"/>
 | 
			
		||||
                    <DataGridTextColumn Header="Vorname"  Binding="{Binding GivenName}"  Width="3*"/>
 | 
			
		||||
                    <DataGridTextColumn Header="Vorname"  Binding="{Binding GivenName}" Width="3*"/>
 | 
			
		||||
                </DataGrid.Columns>
 | 
			
		||||
            </DataGrid>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,7 @@ using Elwig.Models;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
			
		||||
using System.Collections.ObjectModel;
 | 
			
		||||
using Elwig.Documents;
 | 
			
		||||
 | 
			
		||||
namespace Elwig.Windows {
 | 
			
		||||
    public partial class MemberAdminWindow : AdministrationWindow {
 | 
			
		||||
@@ -54,6 +55,9 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Menu_Print_Letterheads_MgNr.IsEnabled = App.IsPrintingReady;
 | 
			
		||||
            Menu_Print_Letterheads_Name.IsEnabled = App.IsPrintingReady;
 | 
			
		||||
 | 
			
		||||
            ActiveMemberInput.IsChecked = true;
 | 
			
		||||
            UpdatePhoneNrInputVisibility();
 | 
			
		||||
            LockInputs();
 | 
			
		||||
@@ -266,7 +270,50 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void Menu_Member_SendEmail_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Utils.MailTo(((Member)MemberList.SelectedItem).EmailAddresses.First().Address);
 | 
			
		||||
            Utils.MailTo(((Member)MemberList.SelectedItem).EmailAddresses.Select(a => a.Address));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_Letterheads_MgNr_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            var n = await Context.Members.CountAsync(m => m.IsActive);
 | 
			
		||||
            var res = MessageBox.Show(
 | 
			
		||||
                $"Sollen wirklich {n} Seiten gedruckt werden?", "Ausdruck Bestätigen",
 | 
			
		||||
                MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
			
		||||
            if (res != MessageBoxResult.Yes)
 | 
			
		||||
                return;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            using var doc = await Document.Merge(Context.Members
 | 
			
		||||
                .Where(m => m.IsActive && m.ContactViaPost)
 | 
			
		||||
                .OrderBy(m => m.MgNr)
 | 
			
		||||
                .Select(m => new Letterhead(m)));
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            if (App.Config.Debug) {
 | 
			
		||||
                doc.Show();
 | 
			
		||||
            } else {
 | 
			
		||||
                await doc.Print();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void Menu_Print_Letterheads_Name_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            var n = await Context.Members.CountAsync(m => m.IsActive);
 | 
			
		||||
            var res = MessageBox.Show(
 | 
			
		||||
                $"Sollen wirklich {n} Seiten gedruckt werden?", "Ausdruck Bestätigen",
 | 
			
		||||
                MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
			
		||||
            if (res != MessageBoxResult.Yes)
 | 
			
		||||
                return;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            using var doc = await Document.Merge(Context.Members
 | 
			
		||||
                .Where(m => m.IsActive && m.ContactViaPost)
 | 
			
		||||
                .OrderBy(m => m.FamilyName)
 | 
			
		||||
                .ThenBy(m => m.GivenName)
 | 
			
		||||
                .Select(m => new Letterhead(m)));
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
            Mouse.OverrideCursor = null;
 | 
			
		||||
            if (App.Config.Debug) {
 | 
			
		||||
                doc.Show();
 | 
			
		||||
            } else {
 | 
			
		||||
                await doc.Print();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void FocusSearchInput(object sender, RoutedEventArgs evt) {
 | 
			
		||||
 
 | 
			
		||||
@@ -19,9 +19,9 @@
 | 
			
		||||
        <Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click"
 | 
			
		||||
                Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
			
		||||
 | 
			
		||||
        <Button x:Name="PdfDeliveryButton" Content="Lieferschein Erzeugen" Click="PdfDeliveryButton_Click" Tag="Print"
 | 
			
		||||
        <Button x:Name="PdfDeliveryButton" Content="Lieferschein Erzeugen" Click="PdfDeliveryButton_Click" Tag="Print" IsEnabled="False"
 | 
			
		||||
                Margin="260,190,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
			
		||||
        <Button x:Name="PdfCreditButton" Content="Gutschrift Erzeugen" Click="PdfCreditButton_Click" Tag="Print"
 | 
			
		||||
        <Button x:Name="PdfCreditButton" Content="Gutschrift Erzeugen" Click="PdfCreditButton_Click" Tag="Print" IsEnabled="False"
 | 
			
		||||
                Margin="260,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</Window>
 | 
			
		||||
 
 | 
			
		||||
@@ -51,7 +51,7 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void PdfDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            using var ctx = new AppDbContext();
 | 
			
		||||
            using var doc = new DeliveryNote(await ctx.Deliveries.OrderBy(d => d.Parts.Count).ThenBy(d => d.Year).ThenBy(d => d.DId).LastAsync(), ctx);
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
@@ -60,7 +60,7 @@ namespace Elwig.Windows {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async void PdfCreditButton_Click(object sender, RoutedEventArgs evt) {
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
			
		||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
			
		||||
            using var ctx = new AppDbContext();
 | 
			
		||||
            using var doc = new CreditNote(await ctx.Credits.FirstAsync(), ctx);
 | 
			
		||||
            await doc.Generate();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user