From 36c1bd35a7b6674dbb9f4fd993428584ac6d18e8 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Sat, 27 Jul 2024 18:44:35 +0200 Subject: [PATCH] [#3] MemberAdminWindow: Add Export item in menu --- Elwig/Helpers/Export/ElwigData.cs | 13 ++++--- Elwig/Services/MemberService.cs | 48 +++++++++++++++++++++++++ Elwig/Windows/MemberAdminWindow.xaml | 11 ++++++ Elwig/Windows/MemberAdminWindow.xaml.cs | 17 +++++++++ 4 files changed, 84 insertions(+), 5 deletions(-) diff --git a/Elwig/Helpers/Export/ElwigData.cs b/Elwig/Helpers/Export/ElwigData.cs index 03af552..2599516 100644 --- a/Elwig/Helpers/Export/ElwigData.cs +++ b/Elwig/Helpers/Export/ElwigData.cs @@ -8,6 +8,7 @@ using System.Text.Json.Nodes; using System.Linq; using System.Windows; using Microsoft.EntityFrameworkCore; +using System.Text.Json; namespace Elwig.Helpers.Export { public static class ElwigData { @@ -16,6 +17,8 @@ namespace Elwig.Helpers.Export { public static readonly string ImportedTxt = Path.Combine(App.DataPath, "imported.txt"); + private static readonly JsonSerializerOptions JsonOpts = new() { Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; + public static async Task GetImportedFiles() { try { return await File.ReadAllLinesAsync(ImportedTxt, Utils.UTF8); @@ -338,7 +341,7 @@ namespace Elwig.Helpers.Export { ["parts"] = Deliveries.Value.Deliveries.Sum(d => d.Parts.Count), ["filters"] = new JsonArray(Deliveries.Value.Filters.Select(f => (JsonNode)f).ToArray()), }; - await writer.WriteAsync(obj.ToJsonString()); + await writer.WriteAsync(obj.ToJsonString(JsonOpts)); } // TODO encrypt files @@ -346,21 +349,21 @@ namespace Elwig.Helpers.Export { var json = zip.CreateEntry("members.json", CompressionLevel.SmallestSize); using var writer = new StreamWriter(json.Open(), Utils.UTF8); foreach (var m in Members.Value.Members) { - await writer.WriteLineAsync(m.ToJson().ToJsonString()); + await writer.WriteLineAsync(m.ToJson().ToJsonString(JsonOpts)); } } if (AreaComs != null) { var json = zip.CreateEntry("area_commitments.json", CompressionLevel.SmallestSize); using var writer = new StreamWriter(json.Open(), Utils.UTF8); foreach (var c in AreaComs.Value.AreaComs) { - await writer.WriteLineAsync(c.ToJson().ToJsonString()); + await writer.WriteLineAsync(c.ToJson().ToJsonString(JsonOpts)); } } if (Deliveries != null) { var json = zip.CreateEntry("deliveries.json", CompressionLevel.SmallestSize); using var writer = new StreamWriter(json.Open(), Utils.UTF8); foreach (var d in Deliveries.Value.Deliveries) { - await writer.WriteLineAsync(d.ToJson().ToJsonString()); + await writer.WriteLineAsync(d.ToJson().ToJsonString(JsonOpts)); } } } @@ -606,7 +609,7 @@ namespace Elwig.Helpers.Export { Temperature = p["temperature"]?.AsValue().GetValue(), Acid = p["acid"]?.AsValue().GetValue(), ScaleId = p["scale_id"]?.AsValue().GetValue(), - WeighingData = p["weighing_data"]?.AsObject().ToJsonString(), + WeighingData = p["weighing_data"]?.AsObject().ToJsonString(JsonOpts), WeighingReason = p["weighing_reason"]?.AsValue().GetValue(), }).ToList(), json["parts"]!.AsArray().SelectMany(p => p!["modids"]!.AsArray().Select(m => new DeliveryPartModifier { Year = year, diff --git a/Elwig/Services/MemberService.cs b/Elwig/Services/MemberService.cs index c001148..6afc96e 100644 --- a/Elwig/Services/MemberService.cs +++ b/Elwig/Services/MemberService.cs @@ -13,6 +13,7 @@ using Elwig.Models.Dtos; using Elwig.Helpers.Export; using Microsoft.Win32; using Elwig.ViewModels; +using System.IO; namespace Elwig.Services { public static class MemberService { @@ -409,6 +410,53 @@ namespace Elwig.Services { } Mouse.OverrideCursor = null; } + } else if (exportMode == ExportMode.Export) { + var d = new SaveFileDialog() { + FileName = $"Mitglieder_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.zip", + DefaultExt = "zip", + Filter = "ZIP-Datei (*.zip)|*.zip", + Title = $"{MemberList.Name} speichern unter - Elwig" + }; + if (d.ShowDialog() == true) { + Mouse.OverrideCursor = Cursors.AppStarting; + try { + await ElwigData.Export(d.FileName, await query + .OrderBy(m => m.MgNr) + .Include(m => m.BillingAddress) + .Include(m => m.TelephoneNumbers) + .Include(m => m.EmailAddresses) + .AsSplitQuery() + .ToListAsync(), filterNames); + } catch (Exception exc) { + MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); + } + Mouse.OverrideCursor = null; + } + } else if (exportMode == ExportMode.Upload && App.Config.SyncUrl != null) { + Mouse.OverrideCursor = Cursors.AppStarting; + try { + var filename = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{App.ZwstId}.zip"; + var path = Path.Combine(App.TempPath, filename); + var list = await query + .OrderBy(m => m.MgNr) + .Include(m => m.BillingAddress) + .Include(m => m.TelephoneNumbers) + .Include(m => m.EmailAddresses) + .AsSplitQuery() + .ToListAsync(); + if (list.Count == 0) { + MessageBox.Show("Es wurden keine Mitglieder zum Hochladen ausgewählt!", "Mitglieder hochladen", + MessageBoxButton.OK, MessageBoxImage.Error); + } else { + await ElwigData.Export(path, list, filterNames); + await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); + MessageBox.Show($"Mitglieder erfolgreich hochgeladen!", "Mitglieder hochgeladen", + MessageBoxButton.OK, MessageBoxImage.Information); + } + } catch (Exception exc) { + MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); + } + Mouse.OverrideCursor = null; } else { Mouse.OverrideCursor = Cursors.AppStarting; try { diff --git a/Elwig/Windows/MemberAdminWindow.xaml b/Elwig/Windows/MemberAdminWindow.xaml index 78fa1bb..26a041a 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml +++ b/Elwig/Windows/MemberAdminWindow.xaml @@ -124,6 +124,17 @@ IsCheckable="True" IsChecked="{Binding MemberListOrderByOrt, Mode=TwoWay}" Click="Menu_List_Order_Click"/> + + + + + + + diff --git a/Elwig/Windows/MemberAdminWindow.xaml.cs b/Elwig/Windows/MemberAdminWindow.xaml.cs index d901503..8f449bf 100644 --- a/Elwig/Windows/MemberAdminWindow.xaml.cs +++ b/Elwig/Windows/MemberAdminWindow.xaml.cs @@ -79,6 +79,9 @@ namespace Elwig.Windows { case 1: ViewModel.MemberListOrderByName = true; break; case 2: ViewModel.MemberListOrderByOrt = true; break; } + + Menu_Export_UploadFilters.IsEnabled = App.Config.SyncUrl != null; + Menu_Export_UploadAll.IsEnabled = App.Config.SyncUrl != null; } private void Window_Loaded(object sender, RoutedEventArgs evt) { @@ -561,6 +564,20 @@ namespace Elwig.Windows { private async void Menu_List_SavePdfAll_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateMemberList(2, ExportMode.SavePdf); } private async void Menu_List_PrintAll_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateMemberList(2, ExportMode.Print); } + private async void Menu_Export_ExportAll_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateMemberList(2, ExportMode.Export); } + private async void Menu_Export_ExportFilters_Click(object sender, RoutedEventArgs evt) { await ViewModel.GenerateMemberList(1, ExportMode.Export); } + + private async void Menu_Export_UploadAll_Click(object sender, RoutedEventArgs evt) { + if (App.Config.SyncUrl == null) return; + await ViewModel.GenerateMemberList(2, ExportMode.Upload); + } + + private async void Menu_Export_UploadFilters_Click(object sender, RoutedEventArgs evt) { + if (App.Config.SyncUrl == null) return; + await ViewModel.GenerateMemberList(1, ExportMode.Upload); + } + + private async void Menu_List_Order_Click(object sender, RoutedEventArgs evt) { Menu_List.IsSubmenuOpen = true; if (sender == Menu_List_OrderMgNr) {