[#10] AreaComAdminWindow: Implement MVVM
This commit is contained in:
@ -6,21 +6,23 @@ using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Elwig.ViewModels;
|
||||
using Elwig.Services;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Elwig.Windows {
|
||||
public partial class AreaComAdminWindow : AdministrationWindow {
|
||||
|
||||
public int MgNr => Member.MgNr;
|
||||
public AreaComAdminViewModel ViewModel => (AreaComAdminViewModel)DataContext;
|
||||
|
||||
private readonly Member Member;
|
||||
private List<string> TextFilter = [];
|
||||
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();
|
||||
Member = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||
Title = $"Flächenbindungen - {Member.AdministrativeName} - Elwig";
|
||||
ViewModel.Member = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value");
|
||||
Title = $"Flächenbindungen - {ViewModel.Member.AdministrativeName} - Elwig";
|
||||
ExemptInputs = [
|
||||
MgNrInput, AreaCommitmentList, NewAreaCommitmentButton,
|
||||
EditAreaCommitmentButton, DeleteAreaCommitmentButton, AreaCommitmentSaveButton,
|
||||
@ -30,6 +32,9 @@ namespace Elwig.Windows {
|
||||
FbNrInput, YearFromInput, KgInput, RdInput,
|
||||
GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput
|
||||
];
|
||||
|
||||
InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||
@ -37,13 +42,16 @@ namespace Elwig.Windows {
|
||||
LockInputs();
|
||||
}
|
||||
|
||||
private async Task RefreshAreaCommitmentList() {
|
||||
await RefreshAreaCommitmentListQuery();
|
||||
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
|
||||
if (!IsEditing && !IsCreating) {
|
||||
SearchInput.Focus();
|
||||
SearchInput.SelectAll();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshAreaCommitmentListQuery(bool updateSort = false) {
|
||||
private async Task RefreshList(bool updateSort = false) {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, areaComQuery, filter) = await GetFilters(ctx);
|
||||
var (_, areaComQuery, filter) = await ViewModel.GetFilters(ctx);
|
||||
var areaComs = await areaComQuery
|
||||
.Include(a => a.Kg.AtKg)
|
||||
.Include(a => a.Rd!.Kg.AtKg)
|
||||
@ -51,7 +59,7 @@ namespace Elwig.Windows {
|
||||
|
||||
if (filter.Count > 0 && areaComs.Count > 0) {
|
||||
var dict = areaComs.AsParallel()
|
||||
.ToDictionary(d => d, d => d.SearchScore(TextFilter))
|
||||
.ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter))
|
||||
.OrderByDescending(c => c.Value);
|
||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||
areaComs = dict
|
||||
@ -65,67 +73,18 @@ namespace Elwig.Windows {
|
||||
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²";
|
||||
ViewModel.StatusAreaCommitments = $"Flächenbindungen: {await areaComQuery.CountAsync()}";
|
||||
ViewModel.StatusArea = $"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²";
|
||||
ViewModel.StatusAreaCommitments = $"Flächenbindungen: {areaComs.Count}";
|
||||
ViewModel.StatusArea = $"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²")) + ")";
|
||||
ViewModel.StatusContracts = $"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(AppDbContext ctx) {
|
||||
List<string> filterNames = [];
|
||||
IQueryable<AreaCom> areaComQuery = ctx.AreaCommitments.Where(a => a.MgNr == Member.MgNr).OrderBy(a => a.FbNr);
|
||||
if (ActiveAreaCommitmentInput.IsChecked == true) {
|
||||
areaComQuery = Utils.ActiveAreaCommitments(areaComQuery);
|
||||
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 ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var attr = await ctx.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) {
|
||||
@ -146,44 +105,14 @@ namespace Elwig.Windows {
|
||||
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();
|
||||
|
||||
ControlUtils.SelectItemWithPk(KgInput, a.KgNr);
|
||||
if (a.RdNr != null) {
|
||||
ControlUtils.SelectItemWithPk(RdInput, a.KgNr, a.RdNr);
|
||||
} else {
|
||||
RdInput.SelectedIndex = 0;
|
||||
}
|
||||
GstNrInput.Text = a.GstNr;
|
||||
AreaInput.Text = a.Area.ToString();
|
||||
|
||||
ControlUtils.SelectItemWithPk(AreaComTypeInput, a.VtrgId);
|
||||
if (a.CultId != null) {
|
||||
ControlUtils.SelectItemWithPk(WineCultivationInput, a.CultId);
|
||||
} else {
|
||||
WineCultivationInput.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
CommentInput.Text = a.Comment;
|
||||
|
||||
ViewModel.FillInputs(a);
|
||||
FinishInputFilling();
|
||||
}
|
||||
|
||||
private async void InitInputs() {
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
|
||||
using (var ctx = new AppDbContext()) {
|
||||
FbNrInput.Text = (await ctx.NextFbNr()).ToString();
|
||||
MgNrInput.Text = Member.MgNr.ToString();
|
||||
YearFromInput.Text = DateTime.Now.Year.ToString();
|
||||
WineCultivationInput.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
await ViewModel.InitInputs();
|
||||
SetDefaultValue(FbNrInput);
|
||||
ValidateRequiredInputs();
|
||||
}
|
||||
@ -205,7 +134,7 @@ namespace Elwig.Windows {
|
||||
.Cast<object>().ToListAsync();
|
||||
cultList.Insert(0, new NullItem());
|
||||
ControlUtils.RenewItemsSource(WineCultivationInput, cultList, null, ControlUtils.RenewSourceDefault.First);
|
||||
await RefreshAreaCommitmentList();
|
||||
await RefreshList();
|
||||
}
|
||||
|
||||
protected override void ShortcutNew() {
|
||||
@ -262,53 +191,10 @@ namespace Elwig.Windows {
|
||||
using var ctx = new AppDbContext();
|
||||
ctx.Remove(a);
|
||||
await ctx.SaveChangesAsync();
|
||||
await RefreshAreaCommitmentList();
|
||||
await RefreshList();
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<int> UpdateAreaCom(int? oldFbNr) {
|
||||
using var ctx = new AppDbContext();
|
||||
int newFbNr = int.Parse(FbNrInput.Text);
|
||||
|
||||
var a = new AreaCom {
|
||||
FbNr = oldFbNr ?? newFbNr,
|
||||
MgNr = int.Parse(MgNrInput.Text),
|
||||
YearFrom = int.Parse(YearFromInput.Text),
|
||||
YearTo = (YearToInput.Text == "") ? null : int.Parse(YearToInput.Text),
|
||||
KgNr = ((AT_Kg)KgInput.SelectedItem).KgNr,
|
||||
RdNr = (RdInput.SelectedItem as WbRd)?.RdNr,
|
||||
GstNr = GstNrInput.Text.Trim(),
|
||||
Area = int.Parse(AreaInput.Text),
|
||||
VtrgId = (AreaComTypeInput.SelectedItem as AreaComType)!.VtrgId,
|
||||
CultId = (WineCultivationInput.SelectedItem as WineCult)?.CultId,
|
||||
Comment = (CommentInput.Text == "") ? null : CommentInput.Text.Trim(),
|
||||
};
|
||||
|
||||
if (RdInput.SelectedItem is WbRd rd) {
|
||||
if (rd.RdNr == 0) {
|
||||
rd.RdNr = await ctx.NextRdNr(a.KgNr);
|
||||
a.RdNr = rd.RdNr;
|
||||
ctx.Add(rd);
|
||||
}
|
||||
}
|
||||
|
||||
if (oldFbNr != null) {
|
||||
ctx.Update(a);
|
||||
} else {
|
||||
ctx.Add(a);
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
if (newFbNr != a.FbNr) {
|
||||
await ctx.Database.ExecuteSqlAsync($"UPDATE area_commitment SET fbnr = {newFbNr} WHERE fbnr = {oldFbNr}");
|
||||
}
|
||||
|
||||
await App.HintContextChange();
|
||||
|
||||
return newFbNr;
|
||||
}
|
||||
|
||||
protected override void ShortcutSave() {
|
||||
if (!AreaCommitmentSaveButton.IsEnabled || AreaCommitmentSaveButton.Visibility != Visibility.Visible)
|
||||
return;
|
||||
@ -318,7 +204,7 @@ namespace Elwig.Windows {
|
||||
private async void AreaCommitmentSaveButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
int? fbnr = null;
|
||||
try {
|
||||
fbnr = await UpdateAreaCom((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr);
|
||||
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;
|
||||
@ -332,9 +218,9 @@ namespace Elwig.Windows {
|
||||
LockInputs();
|
||||
UnlockSearchInputs();
|
||||
FinishInputFilling();
|
||||
await RefreshAreaCommitmentList();
|
||||
await RefreshList();
|
||||
RefreshInputs();
|
||||
SearchInput.Text = "";
|
||||
ViewModel.SearchQuery = "";
|
||||
ControlUtils.SelectItem(AreaCommitmentList, AreaCommitmentList.ItemsSource.Cast<AreaCom>().Where(a => a.FbNr == fbnr).FirstOrDefault());
|
||||
}
|
||||
|
||||
@ -435,12 +321,13 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private async void ActiveAreaCommitmentInput_Changed(object sender, RoutedEventArgs evt) {
|
||||
await RefreshAreaCommitmentListQuery();
|
||||
await RefreshList();
|
||||
}
|
||||
|
||||
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
|
||||
TextFilter = SearchInput.Text.ToLower().Split(" ").ToList().FindAll(e => e.Length > 0);
|
||||
await RefreshAreaCommitmentListQuery(true);
|
||||
var binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
|
||||
binding?.UpdateSource();
|
||||
await RefreshList(true);
|
||||
}
|
||||
|
||||
private void KgInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
||||
|
Reference in New Issue
Block a user