using Elwig.Documents; using Elwig.Helpers; using Elwig.Helpers.Export; using Elwig.Helpers.Weighing; using Elwig.Models.Entities; using Elwig.Services; using Elwig.ViewModels; using Microsoft.EntityFrameworkCore; using Microsoft.Win32; using System; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Threading; namespace Elwig.Windows { public partial class DeliveryAdminWindow : AdministrationWindow { public DeliveryAdminViewModel ViewModel => (DeliveryAdminViewModel)DataContext; private bool IsUpdatingGradation = false; private readonly DispatcherTimer SecondsTimer; private readonly RoutedCommand CtrlF = new("CtrlF", typeof(DeliveryAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]); private readonly RoutedCommand CtrlL = new("CtrlL", typeof(DeliveryAdminWindow), [new KeyGesture(Key.L, ModifierKeys.Control)]); private readonly RoutedCommand CtrlP = new("CtrlP", typeof(DeliveryAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control)]); private readonly RoutedCommand CtrlO = new("CtrlO", typeof(DeliveryAdminWindow), [new KeyGesture(Key.O, ModifierKeys.Control)]); private readonly RoutedCommand CtrlJ = new("CtrlJ", typeof(DeliveryAdminWindow), [new KeyGesture(Key.J, ModifierKeys.Control)]); private readonly RoutedCommand CtrlQ = new("CtrlQ", typeof(DeliveryAdminWindow), [new KeyGesture(Key.Q, ModifierKeys.Control)]); private readonly RoutedCommand CtrlH = new("CtrlH", typeof(DeliveryAdminWindow), [new KeyGesture(Key.H, ModifierKeys.Control)]); private readonly RoutedCommand CtrlShiftP = new("CtrlShiftP", typeof(DeliveryAdminWindow), [new KeyGesture(Key.P, ModifierKeys.Control | ModifierKeys.Shift)]); private readonly RoutedCommand CtrlShiftO = new("CtrlShiftO", typeof(DeliveryAdminWindow), [new KeyGesture(Key.O, ModifierKeys.Control | ModifierKeys.Shift)]); private readonly Button[] WeighingButtons; public DeliveryAdminWindow(bool receipt = false) { InitializeComponent(); CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput)); CommandBindings.Add(new CommandBinding(CtrlL, Menu_DeliveryJournal_SaveFilters_Click)); CommandBindings.Add(new CommandBinding(CtrlP, Menu_DeliveryNote_Show_Click)); CommandBindings.Add(new CommandBinding(CtrlO, Menu_DeliveryJournal_ShowFilters_Click)); CommandBindings.Add(new CommandBinding(CtrlJ, Menu_DeliveryJournal_PrintToday_Click)); CommandBindings.Add(new CommandBinding(CtrlQ, Menu_WineQualityStatistics_PrintToday_Click)); CommandBindings.Add(new CommandBinding(CtrlH, Menu_Export_UploadToday_Click)); CommandBindings.Add(new CommandBinding(CtrlShiftP, Menu_DeliveryNote_Print_Click)); CommandBindings.Add(new CommandBinding(CtrlShiftO, Menu_DeliveryJournal_PrintFilters_Click)); RequiredInputs = [ MgNrInput, MemberInput, LsNrInput, DateInput, BranchInput, SortIdInput, WineVarietyInput, GradationOeInput, GradationKmwInput, WineQualityLevelInput, WineOriginInput, WineKgInput, WeightInput ]; ExemptInputs = [ SearchInput, SeasonInput, TodayOnlyInput, AllSeasonsInput, DeliveryList, DeliveryPartList, MemberAddressField, ]; WeighingButtons = [ WeighingAButton, WeighingBButton, WeighingCButton, WeighingDButton, ]; ViewModel.IsReceipt = receipt; SecondsTimer = new DispatcherTimer(); SecondsTimer.Tick += new EventHandler(OnSecondPassed); SecondsTimer.Interval = new TimeSpan(0, 0, 1); InitializeDelayTimer(SearchInput, SearchInput_TextChanged); SearchInput.TextChanged -= SearchInput_TextChanged; ViewModel.FilterSeason = Utils.CurrentLastSeason; DoShowWarningWindows = false; if (ViewModel.IsReceipt) { ViewModel.Title = $"Übernahme - {App.BranchName} - Elwig"; ViewModel.FilterTodayOnly = true; var n = App.CommandScales.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.CommandScales[0].ScaleId}"; if (n >= 2) WeighingBButton.Content = $"Wiegen {App.CommandScales[1].ScaleId}"; if (n >= 3) WeighingCButton.Content = $"Wiegen {App.CommandScales[2].ScaleId}"; if (n >= 4) WeighingDButton.Content = $"Wiegen {App.CommandScales[3].ScaleId}"; WeighingManualButton.Margin = new Thickness(10, 10 + n * 32, 10, 10); foreach (var s in App.EventScales) { s.WeighingEvent += Scale_Weighing; } } else { WeighingManualButton.Visibility = Visibility.Hidden; WeighingAButton.Visibility = Visibility.Hidden; WeighingBButton.Visibility = Visibility.Hidden; WeighingCButton.Visibility = Visibility.Hidden; WeighingDButton.Visibility = Visibility.Hidden; } Menu_WineQualityStatistics_ModeOe.IsChecked = false; Menu_WineQualityStatistics_ModeKmw1.IsChecked = false; Menu_WineQualityStatistics_ModeKmw2.IsChecked = false; Menu_WineQualityStatistics_ModeKmw5.IsChecked = false; Menu_WineQualityStatistics_ModeKmw10.IsChecked = false; switch (App.Client.OrderingMemberList) { case 0: Menu_WineQualityStatistics_ModeOe.IsChecked = true; break; case 1: Menu_WineQualityStatistics_ModeKmw1.IsChecked = true; break; case 2: Menu_WineQualityStatistics_ModeKmw2.IsChecked = true; break; case 3: Menu_WineQualityStatistics_ModeKmw5.IsChecked = true; break; case 4: Menu_WineQualityStatistics_ModeKmw10.IsChecked = true; break; } Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null; Menu_Export_UploadToday.IsEnabled = App.Config.SyncUrl != null; } public DeliveryAdminWindow(int mgnr) : this() { ViewModel.FilterMember = DeliveryService.GetMember(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value"); ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig"; ViewModel.EnableAllSeasons = true; } private void Window_Loaded(object sender, RoutedEventArgs evt) { OnSecondPassed(null, null); SecondsTimer.Start(); LockInputs(); if (ViewModel.IsReceipt) { NewDeliveryButton_Click(null, null); using var ctx = new AppDbContext(); if (ctx.Seasons.Find(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.Warning); } } } private async void Menu_DeliveryNote_Show_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.Show); } private async void Menu_DeliveryNote_SavePdf_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.SavePdf); } private async void Menu_DeliveryNote_Print_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.Print); } private async void Menu_DeliveryNote_Email_Click(object sender, RoutedEventArgs evt) { if (DeliveryList.SelectedItem is not Delivery d) return; await DeliveryService.GenerateDeliveryNote(d.Year, d.DId, ExportMode.Email); } private async void Menu_Bki_SaveList_Click(object sender, RoutedEventArgs evt) { if (sender is not MenuItem m) return; var year = int.Parse(m.Header.ToString()?.Split(" ")[^1] ?? Utils.CurrentLastSeason.ToString()); var d = new SaveFileDialog() { FileName = $"{App.Client.NameToken}-Traubentransportscheinliste-{year}.{Bki.FileExtension}", DefaultExt = Bki.FileExtension, Filter = "CSV-Datei (*.csv)|*.csv", Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig" }; if (d.ShowDialog() == true) { Mouse.OverrideCursor = Cursors.AppStarting; using var file = new Bki(d.FileName); await file.ExportAsync(year); Mouse.OverrideCursor = null; } } private async void Menu_DeliveryJournal_SaveToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(1, ExportMode.SaveList); } private async void Menu_DeliveryJournal_SavePdfToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(1, ExportMode.SavePdf); } private async void Menu_DeliveryJournal_ShowToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(1, ExportMode.Show); } private async void Menu_Export_ExportToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(1, ExportMode.Export); } private async void Menu_DeliveryJournal_PrintToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(1, ExportMode.Print); } private async void Menu_DeliveryJournal_SaveFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(0, ExportMode.SaveList); } private async void Menu_DeliveryJournal_SavePdfFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(0, ExportMode.SavePdf); } private async void Menu_DeliveryJournal_ShowFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(0, ExportMode.Show); } private async void Menu_DeliveryJournal_PrintFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(0, ExportMode.Print); } private async void Menu_Export_ExportFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateDeliveryJournal(0, ExportMode.Export); } private async void Menu_Export_UploadToday_Click(object sender, RoutedEventArgs evt) { if (App.Config.SyncUrl == null) return; await ViewModel.GenerateDeliveryJournal(1, ExportMode.Upload); } private async void Menu_Export_UploadFilters_Click(object sender, RoutedEventArgs evt) { if (App.Config.SyncUrl == null) return; await ViewModel.GenerateDeliveryJournal(0, ExportMode.Upload); } private async void Menu_WineQualityStatistics_ShowToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateWineQualityStatistics(1, ExportMode.Show); } private async void Menu_WineQualityStatistics_SavePdfToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateWineQualityStatistics(1, ExportMode.SavePdf); } private async void Menu_WineQualityStatistics_PrintToday_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateWineQualityStatistics(1, ExportMode.Print); } private async void Menu_WineQualityStatistics_ShowFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateWineQualityStatistics(0, ExportMode.Show); } private async void Menu_WineQualityStatistics_SavePdfFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateWineQualityStatistics(0, ExportMode.SavePdf); } private async void Menu_WineQualityStatistics_PrintFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateWineQualityStatistics(0, ExportMode.Print); } private async void Menu_WineQualityStatistics_Mode_Click(object sender, RoutedEventArgs evt) { Menu_WineQualityStatistics.IsSubmenuOpen = true; if (sender == Menu_WineQualityStatistics_ModeOe) { App.Client.OrderingMemberList = 0; } else if (sender == Menu_WineQualityStatistics_ModeKmw1) { App.Client.OrderingMemberList = 1; } else if (sender == Menu_WineQualityStatistics_ModeKmw2) { App.Client.OrderingMemberList = 2; } else if (sender == Menu_WineQualityStatistics_ModeKmw5) { App.Client.OrderingMemberList = 3; } else if (sender == Menu_WineQualityStatistics_ModeKmw10) { App.Client.OrderingMemberList = 4; } Menu_WineQualityStatistics_ModeOe.IsChecked = App.Client.OrderingMemberList == 0; Menu_WineQualityStatistics_ModeKmw1.IsChecked = App.Client.OrderingMemberList == 1; Menu_WineQualityStatistics_ModeKmw2.IsChecked = App.Client.OrderingMemberList == 2; Menu_WineQualityStatistics_ModeKmw5.IsChecked = App.Client.OrderingMemberList == 3; Menu_WineQualityStatistics_ModeKmw10.IsChecked = App.Client.OrderingMemberList == 4; await App.Client.UpdateValues(); } private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) { if (IsEditing || IsCreating) { DateInput.IsReadOnly = false; TimeInput.IsReadOnly = false; BranchInput.IsEnabled = true; if (IsCreating) ViewModel.Time = ""; OnSecondPassed(null, null); } } private void Menu_Settings_EnableFreeEditing_Unchecked(object sender, RoutedEventArgs evt) { DateInput.IsReadOnly = true; TimeInput.IsReadOnly = true; BranchInput.IsEnabled = false; OnSecondPassed(null, null); } private void OnSecondPassed(object? sender, EventArgs? evt) { if (ViewModel.IsReceipt && IsCreating && !Menu_Settings_EnableFreeEditing.IsChecked) { var now = DateTime.Now; ViewModel.Time = now.ToString("HH:mm"); ViewModel.Date = now.ToString("dd.MM.yyyy"); SetDefaultValue(TimeInput); SetDefaultValue(DateInput); } } private void InitialDefaultInputs() { if (App.Client.HasNetWeighing(ViewModel.Branch)) { GerebeltGewogenInput.IsEnabled = false; SetDefaultValue(GerebeltGewogenInput, true); } else { GerebeltGewogenInput.IsEnabled = true; UnsetDefaultValue(GerebeltGewogenInput); } if (!App.Client.HasNetWeighing(ViewModel.Branch)) { LesewagenInput.IsEnabled = false; SetDefaultValue(LesewagenInput, false); HandPickedInput.IsThreeState = false; UnsetDefaultValue(HandPickedInput); } else { LesewagenInput.IsEnabled = true; UnsetDefaultValue(LesewagenInput); HandPickedInput.IsThreeState = true; SetDefaultValue(HandPickedInput, null); } if (App.Client.IsMatzen || App.Client.IsWinzerkeller) { GebundenInput.IsEnabled = false; SetDefaultValue(GebundenInput, null); } else { GebundenInput.IsEnabled = true; UnsetDefaultValue(GebundenInput); } } private void InitialInputs() { ViewModel.LastScaleError = null; ViewModel.WeighingData = null; ViewModel.ScaleId = null; ViewModel.ManualWeighingReason = null; ClearOriginalValues(); ClearDefaultValues(); ViewModel.IsNetWeight = App.Client.HasNetWeighing(ViewModel.Branch); ViewModel.IsLesewagen = false; ViewModel.IsHandPicked = !App.Client.HasNetWeighing(ViewModel.Branch) ? true : null; ViewModel.IsGebunden = null; InitialDefaultInputs(); WineQualityLevelInput.IsEnabled = false; ValidateRequiredInputs(); } private void InitInputs() { ControlUtils.SelectItemWithPk(BranchInput, 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 && ch; CancelCreatingButton.IsEnabled = DeliveryList.SelectedItem == null || DeliveryPartList.SelectedItem == null; } private void Input_KeyUp(object sender, KeyEventArgs evt) { if (sender is not Control ctrl) return; if (evt.Key != Key.Enter) return; if (ctrl == MgNrInput || ctrl == MemberInput) { SortIdInput.Focus(); SortIdInput.SelectAll(); } else if (ctrl == SortIdInput || ctrl == WineVarietyInput || ctrl == AttributeInput || ctrl == CultivationInput) { GradationOeInput.Focus(); GradationOeInput.SelectAll(); } else if (ctrl == GradationKmwInput || ctrl == GradationOeInput || ctrl == WineQualityLevelInput) { if (WeighingAButton.IsVisible) WeighingAButton.Focus(); else WeighingManualButton.Focus(); } } private async Task RefreshList(bool updateSort = false) { using var ctx = new AppDbContext(); var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await ViewModel.GetFilters(ctx); var deliveries = await deliveryQuery .Include(d => d.Parts).ThenInclude(p => p.PartModifiers).ThenInclude(m => m.Modifier) .Include(d => d.Parts).ThenInclude(p => p.Attribute) .Include(d => d.Parts).ThenInclude(p => p.Cultivation) .Include(d => d.Parts).ThenInclude(p => p.Variety) .Include(d => d.Member.EmailAddresses) .AsSplitQuery() .ToListAsync(); deliveries.Reverse(); if (filter.Count > 0 && deliveries.Count > 0) { var dict = deliveries.AsParallel() .ToDictionary(d => d, d => d.SearchScore(ViewModel.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(); } deliveries.ForEach(d => { d.PartFilter = predicate; }); ControlUtils.RenewItemsSource(DeliveryList, deliveries, DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort); await RefreshDeliveryParts(); var members = deliveries.Select(d => d.Member).DistinctBy(m => m.MgNr).ToList(); ViewModel.StatusMembers = $"{members.Count}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : ""); ViewModel.StatusDeliveries = $"{deliveries.Count}"; if (filter.Count == 0) { var deliveryParts = deliveryPartsQuery; ViewModel.StatusDeliveries = $"{deliveries.Count} ({await deliveryParts.CountAsync()})"; var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync(); ViewModel.StatusVarieties = $"{varieties.Count}" + (varieties.Count > 0 && varieties.Count <= 10 ? $" ({string.Join(", ", varieties)})" : ""); (ViewModel.StatusWeight, ViewModel.StatusWeightToolTip, ViewModel.StatusGradation, ViewModel.StatusGradationToolTip) = await DeliveryService.GenerateToolTip(deliveryParts); } else { ViewModel.StatusVarieties = "-"; ViewModel.StatusWeight = "-"; ViewModel.StatusGradation = "-"; } if (updateSort && DeliveryList.SelectedItem != null) DeliveryList.ScrollIntoView(DeliveryList.SelectedItem); } protected override async Task OnRenewContext(AppDbContext ctx) { await base.OnRenewContext(ctx); if (ViewModel.FilterMember != null) { if (await DeliveryService.GetMemberAsync(ViewModel.FilterMember.MgNr) is not Member m) { Close(); return; } ViewModel.FilterMember = m; ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig"; } Menu_Bki_SaveList.Items.Clear(); foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) { var i = new MenuItem { Header = $"Saison {s.Year}", }; i.Click += Menu_Bki_SaveList_Click; Menu_Bki_SaveList.Items.Add(i); } await RefreshList(); var d = DeliveryList.SelectedItem as Delivery; var y = d?.Year ?? ViewModel.FilterSeason; ControlUtils.RenewItemsSource(MemberInput, await ctx.Members .Where(m => m.IsActive || !IsCreating) .Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.DefaultWbKg!.AtKg) .OrderBy(m => m.FamilyName) .ThenBy(m => m.GivenName) .ToListAsync()); ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync()); ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync()); var attrList = await ctx.WineAttributes.Where(a => !IsCreating || a.IsActive).OrderBy(a => a.Name).Cast().ToListAsync(); attrList.Insert(0, new NullItem("")); ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First); var cultList = await ctx.WineCultivations.OrderBy(a => a.Name).Cast().ToListAsync(); cultList.Insert(0, new NullItem("")); ControlUtils.RenewItemsSource(CultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First); ControlUtils.RenewItemsSource(WineQualityLevelInput, await ctx.WineQualityLevels.ToListAsync()); ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers .Where(m => m.Year == y && (!IsCreating || m.IsActive)) .OrderBy(m => m.Ordering) .Include(m => m.Season.Currency) .ToListAsync()); ControlUtils.RenewItemsSource(WineOriginInput, (await ctx.WineOrigins.ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId)); var kgList = (await ctx.Katastralgemeinden .Where(k => k.WbKg != null) .Include(k => k.WbKg) .Include(k => k.Gem.WbGem) .OrderBy(k => k.Name) .AsSplitQuery() .ToListAsync()).Cast().ToList(); kgList.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(WineKgInput, kgList); UpdateRdInput(); if (IsCreating) await UpdateLsNr(); await RefreshDeliveryParts(); RefreshInputs(); } private void FocusSearchInput(object sender, RoutedEventArgs evt) { if (!IsEditing && !IsCreating) { SearchInput.Focus(); SearchInput.SelectAll(); } } private async Task RefreshDeliveryParts() { using var ctx = new AppDbContext(); if (DeliveryList.SelectedItem is Delivery d) { ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers .Where(m => m.Year == d.Year && (!IsCreating || m.IsActive)) .OrderBy(m => m.Ordering) .Include(m => m.Season.Currency) .ToListAsync()); ControlUtils.RenewItemsSource(DeliveryPartList, d.FilteredParts.OrderBy(p => p.DPNr).ToList(), DeliveryPartList_SelectionChanged, ControlUtils.RenewSourceDefault.First); } else { ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers .Where(m => m.Year == ViewModel.FilterSeason && (!IsCreating || m.IsActive)) .OrderBy(m => m.Ordering) .Include(m => m.Season.Currency) .ToListAsync()); 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(); ClearDefaultValues(); ClearInputs(validate); ClearInputStates(); } GC.Collect(); } private void FillInputs(Delivery d) { ClearOriginalValues(); ClearDefaultValues(); ViewModel.FillInputs(d); FinishInputFilling(); } private void FillInputs(DeliveryPart p) { FillInputs(p.Delivery); ClearOriginalValues(); ClearDefaultValues(); ViewModel.FillInputs(p); FinishInputFilling(); } new protected void ClearInputs(bool validate = false) { ViewModel.ClearInputs(); base.ClearInputs(validate); } 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(); var start = DateTimeOffset.Now.ToUnixTimeMilliseconds(); FinishButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false; CancelCreatingButton.IsEnabled = false; var s = App.CommandScales[index]; try { var res = await s.Weigh(); OnWeighingResult(s, res); } catch (Exception ex) { ViewModel.LastScaleError = ex.Message.Split(": ")[^1]; OnWeighingResult(s, new()); MessageBox.Show($"Beim Wiegen ist ein Fehler aufgetreten:\n\n{ex.Message}", "Waagenfehler", MessageBoxButton.OK, MessageBoxImage.Error); } ViewModel.ManualWeighingReason = null; ManualWeighingInput.IsChecked = false; var end = DateTimeOffset.Now.ToUnixTimeMilliseconds(); int diff = (int)(end - start); if (diff < 1000 && ViewModel.Weight != null) await Task.Delay(1000 - diff); EnableWeighingButtons(); } private void OnWeighingResult(IScale scale, WeighingResult res) { if ((res.NetWeight ?? 0) > 0 && res.FullWeighingId != null) { ViewModel.Weight = res.NetWeight; ViewModel.ScaleId = scale.ScaleId; ViewModel.WeighingData = res.ToJson().ToJsonString(); ViewModel.ManualWeighingReason = null; ManualWeighingInput.IsChecked = false; } else { ViewModel.Weight = null; ViewModel.ScaleId = null; ViewModel.WeighingData = null; } ViewModel.LastScaleError = null; TextBox_TextChanged(WeightInput, null); UpdateButtons(); } private void Scale_Weighing(object sender, WeighingEventArgs evt) { if (sender is not IScale scale) return; App.MainDispatcher.BeginInvoke(() => OnWeighingResult(scale, evt.Result)); } private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) { await RefreshList(true); } private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) { if (ViewModel.FilterSeason == null || TodayOnlyInput == null || AllSeasonsInput == null) return; TodayOnlyInput.IsChecked = false; AllSeasonsInput.IsChecked = false; await RefreshList(); } private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) { if (TodayOnlyInput.IsChecked == true && AllSeasonsInput.IsChecked == false) { ViewModel.FilterSeason = Utils.Today.Year; ViewModel.FilterTodayOnly = true; } await RefreshList(); } private async void AllSeasonsInput_Changed(object sender, RoutedEventArgs evt) { if (AllSeasonsInput.IsChecked == true) { SeasonInput.IsEnabled = false; ViewModel.FilterSeason = null; } else { SeasonInput.IsEnabled = true; var today = ViewModel.FilterTodayOnly; ViewModel.FilterSeason = Utils.CurrentLastSeason; ViewModel.FilterTodayOnly = today; } await RefreshList(); } private async void DeliveryList_SelectionChanged(object sender, SelectionChangedEventArgs evt) { await RefreshDeliveryParts(); if (DeliveryList.SelectedItem is Delivery d) { DeleteDeliveryButton.IsEnabled = true; Menu_DeliveryNote_Show.IsEnabled = !IsEditing && !IsCreating; Menu_DeliveryNote_SavePdf.IsEnabled = !IsEditing && !IsCreating; Menu_DeliveryNote_Print.IsEnabled = !IsEditing && !IsCreating; Menu_DeliveryNote_Email.IsEnabled = !IsEditing && !IsCreating && App.Config.Smtp != null && d.Member.EmailAddresses.Count > 0; } else { DeleteDeliveryButton.IsEnabled = false; Menu_DeliveryNote_Show.IsEnabled = false; Menu_DeliveryNote_SavePdf.IsEnabled = false; Menu_DeliveryNote_Print.IsEnabled = false; Menu_DeliveryNote_Email.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); ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null); } private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) { var valid = InputLostFocus((TextBox)sender, Validator.CheckMgNr); ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null); } private void MemberInput_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) { var m = MemberInput.SelectedItem as Member; ViewModel.MgNr = m?.MgNr; ViewModel.MemberAddress = m?.FullAddress; if (m == null) { UnsetDefaultValue(WineKgInput); WineKgInput.SelectedIndex = 0; } else { ControlUtils.SelectItemWithPk(WineKgInput, m.DefaultKgNr); SetDefaultValue(WineKgInput); } } private void EmptyScale() { var scale = App.Scales.Where(s => s.ScaleId == ViewModel.ScaleId).FirstOrDefault(); if (scale is not ICommandScale cs) return; cs.Empty(); } private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { FinishButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false; NewDeliveryPartButton.Cursor = Cursors.Wait; DeliveryPartList.IsEnabled = false; var p = await ViewModel.UpdateDeliveryPart( (DeliveryList.SelectedItem as Delivery)?.Year, (DeliveryList.SelectedItem as Delivery)?.DId, (DeliveryPartList.SelectedItem as DeliveryPart)?.DPNr, InputHasChanged(DateInput), InputHasChanged(TimeInput), !InputIsNotDefault(TimeInput) ); EmptyScale(); await RefreshList(); await RefreshDeliveryParts(); NewDeliveryPartButton.Cursor = null; ControlUtils.SelectItem(DeliveryList, p?.Delivery); DeliveryPartList.SelectedItem = null; RefreshInputs(); InitialInputs(); } private async void FinishButton_Click(object sender, RoutedEventArgs evt) { FinishButton.IsEnabled = false; NewDeliveryPartButton.IsEnabled = false; FinishButton.Cursor = Cursors.Wait; DeliveryPartList.IsEnabled = false; var p = await ViewModel.UpdateDeliveryPart( (DeliveryList.SelectedItem as Delivery)?.Year, (DeliveryList.SelectedItem as Delivery)?.DId, (DeliveryPartList.SelectedItem as DeliveryPart)?.DPNr, InputHasChanged(DateInput), InputHasChanged(TimeInput), !InputIsNotDefault(TimeInput) ); EmptyScale(); await RefreshList(); await RefreshDeliveryParts(); if (p?.Delivery != null) { Mouse.OverrideCursor = Cursors.AppStarting; try { using var ctx = new AppDbContext(); using var doc = new DeliveryNote((await ctx.Deliveries.FindAsync(p.Year, p.DId))!, ctx); await doc.Generate(); if (App.Config.Debug) { doc.Show(); } else { await doc.Print(2); } } catch (Exception exc) { MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } FinishButton.Cursor = null; DeliveryList.SelectedItem = null; await RenewContext(); RefreshInputs(); InitInputs(); } private async void CancelCreatingButton_Click(object sender, RoutedEventArgs evt) { if (IsCreating && HasChanged) { var r = MessageBox.Show("Soll der Vorgang wirklich abgebrochen werden?", "Abbrechen bestätigen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No); if (r != MessageBoxResult.Yes) return; } using var ctx = new AppDbContext(); var attrList = await ctx.WineAttributes.OrderBy(a => a.Name).Cast().ToListAsync(); attrList.Insert(0, new NullItem("")); ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First); ControlUtils.RenewItemsSource(MemberInput, await ctx.Members .Where(m => m.IsActive || !ViewModel.IsReceipt) .Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.DefaultWbKg!.AtKg) .OrderBy(m => m.FamilyName) .ThenBy(m => m.GivenName) .ToListAsync()); 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(); await RenewContext(); RefreshInputs(); ClearInputStates(); LockInputs(); UnlockSearchInputs(); } else { // switch to last delivery part DeliveryPartList.IsEnabled = true; ControlUtils.SelectItem(DeliveryPartList, d.FilteredParts.Last()); } } protected override void ShortcutNew() { if (!NewDeliveryButton.IsEnabled || NewDeliveryButton.Visibility != Visibility.Visible) return; NewDeliveryButton_Click(null, null); } private async void NewDeliveryButton_Click(object? sender, RoutedEventArgs? evt) { ViewModel.FilterTodayOnly = true; ViewModel.SearchQuery = ""; using var ctx = new AppDbContext(); var attrList = await ctx.WineAttributes.Where(a => a.IsActive).OrderBy(a => a.Name).Cast().ToListAsync(); attrList.Insert(0, new NullItem("")); ControlUtils.RenewItemsSource(AttributeInput, attrList, null, ControlUtils.RenewSourceDefault.First); ControlUtils.RenewItemsSource(ModifiersInput, await ctx.Modifiers .Where(m => m.Year == ViewModel.FilterSeason && m.IsActive) .OrderBy(m => m.Ordering) .Include(m => m.Season.Currency) .ToListAsync()); ControlUtils.RenewItemsSource(MemberInput, await ctx.Members .Where(m => m.IsActive || !ViewModel.IsReceipt) .Include(m => m.PostalDest.AtPlz!.Ort) .Include(m => m.DefaultWbKg!.AtKg) .OrderBy(m => m.FamilyName) .ThenBy(m => m.GivenName) .ToListAsync()); 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); if (res == null || res <= 0) return; Mouse.OverrideCursor = Cursors.AppStarting; try { using var ctx = new AppDbContext(); ClearOriginalValues(); if (res >= p.Weight) { ControlUtils.SelectItemWithPk(WineQualityLevelInput, "WEI"); ControlUtils.SelectItemWithPk(WineOriginInput, "OEST"); p.QualId = "WEI"; p.HkId = "OEST"; ctx.Update(p); } else { var w = p.Weight - res.Value; ViewModel.Weight = w; p.Weight = w; ctx.Update(p); var d = p.Delivery; var p2 = ctx.CreateProxy(); var values = ctx.Entry(p).CurrentValues; ctx.Entry(p2).CurrentValues.SetValues(values); p2.DPNr = await ctx.NextDPNr(d.Year, d.DId); p2.Weight = res.Value; p2.QualId = "WEI"; p2.HkId = "OEST"; ctx.Add(p2); ctx.UpdateDeliveryPartModifiers(p2, [], p.Modifiers); } await ctx.SaveChangesAsync(); await RefreshDeliveryParts(); FinishInputFilling(); } catch (Exception exc) { var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } private void WeighingManualButton_Click(object sender, RoutedEventArgs evt) { var res = Utils.ShowManualWeighingDialog(ViewModel.LastScaleError); if (res == null) return; ViewModel.Weight = res?.Item1; ManualWeighingInput.IsChecked = true; ViewModel.ManualWeighingReason = res?.Item2; ViewModel.ScaleId = null; ViewModel.WeighingData = null; } protected override void ShortcutEdit() { if (!EditDeliveryButton.IsEnabled || EditDeliveryButton.Visibility != Visibility.Visible) return; EditDeliveryButton_Click(null, 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; } protected override void ShortcutDelete() { if (!DeleteDeliveryButton.IsEnabled || DeleteDeliveryButton.Visibility != Visibility.Visible) return; DeleteDeliveryButton_Click(null, null); } 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.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); if (r == MessageBoxResult.OK) { Mouse.OverrideCursor = Cursors.AppStarting; using (var ctx = new AppDbContext()) { ctx.Remove(d); await ctx.SaveChangesAsync(); } await RefreshList(); await RefreshDeliveryParts(); Mouse.OverrideCursor = null; } } protected override void ShortcutSave() { if (!SaveButton.IsEnabled || SaveButton.Visibility != Visibility.Visible) return; SaveButton_Click(null, null); } private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) { SaveButton.IsEnabled = false; SaveButton.Cursor = Cursors.Wait; IsEditing = false; IsCreating = false; DeliveryList.IsEnabled = true; DeliveryPartList.IsEnabled = true; var p = await ViewModel.UpdateDeliveryPart( (DeliveryList.SelectedItem as Delivery)?.Year, (DeliveryList.SelectedItem as Delivery)?.DId, (DeliveryPartList.SelectedItem as DeliveryPart)?.DPNr, InputHasChanged(DateInput), InputHasChanged(TimeInput), !InputIsNotDefault(TimeInput) ); SaveButton.Cursor = null; HideSaveResetCancelButtons(); ShowNewEditDeleteButtons(); LockInputs(); UnlockSearchInputs(); FinishInputFilling(); await RefreshList(); await RefreshDeliveryParts(); RefreshInputs(); AbwertenButton.IsEnabled = p.QualId != "WEI"; ExtractDeliveryPartButton.IsEnabled = DeliveryPartList.SelectedItem != null && !IsCreating; DeleteDeliveryPartButton.IsEnabled = DeliveryList.SelectedItem is Delivery { Parts.Count: > 1 } && !IsCreating; } protected override void ShortcutReset() { if (!ResetButton.IsEnabled || ResetButton.Visibility != Visibility.Visible) return; ResetButton_Click(null, null); } 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); string? res; using (var ctx = new AppDbContext()) { var lsnrs = await ctx.Deliveries .Where(d => d.ZwstId == delivery.ZwstId) .Where(d => (d.DateString == day.ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") > 0)) || (d.DateString == day.AddDays(1).ToString("yyyy-MM-dd") && (d.TimeString == null || d.TimeString.CompareTo("03:00:00") <= 0))) .Where(d => d.LsNr != delivery.LsNr) .OrderBy(d => d.LsNr) .Select(d => d.LsNr) .ToListAsync(); res = Utils.ShowDeliveryExtractionDialog($"{delivery.LsNr}/{p.DPNr}", delivery.Member.AdministrativeName, count == 1, lsnrs); if (res == null) return; } Mouse.OverrideCursor = Cursors.AppStarting; try { using var ctx = new AppDbContext(); if (res == "new") { var lnr = await ctx.NextLNr(delivery.Date); ctx.Add(new Delivery { Year = p.Year, DId = await ctx.NextDId(p.Year), LNr = lnr, DateString = $"{delivery.Date:yyyy-MM-dd}", TimeString = $"{delivery.Time:HH:mm:ss}", ZwstId = delivery.ZwstId, MgNr = delivery.MgNr, Comment = delivery.Comment, LsNr = Utils.GenerateLsNr(delivery.Date, delivery.ZwstId, lnr), }); await ctx.SaveChangesAsync(); } Delivery? d = await ctx.Deliveries.Where(d => d.LsNr == res).FirstOrDefaultAsync(); if (d == null) return; await ctx.Database.ExecuteSqlAsync($"UPDATE delivery_part SET year = {d.Year}, did = {d.DId}, dpnr = {await ctx.NextDPNr(d.Year, d.DId)} WHERE (year, did, dpnr) = ({p.Year}, {p.DId}, {p.DPNr})"); if (count == 1) { await ctx.Database.ExecuteSqlAsync($"DELETE FROM delivery WHERE (year, did) = ({delivery.Year}, {delivery.DId})"); } await ctx.SaveChangesAsync(); await RefreshList(); ControlUtils.SelectItem(DeliveryList, d); } catch (Exception exc) { var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message; if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message; MessageBox.Show(str, "Lieferung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } private async void DeleteDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { if (DeliveryPartList.SelectedItem is not DeliveryPart p) return; var r = MessageBox.Show( $"Soll die Teillieferung Nr. {p.DPNr} wirklich unwiderruflich gelöscht werden?", "Lieferung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); if (r == MessageBoxResult.OK) { Mouse.OverrideCursor = Cursors.AppStarting; using (var ctx = new AppDbContext()) { ctx.Remove(p); await ctx.SaveChangesAsync(); } await RefreshDeliveryParts(); Mouse.OverrideCursor = null; } } 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 = ViewModel.IsReceipt; AbwertenButton.IsEnabled = DeliveryPartList.SelectedItem is DeliveryPart p && p.QualId == "WEI"; EditDeliveryButton.IsEnabled = DeliveryPartList.SelectedItem != null; DeleteDeliveryButton.IsEnabled = DeliveryList.SelectedItem != null; NewDeliveryButton.Visibility = ViewModel.IsReceipt ? Visibility.Visible : Visibility.Hidden; AbwertenButton.Visibility = !ViewModel.IsReceipt ? Visibility.Visible : Visibility.Hidden; 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 = false; NewDeliveryPartButton.IsEnabled = false; 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 = (ViewModel.FilterMember != 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 = !Menu_Settings_EnableFreeEditing.IsChecked; TimeInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked; BranchInput.IsEnabled = Menu_Settings_EnableFreeEditing.IsChecked; } private void DisableWeighingButtons() { WeighingManualButton.IsEnabled = false; WeighingAButton.IsEnabled = false; WeighingBButton.IsEnabled = false; WeighingCButton.IsEnabled = false; WeighingDButton.IsEnabled = false; } private void EnableWeighingButtons() { WeighingManualButton.IsEnabled = true; var n = App.CommandScales.Count; WeighingAButton.IsEnabled = n > 0 && App.CommandScales[0].IsReady; WeighingBButton.IsEnabled = n > 1 && App.CommandScales[1].IsReady; WeighingCButton.IsEnabled = n > 2 && App.CommandScales[2].IsReady; WeighingDButton.IsEnabled = n > 3 && App.CommandScales[3].IsReady; } private async Task UpdateLsNr() { if (string.IsNullOrEmpty(ViewModel.Date) || ViewModel.Branch == null) { ViewModel.LsNr = ""; } else { try { var branch = (Branch)BranchInput.SelectedItem; var date = DateOnly.ParseExact(ViewModel.Date!, "dd.MM.yyyy"); using var ctx = new AppDbContext(); var lnr = await ctx.NextLNr(date); ViewModel.LsNr = Utils.GenerateLsNr(date, branch.ZwstId, lnr); } catch { ViewModel.LsNr = ""; } } } private new async void DateInput_TextChanged(object sender, TextChangedEventArgs evt) { base.DateInput_TextChanged(sender, evt); if (IsEditing || IsCreating) await UpdateLsNr(); } private async void BranchInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { base.ComboBox_SelectionChanged(sender, evt); if (IsEditing || IsCreating) { await UpdateLsNr(); InitialDefaultInputs(); } } private void UpdateWineVariety(bool valid) { if (valid) { var text = ViewModel.SortId!; ControlUtils.SelectItemWithPk(WineVarietyInput, text[0..2]); if (text.Length >= 3) { ControlUtils.SelectItemWithPk(AttributeInput, text[2..]); ControlUtils.SelectItemWithPk(CultivationInput, text[2..]); ViewModel.SortId = text[0..2]; } } else { WineVarietyInput.SelectedItem = null; AttributeInput.SelectedIndex = 0; CultivationInput.SelectedIndex = 0; } } 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) ViewModel.SortId = s.SortId; } private void UpdateWineQualityLevels() { using var ctx = new AppDbContext(); if (!GetInputValid(GradationKmwInput)) { UnsetDefaultValue(WineQualityLevelInput); WineQualityLevelInput.ItemsSource = ctx.WineQualityLevels.Where(q => q.QualId == "WEI").ToList(); return; } var kmw = (double)ViewModel.GradationKmw!; WineQualityLevelInput.ItemsSource = ctx.WineQualityLevels.Where(q => q.MinKmw == null || q.MinKmw <= kmw).ToList(); var qual = ctx.GetWineQualityLevel(kmw).GetAwaiter().GetResult(); SetDefaultValue(WineQualityLevelInput, qual); if (WineQualityLevelInput.SelectedItem == null || (WineQualityLevelInput.SelectedItem is WineQualLevel selected && !selected.IsPredicate)) { ControlUtils.SelectItem(WineQualityLevelInput, 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 AttributeInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { } private void CultivationInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { } private void ModifiersInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { if (!IsEditing && !IsCreating) return; var mod = ModifiersInput.SelectedItems.Cast(); var source = ModifiersInput.ItemsSource.Cast(); if (App.Client.IsMatzen) { var kl = mod.Where(m => m.Name.StartsWith("Klasse ")); if (kl.Count() > 1) { App.MainDispatcher.BeginInvoke(() => { foreach (var r in kl.Take(kl.Count() - 1)) ModifiersInput.SelectedItems.Remove(r); }); } } } private void LesewagenInput_Changed(object sender, RoutedEventArgs evt) { if (!IsEditing && !IsCreating) return; var mod = ModifiersInput.SelectedItems.Cast(); var source = ModifiersInput.ItemsSource.Cast(); var lw = LesewagenInput.IsChecked == true; if (App.Client.IsMatzen) { var kl = mod.Where(m => m.Name.StartsWith("Klasse ")).Select(m => m.ModId).LastOrDefault("A")[0]; if (lw) kl++; else kl--; var newKl = source.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); ControlUtils.SelectItem(WineOriginInput, o); } private void WineQualityLevelInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { UpdateWineOrigin(); UpdateAbgewertet(); } private void UpdateRdInput() { if (WineKgInput.SelectedItem is AT_Kg kg) { using var ctx = new AppDbContext(); var list = ctx.WbRde.Where(r => r.KgNr == kg.KgNr).OrderBy(r => r.Name).Cast().ToList(); list.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(WineRdInput, list); if (WineRdInput.SelectedItem == null) WineRdInput.SelectedIndex = 0; WineRdInput.IsEnabled = (IsEditing || IsCreating) && list.Count > 1; } else { ViewModel.WineRdSource = []; 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; } using var ctx = new AppDbContext(); var defQual = ctx.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)); } private void GerebeltGewogenInput_Changed(object sender, RoutedEventArgs evt) { if (!App.Client.HasNetWeighing(ViewModel.Branch)) { HandPickedInput.IsChecked = !GerebeltGewogenInput.IsChecked; } CheckBox_Changed(sender, evt); } private void HandPickedInput_Changed(object sender, RoutedEventArgs evt) { if (!App.Client.HasNetWeighing(ViewModel.Branch)) { GerebeltGewogenInput.IsChecked = !HandPickedInput.IsChecked; } CheckBox_Changed(sender, evt); } private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) { if (MemberInput.SelectedItem is not Member m) return; App.FocusMember(m.MgNr); } } }