451 lines
20 KiB
C#
451 lines
20 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 System.Collections.Generic;
|
|
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|
using Xceed.Wpf.Toolkit.Primitives;
|
|
|
|
namespace Elwig.Windows {
|
|
public partial class AreaComAdminWindow : AdministrationWindow {
|
|
|
|
public int MgNr => Member.MgNr;
|
|
|
|
private readonly Member Member;
|
|
private List<string> TextFilter = [];
|
|
|
|
public AreaComAdminWindow(int mgnr) {
|
|
InitializeComponent();
|
|
Member = Context.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
|
Title = $"Flächenbindungen - {Member.AdministrativeName} - Elwig";
|
|
ExemptInputs = [
|
|
MgNrInput, AreaCommitmentList, NewAreaCommitmentButton,
|
|
EditAreaCommitmentButton, DeleteAreaCommitmentButton, AreaCommitmentSaveButton,
|
|
AreaCommitmentResetButton, AreaCommitmentCancelButton, SearchInput, ActiveAreaCommitmentInput
|
|
];
|
|
RequiredInputs = [
|
|
FbNrInput, YearFromInput, KgInput, RdInput,
|
|
GstNrInput, AreaInput.TextBox, AreaComTypeInput, WineCultivationInput
|
|
];
|
|
}
|
|
|
|
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
|
ActiveAreaCommitmentInput.IsChecked = true;
|
|
LockInputs();
|
|
}
|
|
|
|
private async Task RefreshAreaCommitmentList() {
|
|
await Context.AreaCommitments.LoadAsync();
|
|
await RefreshAreaCommitmentListQuery();
|
|
}
|
|
|
|
private async Task RefreshAreaCommitmentListQuery(bool updateSort = false) {
|
|
var (_, areaComQuery, filter) = await GetFilters();
|
|
var areaComs = await areaComQuery.ToListAsync();
|
|
|
|
if (filter.Count > 0 && areaComs.Count > 0) {
|
|
var dict = areaComs.AsParallel()
|
|
.ToDictionary(d => d, d => d.SearchScore(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, i => (i as AreaCom)?.FbNr,
|
|
AreaCommitmentList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
|
RefreshInputs();
|
|
|
|
if(filter.Count == 0) {
|
|
StatusAreaCommitments.Text = $"Flächenbindungen: {await areaComQuery.CountAsync()}";
|
|
StatusArea.Text = $"Fläche: {await areaComQuery.Select(a => a.Area).SumAsync():N0} m²";
|
|
} else {
|
|
StatusAreaCommitments.Text = $"Flächenbindungen: {areaComs.Count}";
|
|
StatusArea.Text = $"Fläche: {areaComs.Select(a => a.Area).Sum():N0} m²";
|
|
}
|
|
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();
|
|
StatusContracts.Text = $"Vertragsarten: {groups.Count} (" + string.Join(", ", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²")) + ")";
|
|
groups = areaComs.GroupBy(a => a.AreaComType.DisplayName).Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
|
|
StatusContracts.ToolTip = $"Vertragsarten: {groups.Count}\n" + string.Join($"\n", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²"));
|
|
}
|
|
|
|
private async Task<(List<string>, IQueryable<AreaCom>, List<string>)> GetFilters() {
|
|
List<string> filterNames = [];
|
|
IQueryable<AreaCom> areaComQuery = Context.AreaCommitments.Where(a => a.MgNr == Member.MgNr).OrderBy(a => a.FbNr);
|
|
if (ActiveAreaCommitmentInput.IsChecked == true) {
|
|
areaComQuery = areaComQuery.Where(a => (a.YearFrom <= Utils.CurrentYear) && (a.YearTo == null || a.YearTo >= Utils.CurrentYear));
|
|
filterNames.Add("aktiv");
|
|
}
|
|
|
|
var filterVar = new List<string>();
|
|
var filterNotVar = new List<string>();
|
|
var filterAttr = new List<string>();
|
|
var filterNotAttr = new List<string>();
|
|
|
|
var filter = TextFilter.ToList();
|
|
if (filter.Count > 0) {
|
|
var var = await Context.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
|
var attr = await Context.WineAttributes.ToDictionaryAsync(a => a.Name.ToLower().Split(" ")[0], a => a);
|
|
|
|
for (int i = 0; i < filter.Count; i++) {
|
|
var e = filter[i];
|
|
if (e.Length == 2 && var.ContainsKey(e.ToUpper())) {
|
|
filterVar.Add(e.ToUpper());
|
|
filter.RemoveAt(i--);
|
|
filterNames.Add(var[e.ToUpper()].Name);
|
|
} else if (e.Length == 3 && e[0] == '!' && var.ContainsKey(e[1..].ToUpper())) {
|
|
filterNotVar.Add(e[1..].ToUpper());
|
|
filter.RemoveAt(i--);
|
|
} else if (attr.ContainsKey(e.ToLower())) {
|
|
var a = attr[e.ToLower()];
|
|
filterAttr.Add(a.AttrId);
|
|
filter.RemoveAt(i--);
|
|
filterNames.Add($"Attribut {a.Name}");
|
|
} else if (e[0] == '!' && attr.ContainsKey(e[1..].ToLower())) {
|
|
var a = attr[e[1..].ToLower()];
|
|
filterNotAttr.Add(a.AttrId);
|
|
filter.RemoveAt(i--);
|
|
filterNames.Add($"ohne Attribut {a.Name}");
|
|
}
|
|
}
|
|
|
|
if (filterVar.Count > 0) areaComQuery = areaComQuery.Where(a => filterVar.Contains(a.AreaComType.WineVar.SortId));
|
|
if (filterNotVar.Count > 0) areaComQuery = areaComQuery.Where(a => !filterNotVar.Contains(a.AreaComType.WineVar.SortId));
|
|
if (filterAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr != null && a.AreaComType.WineAttr.AttrId != null && filterAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
|
if (filterNotAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr == null || a.AreaComType.WineAttr.AttrId == null || !filterAttr.Contains(a.AreaComType.WineAttr.AttrId));
|
|
}
|
|
|
|
return (filterNames, areaComQuery, filter);
|
|
}
|
|
|
|
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();
|
|
|
|
FbNrInput.Text = a.FbNr.ToString();
|
|
MgNrInput.Text = a.MgNr.ToString();
|
|
YearFromInput.Text = a.YearFrom.ToString();
|
|
YearToInput.Text = a.YearTo.ToString();
|
|
|
|
KgInput.SelectedItem = a.Kg.AtKg;
|
|
RdInput.SelectedItem = a.Rd ?? RdInput.Items[0];
|
|
GstNrInput.Text = a.GstNr;
|
|
AreaInput.Text = a.Area.ToString();
|
|
|
|
AreaComTypeInput.SelectedItem = a.AreaComType;
|
|
WineCultivationInput.SelectedItem = a.WineCult;
|
|
|
|
CommentInput.Text = a.Comment;
|
|
|
|
FinishInputFilling();
|
|
}
|
|
|
|
private async void InitInputs() {
|
|
ClearOriginalValues();
|
|
ClearDefaultValues();
|
|
|
|
FbNrInput.Text = (await Context.NextFbNr()).ToString();
|
|
MgNrInput.Text = Member.MgNr.ToString();
|
|
YearFromInput.Text = DateTime.Now.Year.ToString();
|
|
|
|
SetDefaultValue(FbNrInput);
|
|
ValidateRequiredInputs();
|
|
}
|
|
|
|
protected override async Task OnRenewContext() {
|
|
await base.OnRenewContext();
|
|
ControlUtils.RenewItemsSource(KgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr);
|
|
ControlUtils.RenewItemsSource(AreaComTypeInput, await Context.AreaCommitmentTypes.OrderBy(v => v.VtrgId).ToListAsync(), i => (i as AreaComType)?.VtrgId);
|
|
ControlUtils.RenewItemsSource(WineCultivationInput, await Context.WineCultivations.OrderBy(c => c.Name).ToListAsync(), i => (i as WineCult)?.CultId);
|
|
await RefreshAreaCommitmentList();
|
|
}
|
|
|
|
private void NewAreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
|
|
IsCreating = true;
|
|
AreaCommitmentList.IsEnabled = false;
|
|
AreaCommitmentList.SelectedItem = null;
|
|
HideAreaCommitmentNewEditDeleteButtons();
|
|
ShowAreaCommitmentSaveResetCancelButtons();
|
|
UnlockInputs();
|
|
InitInputs();
|
|
LockSearchInputs();
|
|
}
|
|
|
|
private void EditAreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
|
|
if (AreaCommitmentList.SelectedItem == null)
|
|
return;
|
|
|
|
IsEditing = true;
|
|
AreaCommitmentList.IsEnabled = false;
|
|
|
|
HideAreaCommitmentNewEditDeleteButtons();
|
|
ShowAreaCommitmentSaveResetCancelButtons();
|
|
UnlockInputs();
|
|
LockSearchInputs();
|
|
}
|
|
|
|
private async void DeleteAreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
|
|
AreaCom a = (AreaCom)AreaCommitmentList.SelectedItem;
|
|
if (a == null) return;
|
|
|
|
var r = MessageBox.Show(
|
|
$"Soll die Flächenbindung {a.GstNr} ({a.Area} m²) wirklich unwiderruflich gelöscht werden?",
|
|
"Flächenbindung löschen", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
|
if (r == MessageBoxResult.Yes) {
|
|
Context.Remove(a);
|
|
Context.SaveChanges();
|
|
await RefreshAreaCommitmentList();
|
|
}
|
|
}
|
|
|
|
private async Task<AreaCom> UpdateAreaCom(AreaCom a) {
|
|
int newFbNr = int.Parse(FbNrInput.Text);
|
|
a.MgNr = int.Parse(MgNrInput.Text);
|
|
a.YearFrom = int.Parse(YearFromInput.Text);
|
|
a.YearTo = (YearToInput.Text == "") ? null : int.Parse(YearToInput.Text);
|
|
a.KgNr = ((AT_Kg)KgInput.SelectedItem).KgNr;
|
|
a.RdNr = RdInput.SelectedItem.GetType() == typeof(NullItem) ? null : ((WbRd)RdInput.SelectedItem).RdNr;
|
|
a.GstNr = GstNrInput.Text;
|
|
a.Area = int.Parse(AreaInput.Text);
|
|
a.VtrgId = (AreaComTypeInput.SelectedItem as AreaComType)!.VtrgId;
|
|
a.CultId = (WineCultivationInput.SelectedItem as WineCult)!.CultId;
|
|
a.Comment = (CommentInput.Text == "") ? null : CommentInput.Text;
|
|
|
|
EntityEntry<AreaCom>? tr = null;
|
|
try {
|
|
if (RdInput.SelectedItem is WbRd wbRd) {
|
|
a.RdNr = wbRd.RdNr;
|
|
var e = Context.Entry(wbRd);
|
|
if (e.State == EntityState.Detached) {
|
|
await Context.AddAsync(wbRd);
|
|
}
|
|
} else {
|
|
a.RdNr = null;
|
|
}
|
|
|
|
if (IsEditing) {
|
|
tr = Context.Update(a);
|
|
} else if (IsCreating) {
|
|
a.FbNr = newFbNr;
|
|
tr = await Context.AddAsync(a);
|
|
} else {
|
|
throw new Exception();
|
|
}
|
|
|
|
await Context.SaveChangesAsync();
|
|
|
|
if (newFbNr != a.FbNr) {
|
|
await Context.Database.ExecuteSqlAsync($"UPDATE area_commitment SET fbnr = {newFbNr} WHERE fbnr = {a.FbNr}");
|
|
tr.State = EntityState.Detached;
|
|
await Context.SaveChangesAsync();
|
|
await tr.ReloadAsync();
|
|
a = await Context.AreaCommitments.FindAsync(newFbNr);
|
|
}
|
|
|
|
} catch (Exception exc) {
|
|
if (tr != null) {
|
|
tr.State = EntityState.Detached;
|
|
await tr.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, "Flächenbindung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
|
|
return a!;
|
|
}
|
|
|
|
private async void AreaCommitmentSaveButton_Click(object sender, RoutedEventArgs evt) {
|
|
AreaCom a = await UpdateAreaCom(IsEditing ? (AreaCom)AreaCommitmentList.SelectedItem : Context.CreateProxy<AreaCom>());
|
|
IsEditing = false;
|
|
IsCreating = false;
|
|
AreaCommitmentList.IsEnabled = true;
|
|
HideAreaCommitmentSaveResetCancelButtons();
|
|
ShowAreaCommitmentNewEditDeleteButtons();
|
|
LockInputs();
|
|
UnlockSearchInputs();
|
|
await RefreshAreaCommitmentList();
|
|
AreaCommitmentList.SelectedItem = a;
|
|
}
|
|
|
|
private void AreaCommitmentResetButton_Click(object sender, RoutedEventArgs evt) {
|
|
if (IsEditing) {
|
|
RefreshInputs();
|
|
} else if (IsCreating) {
|
|
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, ItemSelectionChangedEventArgs evt) {
|
|
|
|
}
|
|
|
|
private async void ActiveAreaCommitmentInput_Changed(object sender, RoutedEventArgs evt) {
|
|
await RefreshAreaCommitmentListQuery();
|
|
}
|
|
|
|
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
|
TextFilter = SearchInput.Text.ToLower().Split(" ").ToList().FindAll(e => e.Length > 0);
|
|
await RefreshAreaCommitmentListQuery(true);
|
|
}
|
|
|
|
private async void KgInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
|
if (KgInput.SelectedItem is AT_Kg curr_kg) {
|
|
var rdList = await Context.WbRde.Where(r => r.KgNr == curr_kg.KgNr).OrderBy(r => r.Name).Cast<object>().ToListAsync();
|
|
rdList.Insert(0, new NullItem());
|
|
ControlUtils.RenewItemsSource(RdInput, rdList, i => (i as WbRd)?.RdNr, null, ControlUtils.RenewSourceDefault.First);
|
|
} else {
|
|
var rdList = new object[] { new NullItem() };
|
|
ControlUtils.RenewItemsSource(RdInput, rdList, i => (i as WbRd)?.RdNr, 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 async 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, Name = name, RdNr = await Context.NextRdNr(kg.KgNr)});
|
|
RdInput.SelectedIndex = s.Count();
|
|
}
|
|
|
|
protected void InputTextChanged(TextBox input, Func<TextBox, bool, AppDbContext, AreaCom?, ValidationResult> checker) {
|
|
InputTextChanged(input, checker(input, SenderIsRequired(input), Context, (AreaCom)AreaCommitmentList.SelectedItem));
|
|
}
|
|
|
|
protected void InputLostFocus(TextBox input, Func<TextBox, bool, AppDbContext, AreaCom?, ValidationResult> checker, string? msg = null) {
|
|
InputLostFocus(input, checker(input, SenderIsRequired(input), Context, (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);
|
|
}
|
|
|
|
private void GstNrInput_TextChanged(object sender, RoutedEventArgs evt) {
|
|
InputTextChanged((TextBox)sender, Validator.CheckGstNr);
|
|
}
|
|
|
|
private void GstNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
|
InputLostFocus((TextBox)sender, Validator.CheckGstNr);
|
|
}
|
|
}
|
|
}
|