Files
elwig/Elwig/Windows/AreaComAdminWindow.xaml.cs
Lorenz Stechauner 2ee0d56dcc
All checks were successful
Test / Run tests (push) Successful in 1m54s
Windows: Add MailLogWindow
2024-11-13 18:37:50 +01:00

419 lines
18 KiB
C#

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
];
ControlUtils.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, gridData) = await AreaComService.GenerateToolTipData(areaComQuery, s?.MaxKgPerHa ?? 10_000);
ViewModel.StatusArea = text;
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
} 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 = $"Flächenbindungen - {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<object>().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();
}
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) {
AreaCommitmentSaveButton.IsEnabled = false;
Mouse.OverrideCursor = Cursors.AppStarting;
int fbnr;
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);
AreaCommitmentSaveButton.IsEnabled = true;
return;
} finally {
Mouse.OverrideCursor = null;
}
IsEditing = false;
IsCreating = false;
AreaCommitmentList.IsEnabled = true;
HideAreaCommitmentSaveResetCancelButtons();
ShowAreaCommitmentNewEditDeleteButtons();
LockInputs();
UnlockSearchInputs();
FinishInputFilling();
await RefreshList();
RefreshInputs();
ViewModel.SearchQuery = "";
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().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<object>().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<object?>();
RdInput.ItemsSource = s.Append(new WbRd {
KgNr = kg.KgNr,
RdNr = 0,
Name = name,
});
RdInput.SelectedIndex = s.Count();
}
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AreaCom?, ValidationResult> checker) {
InputTextChanged(input, checker(input, SenderIsRequired(input), (AreaCom)AreaCommitmentList.SelectedItem));
}
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AreaCom?, ValidationResult> 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);
}
}
}