Compare commits
	
		
			33 Commits
		
	
	
		
			b4f1eeee84
			...
			v0.3.4
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| de298ffef1 | |||
| eaf7b6bd41 | |||
| 2bb8205da0 | |||
| f623aa1fee | |||
| 00e7eeb774 | |||
| 47d51ded51 | |||
| 532bb826e1 | |||
| 8193bf483c | |||
| 34dcaf26d9 | |||
| 7411f570ee | |||
| 52702f3fa2 | |||
| 7f3573cede | |||
| 72359dc8be | |||
| 0e17aa5408 | |||
| 2bf850bc55 | |||
| aadf536d13 | |||
| 3be6371be1 | |||
| ca1b68aa4f | |||
| d4e5ac6753 | |||
| c9f49927a8 | |||
| 1794b5b8ca | |||
| 7347439034 | |||
| 51ad8f99fd | |||
| 39279a5dda | |||
| 5271f357f5 | |||
| 13ba3f90f6 | |||
| 43be8bf391 | |||
| 826a76c56c | |||
| efaae5f490 | |||
| 3a73265a75 | |||
| a6fef7fd9b | |||
| a08df4c3ed | |||
| 9701af9e36 | 
@@ -157,9 +157,12 @@ namespace Elwig {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        protected void OnPrintingReadyChanged(EventArgs evt) {
 | 
					        protected void OnPrintingReadyChanged(EventArgs evt) {
 | 
				
			||||||
            foreach (Window w in Windows) {
 | 
					            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;
 | 
					                    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;
 | 
					using Elwig.Models;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
@@ -26,14 +27,9 @@ namespace Elwig.Documents {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public string Address {
 | 
					        public string Address {
 | 
				
			||||||
            get {
 | 
					            get {
 | 
				
			||||||
                var b = Member.BillingAddress;
 | 
					                IAddress addr = (Member.BillingAddress != null && UseBillingAddress) ? Member.BillingAddress : Member;
 | 
				
			||||||
                if (b != null && UseBillingAddress) {
 | 
					                var plz = addr.PostalDest.AtPlz;
 | 
				
			||||||
                    var plz = b.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}";
 | 
				
			||||||
                    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";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										67
									
								
								Elwig/Documents/DeliveryJournal.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Elwig/Documents/DeliveryJournal.cshtml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,67 @@
 | 
				
			|||||||
 | 
					@using RazorLight
 | 
				
			||||||
 | 
					@inherits TemplatePage<Elwig.Documents.DeliveryJournal>
 | 
				
			||||||
 | 
					@model Elwig.Documents.DeliveryJournal
 | 
				
			||||||
 | 
					@{ Layout = "Document"; }
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\style-deliveryjournal.css"/>
 | 
				
			||||||
 | 
					<main>
 | 
				
			||||||
 | 
					    <h1>Lieferjournal</h1>
 | 
				
			||||||
 | 
					    <h2>@Model.Filter</h2>
 | 
				
			||||||
 | 
					    <table class="journal">
 | 
				
			||||||
 | 
					        <colgroup>
 | 
				
			||||||
 | 
					            <col style="width: 25mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 5mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 17mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 8mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 38mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 28mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 14mm;"/>
 | 
				
			||||||
 | 
					        </colgroup>
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th rowspan="2" style="text-align: left;">Lieferschein-Nr.</th>
 | 
				
			||||||
 | 
					                <th rowspan="2">Pos.</th>
 | 
				
			||||||
 | 
					                <th rowspan="2">Datum</th>
 | 
				
			||||||
 | 
					                <th rowspan="2">Zeit</th>
 | 
				
			||||||
 | 
					                <th colspan="2" rowspan="2" style="text-align: left;">Mitglied</th>
 | 
				
			||||||
 | 
					                <th rowspan="2" style="text-align: left;">Sorte</th>
 | 
				
			||||||
 | 
					                <th colspan="2">Gradation</th>
 | 
				
			||||||
 | 
					                <th>Gewicht</th>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>[°Oe]</th>
 | 
				
			||||||
 | 
					                <th>[°KMW]</th>
 | 
				
			||||||
 | 
					                <th>[kg]</th>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            @foreach (var p in Model.Deliveries) {
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <td>@p.Delivery.LsNr</td>
 | 
				
			||||||
 | 
					                    <td>@p.DPNr</td>
 | 
				
			||||||
 | 
					                    <td>@($"{p.Delivery.Date:dd.MM.yyyy}")</td>
 | 
				
			||||||
 | 
					                    <td>@($"{p.Delivery.Time:HH:mm}")</td>
 | 
				
			||||||
 | 
					                    <td class="mgnr">@p.Delivery.Member.MgNr</td>
 | 
				
			||||||
 | 
					                    <td>@p.Delivery.Member.AdministrativeName</td>
 | 
				
			||||||
 | 
					                    <td>@p.Variant.Name</td>
 | 
				
			||||||
 | 
					                    <td class="grad">@($"{p.Oe:N0}")</td>
 | 
				
			||||||
 | 
					                    <td class="grad">@($"{p.Kmw:N1}")</td>
 | 
				
			||||||
 | 
					                    <td class="weight">@($"{p.Weight:N0}")</td>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            <tr class="sum">
 | 
				
			||||||
 | 
					                @{
 | 
				
			||||||
 | 
					                    var kmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(Model.Deliveries);
 | 
				
			||||||
 | 
					                    var oe = Elwig.Helpers.Utils.KmwToOe(kmw);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                <td colspan="2">Gesamt:</td>
 | 
				
			||||||
 | 
					                <td colspan="5">(Teil-)Lieferungen: @($"{Model.Deliveries.DistinctBy(p => p.Delivery).Count():N0}") (@($"{Model.Deliveries.Count():N0}"))</td>
 | 
				
			||||||
 | 
					                <td class="grad">@($"{oe:N0}")</td>
 | 
				
			||||||
 | 
					                <td class="grad">@($"{kmw:N1}")</td>
 | 
				
			||||||
 | 
					                <td class="weight">@($"{Model.Deliveries.Sum(p => p.Weight):N0}")</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
							
								
								
									
										34
									
								
								Elwig/Documents/DeliveryJournal.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								Elwig/Documents/DeliveryJournal.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
				
			|||||||
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using Elwig.Models;
 | 
				
			||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
 | 
					    public class DeliveryJournal : Document {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Filter;
 | 
				
			||||||
 | 
					        public IEnumerable<DeliveryPart> Deliveries;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DeliveryJournal(string filter, IEnumerable<DeliveryPart> deliveries) : base($"Lieferjournal {filter}") {
 | 
				
			||||||
 | 
					            Filter = filter;
 | 
				
			||||||
 | 
					            Deliveries = deliveries;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DeliveryJournal(string filter, IQueryable<DeliveryPart> deliveries) :
 | 
				
			||||||
 | 
					            this(filter, deliveries
 | 
				
			||||||
 | 
					                .Include(p => p.Delivery)
 | 
				
			||||||
 | 
					                .Include(p => p.Delivery.Member)
 | 
				
			||||||
 | 
					                .Include(p => p.Variant)
 | 
				
			||||||
 | 
					                .ToList()) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public DeliveryJournal(AppDbContext ctx, DateOnly date) :
 | 
				
			||||||
 | 
					            this(date.ToString("dd.MM.yyyy"), ctx.DeliveryParts
 | 
				
			||||||
 | 
					                .Where(p => p.Delivery.DateString == date.ToString("yyy-MM-dd"))
 | 
				
			||||||
 | 
					                .OrderBy(p => p.Delivery.DateString)
 | 
				
			||||||
 | 
					                .ThenBy(p => p.Delivery.TimeString)
 | 
				
			||||||
 | 
					                .ThenBy(p => p.Delivery.LsNr)
 | 
				
			||||||
 | 
					                .ThenBy(p => p.DPNr)) { }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,11 +2,15 @@ using System;
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using System.IO;
 | 
					using System.IO;
 | 
				
			||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text.RegularExpressions;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					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;
 | 
					        public bool ShowFoldMarks = App.Config.Debug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,17 +39,56 @@ namespace Elwig.Documents {
 | 
				
			|||||||
            Date = DateTime.Today;
 | 
					            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() {
 | 
					        ~Document() {
 | 
				
			||||||
            Dispose();
 | 
					            Dispose();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void Dispose() {
 | 
					        public void Dispose() {
 | 
				
			||||||
            PdfFile?.Dispose();
 | 
					            _pdfFile?.Dispose();
 | 
				
			||||||
            PdfFile = null;
 | 
					            _pdfFile = null;
 | 
				
			||||||
            GC.SuppressFinalize(this);
 | 
					            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;
 | 
					            string name;
 | 
				
			||||||
            if (this is BusinessLetter) {
 | 
					            if (this is BusinessLetter) {
 | 
				
			||||||
                name = "BusinessLetter";
 | 
					                name = "BusinessLetter";
 | 
				
			||||||
@@ -53,14 +96,19 @@ namespace Elwig.Documents {
 | 
				
			|||||||
                name = "DeliveryNote";
 | 
					                name = "DeliveryNote";
 | 
				
			||||||
            } else if (this is CreditNote) {
 | 
					            } else if (this is CreditNote) {
 | 
				
			||||||
                name = "CreditNote";
 | 
					                name = "CreditNote";
 | 
				
			||||||
 | 
					            } else if (this is DeliveryJournal) {
 | 
				
			||||||
 | 
					                name = "DeliveryJournal";
 | 
				
			||||||
 | 
					            } else if (this is Letterhead) {
 | 
				
			||||||
 | 
					                name = "Letterhead";
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                throw new InvalidOperationException("Invalid document object");
 | 
					                throw new InvalidOperationException("Invalid document object");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return Render(name);
 | 
					            return await Render(name);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private Task<string> Render(string name) {
 | 
					        private async Task<string> Render(string name) {
 | 
				
			||||||
            return Html.CompileRenderAsync(name, this);
 | 
					            _renderedHtml = await Html.CompileRenderAsync(name, this);
 | 
				
			||||||
 | 
					            return _renderedHtml;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task Generate() {
 | 
					        public async Task Generate() {
 | 
				
			||||||
@@ -69,22 +117,26 @@ namespace Elwig.Documents {
 | 
				
			|||||||
                await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
 | 
					                await File.WriteAllTextAsync(tmpHtml.FilePath, await Render(), Utils.UTF8);
 | 
				
			||||||
                await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath);
 | 
					                await Pdf.Convert(tmpHtml.FilePath, pdf.FilePath);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            PdfFile = pdf;
 | 
					            _pdfFile = pdf;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void SaveTo(string pdfPath) {
 | 
					        public void SaveTo(string pdfPath) {
 | 
				
			||||||
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
					            if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
				
			||||||
            File.Copy(PdfFile.FilePath, pdfPath);
 | 
					            File.Copy(_pdfFile.FilePath, pdfPath);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task Print(int copies = 1) {
 | 
					        public async Task Print(int copies = 1) {
 | 
				
			||||||
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
					            if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
				
			||||||
            await Pdf.Print(PdfFile.FilePath, copies);
 | 
					            await Pdf.Print(_pdfFile.FilePath, copies);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public void Show() {
 | 
					        public void Show() {
 | 
				
			||||||
            if (PdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
					            if (_pdfFile == null) throw new InvalidOperationException("Pdf file has not been generated yet");
 | 
				
			||||||
            Pdf.Show(PdfFile.NewReference(), Title);
 | 
					            Pdf.Show(_pdfFile.NewReference(), Title);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private class InternalDocument : Document {
 | 
				
			||||||
 | 
					            public InternalDocument(string title) : base(title) { }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,8 @@ namespace Elwig.Documents {
 | 
				
			|||||||
            await e.CompileTemplateAsync("BusinessLetter");
 | 
					            await e.CompileTemplateAsync("BusinessLetter");
 | 
				
			||||||
            await e.CompileTemplateAsync("DeliveryNote");
 | 
					            await e.CompileTemplateAsync("DeliveryNote");
 | 
				
			||||||
            await e.CompileTemplateAsync("CreditNote");
 | 
					            await e.CompileTemplateAsync("CreditNote");
 | 
				
			||||||
 | 
					            await e.CompileTemplateAsync("DeliveryJournal");
 | 
				
			||||||
 | 
					            await e.CompileTemplateAsync("Letterhead");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Engine = e;
 | 
					            Engine = e;
 | 
				
			||||||
            evtHandler();
 | 
					            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) {
 | 
					        public static async Task Print(string path, int copies = 1) {
 | 
				
			||||||
            var p = new Process() { StartInfo = new() { FileName = PdfToPrinter } };
 | 
					            var p = new Process() { StartInfo = new() { FileName = PdfToPrinter } };
 | 
				
			||||||
            p.StartInfo.ArgumentList.Add(path);
 | 
					            p.StartInfo.ArgumentList.Add(path);
 | 
				
			||||||
 | 
					            p.StartInfo.ArgumentList.Add("/s");
 | 
				
			||||||
            p.StartInfo.ArgumentList.Add($"copies={copies}");
 | 
					            p.StartInfo.ArgumentList.Add($"copies={copies}");
 | 
				
			||||||
            p.Start();
 | 
					            p.Start();
 | 
				
			||||||
            await p.WaitForExitAsync();
 | 
					            await p.WaitForExitAsync();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								Elwig/Documents/style-deliveryjournal.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Elwig/Documents/style-deliveryjournal.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					h1 {
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    font-size: 24pt;
 | 
				
			||||||
 | 
					    margin-bottom: 2mm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					h2 {
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					    font-size: 14pt;
 | 
				
			||||||
 | 
					    margin-top: 2mm;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal {
 | 
				
			||||||
 | 
					    font-size: 10pt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal thead {
 | 
				
			||||||
 | 
					    font-size: 8pt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal th {
 | 
				
			||||||
 | 
					    font-weight: normal;
 | 
				
			||||||
 | 
					    font-style: italic;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal td {
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    white-space: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal .mgnr,
 | 
				
			||||||
 | 
					table.journal .weight {
 | 
				
			||||||
 | 
					    text-align: right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal .grad {
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal tr.sum {
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.journal tr.sum td {
 | 
				
			||||||
 | 
					    border-top: 0.5pt solid black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -20,6 +20,9 @@
 | 
				
			|||||||
hr.page-break {
 | 
					hr.page-break {
 | 
				
			||||||
    display: none;
 | 
					    display: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					.document-break {
 | 
				
			||||||
 | 
					    break-before: page;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@page {
 | 
					@page {
 | 
				
			||||||
    size: A4;
 | 
					    size: A4;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
    <UseWPF>true</UseWPF>
 | 
					    <UseWPF>true</UseWPF>
 | 
				
			||||||
    <PreserveCompilationContext>true</PreserveCompilationContext>
 | 
					    <PreserveCompilationContext>true</PreserveCompilationContext>
 | 
				
			||||||
    <ApplicationIcon>elwig.ico</ApplicationIcon>
 | 
					    <ApplicationIcon>elwig.ico</ApplicationIcon>
 | 
				
			||||||
    <Version>0.3.1</Version>
 | 
					    <Version>0.3.4</Version>
 | 
				
			||||||
    <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
 | 
					    <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ using System;
 | 
				
			|||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public static class AppDbUpdater {
 | 
					    public static class AppDbUpdater {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static readonly int RequiredSchemaVersion = 1;
 | 
					        public static readonly int RequiredSchemaVersion = 2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static int _versionOffset = 0;
 | 
					        private static int _versionOffset = 0;
 | 
				
			||||||
        private static readonly Action<SqliteConnection>[] _updaters = new[] {
 | 
					        private static readonly Action<SqliteConnection>[] _updaters = new[] {
 | 
				
			||||||
@@ -42,7 +42,10 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            var minor = (userVers >> 16) & 0xFF;
 | 
					            var minor = (userVers >> 16) & 0xFF;
 | 
				
			||||||
            var patch = userVers & 0xFFFF;
 | 
					            var patch = userVers & 0xFFFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (App.VersionMajor > major || App.VersionMinor > minor || App.VersionPatch > patch) {
 | 
					            if (App.VersionMajor > major ||
 | 
				
			||||||
 | 
					                (App.VersionMajor == major && App.VersionMinor > minor) ||
 | 
				
			||||||
 | 
					                (App.VersionMajor == major && App.VersionMinor == minor && App.VersionPatch > patch))
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                long vers = (App.VersionMajor << 24) | (App.VersionMinor << 16) | App.VersionPatch;
 | 
					                long vers = (App.VersionMajor << 24) | (App.VersionMinor << 16) | App.VersionPatch;
 | 
				
			||||||
                ExecuteNonQuery(cnx, $"PRAGMA user_version = {vers}");
 | 
					                ExecuteNonQuery(cnx, $"PRAGMA user_version = {vers}");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -71,7 +74,11 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            ExecuteNonQuery(cnx, $"PRAGMA schema_version = {toVersion * 100 + _versionOffset}");
 | 
					            ExecuteNonQuery(cnx, $"PRAGMA schema_version = {toVersion * 100 + _versionOffset}");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void UpdateDbSchema_1_To_2(SqliteConnection cnx) { }
 | 
					        private static void UpdateDbSchema_1_To_2(SqliteConnection cnx) {
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "DROP VIEW v_area_commitment");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE delivery_part DROP COLUMN weighing_reason");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE delivery_part ADD COLUMN weighing_reason TEXT CHECK(NOT (manual_weighing = FALSE AND weighing_reason IS NOT NULL))");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void UpdateDbSchema_2_To_3(SqliteConnection cnx) { }
 | 
					        private static void UpdateDbSchema_2_To_3(SqliteConnection cnx) { }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,8 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                } else if (child is T t) {
 | 
					                } else if (child is T t) {
 | 
				
			||||||
                    yield return t;
 | 
					                    yield return t;
 | 
				
			||||||
                } else if (child is DependencyObject childDepOpj) {
 | 
					                }
 | 
				
			||||||
 | 
					                if (child is DependencyObject childDepOpj) {
 | 
				
			||||||
                    foreach (T childOfChild in FindAllChildren<T>(childDepOpj)) {
 | 
					                    foreach (T childOfChild in FindAllChildren<T>(childDepOpj)) {
 | 
				
			||||||
                        yield return childOfChild;
 | 
					                        yield return childOfChild;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -157,8 +157,12 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void MailTo(string emailAddress) {
 | 
					        public static void MailTo(string emailAddress) {
 | 
				
			||||||
 | 
					            MailTo(new string[] { emailAddress });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void MailTo(IEnumerable<string> emailAddresses) {
 | 
				
			||||||
            Process.Start(new ProcessStartInfo() {
 | 
					            Process.Start(new ProcessStartInfo() {
 | 
				
			||||||
                FileName = $"mailto:{emailAddress}",
 | 
					                FileName = $"mailto:{string.Join(",%20", emailAddresses)}",
 | 
				
			||||||
                UseShellExecute = true,
 | 
					                UseShellExecute = true,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -193,28 +197,27 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            if (!searchKeywords.Any())
 | 
					            if (!searchKeywords.Any())
 | 
				
			||||||
                return 0;
 | 
					                return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return words
 | 
					            return searchKeywords
 | 
				
			||||||
                .Select(w => {
 | 
					                .Select(k => {
 | 
				
			||||||
 | 
					                    k = k.ToLower();
 | 
				
			||||||
 | 
					                    var scores = words.Select(w => {
 | 
				
			||||||
                        w = w?.ToLower();
 | 
					                        w = w?.ToLower();
 | 
				
			||||||
                        var p = w?.ToLower()?.Split(" ");
 | 
					                        var p = w?.ToLower()?.Split(" ");
 | 
				
			||||||
                    if (w == null || p == null)
 | 
					                        if (w == null || p == null) {
 | 
				
			||||||
                            return 0;
 | 
					                            return 0;
 | 
				
			||||||
 | 
					                        } else if (k == w) {
 | 
				
			||||||
                    var t1 = searchKeywords.Where(f => w == f).Select(f => f.Length).OrderDescending().FirstOrDefault(0);
 | 
					                            return 4 + k.Length;
 | 
				
			||||||
                    var t2 = searchKeywords.Where(f => p.Any(a => a == f)).Select(f => f.Length).OrderDescending().FirstOrDefault(0);
 | 
					                        } else if (p.Any(a => a == k)) {
 | 
				
			||||||
                    var t3 = searchKeywords.Where(f => p.Any(a => a.StartsWith(f))).Select(f => f.Length).OrderDescending().FirstOrDefault(0);
 | 
					                            return 3 + k.Length;
 | 
				
			||||||
                    var t4 = searchKeywords.Where(f => w.Contains(f)).Select(f => f.Length).OrderDescending().FirstOrDefault(0);
 | 
					                        } else if (p.Any(a => a.StartsWith(k))) {
 | 
				
			||||||
                    if (t1 > 0) {
 | 
					                            return 2 + k.Length;
 | 
				
			||||||
                        return 4 + t1;
 | 
					                        } else if (w.Contains(k)) {
 | 
				
			||||||
                    } else if (t2 > 0) {
 | 
					                            return 1 + k.Length;
 | 
				
			||||||
                        return 3 + t2;
 | 
					 | 
				
			||||||
                    } else if (t3 > 0) {
 | 
					 | 
				
			||||||
                        return 2 + t3;
 | 
					 | 
				
			||||||
                    } else if (t4 > 0) {
 | 
					 | 
				
			||||||
                        return 1 + t4;
 | 
					 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            return 0;
 | 
					                            return 0;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    return scores.Max() + scores.Count(s => s > 0);
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
                .Sum();
 | 
					                .Sum();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -521,6 +521,36 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            return new(true, null);
 | 
					            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) {
 | 
					        public static ValidationResult CheckFbNr(TextBox input, bool required, AppDbContext ctx, AreaCom? c) {
 | 
				
			||||||
            var res = CheckInteger(input, required);
 | 
					            var res = CheckInteger(input, required);
 | 
				
			||||||
            if (!res.IsValid) {
 | 
					            if (!res.IsValid) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,20 +16,20 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        protected Control[] ExemptInputs { private get; set; }
 | 
					        protected Control[] ExemptInputs { private get; set; }
 | 
				
			||||||
        protected Control[] RequiredInputs { private get; set; }
 | 
					        protected Control[] RequiredInputs { private get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private bool _IsEditing;
 | 
					        private bool _isEditing;
 | 
				
			||||||
        private bool _IsCreating;
 | 
					        private bool _isCreating;
 | 
				
			||||||
        protected bool IsEditing {
 | 
					        protected bool IsEditing {
 | 
				
			||||||
            get { return _IsEditing; }
 | 
					            get { return _isEditing; }
 | 
				
			||||||
            set {
 | 
					            set {
 | 
				
			||||||
                _IsEditing = value;
 | 
					                _isEditing = value;
 | 
				
			||||||
                LockContext = IsEditing;
 | 
					                LockContext = IsEditing || IsCreating;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        protected bool IsCreating {
 | 
					        protected bool IsCreating {
 | 
				
			||||||
            get { return _IsCreating; }
 | 
					            get { return _isCreating; }
 | 
				
			||||||
            set {
 | 
					            set {
 | 
				
			||||||
                _IsCreating = value;
 | 
					                _isCreating = value;
 | 
				
			||||||
                LockContext = IsEditing;
 | 
					                LockContext = IsEditing || IsCreating;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        protected bool DoShowWarningWindows = true;
 | 
					        protected bool DoShowWarningWindows = true;
 | 
				
			||||||
@@ -99,7 +99,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        abstract protected void UpdateButtons();
 | 
					        abstract protected void UpdateButtons();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override async Task RenewContext() {
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
            for (int i = 0; i < PlzInputs.Length; i++)
 | 
					            for (int i = 0; i < PlzInputs.Length; i++)
 | 
				
			||||||
                UpdatePlz(PlzInputs[i], PlzOrtInputs[i]);
 | 
					                UpdatePlz(PlzInputs[i], PlzOrtInputs[i]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -482,6 +482,14 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            InputLostFocus((TextBox)sender, Validator.CheckDate);
 | 
					            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) {
 | 
					        protected void PlzInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var plz = (TextBox)sender;
 | 
					            var plz = (TextBox)sender;
 | 
				
			||||||
            InputTextChanged(plz, Validator.CheckPlz);
 | 
					            InputTextChanged(plz, Validator.CheckPlz);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -95,8 +95,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            ValidateRequiredInputs();
 | 
					            ValidateRequiredInputs();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override async Task RenewContext() {
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
            await base.RenewContext();
 | 
					            await base.OnRenewContext();
 | 
				
			||||||
            ControlUtils.RenewItemsSource(KgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr);
 | 
					            ControlUtils.RenewItemsSource(KgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr);
 | 
				
			||||||
            ControlUtils.RenewItemsSource(AreaComTypeInput, await Context.AreaCommitmentTypes.OrderBy(v => v.VtrgId).ToListAsync(), i => (i as AreaComType)?.VtrgId);
 | 
					            ControlUtils.RenewItemsSource(AreaComTypeInput, await Context.AreaCommitmentTypes.OrderBy(v => v.VtrgId).ToListAsync(), i => (i as AreaComType)?.VtrgId);
 | 
				
			||||||
            ControlUtils.RenewItemsSource(WineCultivationInput, await Context.WineCultivations.OrderBy(c => c.Name).ToListAsync(), i => (i as WineCult)?.CultId);
 | 
					            ControlUtils.RenewItemsSource(WineCultivationInput, await Context.WineCultivations.OrderBy(c => c.Name).ToListAsync(), i => (i as WineCult)?.CultId);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,8 +52,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            FillInputs(App.Client);
 | 
					            FillInputs(App.Client);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override async Task RenewContext() {
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
            await base.RenewContext();
 | 
					            await base.OnRenewContext();
 | 
				
			||||||
            ControlUtils.RenewItemsSource(SeasonList, await Context.Seasons.OrderByDescending(s => s.Year).ToListAsync(), s => (s as Season)?.Year, null, ControlUtils.RenewSourceDefault.First);
 | 
					            ControlUtils.RenewItemsSource(SeasonList, await Context.Seasons.OrderByDescending(s => s.Year).ToListAsync(), s => (s as Season)?.Year, null, ControlUtils.RenewSourceDefault.First);
 | 
				
			||||||
            var year = (SeasonList.SelectedItem as Season)?.Year;
 | 
					            var year = (SeasonList.SelectedItem as Season)?.Year;
 | 
				
			||||||
            ControlUtils.RenewItemsSource(SeasonModifierList, await Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToListAsync(), m => (m as Modifier)?.ModId);
 | 
					            ControlUtils.RenewItemsSource(SeasonModifierList, await Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToListAsync(), m => (m as Modifier)?.ModId);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -214,8 +214,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            FinishInputFilling();
 | 
					            FinishInputFilling();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override async Task RenewContext() {
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
            await base.RenewContext();
 | 
					            await base.OnRenewContext();
 | 
				
			||||||
            await RefreshGraphList();
 | 
					            await RefreshGraphList();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,30 +7,32 @@ using System.Windows.Threading;
 | 
				
			|||||||
namespace Elwig.Windows {
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
    public abstract class ContextWindow : Window {
 | 
					    public abstract class ContextWindow : Window {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static readonly int RenewSec = 10;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected AppDbContext Context { get; private set; }
 | 
					        protected AppDbContext Context { get; private set; }
 | 
				
			||||||
        protected bool LockContext { get; set; } = false;
 | 
					        protected bool LockContext { get; set; } = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly DispatcherTimer ContextRenewTimer;
 | 
					        private readonly DispatcherTimer _timer;
 | 
				
			||||||
        private static readonly int ContextRenewSec = 10;
 | 
					        private bool _renewPending = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ContextWindow() : base() {
 | 
					        public ContextWindow() : base() {
 | 
				
			||||||
            ContextRenewTimer = new DispatcherTimer();
 | 
					            _timer = new DispatcherTimer();
 | 
				
			||||||
            ContextRenewTimer.Tick += new EventHandler(OnRenewContext);
 | 
					            _timer.Tick += new EventHandler(OnShouldRenewContext);
 | 
				
			||||||
            ContextRenewTimer.Interval = new TimeSpan(0, 0, ContextRenewSec);
 | 
					            _timer.Interval = new TimeSpan(0, 0, RenewSec);
 | 
				
			||||||
            ContextRenewTimer.Start();
 | 
					            _timer.Start();
 | 
				
			||||||
            Context = new();
 | 
					            Context = new();
 | 
				
			||||||
            Loaded += OnLoaded;
 | 
					            Loaded += OnLoaded;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void OnRenewContext(object? sender, EventArgs evt) {
 | 
					        private async void OnShouldRenewContext(object? sender, EventArgs evt) {
 | 
				
			||||||
            if (LockContext || !Context.HasBackendChanged) return;
 | 
					            if (!Context.HasBackendChanged) return;
 | 
				
			||||||
            Context.Dispose();
 | 
					            _renewPending = true;
 | 
				
			||||||
            Context = new();
 | 
					            if (LockContext) return;
 | 
				
			||||||
            RenewContext().GetAwaiter().GetResult();
 | 
					            await RenewContext();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void OnLoaded(object sender, RoutedEventArgs evt) {
 | 
					        private void OnLoaded(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            RenewContext().GetAwaiter().GetResult();
 | 
					            OnRenewContext().GetAwaiter().GetResult();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override void OnClosed(EventArgs evt) {
 | 
					        protected override void OnClosed(EventArgs evt) {
 | 
				
			||||||
@@ -38,6 +40,14 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            Context.Dispose();
 | 
					            Context.Dispose();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        abstract protected Task RenewContext();
 | 
					        protected async Task RenewContext() {
 | 
				
			||||||
 | 
					            if (!_renewPending) return;
 | 
				
			||||||
 | 
					            Context.Dispose();
 | 
				
			||||||
 | 
					            Context = new();
 | 
				
			||||||
 | 
					            await OnRenewContext();
 | 
				
			||||||
 | 
					            _renewPending = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        abstract protected Task OnRenewContext();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
					        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
				
			||||||
        xmlns:local="clr-namespace:Elwig.Windows"
 | 
					        xmlns:local="clr-namespace:Elwig.Windows"
 | 
				
			||||||
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
					        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">
 | 
					        Loaded="Window_Loaded">
 | 
				
			||||||
    <Window.Resources>
 | 
					    <Window.Resources>
 | 
				
			||||||
        <Style TargetType="Label">
 | 
					        <Style TargetType="Label">
 | 
				
			||||||
@@ -43,36 +43,42 @@
 | 
				
			|||||||
    <Grid>
 | 
					    <Grid>
 | 
				
			||||||
        <Grid.RowDefinitions>
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
            <RowDefinition Height="19"/>
 | 
					            <RowDefinition Height="19"/>
 | 
				
			||||||
            <RowDefinition Height="0.625*"/>
 | 
					 | 
				
			||||||
            <RowDefinition Height="*"/>
 | 
					 | 
				
			||||||
            <RowDefinition Height="*"/>
 | 
					 | 
				
			||||||
            <RowDefinition Height="*"/>
 | 
					            <RowDefinition Height="*"/>
 | 
				
			||||||
            <RowDefinition Height="24"/>
 | 
					            <RowDefinition Height="24"/>
 | 
				
			||||||
        </Grid.RowDefinitions>
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
        <Grid.ColumnDefinitions>
 | 
					        <Grid.ColumnDefinitions>
 | 
				
			||||||
            <ColumnDefinition Width="1*" MinWidth="400"/>
 | 
					            <ColumnDefinition Width="1*" MinWidth="400"/>
 | 
				
			||||||
            <ColumnDefinition Width="1*"/>
 | 
					            <ColumnDefinition Width="5"/>
 | 
				
			||||||
            <ColumnDefinition Width="1*"/>
 | 
					            <ColumnDefinition Width="2*" MinWidth="560"/>
 | 
				
			||||||
        </Grid.ColumnDefinitions>
 | 
					        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White">
 | 
					        <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White">
 | 
				
			||||||
            <MenuItem Header="Lieferung">
 | 
					 | 
				
			||||||
            </MenuItem>
 | 
					 | 
				
			||||||
            <MenuItem Header="Drucken">
 | 
					            <MenuItem Header="Drucken">
 | 
				
			||||||
                <MenuItem x:Name="Menu_Print_ShowDeliveryNote" Header="Lieferschein anzeigen" IsEnabled="False"
 | 
					                <MenuItem x:Name="Menu_Print_ShowDeliveryNote" Header="Lieferschein anzeigen" IsEnabled="False"
 | 
				
			||||||
                          Click="Menu_Print_ShowDeliveryNote_Click"/>
 | 
					                          Click="Menu_Print_ShowDeliveryNote_Click"/>
 | 
				
			||||||
                <MenuItem x:Name="Menu_Print_PrintDeliveryNote" Header="Lieferschein drucken" IsEnabled="False"
 | 
					                <MenuItem x:Name="Menu_Print_PrintDeliveryNote" Header="Lieferschein drucken" IsEnabled="False"
 | 
				
			||||||
                          Click="Menu_Print_PrintDeliveryNote_Click"/>
 | 
					                          Click="Menu_Print_PrintDeliveryNote_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>
 | 
				
			||||||
            <MenuItem Header="Exportieren">
 | 
					            <MenuItem Header="Exportieren">
 | 
				
			||||||
                <MenuItem x:Name="Menu_Export_Bki" Header="Traubentransportscheinliste (BKI)"/>
 | 
					                <MenuItem x:Name="Menu_Export_Bki" Header="Traubentransportscheinliste (BKI)"/>
 | 
				
			||||||
            </MenuItem>
 | 
					            </MenuItem>
 | 
				
			||||||
            <MenuItem Header="Werkzeuge">
 | 
					            <MenuItem Header="Einstellungen">
 | 
				
			||||||
                <MenuItem Header="Alle Lieferscheine überprüfen"/>
 | 
					                <MenuItem x:Name="Menu_Settings_EnableFreeEditing" Header="Freie Bearbeitung aktivieren"
 | 
				
			||||||
 | 
					                          IsCheckable="True" Checked="Menu_Settings_EnableFreeEditing_Checked" Unchecked="Menu_Settings_EnableFreeEditing_Unchecked"/>
 | 
				
			||||||
            </MenuItem>
 | 
					            </MenuItem>
 | 
				
			||||||
        </Menu>
 | 
					        </Menu>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Grid Grid.RowSpan="4" Grid.Row="1" Margin="5,0,5,0">
 | 
					        <Grid Grid.Row="1" Margin="5,0,0,0">
 | 
				
			||||||
            <Grid.RowDefinitions>
 | 
					            <Grid.RowDefinitions>
 | 
				
			||||||
                <RowDefinition Height="42"/>
 | 
					                <RowDefinition Height="42"/>
 | 
				
			||||||
                <RowDefinition Height="*"/>
 | 
					                <RowDefinition Height="*"/>
 | 
				
			||||||
@@ -100,17 +106,49 @@
 | 
				
			|||||||
                      CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False"
 | 
					                      CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False"
 | 
				
			||||||
                      Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
 | 
					                      Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
 | 
				
			||||||
                <DataGrid.Columns>
 | 
					                <DataGrid.Columns>
 | 
				
			||||||
                    <DataGridTextColumn Header="MgNr."   Binding="{Binding MgNr}" Width="70"/>
 | 
					                    <DataGridTextColumn Header="MgNr." Binding="{Binding MgNr, StringFormat='{}{0} '}" Width="50">
 | 
				
			||||||
                    <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.CellStyle>
 | 
					                        <DataGridTextColumn.CellStyle>
 | 
				
			||||||
                            <Style>
 | 
					                            <Style>
 | 
				
			||||||
                                <Setter Property="TextBlock.TextAlignment" Value="Right"/>
 | 
					                                <Setter Property="TextBlock.TextAlignment" Value="Right"/>
 | 
				
			||||||
                            </Style>
 | 
					                            </Style>
 | 
				
			||||||
                        </DataGridTextColumn.CellStyle>
 | 
					                        </DataGridTextColumn.CellStyle>
 | 
				
			||||||
                    </DataGridTextColumn>
 | 
					                    </DataGridTextColumn>
 | 
				
			||||||
 | 
					                    <DataGridTextColumn Header="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.Columns>
 | 
				
			||||||
            </DataGrid>
 | 
					            </DataGrid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -151,7 +189,21 @@
 | 
				
			|||||||
                    Click="CancelButton_Click"/>
 | 
					                    Click="CancelButton_Click"/>
 | 
				
			||||||
        </Grid>
 | 
					        </Grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Mitglied" Grid.Column="1" Grid.Row="1" Margin="5,5,5,5">
 | 
					        <GridSplitter Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            <GroupBox Header="Mitglied" Grid.Column="0" Grid.Row="0" Margin="5,5,5,5">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="70"/>
 | 
					                        <ColumnDefinition Width="70"/>
 | 
				
			||||||
@@ -171,7 +223,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Lieferung" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
 | 
					            <GroupBox Header="Lieferung" Grid.Column="0" Grid.Row="1" Margin="5,5,5,5">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="100"/>
 | 
					                        <ColumnDefinition Width="100"/>
 | 
				
			||||||
@@ -180,18 +232,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <Label Content="LieferscheinNr.:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
					                    <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"
 | 
					                    <TextBox x:Name="LsNrInput" Width="126" Grid.Column="1" HorizontalAlignment="Left" Margin="0,10,0,0"
 | 
				
			||||||
                         IsReadOnly="True" IsTabStop="False"/>
 | 
					                             IsReadOnly="True" IsTabStop="False"
 | 
				
			||||||
 | 
					                             TextChanged="TextBox_TextChanged"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Datum/Uhrzeit:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
					                    <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"
 | 
					                    <TextBox x:Name="DateInput" Width="77" Grid.Column="1" HorizontalAlignment="Left" Margin="0,40,0,0"
 | 
				
			||||||
                         IsReadOnly="True" IsTabStop="False"
 | 
					                             IsReadOnly="True"
 | 
				
			||||||
                         TextChanged="DateInput_TextChanged"/>
 | 
					                             TextChanged="DateInput_TextChanged" LostFocus="DateInput_LostFocus"/>
 | 
				
			||||||
                    <TextBox x:Name="TimeInput" Width="44" Grid.Column="1" HorizontalAlignment="Left" Margin="82,40,0,0"
 | 
					                    <TextBox x:Name="TimeInput" Width="44" Grid.Column="1" HorizontalAlignment="Left" Margin="82,40,0,0"
 | 
				
			||||||
                         IsReadOnly="True" IsTabStop="False"/>
 | 
					                             IsReadOnly="True"
 | 
				
			||||||
 | 
					                             TextChanged="TimeInput_TextChanged" LostFocus="TimeInput_LostFocus"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Zweigstelle:" Margin="10,70,0,0" Grid.Column="0"/>
 | 
					                    <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"
 | 
					                    <ComboBox x:Name="BranchInput" Width="126" Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Left"
 | 
				
			||||||
                              IsEnabled="False"
 | 
					                              IsEnabled="False"
 | 
				
			||||||
 | 
					                              SelectionChanged="BranchInput_SelectionChanged"
 | 
				
			||||||
                              DisplayMemberPath="Name" TextSearch.TextPath="Name"/>
 | 
					                              DisplayMemberPath="Name" TextSearch.TextPath="Name"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Anmerkung:" Margin="10,100,0,10"/>
 | 
					                    <Label Content="Anmerkung:" Margin="10,100,0,10"/>
 | 
				
			||||||
@@ -200,7 +255,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Sorte" Grid.Column="2" Grid.Row="1" Margin="5,5,5,5">
 | 
					            <GroupBox Header="Sorte" Grid.Column="1" Grid.Row="0" Margin="5,5,5,5">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="70"/>
 | 
					                        <ColumnDefinition Width="70"/>
 | 
				
			||||||
@@ -221,7 +276,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Gradation" Grid.Column="2" Grid.Row="2" Margin="5,5,5,5">
 | 
					            <GroupBox Header="Gradation" Grid.Column="1" Grid.Row="1" Margin="5,5,5,5">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="100"/>
 | 
					                        <ColumnDefinition Width="100"/>
 | 
				
			||||||
@@ -230,27 +285,27 @@
 | 
				
			|||||||
                    <Label Content="Gradation:" Margin="10,10,10,10"/>
 | 
					                    <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">
 | 
					                    <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"
 | 
					                        <TextBox x:Name="GradationOeInput"  TextAlignment="Right" Padding="2,2,23,2"
 | 
				
			||||||
                             TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus"/>
 | 
					                                 TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
				
			||||||
                        <Label Content="°Oe" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
					                        <Label Content="°Oe" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
				
			||||||
                    </Grid>
 | 
					                    </Grid>
 | 
				
			||||||
                    <Label Content="=" Margin="60,10,10,10" Grid.Column="1"/>
 | 
					                    <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">
 | 
					                    <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"
 | 
					                        <TextBox x:Name="GradationKmwInput" TextAlignment="Right" Padding="2,2,34,2" SnapsToDevicePixels="True"
 | 
				
			||||||
                             TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus"/>
 | 
					                                 TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus" KeyUp="Input_KeyUp"/>
 | 
				
			||||||
                        <Label Content="°KMW" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
					                        <Label Content="°KMW" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
 | 
				
			||||||
                    </Grid>
 | 
					                    </Grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Qualitätsstufe:" Margin="10,40,10,10"/>
 | 
					                    <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"
 | 
					                    <ComboBox x:Name="WineQualityLevelInput" Width="146" Margin="0,40,10,10" Grid.Column="1" HorizontalAlignment="Left"
 | 
				
			||||||
                              ItemTemplate="{StaticResource WineQualityLevelTemplate}"
 | 
					                              ItemTemplate="{StaticResource WineQualityLevelTemplate}"
 | 
				
			||||||
                          SelectionChanged="WineQualityLevelInput_SelectionChanged"/>
 | 
					                              SelectionChanged="WineQualityLevelInput_SelectionChanged" KeyUp="Input_KeyUp"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False"
 | 
					                    <CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False"
 | 
				
			||||||
                              VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
					                              VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
				
			||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Gewicht" Grid.Column="2" Grid.Row="3" Margin="5,5,5,5">
 | 
					            <GroupBox Header="Gewicht" Grid.Column="1" Grid.Row="2" Margin="5,5,5,5">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="70"/>
 | 
					                        <ColumnDefinition Width="70"/>
 | 
				
			||||||
@@ -290,7 +345,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Sonstiges" Grid.Column="2" Grid.Row="4" Margin="5,5,5,10">
 | 
					            <GroupBox Header="Sonstiges" Grid.Column="1" Grid.Row="3" Margin="5,5,5,10">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="100"/>
 | 
					                        <ColumnDefinition Width="100"/>
 | 
				
			||||||
@@ -330,7 +385,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Teillieferungen" Grid.Column="1" Grid.Row="3" Margin="5,5,5,5">
 | 
					            <GroupBox Header="Teillieferungen" Grid.Column="0" Grid.Row="2" Margin="5,5,5,5">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition/>
 | 
					                        <ColumnDefinition/>
 | 
				
			||||||
@@ -361,7 +416,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <GroupBox Header="Herkunft" Grid.Column="1" Grid.Row="4" Margin="5,5,5,10">
 | 
					            <GroupBox Header="Herkunft" Grid.Column="0" Grid.Row="3" Margin="5,5,5,10">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="100"/>
 | 
					                        <ColumnDefinition Width="100"/>
 | 
				
			||||||
@@ -382,6 +437,7 @@
 | 
				
			|||||||
                              DisplayMemberPath="Name"/>
 | 
					                              DisplayMemberPath="Name"/>
 | 
				
			||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </GroupBox>
 | 
					            </GroupBox>
 | 
				
			||||||
 | 
					        </Grid>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <StatusBar Grid.Row="5" Grid.ColumnSpan="3" BorderThickness="0,1,0,0" BorderBrush="Gray">
 | 
					        <StatusBar Grid.Row="5" Grid.ColumnSpan="3" BorderThickness="0,1,0,0" BorderBrush="Gray">
 | 
				
			||||||
            <StatusBar.ItemsPanel>
 | 
					            <StatusBar.ItemsPanel>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -94,6 +94,11 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
					        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);
 | 
					            OnSecondPassed(null, null);
 | 
				
			||||||
            Timer.Start();
 | 
					            Timer.Start();
 | 
				
			||||||
            LockInputs();
 | 
					            LockInputs();
 | 
				
			||||||
@@ -108,16 +113,16 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private async void Menu_Print_ShowDeliveryNote_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void Menu_Print_ShowDeliveryNote_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
					            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
            using var doc = new DeliveryNote(d, Context);
 | 
					            using var doc = new DeliveryNote(d, Context);
 | 
				
			||||||
            await doc.Generate();
 | 
					            await doc.Generate();
 | 
				
			||||||
            doc.Show();
 | 
					 | 
				
			||||||
            Mouse.OverrideCursor = null;
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					            doc.Show();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
					            if (DeliveryList.SelectedItem is not Delivery d) return;
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
            using var doc = new DeliveryNote(d, Context);
 | 
					            using var doc = new DeliveryNote(d, Context);
 | 
				
			||||||
            await doc.Generate();
 | 
					            await doc.Generate();
 | 
				
			||||||
            Mouse.OverrideCursor = null;
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
@@ -128,23 +133,77 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            if (sender is not MenuItem m) return;
 | 
					            if (sender is not MenuItem m) return;
 | 
				
			||||||
            var year = int.Parse(m.Header.ToString()?.Split(" ")[^1] ?? Utils.CurrentLastSeason.ToString());
 | 
					            var year = int.Parse(m.Header.ToString()?.Split(" ")[^1] ?? Utils.CurrentLastSeason.ToString());
 | 
				
			||||||
            var d = new SaveFileDialog() {
 | 
					            var d = new SaveFileDialog() {
 | 
				
			||||||
                FileName = $"{App.Client.NameToken}-Traubentransportscheinliste-{year}",
 | 
					                FileName = $"{App.Client.NameToken}-Traubentransportscheinliste-{year}.{Bki.FileExtension}",
 | 
				
			||||||
                DefaultExt = Bki.FileExtension,
 | 
					                DefaultExt = Bki.FileExtension,
 | 
				
			||||||
 | 
					                Filter = "CSV-Datei (*.csv)|*.csv",
 | 
				
			||||||
                Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig"
 | 
					                Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig"
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            if (d.ShowDialog() == true) {
 | 
					            if (d.ShowDialog() == true) {
 | 
				
			||||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
					                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
                using var file = new Bki(d.FileName);
 | 
					                using var file = new Bki(d.FileName);
 | 
				
			||||||
                await file.ExportAsync(year);
 | 
					                await file.ExportAsync(year);
 | 
				
			||||||
                Mouse.OverrideCursor = null;
 | 
					                Mouse.OverrideCursor = null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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_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) {
 | 
					        private void OnSecondPassed(object? sender, EventArgs? evt) {
 | 
				
			||||||
            if (IsReceipt && IsCreating) {
 | 
					            if (IsReceipt && IsCreating && !Menu_Settings_EnableFreeEditing.IsChecked) {
 | 
				
			||||||
                var now = DateTime.Now;
 | 
					                var now = DateTime.Now;
 | 
				
			||||||
                TimeInput.Text = now.ToString("HH:mm");
 | 
					                TimeInput.Text = now.ToString("HH:mm");
 | 
				
			||||||
                DateInput.Text = now.ToString("dd.MM.yyyy");
 | 
					                DateInput.Text = now.ToString("dd.MM.yyyy");
 | 
				
			||||||
 | 
					                SetDefaultValue(TimeInput);
 | 
				
			||||||
 | 
					                SetDefaultValue(DateInput);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -195,9 +254,14 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            if (sender is not Control ctrl) return;
 | 
					            if (sender is not Control ctrl) return;
 | 
				
			||||||
            if (evt.Key != Key.Enter) return;
 | 
					            if (evt.Key != Key.Enter) return;
 | 
				
			||||||
            if (ctrl == MgNrInput || ctrl == MemberInput) {
 | 
					            if (ctrl == MgNrInput || ctrl == MemberInput) {
 | 
				
			||||||
                SortIdInput.Focus(); SortIdInput.SelectAll();
 | 
					                SortIdInput.Focus();
 | 
				
			||||||
 | 
					                SortIdInput.SelectAll();
 | 
				
			||||||
            } else if (ctrl == SortIdInput || ctrl == WineVarietyInput || ctrl == AttributesInput) {
 | 
					            } else if (ctrl == SortIdInput || ctrl == WineVarietyInput || ctrl == AttributesInput) {
 | 
				
			||||||
                GradationOeInput.Focus(); GradationOeInput.SelectAll();
 | 
					                GradationOeInput.Focus();
 | 
				
			||||||
 | 
					                GradationOeInput.SelectAll();
 | 
				
			||||||
 | 
					            } else if (ctrl == GradationKmwInput || ctrl == GradationOeInput || ctrl == WineQualityLevelInput) {
 | 
				
			||||||
 | 
					                if (WeighingAButton.IsVisible) WeighingAButton.Focus();
 | 
				
			||||||
 | 
					                else WeighingManualButton.Focus();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -205,19 +269,32 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            await RefreshDeliveryListQuery();
 | 
					            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;
 | 
					            IQueryable<Delivery> deliveryQuery = Context.Deliveries;
 | 
				
			||||||
            if (Member != null) {
 | 
					            if (Member != null) {
 | 
				
			||||||
                deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr);
 | 
					                deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr);
 | 
				
			||||||
 | 
					                filterNames.Add(Member.AdministrativeName);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (TodayOnlyInput.IsChecked == true) {
 | 
					            if (TodayOnlyInput.IsChecked == true) {
 | 
				
			||||||
                deliveryQuery = deliveryQuery
 | 
					                deliveryQuery = deliveryQuery
 | 
				
			||||||
                    .Where(d => (d.DateString == Utils.Today.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.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) {
 | 
					            } else if (AllSeasonsInput.IsChecked == false) {
 | 
				
			||||||
                deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value);
 | 
					                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)
 | 
				
			||||||
 | 
					                .ThenBy(p => p.Delivery.LsNr)
 | 
				
			||||||
 | 
					                .ThenBy(p => p.DPNr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // TODO add filter for:
 | 
				
			||||||
 | 
					            //      attributes
 | 
				
			||||||
 | 
					            //      branches
 | 
				
			||||||
            var filterVar = new List<string>();
 | 
					            var filterVar = new List<string>();
 | 
				
			||||||
            var filterQual = new List<string>();
 | 
					            var filterQual = new List<string>();
 | 
				
			||||||
            var filterMgNr = new List<int>();
 | 
					            var filterMgNr = new List<int>();
 | 
				
			||||||
@@ -234,21 +311,24 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var filter = TextFilter.ToList();
 | 
					            var filter = TextFilter.ToList();
 | 
				
			||||||
            if (filter.Count > 0) {
 | 
					            if (filter.Count > 0) {
 | 
				
			||||||
                var var = await Context.WineVarieties.Select(v => v.SortId).ToListAsync();
 | 
					                var var = await Context.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
 | 
				
			||||||
                var qual = await Context.WineQualityLevels.Select(q => q.QualId).ToListAsync();
 | 
					                var qual = await Context.WineQualityLevels.ToDictionaryAsync(q => q.QualId, q => q);
 | 
				
			||||||
                var mgnr = await Context.Members.Select(m => m.MgNr.ToString()).ToListAsync();
 | 
					                var mgnr = await Context.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for (int i = 0; i < filter.Count; i++) {
 | 
					                for (int i = 0; i < filter.Count; i++) {
 | 
				
			||||||
                    var e = filter[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());
 | 
					                        filterVar.Add(e.ToUpper());
 | 
				
			||||||
                        filter.RemoveAt(i--);
 | 
					                        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());
 | 
					                        filterQual.Add(e.ToUpper());
 | 
				
			||||||
                        filter.RemoveAt(i--);
 | 
					                        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));
 | 
					                        filterMgNr.Add(int.Parse(e));
 | 
				
			||||||
                        filter.RemoveAt(i--);
 | 
					                        filter.RemoveAt(i--);
 | 
				
			||||||
 | 
					                        filterNames.Add(mgnr[e].AdministrativeName);
 | 
				
			||||||
                    } else if (e.StartsWith(">") || e.StartsWith("<")) {
 | 
					                    } else if (e.StartsWith(">") || e.StartsWith("<")) {
 | 
				
			||||||
                        if (double.TryParse(e[1..], out var num)) {
 | 
					                        if (double.TryParse(e[1..], out var num)) {
 | 
				
			||||||
                            switch ((e[0], num)) {
 | 
					                            switch ((e[0], num)) {
 | 
				
			||||||
@@ -297,12 +377,23 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                        filterTimeLt = TimeOnly.TryParse(parts[1], out var to) ? $"{to:HH:mm}" : null;
 | 
					                        filterTimeLt = TimeOnly.TryParse(parts[1], out var to) ? $"{to:HH:mm}" : null;
 | 
				
			||||||
                        filter.RemoveAt(i--);
 | 
					                        filter.RemoveAt(i--);
 | 
				
			||||||
                    } else if (DateOnly.TryParse(e, out var date)) {
 | 
					                    } 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--);
 | 
					                        filter.RemoveAt(i--);
 | 
				
			||||||
 | 
					                        filterNames.Add(date.ToString("dd.MM.yyyy"));
 | 
				
			||||||
                    } else if (Utils.PartialDateRegex.IsMatch(e)) {
 | 
					                    } else if (Utils.PartialDateRegex.IsMatch(e)) {
 | 
				
			||||||
 | 
					                        // TODO allow date ranges
 | 
				
			||||||
                        var parts = e.Split(".");
 | 
					                        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--);
 | 
					                        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("\"")) {
 | 
					                    } else if (e.Length > 2 && e.StartsWith("\"") && e.EndsWith("\"")) {
 | 
				
			||||||
                        filter[i] = e[1..^1];
 | 
					                        filter[i] = e[1..^1];
 | 
				
			||||||
                    } else if (e.Length <= 2) {
 | 
					                    } else if (e.Length <= 2) {
 | 
				
			||||||
@@ -310,22 +401,58 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (filterMgNr.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterMgNr.Contains(d.MgNr));
 | 
					                if (filterMgNr.Count > 0) dpq = dpq.Where(p => filterMgNr.Contains(p.Delivery.MgNr));
 | 
				
			||||||
                if (filterDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterDate.Contains(d.DateString));
 | 
					                if (filterDate.Count > 0) dpq = dpq.Where(p => filterDate.Contains(p.Delivery.DateString));
 | 
				
			||||||
                if (filterPartDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterPartDate.Contains(d.DateString.Substring(4)));
 | 
					                if (filterPartDate.Count > 0) dpq = dpq.Where(p => filterPartDate.Contains(p.Delivery.DateString.Substring(4)));
 | 
				
			||||||
                if (filterYearGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year >= filterYearGt);
 | 
					                if (filterYearGt > 0) dpq = dpq.Where(p => p.Year >= filterYearGt);
 | 
				
			||||||
                if (filterYearLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year < filterYearLt);
 | 
					                if (filterYearLt > 0) dpq = dpq.Where(p => p.Year < filterYearLt);
 | 
				
			||||||
                if (filterTimeGt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeGt.CompareTo(d.TimeString) <= 0);
 | 
					                if (filterTimeGt != null) dpq = dpq.Where(p => p.Delivery.TimeString != null && filterTimeGt.CompareTo(p.Delivery.TimeString) <= 0);
 | 
				
			||||||
                if (filterTimeLt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeLt.CompareTo(d.TimeString) > 0);
 | 
					                if (filterTimeLt != null) dpq = dpq.Where(p => p.Delivery.TimeString != null && filterTimeLt.CompareTo(p.Delivery.TimeString) > 0);
 | 
				
			||||||
                if (filterVar.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterVar.Contains(p.SortId)));
 | 
					                if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId));
 | 
				
			||||||
                if (filterQual.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterQual.Contains(p.QualId)));
 | 
					                if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId));
 | 
				
			||||||
                if (filterKmwGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw >= filterKmwGt));
 | 
					                if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt);
 | 
				
			||||||
                if (filterKmwLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw < filterKmwLt));
 | 
					                if (filterKmwLt > 0) dpq = dpq.Where(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 (filterOeGt > 0) dpq = dpq.Where(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 (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($"unter {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($"unter {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) {
 | 
					            if (filter.Count > 0 && deliveries.Count > 0) {
 | 
				
			||||||
                var dict = deliveries.AsParallel()
 | 
					                var dict = deliveries.AsParallel()
 | 
				
			||||||
                    .ToDictionary(d => d, d => d.SearchScore(TextFilter))
 | 
					                    .ToDictionary(d => d, d => d.SearchScore(TextFilter))
 | 
				
			||||||
@@ -343,18 +470,11 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList();
 | 
					            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.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}";
 | 
					            StatusDeliveries.Text = $"Lieferungen: {deliveries.Count}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (filter.Count == 0) {
 | 
					            if (filter.Count == 0) {
 | 
				
			||||||
                var partsQuery = deliveryQuery.SelectMany(d => d.Parts);
 | 
					                var deliveryParts = deliveryPartsQuery;
 | 
				
			||||||
                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 n = await deliveryParts.CountAsync();
 | 
					                var n = await deliveryParts.CountAsync();
 | 
				
			||||||
                StatusDeliveries.Text = $"Lieferungen: {deliveries.Count} ({n})";
 | 
					                StatusDeliveries.Text = $"Lieferungen: {deliveries.Count} ({n})";
 | 
				
			||||||
                var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync();
 | 
					                var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync();
 | 
				
			||||||
@@ -372,9 +492,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                    StatusGradation.Text = "Gradation: -";
 | 
					                    StatusGradation.Text = "Gradation: -";
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (n > 0 && (n <= 200 || TodayOnlyInput.IsChecked == true)) {
 | 
					                if (n > 0 && (n <= 200 || TodayOnlyInput.IsChecked == true)) {
 | 
				
			||||||
                    var parts = (await deliveryParts.ToListAsync());
 | 
					                    var parts = await deliveryParts.ToListAsync();
 | 
				
			||||||
                    var groups = parts
 | 
					                    var groups = parts
 | 
				
			||||||
                        .GroupBy(p => string.Join("/", p.Attributes.Select(a => a.Name)))
 | 
					                        .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)))
 | 
					                        .Select(g => (g.Key, g.Sum(p => p.Weight), g.Min(p => p.Kmw), Utils.AggregateDeliveryPartsKmw(g), g.Max(p => p.Kmw)))
 | 
				
			||||||
@@ -408,10 +527,14 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                StatusWeight.Text = "Gewicht: -";
 | 
					                StatusWeight.Text = "Gewicht: -";
 | 
				
			||||||
                StatusGradation.Text = "Gradation: -";
 | 
					                StatusGradation.Text = "Gradation: -";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            StatusVarieties.ToolTip = StatusVarieties.Text;
 | 
				
			||||||
 | 
					            StatusWeight.ToolTip = StatusWeight.Text;
 | 
				
			||||||
 | 
					            StatusGradation.ToolTip = StatusGradation.Text;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override async Task RenewContext() {
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
            await base.RenewContext();
 | 
					            await base.OnRenewContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (Member != null) {
 | 
					            if (Member != null) {
 | 
				
			||||||
                if (Context.Members.Find(Member.MgNr) is not Member m) {
 | 
					                if (Context.Members.Find(Member.MgNr) is not Member m) {
 | 
				
			||||||
@@ -563,10 +686,10 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            if (deliveryNew || InputHasChanged(DateInput)) {
 | 
					            if (deliveryNew || InputHasChanged(DateInput)) {
 | 
				
			||||||
                d.LNr = await Context.NextLNr(d.Date);
 | 
					                d.LNr = await Context.NextLNr(d.Date);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (IsCreating) {
 | 
					            if (IsCreating && !InputIsNotDefault(TimeInput)) {
 | 
				
			||||||
                d.TimeString = DateTime.Now.ToString("HH:mm:ss");
 | 
					                d.TimeString = DateTime.Now.ToString("HH:mm:ss");
 | 
				
			||||||
            } else if (InputHasChanged(TimeInput)) {
 | 
					            } else if (IsCreating || InputHasChanged(TimeInput)) {
 | 
				
			||||||
                d.TimeString = TimeInput.Text + ":00";
 | 
					                d.TimeString = (TimeInput.Text != "") ? TimeInput.Text + ":00" : null;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            d.ZwstId = (BranchInput.SelectedItem as Branch)?.ZwstId;
 | 
					            d.ZwstId = (BranchInput.SelectedItem as Branch)?.ZwstId;
 | 
				
			||||||
            d.LsNr = LsNrInput.Text;
 | 
					            d.LsNr = LsNrInput.Text;
 | 
				
			||||||
@@ -651,7 +774,6 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                    WeightInput.Text = $"{res.Weight:N0}";
 | 
					                    WeightInput.Text = $"{res.Weight:N0}";
 | 
				
			||||||
                    ScaleId = s.ScaleId;
 | 
					                    ScaleId = s.ScaleId;
 | 
				
			||||||
                    WeighingId = res.FullWeighingId;
 | 
					                    WeighingId = res.FullWeighingId;
 | 
				
			||||||
                    s.Empty();
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    WeightInput.Text = "";
 | 
					                    WeightInput.Text = "";
 | 
				
			||||||
                    ScaleId = null;
 | 
					                    ScaleId = null;
 | 
				
			||||||
@@ -757,12 +879,19 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void EmptyScale() {
 | 
				
			||||||
 | 
					            var scale = App.Scales.Where(s => s.ScaleId == ScaleId).FirstOrDefault();
 | 
				
			||||||
 | 
					            if (scale == null) return;
 | 
				
			||||||
 | 
					            scale.Empty();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            FinishButton.IsEnabled = false;
 | 
					            FinishButton.IsEnabled = false;
 | 
				
			||||||
            NewDeliveryPartButton.IsEnabled = false;
 | 
					            NewDeliveryPartButton.IsEnabled = false;
 | 
				
			||||||
            NewDeliveryPartButton.Cursor = Cursors.Wait;
 | 
					            NewDeliveryPartButton.Cursor = Cursors.Wait;
 | 
				
			||||||
            DeliveryPartList.IsEnabled = false;
 | 
					            DeliveryPartList.IsEnabled = false;
 | 
				
			||||||
            var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
 | 
					            var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
 | 
				
			||||||
 | 
					            EmptyScale();
 | 
				
			||||||
            await RefreshDeliveryList();
 | 
					            await RefreshDeliveryList();
 | 
				
			||||||
            await RefreshDeliveryParts();
 | 
					            await RefreshDeliveryParts();
 | 
				
			||||||
            NewDeliveryPartButton.Cursor = null;
 | 
					            NewDeliveryPartButton.Cursor = null;
 | 
				
			||||||
@@ -778,21 +907,23 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            FinishButton.Cursor = Cursors.Wait;
 | 
					            FinishButton.Cursor = Cursors.Wait;
 | 
				
			||||||
            DeliveryPartList.IsEnabled = false;
 | 
					            DeliveryPartList.IsEnabled = false;
 | 
				
			||||||
            var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
 | 
					            var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart);
 | 
				
			||||||
 | 
					            EmptyScale();
 | 
				
			||||||
            await RefreshDeliveryList();
 | 
					            await RefreshDeliveryList();
 | 
				
			||||||
            await RefreshDeliveryParts();
 | 
					            await RefreshDeliveryParts();
 | 
				
			||||||
            if (p?.Delivery != null) {
 | 
					            if (p?.Delivery != null) {
 | 
				
			||||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
					                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
                using var doc = new DeliveryNote(p.Delivery, Context);
 | 
					                using var doc = new DeliveryNote(p.Delivery, Context);
 | 
				
			||||||
                await doc.Generate();
 | 
					                await doc.Generate();
 | 
				
			||||||
                Mouse.OverrideCursor = null;
 | 
					                Mouse.OverrideCursor = null;
 | 
				
			||||||
                if (App.Config.Debug) {
 | 
					                if (App.Config.Debug) {
 | 
				
			||||||
                    doc.Show();
 | 
					                    doc.Show();
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    await doc.Print(2);
 | 
					                    doc.Print(2);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            FinishButton.Cursor = null;
 | 
					            FinishButton.Cursor = null;
 | 
				
			||||||
            DeliveryList.SelectedItem = null;
 | 
					            DeliveryList.SelectedItem = null;
 | 
				
			||||||
 | 
					            await RenewContext();
 | 
				
			||||||
            RefreshInputs();
 | 
					            RefreshInputs();
 | 
				
			||||||
            InitInputs();
 | 
					            InitInputs();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -815,6 +946,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                DisableWeighingButtons();
 | 
					                DisableWeighingButtons();
 | 
				
			||||||
                HideFinishNewPartDeliveryCancelButtons();
 | 
					                HideFinishNewPartDeliveryCancelButtons();
 | 
				
			||||||
                ShowNewEditDeleteButtons();
 | 
					                ShowNewEditDeleteButtons();
 | 
				
			||||||
 | 
					                await RenewContext();
 | 
				
			||||||
                RefreshInputs();
 | 
					                RefreshInputs();
 | 
				
			||||||
                ClearInputStates();
 | 
					                ClearInputStates();
 | 
				
			||||||
                LockInputs();
 | 
					                LockInputs();
 | 
				
			||||||
@@ -850,7 +982,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            try {
 | 
					            try {
 | 
				
			||||||
                if (res == null || res <= 0)
 | 
					                if (res == null || res <= 0)
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
					                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
                ClearOriginalValues();
 | 
					                ClearOriginalValues();
 | 
				
			||||||
                if (res >= p.Weight) {
 | 
					                if (res >= p.Weight) {
 | 
				
			||||||
                    ControlUtils.SelectComboBoxItem(WineQualityLevelInput, q => (q as WineQualLevel)?.QualId, "WEI");
 | 
					                    ControlUtils.SelectComboBoxItem(WineQualityLevelInput, q => (q as WineQualLevel)?.QualId, "WEI");
 | 
				
			||||||
@@ -932,7 +1064,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?",
 | 
					                $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?",
 | 
				
			||||||
                "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
					                "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
				
			||||||
            if (r == MessageBoxResult.Yes) {
 | 
					            if (r == MessageBoxResult.Yes) {
 | 
				
			||||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
					                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
                Context.Remove(d);
 | 
					                Context.Remove(d);
 | 
				
			||||||
                await Context.SaveChangesAsync();
 | 
					                await Context.SaveChangesAsync();
 | 
				
			||||||
                await RefreshDeliveryList();
 | 
					                await RefreshDeliveryList();
 | 
				
			||||||
@@ -1007,8 +1139,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                day = day.AddDays(-1);
 | 
					                day = day.AddDays(-1);
 | 
				
			||||||
            var lsnrs = await Context.Deliveries
 | 
					            var lsnrs = await Context.Deliveries
 | 
				
			||||||
                .Where(d => d.ZwstId == delivery.ZwstId)
 | 
					                .Where(d => d.ZwstId == delivery.ZwstId)
 | 
				
			||||||
                .Where(d => (d.DateString == day.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.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)
 | 
					                .Where(d => d.LsNr != delivery.LsNr)
 | 
				
			||||||
                .OrderBy(d => d.LsNr)
 | 
					                .OrderBy(d => d.LsNr)
 | 
				
			||||||
                .Select(d => d.LsNr)
 | 
					                .Select(d => d.LsNr)
 | 
				
			||||||
@@ -1019,7 +1151,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            EntityEntry<Delivery>? entry = null;
 | 
					            EntityEntry<Delivery>? entry = null;
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Delivery? d = null;
 | 
					                Delivery? d = null;
 | 
				
			||||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
					                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
                if (res == "new") {
 | 
					                if (res == "new") {
 | 
				
			||||||
                    d = Context.CreateProxy<Delivery>();
 | 
					                    d = Context.CreateProxy<Delivery>();
 | 
				
			||||||
                    d.Date = delivery.Date;
 | 
					                    d.Date = delivery.Date;
 | 
				
			||||||
@@ -1070,7 +1202,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                $"Soll die Teillieferung Nr. {p.DPNr} wirklich unwiderruflich gelöscht werden?",
 | 
					                $"Soll die Teillieferung Nr. {p.DPNr} wirklich unwiderruflich gelöscht werden?",
 | 
				
			||||||
                "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
					                "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
				
			||||||
            if (r == MessageBoxResult.Yes) {
 | 
					            if (r == MessageBoxResult.Yes) {
 | 
				
			||||||
                Mouse.OverrideCursor = Cursors.Wait;
 | 
					                Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
                Context.Remove(p);
 | 
					                Context.Remove(p);
 | 
				
			||||||
                await Context.SaveChangesAsync();
 | 
					                await Context.SaveChangesAsync();
 | 
				
			||||||
                await RefreshDeliveryParts();
 | 
					                await RefreshDeliveryParts();
 | 
				
			||||||
@@ -1160,9 +1292,9 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            AbgewertetInput.IsEnabled = false;
 | 
					            AbgewertetInput.IsEnabled = false;
 | 
				
			||||||
            ManualWeighingInput.IsEnabled = false;
 | 
					            ManualWeighingInput.IsEnabled = false;
 | 
				
			||||||
            LsNrInput.IsReadOnly = true;
 | 
					            LsNrInput.IsReadOnly = true;
 | 
				
			||||||
            DateInput.IsReadOnly = true;
 | 
					            DateInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked;
 | 
				
			||||||
            TimeInput.IsReadOnly = true;
 | 
					            TimeInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked;
 | 
				
			||||||
            BranchInput.IsEnabled = false;
 | 
					            BranchInput.IsEnabled = Menu_Settings_EnableFreeEditing.IsChecked;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void DisableWeighingButtons() {
 | 
					        private void DisableWeighingButtons() {
 | 
				
			||||||
@@ -1186,15 +1318,25 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            if (DateInput.Text == "" || BranchInput.SelectedItem == null) {
 | 
					            if (DateInput.Text == "" || BranchInput.SelectedItem == null) {
 | 
				
			||||||
                LsNrInput.Text = "";
 | 
					                LsNrInput.Text = "";
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
                    var branch = (Branch)BranchInput.SelectedItem;
 | 
					                    var branch = (Branch)BranchInput.SelectedItem;
 | 
				
			||||||
                    var date = DateOnly.ParseExact(DateInput.Text, "dd.MM.yyyy");
 | 
					                    var date = DateOnly.ParseExact(DateInput.Text, "dd.MM.yyyy");
 | 
				
			||||||
                    var lnr = await Context.NextLNr(date);
 | 
					                    var lnr = await Context.NextLNr(date);
 | 
				
			||||||
                    LsNrInput.Text = Utils.GenerateLsNr(date, branch.ZwstId, lnr);
 | 
					                    LsNrInput.Text = Utils.GenerateLsNr(date, branch.ZwstId, lnr);
 | 
				
			||||||
 | 
					                } catch {
 | 
				
			||||||
 | 
					                    LsNrInput.Text = "";
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void DateInput_TextChanged(object sender, TextChangedEventArgs evt) {
 | 
					        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) {
 | 
					        private void UpdateWineVariety(bool valid) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -55,7 +55,12 @@
 | 
				
			|||||||
            </MenuItem>
 | 
					            </MenuItem>
 | 
				
			||||||
            <MenuItem Header="Drucken">
 | 
					            <MenuItem Header="Drucken">
 | 
				
			||||||
                <MenuItem Header="Stammdatenblatt 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>
 | 
				
			||||||
            <MenuItem Header="Rundschreiben">
 | 
					            <MenuItem Header="Rundschreiben">
 | 
				
			||||||
                <MenuItem Header="Runschreiben ausschicken"/>
 | 
					                <MenuItem Header="Runschreiben ausschicken"/>
 | 
				
			||||||
@@ -88,7 +93,13 @@
 | 
				
			|||||||
                      SelectionChanged="MemberList_SelectionChanged"
 | 
					                      SelectionChanged="MemberList_SelectionChanged"
 | 
				
			||||||
                      Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
 | 
					                      Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
 | 
				
			||||||
                <DataGrid.Columns>
 | 
					                <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="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.Columns>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ using Elwig.Models;
 | 
				
			|||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
using System.Collections.ObjectModel;
 | 
					using System.Collections.ObjectModel;
 | 
				
			||||||
 | 
					using Elwig.Documents;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Windows {
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
    public partial class MemberAdminWindow : AdministrationWindow {
 | 
					    public partial class MemberAdminWindow : AdministrationWindow {
 | 
				
			||||||
@@ -54,6 +55,9 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
					        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;
 | 
					            ActiveMemberInput.IsChecked = true;
 | 
				
			||||||
            UpdatePhoneNrInputVisibility();
 | 
					            UpdatePhoneNrInputVisibility();
 | 
				
			||||||
            LockInputs();
 | 
					            LockInputs();
 | 
				
			||||||
@@ -131,8 +135,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            ValidateRequiredInputs();
 | 
					            ValidateRequiredInputs();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override async Task RenewContext() {
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
            await base.RenewContext();
 | 
					            await base.OnRenewContext();
 | 
				
			||||||
            ControlUtils.RenewItemsSource(BranchInput, await Context.Branches.OrderBy(b => b.Name).ToListAsync(), i => (i as Branch)?.ZwstId);
 | 
					            ControlUtils.RenewItemsSource(BranchInput, await Context.Branches.OrderBy(b => b.Name).ToListAsync(), i => (i as Branch)?.ZwstId);
 | 
				
			||||||
            ControlUtils.RenewItemsSource(DefaultKgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr);
 | 
					            ControlUtils.RenewItemsSource(DefaultKgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr);
 | 
				
			||||||
            await RefreshMemberList();
 | 
					            await RefreshMemberList();
 | 
				
			||||||
@@ -266,7 +270,50 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void Menu_Member_SendEmail_Click(object sender, RoutedEventArgs evt) {
 | 
					        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) {
 | 
					        private void FocusSearchInput(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,9 +19,9 @@
 | 
				
			|||||||
        <Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click"
 | 
					        <Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click"
 | 
				
			||||||
                Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					                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"/>
 | 
					                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"/>
 | 
					                Margin="260,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
				
			||||||
    </Grid>
 | 
					    </Grid>
 | 
				
			||||||
</Window>
 | 
					</Window>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -51,7 +51,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void PdfDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void PdfDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
            using var ctx = new AppDbContext();
 | 
					            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);
 | 
					            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();
 | 
					            await doc.Generate();
 | 
				
			||||||
@@ -60,7 +60,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void PdfCreditButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void PdfCreditButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.Wait;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
            using var ctx = new AppDbContext();
 | 
					            using var ctx = new AppDbContext();
 | 
				
			||||||
            using var doc = new CreditNote(await ctx.Credits.FirstAsync(), ctx);
 | 
					            using var doc = new CreditNote(await ctx.Credits.FirstAsync(), ctx);
 | 
				
			||||||
            await doc.Generate();
 | 
					            await doc.Generate();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user