diff --git a/Elwig/Helpers/Validator.cs b/Elwig/Helpers/Validator.cs index 111405b..bdb58df 100644 --- a/Elwig/Helpers/Validator.cs +++ b/Elwig/Helpers/Validator.cs @@ -576,7 +576,7 @@ namespace Elwig.Helpers { } } - public static ValidationResult CheckFbNr(TextBox input, bool required, AppDbContext ctx, AreaCom? c) { + public static ValidationResult CheckFbNr(TextBox input, bool required, AreaCom? c) { var res = CheckInteger(input, required); if (!res.IsValid) { return res; @@ -584,6 +584,7 @@ namespace Elwig.Helpers { return new(true, null); } + using var ctx = new AppDbContext(); int nr = int.Parse(input.Text); if (nr != c?.FbNr && ctx.FbNrExists(nr).GetAwaiter().GetResult()) { return new(false, "Flächenbindungsnummer wird bereits verwendet"); diff --git a/Elwig/Windows/AreaComAdminWindow.xaml.cs b/Elwig/Windows/AreaComAdminWindow.xaml.cs index 93ffbe3..4502754 100644 --- a/Elwig/Windows/AreaComAdminWindow.xaml.cs +++ b/Elwig/Windows/AreaComAdminWindow.xaml.cs @@ -7,7 +7,6 @@ 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 { @@ -20,7 +19,8 @@ namespace Elwig.Windows { public AreaComAdminWindow(int mgnr) { InitializeComponent(); - Member = Context.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value"); + using var ctx = new AppDbContext(); + Member = ctx.Members.Find(mgnr) ?? throw new ArgumentException("MgNr argument has invalid value"); Title = $"Flächenbindungen - {Member.AdministrativeName} - Elwig"; ExemptInputs = [ MgNrInput, AreaCommitmentList, NewAreaCommitmentButton, @@ -39,13 +39,16 @@ namespace Elwig.Windows { } 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(); + using var ctx = new AppDbContext(); + var (_, areaComQuery, filter) = await GetFilters(ctx); + var areaComs = await areaComQuery + .Include(a => a.Kg.AtKg) + .Include(a => a.Rd!.Kg.AtKg) + .ToListAsync(); if (filter.Count > 0 && areaComs.Count > 0) { var dict = areaComs.AsParallel() @@ -75,9 +78,9 @@ namespace Elwig.Windows { StatusContracts.ToolTip = $"Vertragsarten: {groups.Count}\n" + string.Join($"\n", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²")); } - private async Task<(List, IQueryable, List)> GetFilters() { + private async Task<(List, IQueryable, List)> GetFilters(AppDbContext ctx) { List filterNames = []; - IQueryable areaComQuery = Context.AreaCommitments.Where(a => a.MgNr == Member.MgNr).OrderBy(a => a.FbNr); + IQueryable areaComQuery = ctx.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"); @@ -90,8 +93,8 @@ namespace Elwig.Windows { 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); + 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]; @@ -150,13 +153,21 @@ namespace Elwig.Windows { YearFromInput.Text = a.YearFrom.ToString(); YearToInput.Text = a.YearTo.ToString(); - KgInput.SelectedItem = a.Kg.AtKg; - RdInput.SelectedItem = a.Rd ?? RdInput.Items[0]; + ControlUtils.SelectComboBoxItem(KgInput, k => (k as AT_Kg)?.KgNr, a.KgNr); + if (a.RdNr != null) { + ControlUtils.SelectComboBoxItem(RdInput, r => (r as WbRd)?.RdNr, a.RdNr); + } else { + RdInput.SelectedIndex = 0; + } GstNrInput.Text = a.GstNr; AreaInput.Text = a.Area.ToString(); - AreaComTypeInput.SelectedItem = a.AreaComType; - WineCultivationInput.SelectedItem = a.WineCult ?? WineCultivationInput.Items[0]; + ControlUtils.SelectComboBoxItem(AreaComTypeInput, t => (t as AreaComType)?.VtrgId, a.VtrgId); + if (a.CultId != null) { + ControlUtils.SelectComboBoxItem(WineCultivationInput, c => (c as WineCult)?.CultId, a.CultId); + } else { + WineCultivationInput.SelectedIndex = 0; + } CommentInput.Text = a.Comment; @@ -167,10 +178,12 @@ namespace Elwig.Windows { ClearOriginalValues(); ClearDefaultValues(); - FbNrInput.Text = (await Context.NextFbNr()).ToString(); - MgNrInput.Text = Member.MgNr.ToString(); - YearFromInput.Text = DateTime.Now.Year.ToString(); - WineCultivationInput.SelectedIndex = 0; + 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; + } SetDefaultValue(FbNrInput); ValidateRequiredInputs(); @@ -178,9 +191,20 @@ namespace Elwig.Windows { 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); - var cultList = await Context.WineCultivations.OrderBy(c => c.Name).Cast().ToListAsync(); + using var ctx = new AppDbContext(); + ControlUtils.RenewItemsSource(KgInput, await ctx.WbKgs + .Include(k => k.AtKg.WbKg!.Rds) + .Select(k => k.AtKg) + .OrderBy(k => k.Name) + .ToListAsync(), i => (i as AT_Kg)?.KgNr); + ControlUtils.RenewItemsSource(AreaComTypeInput, await ctx.AreaCommitmentTypes + .Include(c => c.WineVar) + .Include(c => c.WineAttr) + .OrderBy(v => v.VtrgId) + .ToListAsync(), i => (i as AreaComType)?.VtrgId); + var cultList = await ctx.WineCultivations + .OrderBy(c => c.Name) + .Cast().ToListAsync(); cultList.Insert(0, new NullItem()); ControlUtils.RenewItemsSource(WineCultivationInput, cultList, i => (i as WineCult)?.CultId, null, ControlUtils.RenewSourceDefault.First); await RefreshAreaCommitmentList(); @@ -218,71 +242,65 @@ namespace Elwig.Windows { $"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(); + using var ctx = new AppDbContext(); + ctx.Remove(a); + await ctx.SaveChangesAsync(); await RefreshAreaCommitmentList(); } } - private async Task UpdateAreaCom(AreaCom a) { + private async Task UpdateAreaCom(int? oldFbNr) { + using var ctx = new AppDbContext(); 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? tr = null; + 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; + } + + private async void AreaCommitmentSaveButton_Click(object sender, RoutedEventArgs evt) { + int? fbnr = 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); - } - + fbnr = await UpdateAreaCom((AreaCommitmentList.SelectedItem as AreaCom)?.FbNr); } 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()); IsEditing = false; IsCreating = false; AreaCommitmentList.IsEnabled = true; @@ -290,8 +308,11 @@ namespace Elwig.Windows { ShowAreaCommitmentNewEditDeleteButtons(); LockInputs(); UnlockSearchInputs(); - await App.HintContextChange(); - AreaCommitmentList.SelectedItem = a; + FinishInputFilling(); + await RefreshAreaCommitmentList(); + RefreshInputs(); + SearchInput.Text = ""; + AreaCommitmentList.SelectedItem = AreaCommitmentList.ItemsSource.Cast().Where(a => a.FbNr == fbnr).FirstOrDefault(); } private void AreaCommitmentResetButton_Click(object sender, RoutedEventArgs evt) { @@ -393,9 +414,9 @@ namespace Elwig.Windows { 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().ToListAsync(); + 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, i => (i as WbRd)?.RdNr, null, ControlUtils.RenewSourceDefault.First); } else { @@ -417,21 +438,25 @@ namespace Elwig.Windows { RdAddButton.IsEnabled = RdInput.SelectedIndex == -1; } - private async void RdAddButton_Click(object sender, RoutedEventArgs evt) { + 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, Name = name, RdNr = await Context.NextRdNr(kg.KgNr)}); + 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), Context, (AreaCom)AreaCommitmentList.SelectedItem)); + 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), Context, (AreaCom)AreaCommitmentList.SelectedItem), msg); + 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) { diff --git a/Elwig/Windows/MemberAdminWindow.xaml.cs b/Elwig/Windows/MemberAdminWindow.xaml.cs index f486392..602165b 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml.cs +++ b/Elwig/Windows/MemberAdminWindow.xaml.cs @@ -657,6 +657,8 @@ namespace Elwig.Windows { await ctx.Database.ExecuteSqlAsync($"UPDATE member SET mgnr = {newMgNr} WHERE mgnr = {oldMgNr}"); } + await App.HintContextChange(); + return newMgNr; }