diff --git a/Elwig/Services/DeliveryService.cs b/Elwig/Services/DeliveryService.cs
index 9d63fda..b1e5a55 100644
--- a/Elwig/Services/DeliveryService.cs
+++ b/Elwig/Services/DeliveryService.cs
@@ -1180,5 +1180,104 @@ namespace Elwig.Services {
await ctx.SaveChangesAsync();
});
}
+
+ public static async Task<(int Year, int DId, int DPNr)[]> GetDidsFromFilters(this DeliveryAdminViewModel vm) {
+ using var ctx = new AppDbContext();
+ var (_, _, parts, _, _) = await vm.GetFilters(ctx);
+ return [.. (await parts.Select(p => new { p.Year, p.DId, p.DPNr }).ToListAsync()).Select(p => (p.Year, p.DId, p.DPNr))];
+ }
+
+ public static async Task BulkSetAttribute(this DeliveryAdminViewModel vm, string? attributeName) {
+ try {
+ string attrid;
+ if (attributeName == null) {
+ attrid = "NULL";
+ } else {
+ using var ctx = new AppDbContext();
+ var attr = await ctx.WineAttributes.Where(a => a.Name == attributeName).SingleAsync();
+ attrid = $"'{attr.AttrId}'";
+ }
+ var dids = await vm.GetDidsFromFilters();
+ var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) das Attribut\n'{attributeName}' gesetz werden?",
+ "Massenaktion: Attribut setzen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
+ if (res != MessageBoxResult.OK) return;
+
+ Mouse.OverrideCursor = Cursors.Wait;
+ await Task.Run(async () => {
+ using (var cnx = await AppDbContext.ConnectAsync()) {
+ await cnx.ExecuteBatch($"""
+ UPDATE delivery_part SET attrid = {attrid}
+ WHERE (year, did, dpnr) IN ({string.Join(", ", dids.Select(d => $"({d.Year},{d.DId},{d.DPNr})"))})
+ """);
+ }
+ App.HintContextChange();
+ });
+ } catch (Exception exc) {
+ MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
+ } finally {
+ Mouse.OverrideCursor = null;
+ }
+ }
+
+ public static async Task BulkAddModifier(this DeliveryAdminViewModel vm, string modifierName) {
+ try {
+ string modid;
+ using (var ctx = new AppDbContext()) {
+ var attr = await ctx.Modifiers.Where(a => a.Name == modifierName).FirstAsync();
+ modid = $"'{attr.ModId}'";
+ }
+
+ var dids = await vm.GetDidsFromFilters();
+ var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' hinzugefügt werden?",
+ "Massenaktion: Zu-/Abschlag hinzufügen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
+ if (res != MessageBoxResult.OK) return;
+
+ Mouse.OverrideCursor = Cursors.Wait;
+ await Task.Run(async () => {
+ using (var cnx = await AppDbContext.ConnectAsync()) {
+ await cnx.ExecuteBatch($"""
+ INSERT INTO delivery_part_modifier (year, did, dpnr, modid)
+ VALUES {string.Join(", ", dids.Select(d => $"({d.Year},{d.DId},{d.DPNr},{modid})"))}
+ ON CONFLICT DO NOTHING
+ """);
+ }
+ App.HintContextChange();
+ });
+ } catch (Exception exc) {
+ MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
+ } finally {
+ Mouse.OverrideCursor = null;
+ }
+ }
+
+ public static async Task BulkRemoveModifier(this DeliveryAdminViewModel vm, string modifierName) {
+ try {
+ string modid;
+ using (var ctx = new AppDbContext()) {
+ var attr = await ctx.Modifiers.Where(a => a.Name == modifierName).FirstAsync();
+ modid = $"'{attr.ModId}'";
+ }
+
+ var dids = await vm.GetDidsFromFilters();
+ var res = MessageBox.Show($"Soll wirklich für {dids.Length:N0} Teillieferung(en) der Zu-/Abschlag\n'{modifierName}' entfernt werden?",
+ "Massenaktion: Zu-/Abschlag entfernen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
+ if (res != MessageBoxResult.OK) return;
+
+ Mouse.OverrideCursor = Cursors.Wait;
+ await Task.Run(async () => {
+ using (var cnx = await AppDbContext.ConnectAsync()) {
+ await cnx.ExecuteBatch($"""
+ DELETE FROM delivery_part_modifier
+ WHERE (year, did, dpnr, modid) IN ({string.Join(", ", dids.Select(d => $"({d.Year},{d.DId},{d.DPNr},{modid})"))})
+ """);
+ }
+ App.HintContextChange();
+ });
+ } catch (Exception exc) {
+ MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
+ } finally {
+ Mouse.OverrideCursor = null;
+ }
+ }
}
}
diff --git a/Elwig/Windows/DeliveryAdminWindow.xaml b/Elwig/Windows/DeliveryAdminWindow.xaml
index 6c60e12..c3ba734 100644
--- a/Elwig/Windows/DeliveryAdminWindow.xaml
+++ b/Elwig/Windows/DeliveryAdminWindow.xaml
@@ -131,7 +131,11 @@
@@ -162,7 +166,11 @@
+ Click="Menu_Statistic_Locality_SaveFilters_Click">
+
+
+
+
@@ -184,6 +192,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Elwig/Windows/DeliveryAdminWindow.xaml.cs b/Elwig/Windows/DeliveryAdminWindow.xaml.cs
index 4f30a2d..98fc474 100644
--- a/Elwig/Windows/DeliveryAdminWindow.xaml.cs
+++ b/Elwig/Windows/DeliveryAdminWindow.xaml.cs
@@ -14,6 +14,7 @@ using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
+using System.Windows.Media;
using System.Windows.Threading;
namespace Elwig.Windows {
@@ -283,6 +284,21 @@ namespace Elwig.Windows {
private async void Menu_DeliveryDataList_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
await ViewModel.GenerateDeliveryDataList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
+ private async void Menu_BulkAction_SetAttribute_Click(object sender, RoutedEventArgs evt) {
+ if (sender is not MenuItem item) return;
+ await ViewModel.BulkSetAttribute(item.Header as string);
+ }
+
+ private async void Menu_BulkAction_AddModifier_Click(object sender, RoutedEventArgs evt) {
+ if (sender is not MenuItem item || item.Header is not string name) return;
+ await ViewModel.BulkAddModifier(name);
+ }
+
+ private async void Menu_BulkAction_RemoveModifier_Click(object sender, RoutedEventArgs evt) {
+ if (sender is not MenuItem item || item.Header is not string name) return;
+ await ViewModel.BulkRemoveModifier(name);
+ }
+
private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) {
if (IsEditing || IsCreating) {
DateInput.IsReadOnly = false;
@@ -468,8 +484,10 @@ namespace Elwig.Windows {
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
}
+ int year = 0;
Menu_Bki_SaveList.Items.Clear();
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
+ if (s.Year > year) year = s.Year;
var i = new MenuItem {
Header = $"Saison {s.Year}",
};
@@ -477,6 +495,37 @@ namespace Elwig.Windows {
Menu_Bki_SaveList.Items.Add(i);
}
+ var font = new FontFamily("Segoe MDL2 Assets");
+ Menu_BulkAction_SetAttribute.Items.Clear();
+ var noAttr = new MenuItem {
+ Header = new TextBlock() { Text = "Kein Attribut", FontStyle = FontStyles.Italic },
+ Icon = new TextBlock() { Text = "\ue75c", FontFamily = font, FontSize = 16 },
+ };
+ noAttr.Click += Menu_BulkAction_SetAttribute_Click;
+ Menu_BulkAction_SetAttribute.Items.Add(noAttr);
+ foreach (var attr in await ctx.WineAttributes.OrderBy(a => a.AttrId).ToListAsync()) {
+ var i = new MenuItem {
+ Header = attr.Name,
+ };
+ i.Click += Menu_BulkAction_SetAttribute_Click;
+ Menu_BulkAction_SetAttribute.Items.Add(i);
+ }
+
+ Menu_BulkAction_AddModifier.Items.Clear();
+ Menu_BulkAction_RemoveModifier.Items.Clear();
+ foreach (var mod in await ctx.Modifiers.Where(m => m.Year == year).OrderBy(m => m.ModId).ToListAsync()) {
+ var i1 = new MenuItem {
+ Header = mod.Name,
+ };
+ i1.Click += Menu_BulkAction_AddModifier_Click;
+ Menu_BulkAction_AddModifier.Items.Add(i1);
+ var i2 = new MenuItem {
+ Header = mod.Name,
+ };
+ i2.Click += Menu_BulkAction_RemoveModifier_Click;
+ Menu_BulkAction_RemoveModifier.Items.Add(i2);
+ }
+
await RefreshList();
var d = DeliveryList.SelectedItem as Delivery;
var y = d?.Year ?? ViewModel.FilterSeason;