using Elwig.Helpers; using Elwig.Models.Entities; using Elwig.Services; using Elwig.ViewModels; using Microsoft.EntityFrameworkCore; using System; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; namespace Elwig.Windows { public partial class DeliveryScheduleAdminWindow : AdministrationWindow { public DeliveryScheduleAdminViewModel ViewModel => (DeliveryScheduleAdminViewModel)DataContext; private readonly RoutedCommand CtrlF = new("CtrlF", typeof(DeliveryScheduleAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]); public DeliveryScheduleAdminWindow() { InitializeComponent(); CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput)); ExemptInputs = [ SearchInput, SeasonInput, OnlyUpcomingInput, DeliveryScheduleList, ]; RequiredInputs = [ DateInput, BranchInput, DescriptionInput, MainWineVarietiesInput, ]; InitializeDelayTimer(SearchInput, SearchInput_TextChanged); SearchInput.TextChanged -= SearchInput_TextChanged; ViewModel.FilterSeason = Utils.CurrentLastSeason; } private void Window_Loaded(object sender, RoutedEventArgs evt) { ViewModel.FilterOnlyUpcoming = true; LockInputs(); } private async Task RefreshList(bool updateSort = false) { using var ctx = new AppDbContext(); var (_, deliveryScheduleQuery, filter) = await ViewModel.GetFilters(ctx); var deliverySchedules = await deliveryScheduleQuery .Include(s => s.Varieties) .Include(s => s.Branch) .AsSplitQuery() .ToListAsync(); if (filter.Count > 0 && deliverySchedules.Count > 0) { var dict = deliverySchedules.AsParallel() .ToDictionary(s => s, s => s.SearchScore(filter)) .OrderByDescending(a => a.Value) .ThenBy(a => a.Key.DateString) .ThenBy(a => a.Key.Branch.Name) .ThenBy(a => a.Key.Description); var threshold = dict.Select(a => a.Value).Max() * 3 / 4; deliverySchedules = dict .Where(a => a.Value > threshold) .Select(a => a.Key) .ToList(); } else { deliverySchedules = deliverySchedules .OrderBy(s => s.DateString) .ThenBy(s => s.Branch.Name) .ThenBy(s => s.Description) .ToList(); } ControlUtils.RenewItemsSource(DeliveryScheduleList, deliverySchedules, DeliveryScheduleList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort); if (updateSort && DeliveryScheduleList.SelectedItem != null) DeliveryScheduleList.ScrollIntoView(DeliveryScheduleList.SelectedItem); } private async Task RefreshInputs(bool validate = false) { ClearInputStates(); if (ViewModel.SelectedDeliverySchedule is DeliverySchedule s) { EditDeliveryScheduleButton.IsEnabled = true; DeleteDeliveryScheduleButton.IsEnabled = true; await FillInputs(s); } else { EditDeliveryScheduleButton.IsEnabled = false; DeleteDeliveryScheduleButton.IsEnabled = false; ClearOriginalValues(); ClearDefaultValues(); ClearInputs(validate); ClearInputStates(); } GC.Collect(); } private void InitInputs() { ClearOriginalValues(); ClearDefaultValues(); ViewModel.InitInputs(); ValidateRequiredInputs(); } protected override async Task OnRenewContext(AppDbContext ctx) { await base.OnRenewContext(ctx); ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync()); var varieties = await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync(); ControlUtils.RenewItemsSource(MainWineVarietiesInput, varieties); ControlUtils.RenewItemsSource(OtherWineVarietiesInput, varieties); await RefreshList(); } private async void DeliveryScheduleList_SelectionChanged(object sender, RoutedEventArgs evt) { await RefreshInputs(); } private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) { await RefreshList(); } private async void SearchInput_TextChanged(object sender, TextChangedEventArgs evt) { await RefreshList(true); } private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) { if (ViewModel.FilterSeason == null) return; ViewModel.FilterOnlyUpcoming = false; await RefreshList(); } protected override void ShortcutNew() { if (!NewDeliveryScheduleButton.IsEnabled || NewDeliveryScheduleButton.Visibility != Visibility.Visible) return; NewDeliveryScheduleButton_Click(null, null); } private void NewDeliveryScheduleButton_Click(object? sender, RoutedEventArgs? evt) { IsCreating = true; DeliveryScheduleList.IsEnabled = false; ViewModel.SelectedDeliverySchedule = null; HideNewEditDeleteButtons(); ShowSaveResetCancelButtons(); UnlockInputs(); InitInputs(); ViewModel.EnableSearchInputs = false; } protected override void ShortcutEdit() { if (!EditDeliveryScheduleButton.IsEnabled || EditDeliveryScheduleButton.Visibility != Visibility.Visible) return; EditDeliveryScheduleButton_Click(null, null); } private void EditDeliveryScheduleButton_Click(object? sender, RoutedEventArgs? evt) { if (ViewModel.SelectedDeliverySchedule == null) return; IsEditing = true; DeliveryScheduleList.IsEnabled = false; HideNewEditDeleteButtons(); ShowSaveResetCancelButtons(); UnlockInputs(); ViewModel.EnableSearchInputs = false; } protected override void ShortcutDelete() { if (!DeleteDeliveryScheduleButton.IsEnabled || DeleteDeliveryScheduleButton.Visibility != Visibility.Visible) return; DeleteDeliveryScheduleButton_Click(null, null); } private async void DeleteDeliveryScheduleButton_Click(object? sender, RoutedEventArgs? evt) { if (ViewModel.SelectedDeliverySchedule is not DeliverySchedule s) return; var r = MessageBox.Show( $"Soll der Leseplan \"{s.Description}\" vom {s.Date:dd.MM.yyyy} wirklich unwiderruflich gelöscht werden?", "Leseplan löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); if (r == MessageBoxResult.OK) { Mouse.OverrideCursor = Cursors.AppStarting; try { using (var ctx = new AppDbContext()) { ctx.Remove(s); await ctx.SaveChangesAsync(); } await App.HintContextChange(); } 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, "Leseplan löschen", MessageBoxButton.OK, MessageBoxImage.Error); } 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) { Mouse.OverrideCursor = Cursors.AppStarting; try { await ViewModel.UpdateDeliverySchedule(ViewModel.SelectedDeliverySchedule?.Year, ViewModel.SelectedDeliverySchedule?.DsNr); } 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, "Leseplan aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; IsEditing = false; IsCreating = false; DeliveryScheduleList.IsEnabled = true; HideSaveResetCancelButtons(); ShowNewEditDeleteButtons(); LockInputs(); ViewModel.EnableSearchInputs = true; FinishInputFilling(); await RefreshList(); await RefreshInputs(); ViewModel.SearchQuery = ""; } protected override void ShortcutReset() { if (!ResetButton.IsEnabled || ResetButton.Visibility != Visibility.Visible) return; ResetButton_Click(null, null); } private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) { if (IsEditing) { await RefreshInputs(); } else if (IsCreating) { ClearInputs(); InitInputs(); } UpdateButtons(); } private async void CancelButton_Click(object? sender, RoutedEventArgs? evt) { IsEditing = false; IsCreating = false; DeliveryScheduleList.IsEnabled = true; HideSaveResetCancelButtons(); ShowNewEditDeleteButtons(); await RefreshInputs(); LockInputs(); ViewModel.EnableSearchInputs = true; } private async Task FillInputs(DeliverySchedule s) { ClearOriginalValues(); ClearDefaultValues(); await ViewModel.FillInputs(s); FinishInputFilling(); } new protected void ClearInputs(bool validate = false) { ViewModel.ClearInputs(); base.ClearInputs(validate); } protected override void UpdateButtons() { if (!IsEditing && !IsCreating) return; bool ch = HasChanged, v = IsValid; ResetButton.IsEnabled = ch; SaveButton.IsEnabled = v && ch; } private void FocusSearchInput(object sender, RoutedEventArgs evt) { if (!IsEditing && !IsCreating) { SearchInput.Focus(); SearchInput.SelectAll(); } } private void ShowSaveResetCancelButtons() { SaveButton.IsEnabled = false; ResetButton.IsEnabled = false; CancelButton.IsEnabled = true; ViewModel.EditingButtonsVisibility = Visibility.Visible; } private void HideSaveResetCancelButtons() { SaveButton.IsEnabled = false; ResetButton.IsEnabled = false; CancelButton.IsEnabled = false; ViewModel.EditingButtonsVisibility = Visibility.Hidden; } private void ShowNewEditDeleteButtons() { NewDeliveryScheduleButton.IsEnabled = true; EditDeliveryScheduleButton.IsEnabled = ViewModel.SelectedDeliverySchedule != null; DeleteDeliveryScheduleButton.IsEnabled = ViewModel.SelectedDeliverySchedule != null; ViewModel.ControlButtonsVisibility = Visibility.Visible; } private void HideNewEditDeleteButtons() { NewDeliveryScheduleButton.IsEnabled = false; EditDeliveryScheduleButton.IsEnabled = false; DeleteDeliveryScheduleButton.IsEnabled = false; ViewModel.ControlButtonsVisibility = Visibility.Hidden; } private new void DateInput_TextChanged(object sender, TextChangedEventArgs evt) { base.DateInput_TextChanged(sender, evt); if (ViewModel.Date is DateOnly date) { ViewModel.AncmtToDate = date.AddDays(-2); } } private void MaxWeightInput_TextChanged(object sender, TextChangedEventArgs evt) { InputTextChanged((TextBox)sender, Validator.CheckInteger((TextBox)sender, false, 6)); } } }