Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dd6f18117e | |||
| bb1dd3e4e9 |
@@ -47,15 +47,15 @@ namespace Elwig.Controls {
|
|||||||
private void UpdateButtons() {
|
private void UpdateButtons() {
|
||||||
var incButton = GetTemplateChild("IncrementButton") as RepeatButton;
|
var incButton = GetTemplateChild("IncrementButton") as RepeatButton;
|
||||||
var decButton = GetTemplateChild("DecrementButton") as RepeatButton;
|
var decButton = GetTemplateChild("DecrementButton") as RepeatButton;
|
||||||
incButton?.IsEnabled = Maximum == null || Value < Maximum;
|
incButton?.IsEnabled = Maximum != null && Value < Maximum;
|
||||||
decButton?.IsEnabled = Minimum == null || Value > Minimum;
|
decButton?.IsEnabled = Minimum != null && Value > Minimum;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void IntegerUpDown_TextChanged(object sender, TextChangedEventArgs evt) {
|
private void IntegerUpDown_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||||
var idx = CaretIndex;
|
var idx = CaretIndex;
|
||||||
Text = new string([.. Text.Where(char.IsAsciiDigit).Take(4)]);
|
Text = new string([.. Text.Where(char.IsAsciiDigit).Take(4)]);
|
||||||
CaretIndex = idx;
|
CaretIndex = idx;
|
||||||
evt.Handled = !((!Minimum.HasValue || Value >= Minimum) && (!Maximum.HasValue || Value <= Maximum));
|
evt.Handled = !(Value >= Minimum && Value <= Maximum);
|
||||||
if (idx >= 4) {
|
if (idx >= 4) {
|
||||||
if (Value < Minimum) {
|
if (Value < Minimum) {
|
||||||
Value = Minimum;
|
Value = Minimum;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Elwig.Helpers;
|
using Elwig.Helpers;
|
||||||
using System;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
@@ -20,7 +19,6 @@ namespace Elwig.Dialogs {
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Title = delete ? "Flächenbindung löschen" : "Flächenbindung bearbeiten";
|
Title = delete ? "Flächenbindung löschen" : "Flächenbindung bearbeiten";
|
||||||
RetroactiveInput.Content = delete ? "Rückwirkend löschen" : "Rückwirkend bearbeiten";
|
RetroactiveInput.Content = delete ? "Rückwirkend löschen" : "Rückwirkend bearbeiten";
|
||||||
forceRetroactive = forceRetroactive || yearFrom.HasValue && yearTo.HasValue && yearFrom.Value == yearTo.Value;
|
|
||||||
RetroactiveInput.IsEnabled = !forceRetroactive;
|
RetroactiveInput.IsEnabled = !forceRetroactive;
|
||||||
if (delete) {
|
if (delete) {
|
||||||
QuestionBlock1.Visibility = Visibility.Hidden;
|
QuestionBlock1.Visibility = Visibility.Hidden;
|
||||||
@@ -28,8 +26,7 @@ namespace Elwig.Dialogs {
|
|||||||
DescBlock1.Visibility = Visibility.Hidden;
|
DescBlock1.Visibility = Visibility.Hidden;
|
||||||
DescBlock2.Visibility = Visibility.Visible;
|
DescBlock2.Visibility = Visibility.Visible;
|
||||||
}
|
}
|
||||||
SeasonInput.Minimum = yearFrom.HasValue ? yearFrom + 1 : null;
|
SeasonInput.Minimum = yearFrom + 1;
|
||||||
SeasonInput.Maximum = yearTo.HasValue ? yearTo : null;
|
|
||||||
if (forceRetroactive || (yearTo.HasValue && yearTo < Utils.CurrentYear) || (yearFrom.HasValue && yearFrom >= Utils.CurrentYear)) {
|
if (forceRetroactive || (yearTo.HasValue && yearTo < Utils.CurrentYear) || (yearFrom.HasValue && yearFrom >= Utils.CurrentYear)) {
|
||||||
RetroactiveInput.IsChecked = true;
|
RetroactiveInput.IsChecked = true;
|
||||||
} else {
|
} else {
|
||||||
@@ -53,7 +50,7 @@ namespace Elwig.Dialogs {
|
|||||||
DescBlock2.Visibility = Visibility.Hidden;
|
DescBlock2.Visibility = Visibility.Hidden;
|
||||||
} else {
|
} else {
|
||||||
SeasonInput.IsEnabled = true;
|
SeasonInput.IsEnabled = true;
|
||||||
SeasonInput.Text = $"{Math.Max(SeasonInput.Minimum ?? Utils.CurrentYear, Utils.CurrentYear)}";
|
SeasonInput.Text = $"{Utils.CurrentYear}";
|
||||||
DescBlock1.Visibility = QuestionBlock1.Visibility;
|
DescBlock1.Visibility = QuestionBlock1.Visibility;
|
||||||
DescBlock2.Visibility = QuestionBlock2.Visibility;
|
DescBlock2.Visibility = QuestionBlock2.Visibility;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void ClearInputs(this AreaComAdminViewModel vm) {
|
public static void ClearInputs(this AreaComAdminViewModel vm) {
|
||||||
vm.Period = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void FillInputs(this AreaComAdminViewModel vm, AreaComContract c) {
|
public static void FillInputs(this AreaComAdminViewModel vm, AreaComContract c) {
|
||||||
|
|||||||
@@ -318,13 +318,18 @@ namespace Elwig.Services {
|
|||||||
AddToolTipCell(grid, $"{weight * 100.0 / total2:N1} %", row, 4, 1, bold, true);
|
AddToolTipCell(grid, $"{weight * 100.0 / total2:N1} %", row, 4, 1, bold, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task<(string Text, (string?, string?, int, int?, int)[] Grid)> GenerateToolTipData(IQueryable<DeliveryAncmt> deliveryAncmts) {
|
public static async Task<(string, Grid)> GenerateToolTip(IQueryable<DeliveryAncmt> deliveryAncmts) {
|
||||||
var grid = new List<(string?, string?, int, int?, int)>();
|
var grid = new Grid();
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(10) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(60) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(80) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
|
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
||||||
var text = "-";
|
var text = "-";
|
||||||
|
|
||||||
var weight = await deliveryAncmts.SumAsync(p => p.Weight);
|
var weight = await deliveryAncmts.SumAsync(p => p.Weight);
|
||||||
text = $"{weight:N0} kg";
|
text = $"{weight:N0} kg";
|
||||||
grid.Add(("Menge", null, weight, null, weight));
|
AddToolTipRow(grid, 0, "Menge", null, weight, null, weight);
|
||||||
|
|
||||||
if (await deliveryAncmts.AnyAsync()) {
|
if (await deliveryAncmts.AnyAsync()) {
|
||||||
var attrGroups = await deliveryAncmts
|
var attrGroups = await deliveryAncmts
|
||||||
@@ -365,11 +370,13 @@ namespace Elwig.Services {
|
|||||||
.ThenBy(g => g.SortId)
|
.ThenBy(g => g.SortId)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
|
||||||
|
int rowNum = 1;
|
||||||
foreach (var attrG in attrGroups) {
|
foreach (var attrG in attrGroups) {
|
||||||
|
rowNum++;
|
||||||
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
var name = attrG.Attr == null && attrG.Cult == null ? null : attrG.Attr + (attrG.Attr != null && attrG.Cult != null ? " / " : "") + attrG.Cult;
|
||||||
grid.Add((name, null, attrG.Weight, attrG.Weight, weight));
|
AddToolTipRow(grid, rowNum++, name, null, attrG.Weight, attrG.Weight, weight);
|
||||||
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
foreach (var g in groups.Where(g => g.Attr == attrG.Attr && g.Cult == attrG.Cult).OrderByDescending(g => g.Weight).ThenBy(g => g.SortId)) {
|
||||||
grid.Add((null, g.SortId, g.Weight, attrG.Weight, weight));
|
AddToolTipRow(grid, rowNum++, null, g.SortId, g.Weight, attrG.Weight, weight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -388,22 +395,7 @@ namespace Elwig.Services {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (text, grid.ToArray());
|
return (text, grid);
|
||||||
}
|
|
||||||
|
|
||||||
public static Grid GenerateToolTip((string?, string?, int, int?, int)[] data) {
|
|
||||||
var grid = new Grid();
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(10) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(60) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(80) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
||||||
grid.ColumnDefinitions.Add(new() { Width = new(50) });
|
|
||||||
int rowNum = 0;
|
|
||||||
foreach (var row in data) {
|
|
||||||
if (rowNum != 0 && row.Item2 == null) rowNum++;
|
|
||||||
AddToolTipRow(grid, rowNum++, row.Item1, row.Item2, row.Item3, row.Item4, row.Item5);
|
|
||||||
}
|
|
||||||
return grid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
Title="{Binding Title}" Height="600" MinHeight="550" Width="1000" MinWidth="860">
|
Title="{Binding Title}" Height="600" MinHeight="550" Width="1000" MinWidth="860"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:AreaComAdminViewModel/>
|
<vm:AreaComAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.FilterSeason = Utils.CurrentYear;
|
ViewModel.FilterSeason = Utils.CurrentYear;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,55 +51,42 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
var vm = ViewModel;
|
using var ctx = new AppDbContext();
|
||||||
var cursor = Mouse.OverrideCursor != null;
|
var (_, contractQuery, areaComQuery, filter) = await ViewModel.GetFilters(ctx);
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
var contracts = await contractQuery
|
||||||
var query = (vm.SearchQuery, vm.FilterSeason);
|
.Include(c => c.Kg.AtKg)
|
||||||
var (filter, contracts, areaComs, areaComCount, stat) = await Task.Run(async () => {
|
.Include(c => c.Rd!.Kg.AtKg)
|
||||||
using var ctx = new AppDbContext();
|
.Include(c => c.Revisions).ThenInclude(a => a.WineCult)
|
||||||
var (_, contractQuery, areaComQuery, filter) = await vm.GetFilters(ctx);
|
.Include(c => c.Revisions).ThenInclude(a => a.AreaComType.WineAttr)
|
||||||
var contracts = await contractQuery
|
.Include(c => c.Revisions).ThenInclude(a => a.AreaComType.WineVar)
|
||||||
.Include(c => c.Kg.AtKg)
|
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
||||||
.Include(c => c.Rd!.Kg.AtKg)
|
.ToListAsync();
|
||||||
.Include(c => c.Revisions).ThenInclude(a => a.WineCult)
|
var areaComs = await areaComQuery
|
||||||
.Include(c => c.Revisions).ThenInclude(a => a.AreaComType.WineAttr)
|
.Include(c => c.Contract.Kg.AtKg)
|
||||||
.Include(c => c.Revisions).ThenInclude(a => a.AreaComType.WineVar)
|
.Include(c => c.Contract.Rd!.Kg.AtKg)
|
||||||
.Include(c => c.Revisions).ThenInclude(a => a.Member)
|
.Include(a => a.WineCult)
|
||||||
.ToListAsync();
|
.Include(a => a.AreaComType.WineAttr)
|
||||||
var areaComs = await areaComQuery
|
.Include(a => a.AreaComType.WineVar)
|
||||||
.Include(c => c.Contract.Kg.AtKg)
|
.ToListAsync();
|
||||||
.Include(c => c.Contract.Rd!.Kg.AtKg)
|
|
||||||
.Include(a => a.WineCult)
|
|
||||||
.Include(a => a.AreaComType.WineAttr)
|
|
||||||
.Include(a => a.AreaComType.WineVar)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (filter.Count > 0 && contracts.Count > 0) {
|
if (filter.Count > 0 && contracts.Count > 0) {
|
||||||
var dict = contracts.AsParallel()
|
var dict = contracts.AsParallel()
|
||||||
.ToDictionary(d => d, d => d.SearchScore(vm.TextFilter))
|
.ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter))
|
||||||
.OrderByDescending(c => c.Value);
|
.OrderByDescending(c => c.Value);
|
||||||
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||||
contracts = [.. dict
|
contracts = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)];
|
.Select(a => a.Key)];
|
||||||
}
|
}
|
||||||
|
|
||||||
var areaComCount = await areaComQuery.CountAsync();
|
|
||||||
var season = await ctx.Seasons.FindAsync(await ctx.Seasons.MaxAsync(s => s.Year));
|
|
||||||
var stat = await AreaComService.GenerateToolTipData(areaComQuery, season?.MaxKgPerHa ?? 10_000);
|
|
||||||
|
|
||||||
return (filter, contracts, areaComs, areaComCount, stat);
|
|
||||||
});
|
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
|
||||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason)) return;
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(AreaCommitmentList, contracts,
|
ControlUtils.RenewItemsSource(AreaCommitmentList, contracts,
|
||||||
AreaCommitmentList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
AreaCommitmentList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
RefreshInputs();
|
RefreshInputs();
|
||||||
|
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
ViewModel.StatusAreaCommitments = $"{areaComCount:N0}";
|
ViewModel.StatusAreaCommitments = $"{await areaComQuery.CountAsync():N0}";
|
||||||
var (text, gridData) = stat;
|
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.StatusArea = text;
|
||||||
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
|
ViewModel.StatusAreaToolTip = AreaComService.GenerateToolTip(gridData);
|
||||||
} else {
|
} else {
|
||||||
@@ -166,11 +153,6 @@ namespace Elwig.Windows {
|
|||||||
ValidateRequiredInputs();
|
ValidateRequiredInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
new protected void ClearInputs(bool validate = false) {
|
|
||||||
ViewModel.ClearInputs();
|
|
||||||
base.ClearInputs(validate);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||||
await base.OnRenewContext(ctx);
|
await base.OnRenewContext(ctx);
|
||||||
|
|
||||||
@@ -285,10 +267,8 @@ namespace Elwig.Windows {
|
|||||||
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput) || InputHasChanged(MgNrInput)) {
|
if (InputHasChanged(AreaInput) || InputHasChanged(AreaComTypeInput) || InputHasChanged(MgNrInput)) {
|
||||||
var a = (RevisionList.SelectedItem as AreaCom)!;
|
var a = (RevisionList.SelectedItem as AreaCom)!;
|
||||||
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
var d = new AreaComModifyDialog(a.YearFrom, a.YearTo, a.Area, false, RevisionList.ItemsSource.Cast<object>().FirstOrDefault() != a);
|
||||||
if (d.ShowDialog() != true) {
|
if (d.ShowDialog() != true)
|
||||||
SaveButton.IsEnabled = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
yearTo = d.YearTo;
|
yearTo = d.YearTo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Stammdaten - Elwig" Height="520" MinHeight="400" Width="860" MinWidth="810">
|
Title="Stammdaten - Elwig" Height="520" MinHeight="400" Width="860" MinWidth="810"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Label">
|
<Style TargetType="Label">
|
||||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ namespace Elwig.Windows {
|
|||||||
ParameterExportEbicsAddress.IsEnabled = true;
|
ParameterExportEbicsAddress.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
xmlns:ScottPlot="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Auszahlung - Elwig" Height="700" Width="1500" MinWidth="1000" MinHeight="500"
|
Title="Auszahlung - Elwig" Height="700" Width="1500" MinWidth="1000" MinHeight="500"
|
||||||
|
Loaded="Window_Loaded"
|
||||||
Closing="Window_Closing">
|
Closing="Window_Closing">
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
|
|||||||
@@ -80,6 +80,9 @@ namespace Elwig.Windows {
|
|||||||
LockContext = true;
|
LockContext = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
|
}
|
||||||
|
|
||||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
|
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||||
if (HasChanged) {
|
if (HasChanged) {
|
||||||
var r = MessageBox.Show("Soll das Fenster wirklich geschlossen werden? Nicht gespeicherte Änderungen werden NICHT übernommen!", "Schließen bestätigen",
|
var r = MessageBox.Show("Soll das Fenster wirklich geschlossen werden? Nicht gespeicherte Änderungen werden NICHT übernommen!", "Schließen bestätigen",
|
||||||
|
|||||||
@@ -40,11 +40,8 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
|
protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
|
||||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
|
||||||
using var ctx = new AppDbContext();
|
using var ctx = new AppDbContext();
|
||||||
await OnRenewContext(ctx);
|
await OnRenewContext(ctx);
|
||||||
await OnInit(ctx);
|
|
||||||
Mouse.OverrideCursor = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async Task EnsureContextRenewed() {
|
protected async Task EnsureContextRenewed() {
|
||||||
@@ -54,8 +51,6 @@ namespace Elwig.Windows {
|
|||||||
_renewPending = false;
|
_renewPending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual protected async Task OnInit(AppDbContext ctx) { }
|
|
||||||
|
|
||||||
abstract protected Task OnRenewContext(AppDbContext ctx);
|
abstract protected Task OnRenewContext(AppDbContext ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="{Binding Title}" Height="720" Width="1150" MinHeight="720" MinWidth="1000">
|
Title="{Binding Title}" Height="720" Width="1150" MinHeight="720" MinWidth="1000"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryAdminViewModel/>
|
<vm:DeliveryAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -128,14 +128,14 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.EnableAllSeasons = true;
|
ViewModel.EnableAllSeasons = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
await base.OnInit(ctx);
|
|
||||||
OnSecondPassed(null, null);
|
OnSecondPassed(null, null);
|
||||||
SecondsTimer.Start();
|
SecondsTimer.Start();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
if (ViewModel.IsReceipt) {
|
if (ViewModel.IsReceipt) {
|
||||||
NewDeliveryButton_Click(null, null);
|
NewDeliveryButton_Click(null, null);
|
||||||
if (await ctx.Seasons.FindAsync(Utils.CurrentYear) == null) {
|
using var ctx = new AppDbContext();
|
||||||
|
if (ctx.Seasons.Find(Utils.CurrentYear) == null) {
|
||||||
MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n(Stammdaten -> Saisons -> Neu anlegen...)",
|
MessageBox.Show("Die Saison für das aktuelle Jahr wurde noch nicht erstellt. Neue Lieferungen können nicht abgespeichert werden.\n\n(Stammdaten -> Saisons -> Neu anlegen...)",
|
||||||
"Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Warning);
|
"Saison noch nicht erstellt", MessageBoxButton.OK, MessageBoxImage.Warning);
|
||||||
}
|
}
|
||||||
@@ -420,56 +420,43 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
var vm = ViewModel;
|
using var ctx = new AppDbContext();
|
||||||
var cursor = Mouse.OverrideCursor != null;
|
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await ViewModel.GetFilters(ctx);
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
var deliveries = await deliveryQuery
|
||||||
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterAllSeasons, vm.FilterTodayOnly);
|
.Include(d => d.Member.EmailAddresses)
|
||||||
var (filter, deliveries, deliveryPartsNum, varieties, members, stat) = await Task.Run(async () => {
|
.ToListAsync();
|
||||||
using var ctx = new AppDbContext();
|
deliveries.Reverse();
|
||||||
var (_, deliveryQuery, deliveryPartsQuery, predicate, filter) = await vm.GetFilters(ctx);
|
|
||||||
var deliveries = await deliveryQuery
|
|
||||||
.Include(d => d.Member.EmailAddresses)
|
|
||||||
.ToListAsync();
|
|
||||||
deliveries.Reverse();
|
|
||||||
|
|
||||||
if (filter.Count > 0 && deliveries.Count > 0) {
|
if (filter.Count > 0 && deliveries.Count > 0) {
|
||||||
var dict = deliveries.AsParallel()
|
var dict = deliveries.AsParallel()
|
||||||
.ToDictionary(d => d, d => d.SearchScore(vm.TextFilter))
|
.ToDictionary(d => d, d => d.SearchScore(ViewModel.TextFilter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.DateTime);
|
.ThenBy(a => a.Key.DateTime);
|
||||||
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
||||||
deliveries = [.. dict
|
deliveries = [.. dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)];
|
.Select(a => a.Key)];
|
||||||
}
|
}
|
||||||
|
|
||||||
var filteredParts = await deliveryPartsQuery
|
|
||||||
.Include(p => p.PartModifiers).ThenInclude(p => p.Modifier)
|
|
||||||
.GroupBy(p => new { p.Year, p.DId })
|
|
||||||
.ToDictionaryAsync(g => (g.Key.Year, g.Key.DId), g => g.ToList());
|
|
||||||
deliveries.ForEach(d => { d.FilteredParts = filteredParts.GetValueOrDefault((d.Year, d.DId)) ?? []; });
|
|
||||||
|
|
||||||
var deliveryPartsNum = await deliveryPartsQuery.CountAsync();
|
|
||||||
var varieties = await deliveryPartsQuery.Select(d => d.SortId).Distinct().ToListAsync();
|
|
||||||
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
|
||||||
var stat = await DeliveryService.GenerateToolTipData(deliveryPartsQuery);
|
|
||||||
|
|
||||||
return (filter, deliveries, deliveryPartsNum, varieties, members, stat);
|
|
||||||
});
|
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
|
||||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterAllSeasons, ViewModel.FilterTodayOnly)) return;
|
|
||||||
|
|
||||||
|
var filteredParts = await deliveryPartsQuery
|
||||||
|
.Include(p => p.PartModifiers).ThenInclude(p => p.Modifier)
|
||||||
|
.GroupBy(p => new { p.Year, p.DId })
|
||||||
|
.ToDictionaryAsync(g => (g.Key.Year, g.Key.DId), g => g.ToList());
|
||||||
|
deliveries.ForEach(d => { d.FilteredParts = filteredParts.GetValueOrDefault((d.Year, d.DId)) ?? []; });
|
||||||
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
ControlUtils.RenewItemsSource(DeliveryList, deliveries,
|
||||||
DeliveryList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryList_SelectionChanged, filter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
await RefreshDeliveryParts();
|
await RefreshDeliveryParts();
|
||||||
|
|
||||||
|
var members = await deliveryQuery.Select(d => d.Member).Distinct().IgnoreAutoIncludes().ToListAsync();
|
||||||
ViewModel.StatusMembers = $"{members.Count:N0}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
|
ViewModel.StatusMembers = $"{members.Count:N0}" + (members.Count > 0 && members.Count <= 4 ? $" ({string.Join(", ", members.Select(m => m.AdministrativeName))})" : "");
|
||||||
ViewModel.StatusDeliveries = $"{deliveries.Count:N0}";
|
ViewModel.StatusDeliveries = $"{deliveries.Count:N0}";
|
||||||
|
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
ViewModel.StatusDeliveries = $"{deliveries.Count:N0} ({deliveryPartsNum:N0})";
|
var deliveryParts = deliveryPartsQuery;
|
||||||
|
ViewModel.StatusDeliveries = $"{deliveries.Count:N0} ({await deliveryParts.CountAsync():N0})";
|
||||||
|
var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync();
|
||||||
ViewModel.StatusVarieties = $"{varieties.Count:N0}" + (varieties.Count > 0 && varieties.Count <= 10 ? $" ({string.Join(", ", varieties)})" : "");
|
ViewModel.StatusVarieties = $"{varieties.Count:N0}" + (varieties.Count > 0 && varieties.Count <= 10 ? $" ({string.Join(", ", varieties)})" : "");
|
||||||
var (wText, wData, gText, gData) = stat;
|
var (wText, wData, gText, gData) = await DeliveryService.GenerateToolTipData(deliveryParts);
|
||||||
ViewModel.StatusWeight = wText;
|
ViewModel.StatusWeight = wText;
|
||||||
ViewModel.StatusGradation = gText;
|
ViewModel.StatusGradation = gText;
|
||||||
(ViewModel.StatusWeightToolTip, ViewModel.StatusGradationToolTip) = DeliveryService.GenerateToolTip(wData, gData);
|
(ViewModel.StatusWeightToolTip, ViewModel.StatusGradationToolTip) = DeliveryService.GenerateToolTip(wData, gData);
|
||||||
|
|||||||
@@ -8,7 +8,8 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Anmeldungen - Elwig" Height="700" Width="980" MinWidth="600" MinHeight="400">
|
Title="Anmeldungen - Elwig" Height="700" Width="980" MinWidth="600" MinHeight="400"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryAncmtAdminViewModel/>
|
<vm:DeliveryAncmtAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ namespace Elwig.Windows {
|
|||||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||||
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
||||||
ViewModel.FilterOnlyUpcoming = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
|
ViewModel.FilterOnlyUpcoming = true;
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,46 +103,36 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
var vm = ViewModel;
|
using var ctx = new AppDbContext();
|
||||||
var cursor = Mouse.OverrideCursor != null;
|
var (_, deliveryAncmtQuery, filter) = await ViewModel.GetFilters(ctx);
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
var deliveryAncmts = await deliveryAncmtQuery
|
||||||
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterOnlyUpcoming, vm.FilterOnlyUpcoming);
|
.Include(a => a.Member.BillingAddress)
|
||||||
var (filter, deliveryAncmts, stat) = await Task.Run(async () => {
|
.Include(a => a.Schedule)
|
||||||
using var ctx = new AppDbContext();
|
.Include(a => a.Variety)
|
||||||
var (_, deliveryAncmtQuery, filter) = await vm.GetFilters(ctx);
|
.AsSplitQuery()
|
||||||
var deliveryAncmts = await deliveryAncmtQuery
|
.ToListAsync();
|
||||||
.Include(a => a.Member.BillingAddress)
|
|
||||||
.Include(a => a.Schedule)
|
|
||||||
.Include(a => a.Variety)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
||||||
var dict = deliveryAncmts.AsParallel()
|
var dict = deliveryAncmts.AsParallel()
|
||||||
.ToDictionary(a => a, a => a.SearchScore(filter))
|
.ToDictionary(a => a, a => a.SearchScore(filter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.Schedule.DateString)
|
.ThenBy(a => a.Key.Schedule.DateString)
|
||||||
.ThenBy(a => a.Key.Member.Name)
|
.ThenBy(a => a.Key.Member.Name)
|
||||||
.ThenBy(a => a.Key.Member.GivenName)
|
.ThenBy(a => a.Key.Member.GivenName)
|
||||||
.ThenBy(a => a.Key.Member.MgNr);
|
.ThenBy(a => a.Key.Member.MgNr);
|
||||||
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||||
deliveryAncmts = [.. dict
|
deliveryAncmts = dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)];
|
.Select(a => a.Key)
|
||||||
} else {
|
.ToList();
|
||||||
deliveryAncmts = [.. deliveryAncmts
|
} else {
|
||||||
.OrderBy(a => a.Schedule.DateString)
|
deliveryAncmts = deliveryAncmts
|
||||||
.ThenBy(a => a.Member.Name)
|
.OrderBy(a => a.Schedule.DateString)
|
||||||
.ThenBy(a => a.Member.GivenName)
|
.ThenBy(a => a.Member.Name)
|
||||||
.ThenBy(a => a.Member.MgNr)];
|
.ThenBy(a => a.Member.GivenName)
|
||||||
}
|
.ThenBy(a => a.Member.MgNr)
|
||||||
|
.ToList();
|
||||||
var stat = await DeliveryAncmtService.GenerateToolTipData(deliveryAncmtQuery);
|
}
|
||||||
|
|
||||||
return (filter, deliveryAncmts, stat);
|
|
||||||
});
|
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
|
||||||
if (query != (ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterOnlyUpcoming, ViewModel.FilterOnlyUpcoming)) return;
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryAncmtList, deliveryAncmts,
|
ControlUtils.RenewItemsSource(DeliveryAncmtList, deliveryAncmts,
|
||||||
DeliveryAncmtList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryAncmtList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
@@ -151,9 +141,9 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
ViewModel.StatusAncmts = $"{deliveryAncmts.Count:N0}";
|
ViewModel.StatusAncmts = $"{deliveryAncmts.Count:N0}";
|
||||||
if (filter.Count == 0) {
|
if (filter.Count == 0) {
|
||||||
var (text, data) = stat;
|
var (text, grid) = await DeliveryAncmtService.GenerateToolTip(deliveryAncmtQuery);
|
||||||
ViewModel.StatusWeight = text;
|
ViewModel.StatusWeight = text;
|
||||||
ViewModel.StatusWeightToolTip = DeliveryAncmtService.GenerateToolTip(data);
|
ViewModel.StatusWeightToolTip = grid;
|
||||||
} else {
|
} else {
|
||||||
ViewModel.StatusWeight = $"{deliveryAncmts.Sum(a => a.Weight):N0} kg";
|
ViewModel.StatusWeight = $"{deliveryAncmts.Sum(a => a.Weight):N0} kg";
|
||||||
ViewModel.StatusWeightToolTip = null;
|
ViewModel.StatusWeightToolTip = null;
|
||||||
|
|||||||
@@ -7,7 +7,8 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Leseplanung - Elwig" Height="600" Width="850" MinHeight="450" MinWidth="800">
|
Title="Leseplanung - Elwig" Height="600" Width="850" MinHeight="450" MinWidth="800"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:DeliveryScheduleAdminViewModel/>
|
<vm:DeliveryScheduleAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -30,49 +30,41 @@ namespace Elwig.Windows {
|
|||||||
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||||
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
||||||
ViewModel.FilterOnlyUpcoming = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
|
ViewModel.FilterOnlyUpcoming = true;
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
var vm = ViewModel;
|
using var ctx = new AppDbContext();
|
||||||
var cursor = Mouse.OverrideCursor != null;
|
var (_, deliveryScheduleQuery, filter) = await ViewModel.GetFilters(ctx);
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
var deliverySchedules = await deliveryScheduleQuery
|
||||||
var query = (vm.SearchQuery, vm.FilterSeason, vm.FilterOnlyUpcoming);
|
.Include(s => s.Varieties)
|
||||||
var deliverySchedules = await Task.Run(async () => {
|
.Include(s => s.Branch)
|
||||||
using var ctx = new AppDbContext();
|
.AsSplitQuery()
|
||||||
var (_, deliveryScheduleQuery, filter) = await vm.GetFilters(ctx);
|
.ToListAsync();
|
||||||
var deliverySchedules = await deliveryScheduleQuery
|
|
||||||
.Include(s => s.Varieties)
|
|
||||||
.Include(s => s.Branch)
|
|
||||||
.AsSplitQuery()
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (filter.Count > 0 && deliverySchedules.Count > 0) {
|
if (filter.Count > 0 && deliverySchedules.Count > 0) {
|
||||||
var dict = deliverySchedules.AsParallel()
|
var dict = deliverySchedules.AsParallel()
|
||||||
.ToDictionary(s => s, s => s.SearchScore(filter))
|
.ToDictionary(s => s, s => s.SearchScore(filter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.DateString)
|
.ThenBy(a => a.Key.DateString)
|
||||||
.ThenBy(a => a.Key.Branch.Name)
|
.ThenBy(a => a.Key.Branch.Name)
|
||||||
.ThenBy(a => a.Key.Description);
|
.ThenBy(a => a.Key.Description);
|
||||||
var threshold = dict.Max(a => a.Value) * 3 / 4;
|
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||||
deliverySchedules = [.. dict
|
deliverySchedules = dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)];
|
.Select(a => a.Key)
|
||||||
} else {
|
.ToList();
|
||||||
deliverySchedules = [.. deliverySchedules
|
} else {
|
||||||
.OrderBy(s => s.DateString)
|
deliverySchedules = deliverySchedules
|
||||||
.ThenBy(s => s.Branch.Name)
|
.OrderBy(s => s.DateString)
|
||||||
.ThenBy(s => s.Description)];
|
.ThenBy(s => s.Branch.Name)
|
||||||
}
|
.ThenBy(s => s.Description)
|
||||||
|
.ToList();
|
||||||
return deliverySchedules;
|
}
|
||||||
});
|
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
|
||||||
if (query != ((ViewModel.SearchQuery, ViewModel.FilterSeason, ViewModel.FilterOnlyUpcoming))) return;
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(DeliveryScheduleList, deliverySchedules,
|
ControlUtils.RenewItemsSource(DeliveryScheduleList, deliverySchedules,
|
||||||
DeliveryScheduleList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
DeliveryScheduleList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||||
Title="Elwig" Height="390" Width="520" ResizeMode="CanMinimize"
|
Title="Elwig" Height="390" Width="520" ResizeMode="CanMinimize"
|
||||||
Closing="Window_Closing">
|
Loaded="Window_Loaded" Closing="Window_Closing">
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<Style TargetType="Button">
|
<Style TargetType="Button">
|
||||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||||
|
|||||||
@@ -37,10 +37,11 @@ namespace Elwig.Windows {
|
|||||||
SyncButton.Visibility = App.Config.SyncUrl != null ? Visibility.Visible : Visibility.Hidden;
|
SyncButton.Visibility = App.Config.SyncUrl != null ? Visibility.Visible : Visibility.Hidden;
|
||||||
Menu_Database_Upload.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Database_Upload.IsEnabled = App.Config.SyncUrl != null;
|
||||||
Menu_Database_Download.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Database_Download.IsEnabled = App.Config.SyncUrl != null;
|
||||||
SeasonInput.Value = Utils.CurrentLastSeason;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
|
SeasonInput.Value = Utils.CurrentLastSeason;
|
||||||
|
|
||||||
if (Utils.HasInternetConnectivity()) {
|
if (Utils.HasInternetConnectivity()) {
|
||||||
CheckSync(200);
|
CheckSync(200);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:local="clr-namespace:Elwig.Windows"
|
xmlns:local="clr-namespace:Elwig.Windows"
|
||||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||||
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150">
|
Title="Mitglieder - Elwig" Height="700" Width="1250" MinHeight="650" MinWidth="1150"
|
||||||
|
Loaded="Window_Loaded">
|
||||||
<Window.DataContext>
|
<Window.DataContext>
|
||||||
<vm:MemberAdminViewModel/>
|
<vm:MemberAdminViewModel/>
|
||||||
</Window.DataContext>
|
</Window.DataContext>
|
||||||
|
|||||||
@@ -82,10 +82,10 @@ namespace Elwig.Windows {
|
|||||||
|
|
||||||
Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null;
|
||||||
Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null;
|
Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null;
|
||||||
ViewModel.ShowOnlyActiveMembers = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override async Task OnInit(AppDbContext ctx) {
|
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||||
|
ViewModel.ShowOnlyActiveMembers = true;
|
||||||
UpdateContactInfoVisibility();
|
UpdateContactInfoVisibility();
|
||||||
LockInputs();
|
LockInputs();
|
||||||
}
|
}
|
||||||
@@ -113,57 +113,46 @@ namespace Elwig.Windows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshList(bool updateSort = false) {
|
private async Task RefreshList(bool updateSort = false) {
|
||||||
var vm = ViewModel;
|
using var ctx = new AppDbContext();
|
||||||
var cursor = Mouse.OverrideCursor != null;
|
var (_, memberQuery, filter) = await ViewModel.GetFilters(ctx);
|
||||||
if (!cursor) Mouse.OverrideCursor = Cursors.Wait;
|
var members = await memberQuery
|
||||||
var query = (vm.SearchQuery, vm.ShowOnlyActiveMembers);
|
.Include(m => m.Branch)
|
||||||
var (members, totalMemberCount, totalBusinessShares) = await Task.Run(async () => {
|
.Include(m => m.DefaultWbKg!.AtKg)
|
||||||
using var ctx = new AppDbContext();
|
.Include(m => m.EmailAddresses)
|
||||||
var (_, memberQuery, filter) = await vm.GetFilters(ctx);
|
.Include(m => m.TelephoneNumbers)
|
||||||
var members = await memberQuery
|
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||||
.Include(m => m.Branch)
|
.Include(m => m.PostalDest.AtPlz!.Country)
|
||||||
.Include(m => m.DefaultWbKg!.AtKg)
|
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
||||||
.Include(m => m.EmailAddresses)
|
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
||||||
.Include(m => m.TelephoneNumbers)
|
.ToListAsync();
|
||||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.PostalDest.AtPlz!.Country)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Ort)
|
|
||||||
.Include(m => m.BillingAddress!.PostalDest.AtPlz!.Country)
|
|
||||||
.ToListAsync();
|
|
||||||
|
|
||||||
if (filter.Count > 0 && members.Count > 0) {
|
if (filter.Count > 0 && members.Count > 0) {
|
||||||
var dict = members.AsParallel()
|
var dict = members.AsParallel()
|
||||||
.ToDictionary(m => m, m => m.SearchScore(filter))
|
.ToDictionary(m => m, m => m.SearchScore(filter))
|
||||||
.OrderByDescending(a => a.Value)
|
.OrderByDescending(a => a.Value)
|
||||||
.ThenBy(a => a.Key.Name)
|
.ThenBy(a => a.Key.Name)
|
||||||
.ThenBy(a => a.Key.GivenName)
|
.ThenBy(a => a.Key.GivenName)
|
||||||
.ThenBy(a => a.Key.MgNr);
|
.ThenBy(a => a.Key.MgNr);
|
||||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||||
members = [.. dict
|
members = dict
|
||||||
.Where(a => a.Value > threshold)
|
.Where(a => a.Value > threshold)
|
||||||
.Select(a => a.Key)];
|
.Select(a => a.Key)
|
||||||
} else {
|
.ToList();
|
||||||
members = [.. members
|
} else {
|
||||||
.OrderBy(m => m.Name)
|
members = members
|
||||||
.ThenBy(m => m.GivenName)
|
.OrderBy(m => m.Name)
|
||||||
.ThenBy(m => m.MgNr)];
|
.ThenBy(m => m.GivenName)
|
||||||
}
|
.ThenBy(m => m.MgNr)
|
||||||
|
.ToList();
|
||||||
var totalMemberCount = await ctx.Members.CountAsync();
|
}
|
||||||
var totalBusinessShares = await ctx.Members.SumAsync(m => m.BusinessShares);
|
|
||||||
|
|
||||||
return (members, totalMemberCount, totalBusinessShares);
|
|
||||||
});
|
|
||||||
if (!cursor) Mouse.OverrideCursor = null;
|
|
||||||
if (query != (ViewModel.SearchQuery, ViewModel.ShowOnlyActiveMembers)) return;
|
|
||||||
|
|
||||||
ControlUtils.RenewItemsSource(MemberList, members,
|
ControlUtils.RenewItemsSource(MemberList, members,
|
||||||
MemberList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
MemberList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||||
if (updateSort && MemberList.SelectedItem != null)
|
if (updateSort && MemberList.SelectedItem != null)
|
||||||
MemberList.ScrollIntoView(MemberList.SelectedItem);
|
MemberList.ScrollIntoView(MemberList.SelectedItem);
|
||||||
|
|
||||||
ViewModel.StatusMembers = $"{members.Count:N0} ({totalMemberCount:N0})";
|
ViewModel.StatusMembers = $"{members.Count:N0} ({await ctx.Members.CountAsync():N0})";
|
||||||
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.BusinessShares):N0} ({totalBusinessShares:N0})";
|
ViewModel.StatusBusinessShares = $"{members.Sum(m => m.BusinessShares):N0} ({await ctx.Members.SumAsync(m => m.BusinessShares):N0})";
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshInputs(bool validate = false) {
|
private void RefreshInputs(bool validate = false) {
|
||||||
|
|||||||
Reference in New Issue
Block a user