using Elwig.Documents; using Elwig.Helpers; using Elwig.Models; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; using Xceed.Wpf.Toolkit.Primitives; namespace Elwig.Windows { public partial class DeliveryAdminWindow : AdministrationWindow { private bool IsUpdatingGradation = false; private readonly bool IsReceipt = false; private Member? Member = null; private readonly DispatcherTimer Timer; private List TextFilter = new(); private readonly RoutedCommand CtrlF = new(); private string? ManualWeighingReason = null; private string? ScaleId = null; private string? WeighingId = null; private readonly Button[] WeighingButtons; public DeliveryAdminWindow(bool receipt = false) { InitializeComponent(); CtrlF.InputGestures.Add(new KeyGesture(Key.F, ModifierKeys.Control)); CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput)); RequiredInputs = new Control[] { MgNrInput, MemberInput, LsNrInput, DateInput, BranchInput, SortIdInput, WineVarietyInput, GradationOeInput, GradationKmwInput, WineQualityLevelInput, WineOriginInput, WineKgInput, WeightInput }; ExemptInputs = new Control[] { SearchInput, SeasonInput, TodayOnlyInput, AllSeasonsInput, DeliveryList, DeliveryPartList, MemberAddressField, }; WeighingButtons = new Button[] { WeighingAButton, WeighingBButton, WeighingCButton, WeighingDButton, }; IsReceipt = receipt; Timer = new DispatcherTimer(); Timer.Tick += new EventHandler(OnSecondPassed); Timer.Interval = new TimeSpan(0, 0, 1); InitializeDelayTimer(SearchInput, SearchInput_TextChanged); SearchInput.TextChanged -= SearchInput_TextChanged; SeasonInput.Value = Utils.CurrentLastSeason; if (IsReceipt) { Title = "Übernahme - Elwig"; TodayOnlyInput.IsChecked = true; var n = App.Scales.Count; if (n < 1) WeighingAButton.Visibility = Visibility.Hidden; if (n < 2) WeighingBButton.Visibility = Visibility.Hidden; if (n < 3) WeighingCButton.Visibility = Visibility.Hidden; if (n < 4) WeighingDButton.Visibility = Visibility.Hidden; if (n == 1) WeighingAButton.Content = "Wiegen"; if (n > 1) WeighingAButton.Content = $"Wiegen {App.Scales[0].ScaleId}"; if (n >= 2) WeighingBButton.Content = $"Wiegen {App.Scales[1].ScaleId}"; if (n >= 3) WeighingCButton.Content = $"Wiegen {App.Scales[2].ScaleId}"; if (n >= 4) WeighingDButton.Content = $"Wiegen {App.Scales[3].ScaleId}"; } else { WeighingManualButton.Visibility = Visibility.Hidden; WeighingAButton.Visibility = Visibility.Hidden; WeighingBButton.Visibility = Visibility.Hidden; WeighingCButton.Visibility = Visibility.Hidden; WeighingDButton.Visibility = Visibility.Hidden; } if (App.Client.IsMatzen) { SetDefaultValue(GerebeltGewogenInput, true); } } public DeliveryAdminWindow(int mgnr) : this() { Member = Context.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value"); Title = $"Lieferungen - {Member.AdministrativeName} - Elwig"; AllSeasonsInput.IsEnabled = true; AllSeasonsInput.IsChecked = true; } private async void Window_Loaded(object sender, RoutedEventArgs evt) { OnSecondPassed(null, null); Timer.Start(); LockInputs(); if (IsReceipt) { NewDeliveryButton_Click(null, null); if ((await Context.Seasons.FindAsync(Utils.CurrentYear)) == null) { MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.", "Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Error); } } } private async void Menu_Print_ShowDeliveryNote_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; using var doc = new DeliveryNote(d, Context); await doc.Generate(); doc.Show(); } private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; using var doc = new DeliveryNote(d, Context); await doc.Generate(); await doc.Print(); } private void Menu_Export_Bki_Click(object sender, RoutedEventArgs evt) { // TODO export Traubentransportscheinliste } private void OnSecondPassed(object? sender, EventArgs? evt) { if (IsReceipt && IsCreating) { var now = DateTime.Now; TimeInput.Text = now.ToString("HH:mm"); DateInput.Text = now.ToString("dd.MM.yyyy"); } } private void InitialInputs() { HandPickedInput.IsChecked = null; SetDefaultValue(HandPickedInput, null); if (App.Client.IsMatzen) { GerebeltGewogenInput.IsChecked = true; GerebeltGewogenInput.IsEnabled = false; } else { GerebeltGewogenInput.IsChecked = false; UnsetDefaultValue(GerebeltGewogenInput); GerebeltGewogenInput.IsEnabled = true; } ClearOriginalValues(); ValidateRequiredInputs(); } private void InitInputs() { ControlUtils.SelectComboBoxItem(BranchInput, i => (i as Branch)?.ZwstId, App.ZwstId); OnSecondPassed(null, null); UpdateLsNr().GetAwaiter().GetResult(); InitialInputs(); } protected override void UpdateButtons() { if (!IsEditing && !IsCreating) return; bool ch = HasChanged, v = IsValid; ResetButton.IsEnabled = ch; SaveButton.IsEnabled = v && ch; FinishButton.IsEnabled = v || !ch; NewDeliveryPartButton.IsEnabled = v; CancelCreatingButton.IsEnabled = DeliveryList.SelectedItem == null || DeliveryPartList.SelectedItem == null; } private async Task RefreshDeliveryList() { await RefreshDeliveryListQuery(); } private async Task RefreshDeliveryListQuery(bool updateSort = false) { IQueryable deliveryQuery = Context.Deliveries; if (Member != null) { deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr); } if (TodayOnlyInput.IsChecked == true) { deliveryQuery = deliveryQuery .Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) || (d.DateString == Utils.Today.AddDays(1).ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") <= 0)); } else if (AllSeasonsInput.IsChecked == false) { deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value); } var filterVar = new List(); var filterQual = new List(); var filterMgNr = new List(); var filterDate = new List(); var filterPartDate = new List(); string? filterTimeGt = null; string? filterTimeLt = null; int filterYearGt = 0; int filterYearLt = 0; double filterKmwGt = 0; double filterKmwLt = 0; double filterOeGt = 0; double filterOeLt = 0; var filter = TextFilter.ToList(); if (filter.Count > 0) { var var = await Context.WineVarieties.Select(v => v.SortId).ToListAsync(); var qual = await Context.WineQualityLevels.Select(q => q.QualId).ToListAsync(); var mgnr = await Context.Members.Select(m => m.MgNr.ToString()).ToListAsync(); for (int i = 0; i < filter.Count; i++) { var e = filter[i]; if (e.Length == 2 && var.Contains(e.ToUpper())) { filterVar.Add(e.ToUpper()); filter.RemoveAt(i--); } else if (e.Length == 3 && qual.Contains(e.ToUpper())) { filterQual.Add(e.ToUpper()); filter.RemoveAt(i--); } else if (e.All(char.IsAsciiDigit) && mgnr.Contains(e)) { filterMgNr.Add(int.Parse(e)); filter.RemoveAt(i--); } else if (e.StartsWith(">") || e.StartsWith("<")) { if (double.TryParse(e[1..], out var num)) { switch ((e[0], num)) { case ('>', <= 30): filterKmwGt = num; break; case ('<', <= 30): filterKmwLt = num; break; case ('>', >= 1900): filterYearGt = (int)num; break; case ('<', >= 1900): filterYearLt = (int)num; break; case ('>', _): filterOeGt = num; break; case ('<', _): filterOeLt = num; break; } filter.RemoveAt(i--); } else if (TimeOnly.TryParse(e[1..], out var time)) { switch ((e[0], time)) { case ('>', _): filterTimeGt = $"{time:HH:mm}"; break; case ('<', _): filterTimeLt = $"{time:HH:mm}"; break; } filter.RemoveAt(i--); } if (e.Length == 1) filter.RemoveAt(i--); } else if (e.Length > 1 && Utils.FromToRegex.IsMatch(e)) { var parts = e.Split("-"); double? from = (parts[0].Length > 0) ? double.Parse(parts[0].Replace(".", ",")) : null; double? to = (parts[1].Length > 0) ? double.Parse(parts[1].Replace(".", ",")) : null; switch ((from, to)) { case (<= 30, <= 30): case (<= 30, null): case (null, <= 30): filterKmwGt = from ?? 0; filterKmwLt = to ?? 0; break; case (>= 1900, >= 1900): case (>= 1900, null): case (null, >= 1900): filterYearGt = (int)(from ?? 0); filterYearLt = (int)(to ?? -1) + 1; break; case (_, _): filterOeGt = from ?? 0; filterOeLt = to ?? 0; break; } filter.RemoveAt(i--); } else if (e.Length > 1 && Utils.FromToTimeRegex.IsMatch(e)) { var parts = e.Split("-"); filterTimeGt = TimeOnly.TryParse(parts[0], out var from) ? $"{from:HH:mm}" : null; filterTimeLt = TimeOnly.TryParse(parts[1], out var to) ? $"{to:HH:mm}" : null; filter.RemoveAt(i--); } else if (DateOnly.TryParse(e, out var date)) { filterDate.Add($"{date:yyyy-MM-dd}"); filter.RemoveAt(i--); } else if (Utils.PartialDateRegex.IsMatch(e)) { var parts = e.Split("."); filterPartDate.Add($"-{int.Parse(parts[1]):00}-{int.Parse(parts[0]):00}"); filter.RemoveAt(i--); } else if (e.Length > 2 && e.StartsWith("\"") && e.EndsWith("\"")) { filter[i] = e[1..^1]; } else if (e.Length <= 2) { filter.RemoveAt(i--); } } if (filterMgNr.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterMgNr.Contains(d.MgNr)); if (filterDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterDate.Contains(d.DateString)); if (filterPartDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterPartDate.Contains(d.DateString.Substring(4))); if (filterYearGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year >= filterYearGt); if (filterYearLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year < filterYearLt); if (filterTimeGt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeGt.CompareTo(d.TimeString) <= 0); if (filterTimeLt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeLt.CompareTo(d.TimeString) > 0); if (filterVar.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterVar.Contains(p.SortId))); if (filterQual.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterQual.Contains(p.QualId))); if (filterKmwGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw >= filterKmwGt)); if (filterKmwLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw < filterKmwLt)); if (filterOeGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt)); if (filterOeLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt)); } List deliveries = await deliveryQuery.OrderByDescending(d => d.DateString).ThenByDescending(d => d.TimeString).ToListAsync(); if (filter.Count > 0 && deliveries.Count > 0) { var dict = deliveries.AsParallel() .ToDictionary(d => d, d => d.SearchScore(TextFilter)) .OrderByDescending(a => a.Value) .ThenBy(a => a.Key.DateTime); var threshold = dict.Select(a => a.Value).Max() * 3 / 4; deliveries = dict .Where(a => a.Value > threshold) .Select(a => a.Key) .ToList(); } ControlUtils.RenewItemsSource(DeliveryList, deliveries, d => ((d as Delivery)?.Year, (d as Delivery)?.DId), DeliveryList_SelectionChanged, ControlUtils.RenewSourceDefault.IfOnly, !updateSort); 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))})" : ""); StatusDeliveries.Text = $"Lieferungen: {deliveries.Count}"; if (filter.Count == 0) { var partsQuery = deliveryQuery.SelectMany(d => d.Parts); if (filterVar.Count > 0) partsQuery = partsQuery.Where(p => filterVar.Contains(p.SortId)); if (filterQual.Count > 0) partsQuery = partsQuery.Where(p => filterQual.Contains(p.QualId)); if (filterKmwGt > 0) partsQuery = partsQuery.Where(p => p.Kmw >= filterKmwGt); if (filterKmwLt > 0) partsQuery = partsQuery.Where(p => p.Kmw < filterKmwLt); if (filterOeGt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt); if (filterOeLt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt); var deliveryParts = partsQuery; var n = await deliveryParts.CountAsync(); StatusDeliveries.Text = $"Lieferungen: {deliveries.Count} ({n})"; var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync(); StatusVarieties.Text = $"Sorten: {varieties.Count}" + (varieties.Count > 0 && varieties.Count <= 10 ? $" ({string.Join(", ", varieties)})" : ""); var weight = await deliveryParts.SumAsync(p => p.Weight); StatusWeight.Text = $"Gewicht: {weight:N0} kg"; if (n > 0) { var kmwMin = await deliveryParts.MinAsync(p => p.Kmw); var kmwAvg = Utils.AggregateDeliveryPartsKmw(deliveryParts); var kmwMax = await deliveryParts.MaxAsync(p => p.Kmw); StatusGradation.Text = $"Gradation: {kmwMin:N1}° / {kmwAvg:N1}° / {kmwMax:N1}°"; } else { StatusGradation.Text = "Gradation: -"; } if (n > 0 && (n <= 200 || TodayOnlyInput.IsChecked == true)) { var parts = (await deliveryParts.ToListAsync()); var groups = parts .GroupBy(p => string.Join("/", p.Attributes.Select(a => a.Name))) .Select(g => (g.Key, g.Sum(p => p.Weight), g.Min(p => p.Kmw), Utils.AggregateDeliveryPartsKmw(g), g.Max(p => p.Kmw))) .OrderByDescending(g => g.Item2) .ToList(); if (groups.Count == 1) { var g = groups.First().Key; if (g != "") { StatusWeight.Text += $" ({g})"; StatusGradation.Text += $" ({g})"; } var sortGroups = parts .GroupBy(p => p.SortId) .Select(g => (g.Key, g.Sum(p => p.Weight), g.Min(p => p.Kmw), Utils.AggregateDeliveryPartsKmw(g), g.Max(p => p.Kmw))) .OrderByDescending(g => g.Item2) .ToList(); if (sortGroups.Count > 1 && sortGroups.Count <= 4) { StatusWeight.Text += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Item2:N0} kg" + (g.Key == "" ? "" : $" ({g.Key})")))}"; StatusGradation.Text += $" = {string.Join(" + ", sortGroups.Select(g => $"{g.Item3:N1}/{g.Item4:N1}/{g.Item5:N1}" + (g.Key == "" ? "" : $" ({g.Key})")))}"; } } else if (groups.Count <= 4) { StatusWeight.Text += $" = {string.Join(" + ", groups.Select(g => $"{g.Item2:N0} kg" + (g.Key == "" ? "" : $" ({g.Key})")))}"; StatusGradation.Text += $" = {string.Join(" + ", groups.Select(g => $"{g.Item3:N1}/{g.Item4:N1}/{g.Item5:N1}" + (g.Key == "" ? "" : $" ({g.Key})")))}"; } } } else { StatusVarieties.Text = "Sorten: -"; StatusWeight.Text = "Gewicht: -"; StatusGradation.Text = "Gradation: -"; } } protected override async Task RenewContext() { await base.RenewContext(); if (Member != null) { if (Context.Members.Find(Member.MgNr) is not Member m) { Close(); return; } Member = m; Title = $"Lieferungen - {Member.AdministrativeName} - Elwig"; } await RefreshDeliveryList(); var d = DeliveryList.SelectedItem as Delivery; var y = d?.Year ?? Utils.CurrentLastSeason; ControlUtils.RenewItemsSource(MemberInput, await Context.Members.OrderBy(m => m.FamilyName).ThenBy(m => m.GivenName).ToListAsync(), i => (i as Member)?.MgNr); ControlUtils.RenewItemsSource(BranchInput, await Context.Branches.OrderBy(b => b.Name).ToListAsync(), i => (i as Branch)?.ZwstId); ControlUtils.RenewItemsSource(WineVarietyInput, await Context.WineVarieties.OrderBy(v => v.Name).ToListAsync(), i => (i as WineVar)?.SortId); ControlUtils.RenewItemsSource(AttributesInput, await Context.WineAttributes.Where(a => IsCreating || a.IsActive).OrderBy(a => a.Name).ToListAsync(), i => (i as WineAttr)?.AttrId); ControlUtils.RenewItemsSource(WineQualityLevelInput, await Context.WineQualityLevels.ToListAsync(), i => (i as WineQualLevel)?.QualId); ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == y).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId); ControlUtils.RenewItemsSource(WineOriginInput, (await Context.WineOrigins.ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId), i => (i as WineOrigin)?.HkId); var kgList = await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).Cast().ToListAsync(); kgList.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(WineKgInput, kgList, i => (i as AT_Kg)?.KgNr); UpdateRdInput(); if (IsCreating) await UpdateLsNr(); await RefreshDeliveryParts(); } private void FocusSearchInput(object sender, RoutedEventArgs evt) { if (!IsEditing && !IsCreating) { SearchInput.Focus(); SearchInput.SelectAll(); } } private async Task RefreshDeliveryParts() { if (DeliveryList.SelectedItem is Delivery d) { ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == d.Year).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId); ControlUtils.RenewItemsSource(DeliveryPartList, d.Parts.OrderBy(p => p.DPNr).ToList(), i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId, (i as DeliveryPart)?.DPNr), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First); } else { ControlUtils.RenewItemsSource(ModifiersInput, await Context.Modifiers.Where(m => m.Year == Utils.CurrentLastSeason).OrderBy(m => m.Ordering).ToListAsync(), i => (i as Modifier)?.ModId); DeliveryPartList.ItemsSource = null; } } private void RefreshInputs(bool validate = false) { ClearInputStates(); if (DeliveryPartList.SelectedItem is DeliveryPart p) { FillInputs(p); } else if (DeliveryList.SelectedItem is Delivery d) { FillInputs(d); } else { ClearOriginalValues(); ClearInputs(validate); ClearInputStates(); } GC.Collect(); } private void FillInputs(Delivery d) { ClearOriginalValues(); MgNrInput.Text = d.MgNr.ToString(); ControlUtils.SelectComboBoxItem(BranchInput, i => (i as Branch)?.ZwstId, d.ZwstId); LsNrInput.Text = d.LsNr; DateInput.Text = d.Date.ToString("dd.MM.yyyy"); TimeInput.Text = d.Time?.ToString("HH:mm") ?? ""; CommentInput.Text = d.Comment ?? ""; SortIdInput.Text = ""; GradationKmwInput.Text = ""; WeightInput.Text = ""; ManualWeighingInput.IsChecked = false; PartCommentInput.Text = ""; TemperatureInput.Text = ""; AcidInput.Text = ""; FinishInputFilling(); } private void FillInputs(DeliveryPart p) { FillInputs(p.Delivery); ClearOriginalValues(); SortIdInput.Text = p?.SortId ?? ""; ControlUtils.SelectCheckComboBoxItems(AttributesInput, p?.Attributes, i => (i as WineAttr)?.AttrId); GradationKmwInput.Text = (p != null) ? $"{p.Kmw:N1}" : ""; ControlUtils.SelectComboBoxItem(WineQualityLevelInput, q => (q as WineQualLevel)?.QualId, p?.QualId); ControlUtils.SelectComboBoxItem(WineKgInput, k => (k as AT_Kg)?.KgNr, p?.KgNr); ControlUtils.SelectComboBoxItem(WineRdInput, r => (r as WbRd)?.RdNr, p?.RdNr); ControlUtils.SelectComboBoxItem(WineOriginInput, r => (r as WineOrigin)?.HkId, p?.HkId); WeightInput.Text = (p != null) ? $"{p.Weight:N0}" : ""; ManualWeighingInput.IsChecked = p?.ManualWeighing ?? false; GerebeltGewogenInput.IsChecked = p?.IsGerebelt ?? false; ControlUtils.SelectCheckComboBoxItems(ModifiersInput, p?.Modifiers, i => (i as Modifier)?.ModId); PartCommentInput.Text = p?.Comment ?? ""; TemperatureInput.Text = (p != null && p.Temperature != null) ? $"{p.Temperature:N1}" : ""; AcidInput.Text = (p != null && p.Acid != null) ? $"{p.Acid:N1}" : ""; LesewagenInput.IsChecked = p?.IsLesewagen ?? false; HandPickedInput.IsChecked = p?.IsHandPicked; ScaleId = p?.ScaleId; WeighingId = p?.WeighingId; FinishInputFilling(); } private async Task UpdateDeliveryPart(Delivery? d, DeliveryPart? p) { int year, did, dpnr; bool deliveryNew = (d == null), partNew = (p == null); var originalMgNr = d?.MgNr; var originalMemberKgNr = d?.Member?.DefaultKgNr; if (d == null) { d = Context.CreateProxy(); year = Utils.CurrentNextSeason; did = await Context.NextDId(year); } else { year = d.Year; did = d.DId; } if (p == null) { p = Context.CreateProxy(); dpnr = await Context.NextDPNr(year, did); } else { dpnr = p.DPNr; } d.Year = year; d.DId = did; p.Year = year; p.DId = did; p.DPNr = dpnr; d.DateString = string.Join("-", DateInput.Text.Split(".").Reverse()); if (IsCreating || InputHasChanged(DateInput)) { d.LNr = await Context.NextLNr(d.Date); } if (IsCreating) { d.TimeString = DateTime.Now.ToString("HH:mm:ss"); } else if (InputHasChanged(TimeInput)) { d.TimeString = TimeInput.Text + ":00"; } d.ZwstId = (BranchInput.SelectedItem as Branch)?.ZwstId; d.LsNr = LsNrInput.Text; d.MgNr = int.Parse(MgNrInput.Text); d.Comment = (CommentInput.Text == "") ? null : CommentInput.Text; p.SortId = (WineVarietyInput.SelectedItem as WineVar)?.SortId; p.Kmw = double.Parse(GradationKmwInput.Text); p.QualId = (WineQualityLevelInput.SelectedItem as WineQualLevel)?.QualId; p.HkId = (WineOriginInput.SelectedItem as WineOrigin)?.HkId; p.KgNr = (WineKgInput.SelectedItem as AT_Kg)?.KgNr; p.RdNr = (WineRdInput.SelectedItem as WbRd)?.RdNr; p.IsGerebelt = GerebeltGewogenInput.IsChecked ?? false; p.IsHandPicked = HandPickedInput.IsChecked; p.IsLesewagen = LesewagenInput.IsChecked; p.Temperature = (TemperatureInput.Text == "") ? null : double.Parse(TemperatureInput.Text); p.Acid = (AcidInput.Text == "") ? null : double.Parse(AcidInput.Text); p.Comment = (PartCommentInput.Text == "") ? null : PartCommentInput.Text; p.Weight = int.Parse(WeightInput.Text.Replace("\u202f", "")); p.ManualWeighing = ManualWeighingInput.IsChecked ?? false; p.ScaleId = ScaleId; p.WeighingId = WeighingId; if (ManualWeighingReason != null) p.Comment = (p.Comment != null ? $"{p.Comment} / " : "") + $"Begründung Handwiegung: {ManualWeighingReason}"; EntityEntry? dEntry = null; EntityEntry? pEntry = null; try { if (IsEditing) { dEntry = Context.Update(d); pEntry = Context.Update(p); } else if (IsCreating) { dEntry = deliveryNew ? await Context.AddAsync(d) : Context.Update(d); pEntry = partNew ? await Context.AddAsync(p) : Context.Update(p); } await Context.UpdateDeliveryPartAttributes(p, AttributesInput.SelectedItems.Cast()); await Context.UpdateDeliveryPartModifiers(p, ModifiersInput.SelectedItems.Cast()); if (originalMgNr != null && originalMgNr.Value != d.MgNr) { // update origin (KgNr), if default is selected var newKgNr = (await Context.Members.FindAsync(d.MgNr))?.DefaultKgNr; foreach (var part in d.Parts.Where(part => part.DPNr != dpnr && part.KgNr == originalMemberKgNr)) { part.KgNr = newKgNr; Context.Update(part); } } await Context.SaveChangesAsync(); } catch (Exception exc) { if (dEntry != null) { dEntry.State = EntityState.Detached; await dEntry.ReloadAsync(); } if (pEntry != null) { pEntry.State = EntityState.Detached; await pEntry.ReloadAsync(); } var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } return p; } private void WeighingButton_Click(object sender, RoutedEventArgs evt) { int index = Array.IndexOf(WeighingButtons, sender as Button); if (index >= 0) WeighingButton_Click(index); } private async void WeighingButton_Click(int index) { DisableWeighingButtons(); FinishButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false; CancelCreatingButton.IsEnabled = false; try { var s = App.Scales[index]; var res = await s.Weigh(); if ((res.Weight ?? 0) > 0 && res.FullWeighingId != null) { WeightInput.Text = $"{res.Weight:N0}"; ScaleId = s.ScaleId; WeighingId = res.FullWeighingId; s.Empty(); } else { WeightInput.Text = ""; ScaleId = null; WeighingId = null; } ManualWeighingReason = null; ManualWeighingInput.IsChecked = false; } catch (Exception e) { MessageBox.Show($"Beim Wiegen ist ein Fehler aufgetreten:\n\n{e.Message}", "Waagenfehler", MessageBoxButton.OK, MessageBoxImage.Error); } EnableWeighingButtons(); UpdateButtons(); } private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) { TextFilter = SearchInput.Text.ToLower().Split(" ").ToList().FindAll(e => e.Length > 0); await RefreshDeliveryListQuery(true); } private async void SeasonInput_ValueChanged(object sender, RoutedEventArgs evt) { if (SeasonInput.Value == null) return; TodayOnlyInput.IsChecked = false; AllSeasonsInput.IsChecked = false; await RefreshDeliveryListQuery(); } private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) { if (TodayOnlyInput.IsChecked == true && AllSeasonsInput.IsChecked == false) { SeasonInput.Value = Utils.Today.Year; TodayOnlyInput.IsChecked = true; } await RefreshDeliveryListQuery(); } private async void AllSeasonsInput_Changed(object sender, RoutedEventArgs evt) { if (AllSeasonsInput.IsChecked == true) { SeasonInput.IsEnabled = false; SeasonInput.Text = ""; } else { SeasonInput.IsEnabled = true; var today = TodayOnlyInput.IsChecked; SeasonInput.Value = Utils.CurrentLastSeason; TodayOnlyInput.IsChecked = today; } await RefreshDeliveryListQuery(); } private async void DeliveryList_SelectionChanged(object sender, SelectionChangedEventArgs evt) { await RefreshDeliveryParts(); if (DeliveryList.SelectedItem != null) { DeleteDeliveryButton.IsEnabled = true; Menu_Print_ShowDeliveryNote.IsEnabled = !IsEditing && !IsCreating; Menu_Print_PrintDeliveryNote.IsEnabled = !IsEditing && !IsCreating; } else { DeleteDeliveryButton.IsEnabled = false; Menu_Print_ShowDeliveryNote.IsEnabled = false; Menu_Print_PrintDeliveryNote.IsEnabled = false; } } private void DeliveryPartList_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) { RefreshInputs(); if (DeliveryPartList.SelectedItem is DeliveryPart p) { AbwertenButton.IsEnabled = p.QualId != "WEI"; EditDeliveryButton.IsEnabled = true; ExtractDeliveryPartButton.IsEnabled = !IsCreating; DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating; } else { AbwertenButton.IsEnabled = false; EditDeliveryButton.IsEnabled = false; ExtractDeliveryPartButton.IsEnabled = false; DeleteDeliveryPartButton.IsEnabled = false; } } private void MgNrInput_TextChanged(object sender, TextChangedEventArgs evt) { var valid = InputTextChanged((TextBox)sender, Validator.CheckMgNr); MemberInput.SelectedItem = valid ? Context.Members.Find(int.Parse(MgNrInput.Text)) : null; } private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) { var valid = InputLostFocus((TextBox)sender, Validator.CheckMgNr); MemberInput.SelectedItem = valid ? Context.Members.Find(int.Parse(MgNrInput.Text)) : null; } private void MemberInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { var m = MemberInput.SelectedItem as Member; if (m != null) MgNrInput.Text = m.MgNr.ToString(); MemberAddressField.Text = m?.FullAddress; if (m == null) { UnsetDefaultValue(WineKgInput); WineKgInput.SelectedIndex = 0; } else { SetDefaultValue(WineKgInput, m.DefaultKg); WineKgInput.SelectedItem = m.DefaultKg; } } private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { DeliveryPartList.IsEnabled = false; var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); await RefreshDeliveryList(); await RefreshDeliveryParts(); DeliveryList.SelectedItem = p?.Delivery; DeliveryPartList.SelectedItem = null; InitialInputs(); } private async void FinishButton_Click(object sender, RoutedEventArgs evt) { DeliveryPartList.IsEnabled = false; var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); await RefreshDeliveryList(); await RefreshDeliveryParts(); if (p?.Delivery != null) { using var doc = new DeliveryNote(p.Delivery, Context); await doc.Generate(); doc.Show(); //await doc.Print(2); } DeliveryList.SelectedItem = null; InitInputs(); } private void CancelCreatingButton_Click(object sender, RoutedEventArgs evt) { ControlUtils.RenewItemsSource(AttributesInput, Context.WineAttributes.OrderBy(a => a.Name).ToList(), i => (i as WineAttr)?.AttrId); if (DeliveryList.SelectedItem is not Delivery d) { // switch away from creating mode IsCreating = false; IsEditing = false; DeliveryList.IsEnabled = true; DeliveryPartList.IsEnabled = true; DisableWeighingButtons(); HideFinishNewPartDeliveryCancelButtons(); ShowNewEditDeleteButtons(); RefreshInputs(); ClearInputStates(); LockInputs(); UnlockSearchInputs(); } else { // switch to last delivery part DeliveryPartList.IsEnabled = true; DeliveryPartList.SelectedItem = d.Parts.Last(); } } private void NewDeliveryButton_Click(object? sender, RoutedEventArgs? evt) { ControlUtils.RenewItemsSource(AttributesInput, Context.WineAttributes.Where(a => a.IsActive).OrderBy(a => a.Name).ToList(), i => (i as WineAttr)?.AttrId); IsCreating = true; DeliveryList.IsEnabled = false; DeliveryPartList.IsEnabled = false; EnableWeighingButtons(); DeliveryList.SelectedItem = null; HideNewEditDeleteButtons(); UnlockInputs(); InitInputs(); ShowFinishNewPartDeliveryCancelButtons(); LockSearchInputs(); } private async void AbwertenButton_Click(object sender, RoutedEventArgs evt) { if (DeliveryPartList.SelectedItem is not DeliveryPart p) return; var res = Utils.ShowAbwertenDialog($"{p.Delivery.LsNr}/{p.DPNr}", p.Delivery.Member.AdministrativeName, p.Weight); EntityEntry? entry1 = null, entry2 = null; try { if (res == null || res <= 0) return; ClearOriginalValues(); if (res >= p.Weight) { ControlUtils.SelectComboBoxItem(WineQualityLevelInput, q => (q as WineQualLevel)?.QualId, "WEI"); ControlUtils.SelectComboBoxItem(WineOriginInput, o => (o as WineOrigin)?.HkId, "OEST"); p.QualId = "WEI"; p.HkId = "OEST"; entry1 = Context.Update(p); } else { var w = p.Weight - res.Value; WeightInput.Text = $"{w:N0}"; p.Weight = w; entry1 = Context.Update(p); var d = p.Delivery; var p2 = Context.CreateProxy(); var values = Context.Entry(p).CurrentValues; Context.Entry(p2).CurrentValues.SetValues(values); p2.DPNr = await Context.NextDPNr(d.Year, d.DId); p2.Weight = res.Value; p2.QualId = "WEI"; p2.HkId = "OEST"; entry2 = await Context.AddAsync(p2); await Context.UpdateDeliveryPartAttributes(p2, p.Attributes); await Context.UpdateDeliveryPartModifiers(p2, p.Modifiers); } await Context.SaveChangesAsync(); await RefreshDeliveryParts(); FinishInputFilling(); } catch (Exception exc) { if (entry1 != null) { entry1.State = EntityState.Detached; await entry1.ReloadAsync(); } if (entry2 != null) { entry2.State = EntityState.Detached; await entry2.ReloadAsync(); } var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } } private void WeighingManualButton_Click(object sender, RoutedEventArgs evt) { var res = Utils.ShowManualWeighingDialog(); if (res == null) return; WeightInput.Text = $"{res?.Item1:N0}"; ManualWeighingInput.IsChecked = true; ManualWeighingReason = res?.Item2; ScaleId = null; WeighingId = null; } private void EditDeliveryButton_Click(object sender, RoutedEventArgs evt) { if (DeliveryPartList.SelectedItem == null) return; IsEditing = true; DeliveryList.IsEnabled = false; DeliveryPartList.IsEnabled = false; HideNewEditDeleteButtons(); ShowSaveResetCancelButtons(); UnlockInputs(); LockSearchInputs(); AbwertenButton.IsEnabled = false; ExtractDeliveryPartButton.IsEnabled = false; DeleteDeliveryPartButton.IsEnabled = false; } private async void DeleteDeliveryButton_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; var r = MessageBox.Show( $"Soll die Lieferung {d.LsNr} ({d.Member.AdministrativeName}, MgNr. {d.Member.MgNr}) wirklich unwiderruflich gelöscht werden?", "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); if (r == MessageBoxResult.Yes) { Context.Remove(d); await Context.SaveChangesAsync(); await RefreshDeliveryList(); await RefreshDeliveryParts(); } } private async void SaveButton_Click(object sender, RoutedEventArgs evt) { DeliveryPart p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); IsEditing = false; IsCreating = false; DeliveryList.IsEnabled = true; DeliveryPartList.IsEnabled = true; HideSaveResetCancelButtons(); ShowNewEditDeleteButtons(); LockInputs(); UnlockSearchInputs(); FinishInputFilling(); await RefreshDeliveryList(); await RefreshDeliveryParts(); RefreshInputs(); AbwertenButton.IsEnabled = p.QualId != "WEI"; ExtractDeliveryPartButton.IsEnabled = DeliveryPartList.SelectedItem != null && !IsCreating; DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating; } private void ResetButton_Click(object sender, RoutedEventArgs evt) { if (IsEditing) { RefreshInputs(); } else if (IsCreating) { ClearInputs(); InitInputs(); } UpdateButtons(); } private void CancelButton_Click(object sender, RoutedEventArgs evt) { IsEditing = false; IsCreating = false; DeliveryList.IsEnabled = true; DeliveryPartList.IsEnabled = true; HideSaveResetCancelButtons(); ShowNewEditDeleteButtons(); RefreshInputs(); LockInputs(); UnlockSearchInputs(); AbwertenButton.IsEnabled = DeliveryPartList.SelectedItem is DeliveryPart p && p.QualId != "WEI"; ExtractDeliveryPartButton.IsEnabled = DeliveryPartList.SelectedItem != null && !IsCreating; DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating; } private async void ExtractDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { if (DeliveryPartList.SelectedItem is not DeliveryPart p) return; var delivery = p.Delivery; var day = delivery.Date; var count = delivery.Parts.Count; if (delivery.Time <= new TimeOnly(3, 0)) day = day.AddDays(-1); var lsnrs = await Context.Deliveries .Where(d => d.ZwstId == delivery.ZwstId) .Where(d => (d.DateString == day.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) || (d.DateString == day.AddDays(1).ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") <= 0)) .Where(d => d.LsNr != delivery.LsNr) .OrderBy(d => d.LsNr) .Select(d => d.LsNr) .ToListAsync(); var res = Utils.ShowDeliveryExtractionDialog($"{delivery.LsNr}/{p.DPNr}", delivery.Member.AdministrativeName, count == 1, lsnrs); EntityEntry? entry = null; try { Delivery? d = null; if (res == null) { return; } else if (res == "new") { d = Context.CreateProxy(); d.Date = delivery.Date; d.Time = delivery.Time; d.Year = p.Year; d.DId = await Context.NextDId(d.Year); d.LNr = await Context.NextLNr(d.Date); d.ZwstId = delivery.ZwstId; d.MgNr = delivery.MgNr; d.Comment = delivery.Comment; d.LsNr = Utils.GenerateLsNr(d); entry = await Context.AddAsync(d); await Context.SaveChangesAsync(); } else { d = await Context.Deliveries.Where(d => d.LsNr == res).FirstOrDefaultAsync(); } if (d == null) return; await Context.Database.ExecuteSqlAsync($"UPDATE delivery_part SET year = {d.Year}, did = {d.DId}, dpnr = {await Context.NextDPNr(d.Year, d.DId)} WHERE (year, did, dpnr) = ({p.Year}, {p.DId}, {p.DPNr})"); Context.Entry(p).State = EntityState.Detached; if (count == 1) { await Context.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({delivery.Year}, {delivery.DId})"); Context.Entry(delivery).State = EntityState.Detached; } await Context.SaveChangesAsync(); await Context.Entry(p).ReloadAsync(); await Context.Entry(delivery).ReloadAsync(); await RefreshDeliveryList(); DeliveryList.SelectedItem = d; } catch (Exception exc) { if (entry != null) { entry.State = EntityState.Detached; await entry.ReloadAsync(); } var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } } private async void DeleteDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { if (DeliveryPartList.SelectedItem is not DeliveryPart p) return; var r = MessageBox.Show( $"Soll die Teillieferung Nr. {p.DPNr} wirklich unwiderruflich gelöscht werden?", "Lieferung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); if (r == MessageBoxResult.Yes) { Context.Remove(p); await Context.SaveChangesAsync(); await RefreshDeliveryParts(); } } private void ShowSaveResetCancelButtons() { SaveButton.IsEnabled = false; ResetButton.IsEnabled = false; CancelButton.IsEnabled = true; SaveButton.Visibility = Visibility.Visible; ResetButton.Visibility = Visibility.Visible; CancelButton.Visibility = Visibility.Visible; } private void HideSaveResetCancelButtons() { SaveButton.IsEnabled = false; ResetButton.IsEnabled = false; CancelButton.IsEnabled = false; SaveButton.Visibility = Visibility.Hidden; ResetButton.Visibility = Visibility.Hidden; CancelButton.Visibility = Visibility.Hidden; } private void ShowNewEditDeleteButtons() { NewDeliveryButton.IsEnabled = IsReceipt; AbwertenButton.IsEnabled = DeliveryPartList.SelectedItem is DeliveryPart p && p.QualId == "WEI"; EditDeliveryButton.IsEnabled = DeliveryPartList.SelectedItem != null; DeleteDeliveryButton.IsEnabled = DeliveryList.SelectedItem != null; NewDeliveryButton.Visibility = IsReceipt ? Visibility.Visible : Visibility.Hidden; AbwertenButton.Visibility = !IsReceipt ? Visibility.Visible : Visibility.Hidden; EditDeliveryButton.Visibility = Visibility.Visible; DeleteDeliveryButton.Visibility = Visibility.Visible; } private void HideNewEditDeleteButtons() { NewDeliveryButton.IsEnabled = false; AbwertenButton.IsEnabled = false; EditDeliveryButton.IsEnabled = false; DeleteDeliveryButton.IsEnabled = false; NewDeliveryButton.Visibility = Visibility.Hidden; AbwertenButton.Visibility = Visibility.Hidden; EditDeliveryButton.Visibility = Visibility.Hidden; DeleteDeliveryButton.Visibility = Visibility.Hidden; } private void ShowFinishNewPartDeliveryCancelButtons() { FinishButton.IsEnabled = IsCreating && IsValid; NewDeliveryPartButton.IsEnabled = IsCreating && IsValid; CancelCreatingButton.IsEnabled = true; FinishButton.Visibility = Visibility.Visible; NewDeliveryPartButton.Visibility = Visibility.Visible; CancelCreatingButton.Visibility = Visibility.Visible; } private void HideFinishNewPartDeliveryCancelButtons() { FinishButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false; CancelCreatingButton.IsEnabled = false; FinishButton.Visibility = Visibility.Hidden; NewDeliveryPartButton.Visibility = Visibility.Hidden; CancelCreatingButton.Visibility = Visibility.Hidden; } private void LockSearchInputs() { SearchInput.IsEnabled = false; SeasonInput.IsEnabled = false; TodayOnlyInput.IsEnabled = false; AllSeasonsInput.IsEnabled = false; } private void UnlockSearchInputs() { SearchInput.IsEnabled = true; SeasonInput.IsEnabled = true; TodayOnlyInput.IsEnabled = true; AllSeasonsInput.IsEnabled = (Member != null); } new protected void UnlockInputs() { base.UnlockInputs(); if (WineQualityLevelInput.SelectedItem != null && WineKgInput.SelectedItem != null) WineOriginInput.IsEnabled = false; if (WineKgInput.SelectedItem == null) WineRdInput.IsEnabled = false; WeightInput.IsReadOnly = true; AbgewertetInput.IsEnabled = false; ManualWeighingInput.IsEnabled = false; LsNrInput.IsReadOnly = true; DateInput.IsReadOnly = true; TimeInput.IsReadOnly = true; BranchInput.IsEnabled = false; } private void DisableWeighingButtons() { WeighingManualButton.IsEnabled = false; WeighingAButton.IsEnabled = false; WeighingBButton.IsEnabled = false; WeighingCButton.IsEnabled = false; WeighingDButton.IsEnabled = false; } private void EnableWeighingButtons() { WeighingManualButton.IsEnabled = true; WeighingAButton.IsEnabled = true; WeighingBButton.IsEnabled = true; WeighingCButton.IsEnabled = true; WeighingDButton.IsEnabled = true; } private async Task UpdateLsNr() { if (DateInput.Text == "" || BranchInput.SelectedItem == null) { LsNrInput.Text = ""; } else { var branch = (Branch)BranchInput.SelectedItem; var date = DateOnly.ParseExact(DateInput.Text, "dd.MM.yyyy"); var lnr = await Context.NextLNr(date); LsNrInput.Text = Utils.GenerateLsNr(date, branch.ZwstId, lnr); } } private void DateInput_TextChanged(object sender, TextChangedEventArgs evt) { if (IsCreating) UpdateLsNr().GetAwaiter().GetResult(); } private void UpdateWineVariety(bool valid) { if (valid) { var text = SortIdInput.Text; WineVarietyInput.SelectedItem = Context.WineVarieties.Find(text[0..2]); if (text.Length >= 3) { AttributesInput.UnSelectAll(); AttributesInput.SelectedItems.Add(Context.WineAttributes.Find(text[2..])); SortIdInput.Text = text[0..2]; } } else { WineVarietyInput.SelectedItem = null; AttributesInput.UnSelectAll(); } } private void SortIdInput_TextChanged(object sender, TextChangedEventArgs evt) { UpdateWineVariety(InputTextChanged((TextBox)sender, Validator.CheckSortId)); } private void SortIdInput_LostFocus(object sender, RoutedEventArgs evt) { UpdateWineVariety(InputLostFocus((TextBox)sender, Validator.CheckSortId)); } private void WineVarietyInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { if (WineVarietyInput.SelectedItem is WineVar s) SortIdInput.Text = s.SortId; } private void UpdateWineQualityLevels() { if (!GetInputValid(GradationKmwInput)) { UnsetDefaultValue(WineQualityLevelInput); WineQualityLevelInput.ItemsSource = Context.WineQualityLevels.Where(q => q.QualId == "WEI").ToList(); return; } var kmw = double.Parse(GradationKmwInput.Text); WineQualityLevelInput.ItemsSource = Context.WineQualityLevels.Where(q => q.MinKmw == null || q.MinKmw <= kmw).ToList(); var qual = Context.GetWineQualityLevel(kmw).GetAwaiter().GetResult(); SetDefaultValue(WineQualityLevelInput, qual); if (WineQualityLevelInput.SelectedItem == null || (WineQualityLevelInput.SelectedItem is WineQualLevel selected && !selected.IsPredicate)) { WineQualityLevelInput.SelectedItem = qual; } } private void UpdateGradationKmw() { IsUpdatingGradation = true; var caret = GradationKmwInput.CaretIndex; GradationKmwInput.Text = $"{Utils.OeToKmw(double.Parse(GradationOeInput.Text)):#.0}"; GradationKmwInput.CaretIndex = caret; IsUpdatingGradation = false; } private void UpdateGradationOe() { IsUpdatingGradation = true; var caret = GradationOeInput.CaretIndex; GradationOeInput.Text = $"{Utils.KmwToOe(double.Parse(GradationKmwInput.Text)):#}"; GradationOeInput.CaretIndex = caret; IsUpdatingGradation = false; } private void GradationOeInput_TextChanged(object sender, TextChangedEventArgs evt) { var valid = InputTextChanged((TextBox)sender, Validator.CheckGradatoinOe); if (!IsUpdatingGradation) { if (valid) UpdateGradationKmw(); else if (GradationOeInput.Text.Length == 0) GradationKmwInput.Text = ""; if (valid || GradationOeInput.Text.Length == 0) UpdateWineQualityLevels(); } } private void GradationOeInput_LostFocus(object sender, RoutedEventArgs evt) { InputLostFocus((TextBox)sender, Validator.CheckGradatoinOe); } private void GradationKmwInput_TextChanged(object sender, TextChangedEventArgs evt) { var valid = InputTextChanged((TextBox)sender, Validator.CheckGradationKmw); if (!IsUpdatingGradation) { if (valid) UpdateGradationOe(); else if (GradationKmwInput.Text.Length == 0) GradationOeInput.Text = ""; if (valid || GradationKmwInput.Text.Length == 0) UpdateWineQualityLevels(); } } private void GradationKmwInput_LostFocus(object sender, RoutedEventArgs evt) { if (GradationKmwInput.Text.EndsWith(",")) GradationKmwInput.Text += "0"; InputLostFocus((TextBox)sender, Validator.CheckGradationKmw); if (GradationKmwInput.Text.Length != 0 && !GradationKmwInput.Text.Contains(',')) GradationKmwInput.Text += ",0"; } private void AttributesInput_SelectionChanged(object sender, ItemSelectionChangedEventArgs evt) { } private void ModifiersInput_SelectionChanged(object sender, ItemSelectionChangedEventArgs evt) { if ((IsEditing || IsCreating) && App.Client.IsMatzen) { var mod = ModifiersInput.SelectedItems.Cast(); var kl = mod.Where(m => m.Name.StartsWith("Klasse ")); if (kl.Count() > 1) { foreach (var r in kl.Take(kl.Count() - 1)) ModifiersInput.SelectedItems.Remove(r); } } } private void LesewagenInput_Changed(object sender, RoutedEventArgs evt) { if ((IsEditing || IsCreating) && App.Client.IsMatzen) { var mod = ModifiersInput.SelectedItems.Cast(); var kl = mod.Where(m => m.Name.StartsWith("Klasse ")).Select(m => m.ModId).LastOrDefault("A")[0]; if (LesewagenInput.IsChecked == true) kl++; else kl--; var newKl = ModifiersInput.ItemsSource.Cast().Where(m => m.ModId == kl.ToString()).FirstOrDefault(); if (newKl != null) ModifiersInput.SelectedItems.Add(newKl); } CheckBox_Changed(sender, evt); } private void UpdateWineOrigin() { var qual = WineQualityLevelInput.SelectedItem as WineQualLevel; var kg = (WineKgInput.SelectedItem as AT_Kg)?.WbKg; if (qual == null || kg == null) { WineOriginInput.IsEnabled = (IsEditing || IsCreating); UnsetDefaultValue(WineOriginInput); return; } WineOriginInput.IsEnabled = false; var o = kg.Origin; while (o != null && o.Level > qual.OriginLevel) o = o.Parent; SetDefaultValue(WineOriginInput, o); WineOriginInput.SelectedItem = o; } private void WineQualityLevelInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { UpdateWineOrigin(); UpdateAbgewertet(); } private void UpdateRdInput() { if (WineKgInput.SelectedItem is AT_Kg kg) { var list = Context.WbRde.Where(r => r.KgNr == kg.KgNr).OrderBy(r => r.Name).Cast().ToList(); list.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(WineRdInput, list, i => ((i as WbRd)?.KgNr, (i as WbRd)?.RdNr)); if (WineRdInput.SelectedItem == null) WineRdInput.SelectedIndex = 0; WineRdInput.IsEnabled = (IsEditing || IsCreating) && list.Count > 1; } else { WineRdInput.ItemsSource = null; WineRdInput.IsEnabled = false; } } private void WineKgInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { UpdateWineOrigin(); UpdateRdInput(); } private void UpdateAbgewertet() { if (!GetInputValid(GradationKmwInput)) return; var qual = WineQualityLevelInput.SelectedItem as WineQualLevel; if (qual == null) { AbgewertetInput.IsChecked = false; return; } var defQual = Context.GetWineQualityLevel(double.Parse(GradationKmwInput.Text)).GetAwaiter().GetResult(); AbgewertetInput.IsChecked = !qual.IsPredicate && defQual != qual; } private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) { InputTextChanged((TextBox)sender); } private void TemperatureAcidInput_TextChanged(object sender, TextChangedEventArgs evt) { InputTextChanged((TextBox)sender, Validator.CheckDecimal((TextBox)sender, false, 2, 1)); } private void TemperatureAcidInput_LostFocus(object sender, RoutedEventArgs evt) { if (sender is not TextBox tb) return; if (tb.Text.Length > 0) { if (!tb.Text.Contains(',')) tb.Text += ",0"; if (tb.Text.EndsWith(",")) tb.Text += "0"; } InputLostFocus(tb, Validator.CheckDecimal(tb, false, 2, 1)); } } }