[#78] DeliveryService: Add bulk actions for attributes and modifiers
All checks were successful
Test / Run tests (push) Successful in 1m42s
All checks were successful
Test / Run tests (push) Successful in 1m42s
This commit is contained in:
@@ -1180,5 +1180,104 @@ namespace Elwig.Services {
|
|||||||
await ctx.SaveChangesAsync();
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,11 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Liefermengen" x:Name="Menu_DeliveryDataList">
|
<MenuItem Header="Liefermengen" x:Name="Menu_DeliveryDataList">
|
||||||
<MenuItem x:Name="Menu_DeliveryDataList_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
<MenuItem x:Name="Menu_DeliveryDataList_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
||||||
Click="Menu_DeliveryDataList_SaveFilters_Click"/>
|
Click="Menu_DeliveryDataList_SaveFilters_Click">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="Statistik" x:Name="Menu_Statistics">
|
<MenuItem Header="Statistik" x:Name="Menu_Statistics">
|
||||||
<MenuItem Header="Qualitätsstatistik..." x:Name="Menu_Statistics_WineQuality">
|
<MenuItem Header="Qualitätsstatistik..." x:Name="Menu_Statistics_WineQuality">
|
||||||
@@ -162,7 +166,11 @@
|
|||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem x:Name="Menu_Statistics_Locality" Header="Lieferstatistik pro Ort...">
|
<MenuItem x:Name="Menu_Statistics_Locality" Header="Lieferstatistik pro Ort...">
|
||||||
<MenuItem x:Name="Menu_Statistic_Locality_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
<MenuItem x:Name="Menu_Statistic_Locality_SaveFilters" Header="...aus Filtern speichern... (Excel)"
|
||||||
Click="Menu_Statistic_Locality_SaveFilters_Click"/>
|
Click="Menu_Statistic_Locality_SaveFilters_Click">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem Header="BKI">
|
<MenuItem Header="BKI">
|
||||||
@@ -184,6 +192,23 @@
|
|||||||
<MenuItem x:Name="Menu_Export_UploadSeason" Header="...von Saison/Zweigstelle hochladen"
|
<MenuItem x:Name="Menu_Export_UploadSeason" Header="...von Saison/Zweigstelle hochladen"
|
||||||
Click="Menu_Export_UploadSeason_Click"/>
|
Click="Menu_Export_UploadSeason_Click"/>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem Header="Massenaktion">
|
||||||
|
<MenuItem x:Name="Menu_BulkAction_SetAttribute" Header="Attribut auf Lieferungen aus Filtern setzen...">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem x:Name="Menu_BulkAction_AddModifier" Header="Zu-/Abschlag auf Lieferungen aus Filtern hinzufügen...">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem x:Name="Menu_BulkAction_RemoveModifier" Header="Zu-/Abschlag auf Lieferungen aus Filtern entfernen...">
|
||||||
|
<MenuItem.Icon>
|
||||||
|
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/>
|
||||||
|
</MenuItem.Icon>
|
||||||
|
</MenuItem>
|
||||||
|
</MenuItem>
|
||||||
<MenuItem Header="Einstellungen">
|
<MenuItem Header="Einstellungen">
|
||||||
<MenuItem x:Name="Menu_Settings_EnableFreeEditing" Header="Freie Bearbeitung aktivieren"
|
<MenuItem x:Name="Menu_Settings_EnableFreeEditing" Header="Freie Bearbeitung aktivieren"
|
||||||
IsCheckable="True" Checked="Menu_Settings_EnableFreeEditing_Checked" Unchecked="Menu_Settings_EnableFreeEditing_Unchecked"/>
|
IsCheckable="True" Checked="Menu_Settings_EnableFreeEditing_Checked" Unchecked="Menu_Settings_EnableFreeEditing_Unchecked"/>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ using System.Threading.Tasks;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Elwig.Windows {
|
namespace Elwig.Windows {
|
||||||
@@ -283,6 +284,21 @@ namespace Elwig.Windows {
|
|||||||
private async void Menu_DeliveryDataList_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
|
private async void Menu_DeliveryDataList_SaveFilters_Click(object sender, RoutedEventArgs evt) =>
|
||||||
await ViewModel.GenerateDeliveryDataList(DeliveryService.ExportSubject.FromFilters, ExportMode.SaveList);
|
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) {
|
private void Menu_Settings_EnableFreeEditing_Checked(object sender, RoutedEventArgs evt) {
|
||||||
if (IsEditing || IsCreating) {
|
if (IsEditing || IsCreating) {
|
||||||
DateInput.IsReadOnly = false;
|
DateInput.IsReadOnly = false;
|
||||||
@@ -468,8 +484,10 @@ namespace Elwig.Windows {
|
|||||||
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
ViewModel.Title = $"Lieferungen - {ViewModel.FilterMember.AdministrativeName} - Elwig";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int year = 0;
|
||||||
Menu_Bki_SaveList.Items.Clear();
|
Menu_Bki_SaveList.Items.Clear();
|
||||||
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
|
foreach (var s in await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync()) {
|
||||||
|
if (s.Year > year) year = s.Year;
|
||||||
var i = new MenuItem {
|
var i = new MenuItem {
|
||||||
Header = $"Saison {s.Year}",
|
Header = $"Saison {s.Year}",
|
||||||
};
|
};
|
||||||
@@ -477,6 +495,37 @@ namespace Elwig.Windows {
|
|||||||
Menu_Bki_SaveList.Items.Add(i);
|
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();
|
await RefreshList();
|
||||||
var d = DeliveryList.SelectedItem as Delivery;
|
var d = DeliveryList.SelectedItem as Delivery;
|
||||||
var y = d?.Year ?? ViewModel.FilterSeason;
|
var y = d?.Year ?? ViewModel.FilterSeason;
|
||||||
|
|||||||
Reference in New Issue
Block a user