using Microsoft.EntityFrameworkCore; using System.Linq; using System.Windows; using System.Windows.Controls; using Elwig.Helpers; using Elwig.Models.Entities; using System; using System.Threading.Tasks; using Elwig.ViewModels; using Elwig.Services; using System.Windows.Input; namespace Elwig.Windows { public partial class AreaComAdminWindow : AdministrationWindow { public AreaComAdminViewModel ViewModel => (AreaComAdminViewModel)DataContext; private readonly RoutedCommand CtrlF = new("CtrlF", typeof(AreaComAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]); public AreaComAdminWindow(int mgnr) { InitializeComponent(); CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput)); using var ctx = new AppDbContext(); ViewModel.FilterMember = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value"); ViewModel.Title = $"Flächenbindungen - {ViewModel.FilterMember.AdministrativeName} - Elwig"; ExemptInputs = [ MgNrInput, AreaCommitmentList, NewAreaCommitmentButton, EditAreaCommitmentButton, DeleteAreaCommitmentButton, AreaCommitmentSaveButton, AreaCommitmentResetButton, AreaCommitmentCancelButton, SearchInput, ActiveAreaCommitmentInput ]; RequiredInputs = [ FbNrInput, YearFromInput, KgInput, RdInput, GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput ]; InitializeDelayTimer(SearchInput, SearchInput_TextChanged); SearchInput.TextChanged -= SearchInput_TextChanged; ActiveAreaCommitmentInput.Content = ((string)ActiveAreaCommitmentInput.Content).Replace("2020", $"{Utils.CurrentLastSeason}"); } private void Window_Loaded(object sender, RoutedEventArgs e) { ActiveAreaCommitmentInput.IsChecked = true; LockInputs(); } private void FocusSearchInput(object sender, RoutedEventArgs evt) { if (!IsEditing && !IsCreating) { SearchInput.Focus(); SearchInput.SelectAll(); } } private async Task RefreshList(bool updateSort = false) { using var ctx = new AppDbContext(); var (_, areaComQuery, filter) = await ViewModel.GetFilters(ctx); var areaComs = await areaComQuery .Include(a => a.Kg.AtKg) .Include(a => a.Rd!.Kg.AtKg) .Include(a => a.WineCult) .Include(a => a.AreaComType.WineAttr) .Include(a => a.AreaComType.WineVar) .ToListAsync(); if (filter.Count > 0 && areaComs.Count > 0) { var dict = areaComs.AsParallel() .ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter)) .OrderByDescending(c => c.Value); var threshold = dict.Select(a => a.Value).Max() * 3 / 4; areaComs = dict .Where(a => a.Value > threshold) .Select(a => a.Key) .ToList(); } ControlUtils.RenewItemsSource(AreaCommitmentList, areaComs, AreaCommitmentList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort); RefreshInputs(); if (filter.Count == 0) { ViewModel.StatusAreaCommitments = $"{await areaComQuery.CountAsync():N0}"; var s = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year)); var (text, grid) = await AreaComService.GenerateToolTip(areaComQuery, s?.MaxKgPerHa ?? 10_000); ViewModel.StatusArea = text; ViewModel.StatusAreaToolTip = grid; } else { ViewModel.StatusAreaCommitments = $"{areaComs.Count:N0}"; ViewModel.StatusArea = $"{areaComs.Select(a => a.Area).Sum():N0} m²"; ViewModel.StatusAreaToolTip = null; } var groups = areaComs.GroupBy(a => $"{a.AreaComType.SortId}{a.AreaComType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList(); ViewModel.StatusContracts = $"{groups.Count:N0}"; if (groups.Count > 0) ViewModel.StatusContracts += $" ({string.Join(", ", groups.Select(g => g.Key))})"; } private void RefreshInputs(bool validate = false) { ClearInputStates(); if (AreaCommitmentList.SelectedItem is AreaCom a) { EditAreaCommitmentButton.IsEnabled = true; DeleteAreaCommitmentButton.IsEnabled = true; FillInputs(a); } else { EditAreaCommitmentButton.IsEnabled = false; DeleteAreaCommitmentButton.IsEnabled = false; ClearOriginalValues(); ClearDefaultValues(); ClearInputs(validate); ClearInputStates(); } GC.Collect(); } private void FillInputs(AreaCom a) { ClearOriginalValues(); ClearDefaultValues(); ViewModel.FillInputs(a); FinishInputFilling(); } private async Task InitInputs() { ClearOriginalValues(); ClearDefaultValues(); await ViewModel.InitInputs(); SetDefaultValue(FbNrInput); ValidateRequiredInputs(); } protected override async Task OnRenewContext(AppDbContext ctx) { await base.OnRenewContext(ctx); if (await ctx.Members.FindAsync(ViewModel.FilterMember.MgNr) is not Member m) { Close(); return; } ViewModel.FilterMember = m; ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig"; ControlUtils.RenewItemsSource(KgInput, await ctx.WbKgs .Include(k => k.AtKg.WbKg!.Rds) .Select(k => k.AtKg) .OrderBy(k => k.Name) .ToListAsync()); ControlUtils.RenewItemsSource(AreaComTypeInput, await ctx.AreaCommitmentTypes .Include(c => c.WineVar) .Include(c => c.WineAttr) .OrderBy(v => v.VtrgId) .ToListAsync()); var cultList = await ctx.WineCultivations .OrderBy(c => c.Name) .Cast().ToListAsync(); cultList.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(WineCultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First); await RefreshList(); } protected override void ShortcutNew() { if (!NewAreaCommitmentButton.IsEnabled || NewAreaCommitmentButton.Visibility != Visibility.Visible) return; NewAreaCommitmentButton_Click(null, null); } private async void NewAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) { IsCreating = true; AreaCommitmentList.IsEnabled = false; AreaCommitmentList.SelectedItem = null; HideAreaCommitmentNewEditDeleteButtons(); ShowAreaCommitmentSaveResetCancelButtons(); UnlockInputs(); await InitInputs(); LockSearchInputs(); } protected override void ShortcutEdit() { if (!EditAreaCommitmentButton.IsEnabled || EditAreaCommitmentButton.Visibility != Visibility.Visible) return; EditAreaCommitmentButton_Click(null, null); } private void EditAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) { if (AreaCommitmentList.SelectedItem == null) return; IsEditing = true; AreaCommitmentList.IsEnabled = false; HideAreaCommitmentNewEditDeleteButtons(); ShowAreaCommitmentSaveResetCancelButtons(); UnlockInputs(); LockSearchInputs(); } protected override void ShortcutDelete() { if (!DeleteAreaCommitmentButton.IsEnabled || DeleteAreaCommitmentButton.Visibility != Visibility.Visible) return; DeleteAreaCommitmentButton_Click(null, null); } private async void DeleteAreaCommitmentButton_Click(object? sender, RoutedEventArgs? evt) { if (AreaCommitmentList.SelectedItem is not AreaCom a) return; var r = MessageBox.Show( $"Soll die Flächenbindung {a.GstNr} ({a.Area} m²) wirklich unwiderruflich gelöscht werden?", "Flächenbindung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); if (r == MessageBoxResult.OK) { Mouse.OverrideCursor = Cursors.AppStarting; try { using (var ctx = new AppDbContext()) { ctx.Remove(a); 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, "Flächenbindung löschen", MessageBoxButton.OK, MessageBoxImage.Error); } Mouse.OverrideCursor = null; } } protected override void ShortcutSave() { if (!AreaCommitmentSaveButton.IsEnabled || AreaCommitmentSaveButton.Visibility != Visibility.Visible) return; AreaCommitmentSaveButton_Click(null, null); } private async void AreaCommitmentSaveButton_Click(object? sender, RoutedEventArgs? evt) { int? fbnr = null; try { fbnr = await ViewModel.UpdateAreaCommitment((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr); } 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, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error); } IsEditing = false; IsCreating = false; AreaCommitmentList.IsEnabled = true; HideAreaCommitmentSaveResetCancelButtons(); ShowAreaCommitmentNewEditDeleteButtons(); LockInputs(); UnlockSearchInputs(); FinishInputFilling(); await RefreshList(); RefreshInputs(); ViewModel.SearchQuery = ""; ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast().Where(a => a.FbNr == fbnr).FirstOrDefault()); } protected override void ShortcutReset() { if (!AreaCommitmentResetButton.IsEnabled || AreaCommitmentResetButton.Visibility != Visibility.Visible) return; AreaCommitmentResetButton_Click(null, null); } private async void AreaCommitmentResetButton_Click(object? sender, RoutedEventArgs? evt) { if (IsEditing) { RefreshInputs(); } else if (IsCreating) { await InitInputs(); } UpdateButtons(); } private void AreaCommitmentCancelButton_Click(object sender, RoutedEventArgs evt) { IsEditing = false; IsCreating = false; AreaCommitmentList.IsEnabled = true; HideAreaCommitmentSaveResetCancelButtons(); ShowAreaCommitmentNewEditDeleteButtons(); RefreshInputs(); ClearInputStates(); LockInputs(); UnlockSearchInputs(); } override protected void UpdateButtons() { if (!IsEditing && !IsCreating) return; bool ch = HasChanged, v = IsValid; AreaCommitmentResetButton.IsEnabled = (ch); AreaCommitmentSaveButton.IsEnabled = (ch && v); } private void DisableAreaCommitmentNewEditDeleteButtons() { NewAreaCommitmentButton.IsEnabled = false; EditAreaCommitmentButton.IsEnabled = false; DeleteAreaCommitmentButton.IsEnabled = false; } private void EnableAreaCommitmentNewEditDeleteButtons() { NewAreaCommitmentButton.IsEnabled = true; EditAreaCommitmentButton.IsEnabled = AreaCommitmentList.SelectedItem != null; DeleteAreaCommitmentButton.IsEnabled = AreaCommitmentList.SelectedItem != null; } private void ShowAreaCommitmentSaveResetCancelButtons() { AreaCommitmentSaveButton.IsEnabled = false; AreaCommitmentResetButton.IsEnabled = false; AreaCommitmentCancelButton.IsEnabled = true; AreaCommitmentSaveButton.Visibility = Visibility.Visible; AreaCommitmentResetButton.Visibility = Visibility.Visible; AreaCommitmentCancelButton.Visibility = Visibility.Visible; } private void HideAreaCommitmentSaveResetCancelButtons() { AreaCommitmentSaveButton.IsEnabled = false; AreaCommitmentResetButton.IsEnabled = false; AreaCommitmentCancelButton.IsEnabled = false; AreaCommitmentSaveButton.Visibility = Visibility.Hidden; AreaCommitmentResetButton.Visibility = Visibility.Hidden; AreaCommitmentCancelButton.Visibility = Visibility.Hidden; } private void ShowAreaCommitmentNewEditDeleteButtons() { EnableAreaCommitmentNewEditDeleteButtons(); NewAreaCommitmentButton.Visibility = Visibility.Visible; EditAreaCommitmentButton.Visibility = Visibility.Visible; DeleteAreaCommitmentButton.Visibility = Visibility.Visible; } private void HideAreaCommitmentNewEditDeleteButtons() { DisableAreaCommitmentNewEditDeleteButtons(); NewAreaCommitmentButton.Visibility = Visibility.Hidden; EditAreaCommitmentButton.Visibility = Visibility.Hidden; DeleteAreaCommitmentButton.Visibility = Visibility.Hidden; } private void LockSearchInputs() { SearchInput.IsEnabled = false; ActiveAreaCommitmentInput.IsEnabled = false; } private void UnlockSearchInputs() { SearchInput.IsEnabled = true; ActiveAreaCommitmentInput.IsEnabled = true; } private void AreaCommitmentList_SelectionChanged(object sender, SelectionChangedEventArgs evt) { RefreshInputs(); } private void AttributesInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { } private async void ActiveAreaCommitmentInput_Changed(object sender, RoutedEventArgs evt) { await RefreshList(); } private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) { var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty); binding?.UpdateSource(); await RefreshList(true); } private void KgInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { if (KgInput.SelectedItem is AT_Kg kg) { var rdList = kg.WbKg!.Rds.OrderBy(r => r.Name).Cast().ToList(); rdList.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(RdInput, rdList, null, ControlUtils.RenewSourceDefault.First); } else { var rdList = new object[] { new NullItem() }; ControlUtils.RenewItemsSource(RdInput, rdList, null, ControlUtils.RenewSourceDefault.First); } ComboBox_SelectionChanged(sender, evt); } private void KgDetailsButton_Click(object sender, RoutedEventArgs evt) { if (KgInput.SelectedItem is AT_Kg kg) { App.FocusOriginHierarchyKg(kg.KgNr); } else { App.FocusOriginHierarchy(); } } private void RdInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) { RdAddButton.IsEnabled = RdInput.SelectedIndex == -1; } private void RdAddButton_Click(object sender, RoutedEventArgs evt) { if (KgInput.SelectedItem is not AT_Kg kg) return; string name = RdInput.Text.Trim(); if (name.Length == 0) return; var s = RdInput.ItemsSource.Cast(); RdInput.ItemsSource = s.Append(new WbRd { KgNr = kg.KgNr, RdNr = 0, Name = name, }); RdInput.SelectedIndex = s.Count(); } protected void InputTextChanged(TextBox input, Func checker) { InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaCom)AreaCommitmentList.SelectedItem)); } protected void InputLostFocus(TextBox input, Func checker, string? msg = null) { InputLostFocus(input, checker(input, SenderIsRequired(input), (AreaCom)AreaCommitmentList.SelectedItem), msg); } private void FbNrInput_TextChanged(object sender, RoutedEventArgs evt) { InputTextChanged((TextBox)sender, Validator.CheckFbNr); } private void FbNrInput_LostFocus(object sender, RoutedEventArgs evt) { InputLostFocus((TextBox)sender, Validator.CheckFbNr); } } }