Compare commits
	
		
			9 Commits
		
	
	
		
			dev
			...
			98f8907817
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 98f8907817 | |||
| 44dcc5e19f | |||
| d7012ebfa1 | |||
| a9b5317e79 | |||
| f02598760f | |||
| 4b8cd2a0d7 | |||
| 104798d4f2 | |||
| 4653a4f129 | |||
| 07f9a0f522 | 
							
								
								
									
										17
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -2,6 +2,23 @@ | |||||||
| Changelog | Changelog | ||||||
| ========= | ========= | ||||||
|  |  | ||||||
|  | [v1.0.0.4][v1.0.0.4] (2025-09-01) {#v1.0.0.4} | ||||||
|  | --------------------------------------------- | ||||||
|  |  | ||||||
|  | ### Behobene Fehler {#v1.0.0.4-bugfixes} | ||||||
|  |  | ||||||
|  | * Absturz beim Verschicken von einzelnen E-Mails außerhalb des Rundschreiben-Fensters (`MailWindow`) behoben. (07f9a0f522) | ||||||
|  |  | ||||||
|  | ### Sonstiges {#v1.0.0.4-misc} | ||||||
|  |  | ||||||
|  | * Ladezeit des Fehler-Protokoll-Fensters (`LogWindow`) verbessert. (4653a4f129) | ||||||
|  | * Im Übernahme-Fenster (`DeliveryAdminWindow`) ist es nun möglich die Qualitätsstufe zu verändern. (104798d4f2) | ||||||
|  |  | ||||||
|  | [v1.0.0.4]: https://git.necronda.net/winzer/elwig/releases/tag/v1.0.0.4 | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| [v1.0.0.3][v1.0.0.3] (2025-08-11) {#v1.0.0.3} | [v1.0.0.3][v1.0.0.3] (2025-08-11) {#v1.0.0.3} | ||||||
| --------------------------------------------- | --------------------------------------------- | ||||||
|  |  | ||||||
|   | |||||||
| @@ -115,6 +115,16 @@ namespace Elwig { | |||||||
|                 BranchNum = branches.Count; |                 BranchNum = branches.Count; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             if (Config.WeighingMode == null) { | ||||||
|  |                 if (App.Client.IsMatzen || App.Client.IsWolkersdorf) { | ||||||
|  |                     Config.WeighingMode = WeighingMode.Net; | ||||||
|  |                 } else if (App.Client.IsHaugsdorf || App.Client.IsSitzendorf) { | ||||||
|  |                     Config.WeighingMode = WeighingMode.Box; | ||||||
|  |                 } else if (App.Client.IsBaden || App.Client.IsGrInzersdorf) { | ||||||
|  |                     Config.WeighingMode = WeighingMode.Gross; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|             Utils.RunBackground("Temp File Cleanup", () => { |             Utils.RunBackground("Temp File Cleanup", () => { | ||||||
|                 Utils.CleanupTempFiles(); |                 Utils.CleanupTempFiles(); | ||||||
|                 return Task.CompletedTask; |                 return Task.CompletedTask; | ||||||
| @@ -242,7 +252,9 @@ namespace Elwig { | |||||||
|  |  | ||||||
|         public static async Task ReplaceDatabase(string filename) { |         public static async Task ReplaceDatabase(string filename) { | ||||||
|             try { |             try { | ||||||
|                 await ElwigData.ImportDatabase(filename); |                 await Task.Run(async () => { | ||||||
|  |                     await Database.Import(filename); | ||||||
|  |                 }); | ||||||
|                 MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information); |                 MessageBox.Show("Das Ersetzen war erfolgreich!\n\nBitte starten Sie Elwig neu!", "Datenbank ersetzen", MessageBoxButton.OK, MessageBoxImage.Information); | ||||||
|                 ForceShutdown = true; |                 ForceShutdown = true; | ||||||
|                 Current.Shutdown(); |                 Current.Shutdown(); | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
|     <UseWPF>true</UseWPF> |     <UseWPF>true</UseWPF> | ||||||
|     <PreserveCompilationContext>true</PreserveCompilationContext> |     <PreserveCompilationContext>true</PreserveCompilationContext> | ||||||
|     <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon> |     <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon> | ||||||
|     <Version>1.0.0.3</Version> |     <Version>1.0.0.4</Version> | ||||||
|     <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> |     <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> | ||||||
|     <AllowUnsafeBlocks>true</AllowUnsafeBlocks> |     <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||||
|     <ApplicationManifest>app.manifest</ApplicationManifest> |     <ApplicationManifest>app.manifest</ApplicationManifest> | ||||||
| @@ -25,19 +25,19 @@ | |||||||
|     <PackageReference Include="LinqKit" Version="1.3.8" /> |     <PackageReference Include="LinqKit" Version="1.3.8" /> | ||||||
|     <PackageReference Include="MailKit" Version="4.13.0" /> |     <PackageReference Include="MailKit" Version="4.13.0" /> | ||||||
|     <PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" /> |     <PackageReference Include="Microsoft.AspNetCore.Razor.Language" Version="6.0.36" /> | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.8" /> |     <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="9.0.9" /> | ||||||
|     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.8" /> |     <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.9" /> | ||||||
|     <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.8" /> |     <PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="9.0.9" /> | ||||||
|     <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3405.78" /> |     <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3485.44" /> | ||||||
|     <PackageReference Include="NJsonSchema" Version="11.4.0" /> |     <PackageReference Include="NJsonSchema" Version="11.4.0" /> | ||||||
|     <PackageReference Include="PdfiumViewer" Version="2.13.0" /> |     <PackageReference Include="PdfiumViewer" Version="2.13.0" /> | ||||||
|     <PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" /> |     <PackageReference Include="PdfiumViewer.Native.x86_64.no_v8-no_xfa" Version="2018.4.8.256" /> | ||||||
|     <PackageReference Include="RazorLight" Version="2.3.1" /> |     <PackageReference Include="RazorLight" Version="2.3.1" /> | ||||||
|     <PackageReference Include="ScottPlot.WPF" Version="5.0.55" /> |     <PackageReference Include="ScottPlot.WPF" Version="5.0.56" /> | ||||||
|     <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.1" /> |     <PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.2" /> | ||||||
|     <PackageReference Include="System.IO.Hashing" Version="9.0.8" /> |     <PackageReference Include="System.IO.Hashing" Version="9.0.9" /> | ||||||
|     <PackageReference Include="System.IO.Ports" Version="9.0.8" /> |     <PackageReference Include="System.IO.Ports" Version="9.0.9" /> | ||||||
|     <PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.8" /> |     <PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.9" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|  |  | ||||||
| </Project> | </Project> | ||||||
|   | |||||||
| @@ -19,14 +19,6 @@ namespace Elwig.Helpers { | |||||||
|         public bool IsSitzendorf => IsWinzerkeller && App.ZwstId == "S"; |         public bool IsSitzendorf => IsWinzerkeller && App.ZwstId == "S"; | ||||||
|         public bool IsGrInzersdorf => IsWeinland; |         public bool IsGrInzersdorf => IsWeinland; | ||||||
|  |  | ||||||
|         public bool HasNetWeighing(string? zwstId) => IsMatzen || (IsWinzerkeller && zwstId == "W"); |  | ||||||
|         public bool HasNetWeighing(Branch? b) => HasNetWeighing(b?.ZwstId); |  | ||||||
|         public bool HasNetWeighing() => HasNetWeighing(App.ZwstId); |  | ||||||
|  |  | ||||||
|         public bool HasBoxWeighing(string? zwstId) => IsWinzerkeller && (zwstId != "W"); |  | ||||||
|         public bool HasBoxWeighing(Branch? b) => HasBoxWeighing(b?.ZwstId); |  | ||||||
|         public bool HasBoxWeighing() => HasBoxWeighing(App.ZwstId); |  | ||||||
|  |  | ||||||
|         public string NameToken; |         public string NameToken; | ||||||
|         public string NameShort; |         public string NameShort; | ||||||
|         public string Name; |         public string Name; | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| @@ -5,6 +6,8 @@ using Microsoft.Extensions.Configuration; | |||||||
|  |  | ||||||
| namespace Elwig.Helpers { | namespace Elwig.Helpers { | ||||||
|  |  | ||||||
|  |     public enum WeighingMode { Gross, Net, Box } | ||||||
|  |  | ||||||
|     public record struct ScaleConfig { |     public record struct ScaleConfig { | ||||||
|         public string Id; |         public string Id; | ||||||
|         public string? Type; |         public string? Type; | ||||||
| @@ -41,6 +44,7 @@ namespace Elwig.Helpers { | |||||||
|         public string DatabaseFile = App.DataPath + "database.sqlite3"; |         public string DatabaseFile = App.DataPath + "database.sqlite3"; | ||||||
|         public string? DatabaseLog = null; |         public string? DatabaseLog = null; | ||||||
|         public string? Branch = null; |         public string? Branch = null; | ||||||
|  |         public WeighingMode? WeighingMode; | ||||||
|         public string? UpdateUrl = null; |         public string? UpdateUrl = null; | ||||||
|         public bool UpdateAuto = false; |         public bool UpdateAuto = false; | ||||||
|         public string? SyncUrl = null; |         public string? SyncUrl = null; | ||||||
| @@ -74,6 +78,8 @@ namespace Elwig.Helpers { | |||||||
|             DatabaseLog = log != null ? Path.Combine(Path.GetDirectoryName(FileName) ?? App.DataPath, log) : null; |             DatabaseLog = log != null ? Path.Combine(Path.GetDirectoryName(FileName) ?? App.DataPath, log) : null; | ||||||
|             Branch = config["general:branch"]; |             Branch = config["general:branch"]; | ||||||
|             Debug = TrueValues.Contains(config["general:debug"]?.ToLower()); |             Debug = TrueValues.Contains(config["general:debug"]?.ToLower()); | ||||||
|  |             var weighing = config["general:weighing"]; | ||||||
|  |             WeighingMode = weighing != null && Enum.TryParse<WeighingMode>(weighing, true, out var w) ? w : null; | ||||||
|             UpdateUrl = config["update:url"]; |             UpdateUrl = config["update:url"]; | ||||||
|             UpdateAuto = TrueValues.Contains(config["update:auto"]?.ToLower()); |             UpdateAuto = TrueValues.Contains(config["update:auto"]?.ToLower()); | ||||||
|             SyncUrl = config["sync:url"]; |             SyncUrl = config["sync:url"]; | ||||||
|   | |||||||
							
								
								
									
										188
									
								
								Elwig/Helpers/Export/Database.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										188
									
								
								Elwig/Helpers/Export/Database.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,188 @@ | |||||||
|  | using System; | ||||||
|  | using System.Collections.Generic; | ||||||
|  | using System.IO; | ||||||
|  | using System.IO.Compression; | ||||||
|  | using System.Threading.Tasks; | ||||||
|  |  | ||||||
|  | namespace Elwig.Helpers.Export { | ||||||
|  |     public static class Database { | ||||||
|  |  | ||||||
|  |         public static async Task ExportSqlite(string filename, bool zipFile) { | ||||||
|  |             if (zipFile) { | ||||||
|  |                 File.Delete(filename); | ||||||
|  |                 using var zip = ZipFile.Open(filename, ZipArchiveMode.Create); | ||||||
|  |                 await zip.CheckIntegrity(); | ||||||
|  |                 var db = zip.CreateEntryFromFile(App.Config.DatabaseFile, "database.sqlite3", CompressionLevel.SmallestSize); | ||||||
|  |             } else { | ||||||
|  |                 File.Copy(App.Config.DatabaseFile, filename, true); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task ExportSql(string filename, bool zipFile) { | ||||||
|  |             if (zipFile) { | ||||||
|  |                 File.Delete(filename); | ||||||
|  |                 using var zip = ZipFile.Open(filename, ZipArchiveMode.Create); | ||||||
|  |                 var entry = zip.CreateEntry("database.sql", CompressionLevel.SmallestSize); | ||||||
|  |                 using var stream = entry.Open(); | ||||||
|  |                 using var writer = new StreamWriter(stream, Utils.UTF8); | ||||||
|  |                 await ExportSql(writer); | ||||||
|  |             } else { | ||||||
|  |                 using var stream = File.OpenWrite(filename); | ||||||
|  |                 using var writer = new StreamWriter(stream, Utils.UTF8); | ||||||
|  |                 await ExportSql(writer); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task ExportSql(StreamWriter writer) { | ||||||
|  |             using var cnx = await AppDbContext.ConnectAsync(); | ||||||
|  |  | ||||||
|  |             var tables = new List<(string Name, string Sql)>(); | ||||||
|  |             using (var cmd = cnx.CreateCommand()) { | ||||||
|  |                 cmd.CommandText = "SELECT name, sql FROM sqlite_schema WHERE type = 'table'"; | ||||||
|  |                 using var reader = await cmd.ExecuteReaderAsync(); | ||||||
|  |                 while (await reader.ReadAsync()) { | ||||||
|  |                     tables.Add((reader.GetString(0), reader.GetString(1))); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             var applId = (long?)await AppDbContext.ExecuteScalar(cnx, "PRAGMA application_id") ?? 0; | ||||||
|  |             var userVers = (long?)await AppDbContext.ExecuteScalar(cnx, "PRAGMA user_version") ?? 0; | ||||||
|  |             var schemaVers = (long?)await AppDbContext.ExecuteScalar(cnx, "PRAGMA schema_version") ?? 0; | ||||||
|  |  | ||||||
|  |             await writer.WriteLineAsync($"-- Elwig database dump, {DateTime.Now:yyyy-MM-dd, HH:mm:ss}"); | ||||||
|  |             await writer.WriteLineAsync($"-- {Environment.MachineName}, Zwst. {App.BranchName}, {App.Client.Name}"); | ||||||
|  |             await writer.WriteLineAsync("BEGIN TRANSACTION;"); | ||||||
|  |             await writer.WriteLineAsync("PRAGMA foreign_keys=OFF;"); | ||||||
|  |             await writer.WriteLineAsync($"PRAGMA application_id=0x{applId:X8};"); | ||||||
|  |             await writer.WriteLineAsync($"PRAGMA user_version=0x{userVers:X8};"); | ||||||
|  |  | ||||||
|  |             foreach (var t in tables) { | ||||||
|  |                 await writer.WriteAsync(t.Sql); | ||||||
|  |                 await writer.WriteLineAsync(";"); | ||||||
|  |  | ||||||
|  |                 var columnNames = new List<string>(); | ||||||
|  |                 using (var cmd = cnx.CreateCommand()) { | ||||||
|  |                     cmd.CommandText = $"PRAGMA table_info({t.Name})"; | ||||||
|  |                     using var reader = await cmd.ExecuteReaderAsync(); | ||||||
|  |                     while (await reader.ReadAsync()) { | ||||||
|  |                         columnNames.Add(reader.GetString(1)); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 using (var cmd = cnx.CreateCommand()) { | ||||||
|  |                     cmd.CommandText = $"SELECT {string.Join(',', columnNames)} FROM {t.Name}"; | ||||||
|  |                     using var reader = await cmd.ExecuteReaderAsync(); | ||||||
|  |                     var columns = await reader.GetColumnSchemaAsync(); | ||||||
|  |                     var values = new object[reader.FieldCount]; | ||||||
|  |                     while (await reader.ReadAsync()) { | ||||||
|  |                         await writer.WriteAsync($"INSERT INTO {t.Name} VALUES ("); | ||||||
|  |  | ||||||
|  |                         reader.GetValues(values); | ||||||
|  |                         for (int i = 0; i < columns.Count; i++) { | ||||||
|  |                             var c = columns[i]; | ||||||
|  |                             var v = values[i]; | ||||||
|  |                             if (i > 0) await writer.WriteAsync(","); | ||||||
|  |                             if (v == null || v is DBNull) { | ||||||
|  |                                 await writer.WriteAsync("NULL"); | ||||||
|  |                             } else if (c.DataTypeName == "TEXT") { | ||||||
|  |                                 await writer.WriteAsync($"'{v.ToString()?.Replace("'", "''")}'"); | ||||||
|  |                             } else { | ||||||
|  |                                 await writer.WriteAsync(v.ToString()?.Replace(',', '.')); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         await writer.WriteLineAsync(");"); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             using (var cmd = cnx.CreateCommand()) { | ||||||
|  |                 cmd.CommandText = "SELECT sql FROM sqlite_schema WHERE type != 'table' AND sql IS NOT NULL"; | ||||||
|  |                 using var reader = await cmd.ExecuteReaderAsync(); | ||||||
|  |                 while (await reader.ReadAsync()) { | ||||||
|  |                     await writer.WriteAsync(reader.GetString(0)); | ||||||
|  |                     await writer.WriteLineAsync(";"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             await writer.WriteLineAsync($"PRAGMA schema_version={schemaVers};"); | ||||||
|  |             await writer.WriteLineAsync("PRAGMA foreign_keys=ON;"); | ||||||
|  |             await writer.WriteLineAsync("COMMIT;"); | ||||||
|  |             await writer.WriteLineAsync("VACUUM;"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task Import(string filename) { | ||||||
|  |             if (filename.EndsWith(".sql")) { | ||||||
|  |                 await ImportSql(filename, false); | ||||||
|  |             } else if (filename.EndsWith(".sql.zip")) { | ||||||
|  |                 await ImportSql(filename, true); | ||||||
|  |             } else if (filename.EndsWith(".sqlite3")) { | ||||||
|  |                 await ImportSqlite(filename, false); | ||||||
|  |             } else if (filename.EndsWith(".sqlite3.zip")) { | ||||||
|  |                 await ImportSqlite(filename, true); | ||||||
|  |             } else { | ||||||
|  |                 throw new ArgumentException($"Unknown file extension for importing: '{filename}'"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task ImportSql(string filename, bool zipFile = false) { | ||||||
|  |             if (zipFile) { | ||||||
|  |                 using var zip = ZipFile.Open(filename, ZipArchiveMode.Read); | ||||||
|  |                 await zip.CheckIntegrity(); | ||||||
|  |                 foreach (var entry in zip.Entries) { | ||||||
|  |                     if (entry.Name.EndsWith(".sql")) { | ||||||
|  |                         using var stream = entry.Open(); | ||||||
|  |                         using var reader = new StreamReader(stream, Utils.UTF8); | ||||||
|  |                         await ImportSql(reader); | ||||||
|  |                         return; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 throw new FileFormatException("ZIP archive has to contain at least one .sql file"); | ||||||
|  |             } else { | ||||||
|  |                 using var stream = File.Open(filename, FileMode.Open); | ||||||
|  |                 using var reader = new StreamReader(stream, Utils.UTF8); | ||||||
|  |                 await ImportSql(reader); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task ImportSqlite(string filename, bool zipFile = false) { | ||||||
|  |             if (zipFile) { | ||||||
|  |                 var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3"); | ||||||
|  |                 try { | ||||||
|  |                     using var zip = ZipFile.Open(filename, ZipArchiveMode.Read); | ||||||
|  |                     await zip.CheckIntegrity(); | ||||||
|  |                     foreach (var entry in zip.Entries) { | ||||||
|  |                         if (entry.Name.EndsWith(".sqlite3")) { | ||||||
|  |                             entry.ExtractToFile(newName); | ||||||
|  |                             await ImportSqlite(newName); | ||||||
|  |                             return; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     throw new FileFormatException("ZIP archive has to contain at least one .sqlite3 file"); | ||||||
|  |                 } finally { | ||||||
|  |                     if (File.Exists(newName)) File.Delete(newName); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3"); | ||||||
|  |             File.Move(App.Config.DatabaseFile, oldName, true); | ||||||
|  |             File.Move(filename, App.Config.DatabaseFile, false); | ||||||
|  |  | ||||||
|  |             using var cnx = await AppDbContext.ConnectAsync(); | ||||||
|  |             await AppDbContext.ExecuteBatch(cnx, "VACUUM"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static async Task ImportSql(StreamReader reader) { | ||||||
|  |             var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3"); | ||||||
|  |             File.Delete(newName); | ||||||
|  |             try { | ||||||
|  |                 using (var cnx = await AppDbContext.ConnectAsync($"Data Source=\"{newName}\"; Mode=ReadWriteCreate; Foreign Keys=False; Cache=Default; Pooling=False")) { | ||||||
|  |                     await AppDbContext.ExecuteBatch(cnx, await reader.ReadToEndAsync()); | ||||||
|  |                 } | ||||||
|  |                 await ImportSqlite(newName); | ||||||
|  |             } finally { | ||||||
|  |                 if (File.Exists(newName)) File.Delete(newName); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -405,29 +405,6 @@ namespace Elwig.Helpers.Export { | |||||||
|             }.Export(filename); |             }.Export(filename); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static async Task ImportDatabase(string filename) { |  | ||||||
|             var oldName = Path.ChangeExtension(App.Config.DatabaseFile, ".old.sqlite3"); |  | ||||||
|             var newName = Path.ChangeExtension(App.Config.DatabaseFile, ".new.sqlite3"); |  | ||||||
|             try { |  | ||||||
|                 using (var zip = ZipFile.Open(filename, ZipArchiveMode.Read)) { |  | ||||||
|                     await zip.CheckIntegrity(); |  | ||||||
|                     var db = zip.GetEntry("database.sqlite3")!; |  | ||||||
|                     db.ExtractToFile(newName, true); |  | ||||||
|                 } |  | ||||||
|                 File.Move(App.Config.DatabaseFile, oldName, true); |  | ||||||
|                 File.Move(newName, App.Config.DatabaseFile, false); |  | ||||||
|             } finally { |  | ||||||
|                 if (File.Exists(newName)) |  | ||||||
|                     File.Delete(newName); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public static void ExportDatabase(string filename) { |  | ||||||
|             File.Delete(filename); |  | ||||||
|             using var zip = ZipFile.Open(filename, ZipArchiveMode.Create); |  | ||||||
|             var db = zip.CreateEntryFromFile(App.Config.DatabaseFile, "database.sqlite3", CompressionLevel.SmallestSize); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public class ElwigExport { |         public class ElwigExport { | ||||||
|             public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; } |             public (IEnumerable<WbKg> WbKgs, IEnumerable<string> Filters)? WbKgs { get; set; } | ||||||
|             public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; } |             public (IEnumerable<Member> Members, IEnumerable<string> Filters)? Members { get; set; } | ||||||
|   | |||||||
| @@ -498,10 +498,7 @@ namespace Elwig.Helpers { | |||||||
|         public static async Task<bool> SendEmail(Member member, string subject, string text, IEnumerable<Document> docs) { |         public static async Task<bool> SendEmail(Member member, string subject, string text, IEnumerable<Document> docs) { | ||||||
|             if (App.Config.Smtp == null) |             if (App.Config.Smtp == null) | ||||||
|                 return false; |                 return false; | ||||||
|  |             return await Task.Run(async () => { | ||||||
|             Mouse.OverrideCursor = Cursors.Wait; |  | ||||||
|  |  | ||||||
|             var success = await Task.Run(async () => { |  | ||||||
|                 SmtpClient? client = null; |                 SmtpClient? client = null; | ||||||
|                 try { |                 try { | ||||||
|                     client = await GetSmtpClient(); |                     client = await GetSmtpClient(); | ||||||
| @@ -529,18 +526,15 @@ namespace Elwig.Helpers { | |||||||
|                 } |                 } | ||||||
|                 return true; |                 return true; | ||||||
|             }); |             }); | ||||||
|  |  | ||||||
|             Mouse.OverrideCursor = null; |  | ||||||
|             return success; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member, string, string)? emailData = null) { |         public static async Task ExportDocument(Document doc, ExportMode mode, string? filename = null, (Member Member, string Subject, string Text)? emailData = null) { | ||||||
|             if (mode == ExportMode.Print && !App.Config.Debug) { |             if (mode == ExportMode.Print && !App.Config.Debug) { | ||||||
|                 await doc.Generate(); |                 await doc.Generate(); | ||||||
|                 await doc.Print(); |                 await doc.Print(); | ||||||
|             } else if (mode == ExportMode.Email && emailData is (Member, string, string) e) { |             } else if (mode == ExportMode.Email && emailData is (Member, string, string) e) { | ||||||
|                 await doc.Generate(); |                 await doc.Generate(); | ||||||
|                 var success = await SendEmail(e.Item1, e.Item2, e.Item3, [doc]); |                 var success = await SendEmail(e.Member, e.Subject, e.Text, [doc]); | ||||||
|                 if (success) |                 if (success) | ||||||
|                     MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!", "E-Mail verschickt", |                     MessageBox.Show("Die E-Mail wurde erfolgreich verschickt!", "E-Mail verschickt", | ||||||
|                         MessageBoxButton.OK, MessageBoxImage.Information); |                         MessageBoxButton.OK, MessageBoxImage.Information); | ||||||
| @@ -567,9 +561,7 @@ namespace Elwig.Helpers { | |||||||
|                 Log = "Application", |                 Log = "Application", | ||||||
|                 Source = ".NET Runtime", |                 Source = ".NET Runtime", | ||||||
|             }; |             }; | ||||||
|             return log.Entries.Cast<EventLogEntry>() |             return [.. log.Entries.OfType<EventLogEntry>().Where(e => e.InstanceId == 1026).Where(e => e.Message.StartsWith("Application: Elwig.exe"))]; | ||||||
|                 .Where(e => e.Message.StartsWith("Application: Elwig.exe")) |  | ||||||
|                 .ToList(); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static int GetEntityIdetifierForPk(params object?[] primaryKey) { |         public static int GetEntityIdetifierForPk(params object?[] primaryKey) { | ||||||
|   | |||||||
| @@ -13,8 +13,8 @@ using System.Windows.Input; | |||||||
| namespace Elwig.Windows { | namespace Elwig.Windows { | ||||||
|     public abstract class AdministrationWindow : ContextWindow { |     public abstract class AdministrationWindow : ContextWindow { | ||||||
|  |  | ||||||
|         protected Control[] ExemptInputs { private get; set; } |         protected Control[] ExemptInputs { get; set; } | ||||||
|         protected Control[] RequiredInputs { private get; set; } |         protected Control[] RequiredInputs { get; set; } | ||||||
|  |  | ||||||
|         private bool _isEditing; |         private bool _isEditing; | ||||||
|         private bool _isCreating; |         private bool _isCreating; | ||||||
| @@ -166,8 +166,10 @@ namespace Elwig.Windows { | |||||||
|                     Valid[input] = false; |                     Valid[input] = false; | ||||||
|                 } else if (input is ComboBox cb && cb.SelectedItem == null && cb.ItemsSource != null && cb.ItemsSource.Cast<object>().Any()) { |                 } else if (input is ComboBox cb && cb.SelectedItem == null && cb.ItemsSource != null && cb.ItemsSource.Cast<object>().Any()) { | ||||||
|                     ControlUtils.SetInputInvalid(input); |                     ControlUtils.SetInputInvalid(input); | ||||||
|  |                     Valid[input] = false; | ||||||
|                 } else if (input is ListBox lb && lb.SelectedItem == null && lb.ItemsSource != null && lb.ItemsSource.Cast<object>().Any()) { |                 } else if (input is ListBox lb && lb.SelectedItem == null && lb.ItemsSource != null && lb.ItemsSource.Cast<object>().Any()) { | ||||||
|                     ControlUtils.SetInputInvalid(input); |                     ControlUtils.SetInputInvalid(input); | ||||||
|  |                     Valid[input] = false; | ||||||
|                 } else if (input is CheckBox ckb && ((ckb.IsThreeState && ckb.IsChecked == null) || (!ckb.IsThreeState && ckb.IsChecked != true))) { |                 } else if (input is CheckBox ckb && ((ckb.IsThreeState && ckb.IsChecked == null) || (!ckb.IsThreeState && ckb.IsChecked != true))) { | ||||||
|                     ControlUtils.SetInputInvalid(input); |                     ControlUtils.SetInputInvalid(input); | ||||||
|                     Valid[input] = false; |                     Valid[input] = false; | ||||||
|   | |||||||
| @@ -89,6 +89,9 @@ namespace Elwig.Windows { | |||||||
|                 foreach (var s in App.EventScales) { |                 foreach (var s in App.EventScales) { | ||||||
|                     s.WeighingEvent += Scale_Weighing; |                     s.WeighingEvent += Scale_Weighing; | ||||||
|                 } |                 } | ||||||
|  |                 if (App.Client.IsMatzen) { | ||||||
|  |                     RequiredInputs = [.. RequiredInputs, ModifiersInput]; | ||||||
|  |                 } | ||||||
|             } else { |             } else { | ||||||
|                 WeighingManualButton.Visibility = Visibility.Hidden; |                 WeighingManualButton.Visibility = Visibility.Hidden; | ||||||
|                 WeighingAButton.Visibility = Visibility.Hidden; |                 WeighingAButton.Visibility = Visibility.Hidden; | ||||||
| @@ -278,6 +281,7 @@ namespace Elwig.Windows { | |||||||
|                 DateInput.IsReadOnly = false; |                 DateInput.IsReadOnly = false; | ||||||
|                 TimeInput.IsReadOnly = false; |                 TimeInput.IsReadOnly = false; | ||||||
|                 BranchInput.IsEnabled = true; |                 BranchInput.IsEnabled = true; | ||||||
|  |                 GerebeltGewogenInput.IsEnabled = true; | ||||||
|                 if (IsCreating) ViewModel.Time = ""; |                 if (IsCreating) ViewModel.Time = ""; | ||||||
|                 OnSecondPassed(null, null); |                 OnSecondPassed(null, null); | ||||||
|             } |             } | ||||||
| @@ -287,6 +291,7 @@ namespace Elwig.Windows { | |||||||
|             DateInput.IsReadOnly = true; |             DateInput.IsReadOnly = true; | ||||||
|             TimeInput.IsReadOnly = true; |             TimeInput.IsReadOnly = true; | ||||||
|             BranchInput.IsEnabled = false; |             BranchInput.IsEnabled = false; | ||||||
|  |             GerebeltGewogenInput.IsEnabled = App.Config.WeighingMode != WeighingMode.Net; | ||||||
|             OnSecondPassed(null, null); |             OnSecondPassed(null, null); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -301,7 +306,7 @@ namespace Elwig.Windows { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void InitialDefaultInputs() { |         private void InitialDefaultInputs() { | ||||||
|             if (App.Client.HasNetWeighing(ViewModel.Branch)) { |             if (App.Config.WeighingMode == WeighingMode.Net) { | ||||||
|                 GerebeltGewogenInput.IsEnabled = false; |                 GerebeltGewogenInput.IsEnabled = false; | ||||||
|                 SetDefaultValue(GerebeltGewogenInput, true); |                 SetDefaultValue(GerebeltGewogenInput, true); | ||||||
|             } else { |             } else { | ||||||
| @@ -310,7 +315,7 @@ namespace Elwig.Windows { | |||||||
|                 UnsetDefaultValue(GerebeltGewogenInput); |                 UnsetDefaultValue(GerebeltGewogenInput); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (App.Client.HasBoxWeighing(ViewModel.Branch)) { |             if (App.Config.WeighingMode == WeighingMode.Box) { | ||||||
|                 LesewagenInput.IsEnabled = false; |                 LesewagenInput.IsEnabled = false; | ||||||
|                 SetDefaultValue(LesewagenInput, false); |                 SetDefaultValue(LesewagenInput, false); | ||||||
|             } else { |             } else { | ||||||
| @@ -318,7 +323,7 @@ namespace Elwig.Windows { | |||||||
|                 UnsetDefaultValue(LesewagenInput); |                 UnsetDefaultValue(LesewagenInput); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (!App.Client.HasNetWeighing(ViewModel.Branch)) { |             if (App.Config.WeighingMode != WeighingMode.Net) { | ||||||
|                 HandPickedInput.IsThreeState = false; |                 HandPickedInput.IsThreeState = false; | ||||||
|                 UnsetDefaultValue(HandPickedInput); |                 UnsetDefaultValue(HandPickedInput); | ||||||
|             } else { |             } else { | ||||||
| @@ -344,13 +349,13 @@ namespace Elwig.Windows { | |||||||
|             ClearOriginalValues(); |             ClearOriginalValues(); | ||||||
|             ClearDefaultValues(); |             ClearDefaultValues(); | ||||||
|  |  | ||||||
|             ViewModel.IsNetWeight = App.Client.HasNetWeighing(ViewModel.Branch); |             ViewModel.IsNetWeight = App.Config.WeighingMode == WeighingMode.Net; | ||||||
|             ViewModel.IsLesewagen = false; |             ViewModel.IsLesewagen = false; | ||||||
|             ViewModel.IsHandPicked = !App.Client.HasNetWeighing(ViewModel.Branch) ? true : null; |             ViewModel.IsHandPicked = App.Config.WeighingMode != WeighingMode.Net ? true : null; | ||||||
|             ViewModel.IsGebunden = null; |             ViewModel.IsGebunden = null; | ||||||
|             InitialDefaultInputs(); |             InitialDefaultInputs(); | ||||||
|  |  | ||||||
|             WineQualityLevelInput.IsEnabled = false; |             //WineQualityLevelInput.IsEnabled = false;  // disable wine quality level input in Übernahme | ||||||
|             ValidateRequiredInputs(); |             ValidateRequiredInputs(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -1139,6 +1144,7 @@ namespace Elwig.Windows { | |||||||
|             DateInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked; |             DateInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked; | ||||||
|             TimeInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked; |             TimeInput.IsReadOnly = !Menu_Settings_EnableFreeEditing.IsChecked; | ||||||
|             BranchInput.IsEnabled = Menu_Settings_EnableFreeEditing.IsChecked; |             BranchInput.IsEnabled = Menu_Settings_EnableFreeEditing.IsChecked; | ||||||
|  |             GerebeltGewogenInput.IsEnabled = App.Config.WeighingMode == WeighingMode.Net || Menu_Settings_EnableFreeEditing.IsChecked; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void DisableWeighingButtons() { |         private void DisableWeighingButtons() { | ||||||
| @@ -1389,17 +1395,17 @@ namespace Elwig.Windows { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void GerebeltGewogenInput_Changed(object sender, RoutedEventArgs evt) { |         private void GerebeltGewogenInput_Changed(object sender, RoutedEventArgs evt) { | ||||||
|             if ((IsEditing || IsCreating) && !App.Client.HasNetWeighing(ViewModel.Branch)) { |             if ((IsEditing || IsCreating) && App.Config.WeighingMode != WeighingMode.Net) { | ||||||
|                 HandPickedInput.IsChecked = !GerebeltGewogenInput.IsChecked; |                 HandPickedInput.IsChecked = !GerebeltGewogenInput.IsChecked; | ||||||
|             } |             } | ||||||
|             if (!ViewModel.IsReceipt || App.Client.HasNetWeighing(ViewModel.Branch)) { |             if (!ViewModel.IsReceipt || App.Config.WeighingMode == WeighingMode.Net) { | ||||||
|                 GerebeltGewogenInput.IsChecked ??= false; |                 GerebeltGewogenInput.IsChecked ??= false; | ||||||
|             } |             } | ||||||
|             CheckBox_Changed(sender, evt); |             CheckBox_Changed(sender, evt); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void HandPickedInput_Changed(object sender, RoutedEventArgs evt) { |         private void HandPickedInput_Changed(object sender, RoutedEventArgs evt) { | ||||||
|             if ((IsEditing || IsCreating) && !App.Client.HasNetWeighing(ViewModel.Branch)) { |             if ((IsEditing || IsCreating) && App.Config.WeighingMode != WeighingMode.Net) { | ||||||
|                 GerebeltGewogenInput.IsChecked = !HandPickedInput.IsChecked; |                 GerebeltGewogenInput.IsChecked = !HandPickedInput.IsChecked; | ||||||
|             } |             } | ||||||
|             CheckBox_Changed(sender, evt); |             CheckBox_Changed(sender, evt); | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| using Elwig.Helpers; | using Elwig.Helpers; | ||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.Linq; | using System.Linq; | ||||||
|  | using System.Threading.Tasks; | ||||||
| using System.Windows; | using System.Windows; | ||||||
|  | using System.Windows.Input; | ||||||
|  |  | ||||||
| namespace Elwig.Windows { | namespace Elwig.Windows { | ||||||
|     public partial class LogWindow : Window { |     public partial class LogWindow : Window { | ||||||
| @@ -11,28 +13,34 @@ namespace Elwig.Windows { | |||||||
|             WindowState = WindowState.Maximized; |             WindowState = WindowState.Maximized; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void Window_Loaded(object sender, RoutedEventArgs evt) { |         private async void Window_Loaded(object sender, RoutedEventArgs evt) { | ||||||
|             var log = Utils.GetLogEntries(); |             Mouse.OverrideCursor = Cursors.Wait; | ||||||
|             EventList.ItemsSource = log |             await Task.Run(async () => { | ||||||
|                 .Select(e => new { |                 var list = Utils.GetLogEntries() | ||||||
|                     Event = e, |                   .Select(e => new { | ||||||
|                     Lines = e.Message.Split('\n').ToArray(), |                       Event = e, | ||||||
|                 }) |                       Lines = e.Message.Split('\n').ToArray(), | ||||||
|                 .Select(e => new { |                   }) | ||||||
|                     e.Event, |                   .Select(e => new { | ||||||
|                     Exception = e.Lines.FirstOrDefault(l => l.StartsWith("Exception Info: "))?[16..].Trim().Split(':', 2), |                       e.Event, | ||||||
|                     Location = e.Lines.FirstOrDefault(l => l.StartsWith("   at Elwig."))?[5..].Trim(), |                       Exception = e.Lines.FirstOrDefault(l => l.StartsWith("Exception Info: "))?[16..].Trim().Split(':', 2), | ||||||
|                 }) |                       Location = e.Lines.FirstOrDefault(l => l.StartsWith("   at Elwig."))?[5..].Trim(), | ||||||
|                 .Select(e => new { |                   }) | ||||||
|                     e.Event, |                   .Select(e => new { | ||||||
|                     e.Exception, |                       e.Event, | ||||||
|                     ExceptionName = e.Exception?[0].Trim(), |                       e.Exception, | ||||||
|                     ExceptionMessage = e.Exception?.Length >= 2 ? e.Exception?[1].Trim() : null, |                       ExceptionName = e.Exception?[0].Trim(), | ||||||
|                     e.Location, |                       ExceptionMessage = e.Exception?.Length >= 2 ? e.Exception?[1].Trim() : null, | ||||||
|                 }) |                       e.Location, | ||||||
|                 .OrderByDescending(e => e.Event.TimeGenerated) |                   }) | ||||||
|                 .ToList(); |                   .OrderByDescending(e => e.Event.TimeGenerated) | ||||||
|             EventList.SelectedIndex = 0; |                   .ToList(); | ||||||
|  |                 await App.MainDispatcher.BeginInvoke(() => { | ||||||
|  |                     EventList.ItemsSource = list; | ||||||
|  |                     EventList.SelectedIndex = 0; | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|  |             Mouse.OverrideCursor = null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private void EventList_SelectionChanged(object sender, RoutedEventArgs evt) { |         private void EventList_SelectionChanged(object sender, RoutedEventArgs evt) { | ||||||
|   | |||||||
| @@ -31,6 +31,17 @@ | |||||||
|                     </MenuItem.Icon> |                     </MenuItem.Icon> | ||||||
|                 </MenuItem> |                 </MenuItem> | ||||||
|                 <Separator/> |                 <Separator/> | ||||||
|  |                 <MenuItem Header="Datenbank sichern..." Click="Menu_Database_Backup_Click"> | ||||||
|  |                     <MenuItem.Icon> | ||||||
|  |                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||||
|  |                     </MenuItem.Icon> | ||||||
|  |                 </MenuItem> | ||||||
|  |                 <MenuItem Header="Datenbank wiederherstellen..." Click="Menu_Database_Restore_Click"> | ||||||
|  |                     <MenuItem.Icon> | ||||||
|  |                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||||
|  |                     </MenuItem.Icon> | ||||||
|  |                 </MenuItem> | ||||||
|  |                 <Separator/> | ||||||
|                 <MenuItem Header="Abfragen stellen" Click="Menu_Database_Query_Click"> |                 <MenuItem Header="Abfragen stellen" Click="Menu_Database_Query_Click"> | ||||||
|                     <MenuItem.Icon> |                     <MenuItem.Icon> | ||||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> |                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||||
|   | |||||||
| @@ -146,6 +146,48 @@ namespace Elwig.Windows { | |||||||
|             Mouse.OverrideCursor = null; |             Mouse.OverrideCursor = null; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         private async void Menu_Database_Backup_Click(object sender, RoutedEventArgs evt) { | ||||||
|  |             try { | ||||||
|  |                 var d = new SaveFileDialog() { | ||||||
|  |                     Title = "Datenbank sichern - Elwig", | ||||||
|  |                     FileName = $"database_{Utils.Today:yyyy-MM-dd}.sql.zip", | ||||||
|  |                     DefaultExt = "sql.zip", | ||||||
|  |                     Filter = "Komprimierte SQL-Datei (*.sql.zip)|*.sql.zip", | ||||||
|  |                 }; | ||||||
|  |                 if (d.ShowDialog() == true) { | ||||||
|  |                     Mouse.OverrideCursor = Cursors.Wait; | ||||||
|  |                     await Task.Run(async () => { | ||||||
|  |                         await Database.ExportSql(d.FileName, true); | ||||||
|  |                     }); | ||||||
|  |                 } | ||||||
|  |             } catch (Exception exc) { | ||||||
|  |                 MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||||
|  |             } | ||||||
|  |             Mouse.OverrideCursor = null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private async void Menu_Database_Restore_Click(object sender, RoutedEventArgs evt) { | ||||||
|  |             try { | ||||||
|  |                 var d = new OpenFileDialog() { | ||||||
|  |                     Title = "Datenbank wiederherstellen - Elwig", | ||||||
|  |                     DefaultExt = "sql.zip", | ||||||
|  |                     Filter = "SQLite-Datenbank (*.sqlite3, *.sqlite3.zip, *.sql, *.sql.zip)|*.sqlite3;*.sqlite3.zip;*.sql;*.sql.zip", | ||||||
|  |                 }; | ||||||
|  |                 if (d.ShowDialog() == true) { | ||||||
|  |                     var res = MessageBox.Show("Soll die Datenbank wirklich unwiederruflich durch die wiederhergestellte Version ersetzt werden?", "Datenbank wiederherstellen", | ||||||
|  |                         MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); | ||||||
|  |                     if (res != MessageBoxResult.OK) | ||||||
|  |                         return; | ||||||
|  |  | ||||||
|  |                     Mouse.OverrideCursor = Cursors.Wait; | ||||||
|  |                     await App.ReplaceDatabase(d.FileName); | ||||||
|  |                 } | ||||||
|  |             } catch (Exception exc) { | ||||||
|  |                 MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||||
|  |             } | ||||||
|  |             Mouse.OverrideCursor = null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         private async void DownloadButton_Click(object sender, RoutedEventArgs evt) { |         private async void DownloadButton_Click(object sender, RoutedEventArgs evt) { | ||||||
|             if (App.Config.SyncUrl == null) |             if (App.Config.SyncUrl == null) | ||||||
|                 return; |                 return; | ||||||
| @@ -243,21 +285,23 @@ namespace Elwig.Windows { | |||||||
|             await Task.Run(async () => { |             await Task.Run(async () => { | ||||||
|                 try { |                 try { | ||||||
|                     var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); |                     var data = await Utils.GetExportMetaData(App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); | ||||||
|                     var file = data |                     var files = data | ||||||
|                         .Select(f => new { |                         .Select(f => new { | ||||||
|                             Name = f!["name"]!.AsValue().GetValue<string>(), |                             Name = f!["name"]!.AsValue().GetValue<string>(), | ||||||
|                             Timestamp = f!["modified"] != null && DateTime.TryParseExact(f!["modified"]!.AsValue().GetValue<string>(), "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? dt : (DateTime?)null, |                             Timestamp = f!["modified"] != null && DateTime.TryParseExact(f!["modified"]!.AsValue().GetValue<string>(), "yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture, DateTimeStyles.None, out var dt) ? dt : (DateTime?)null, | ||||||
|                             Url = f!["url"]!.AsValue().GetValue<string>(), |                             Url = f!["url"]!.AsValue().GetValue<string>(), | ||||||
|                             Size = f!["size"]!.AsValue().GetValue<long>(), |                             Size = f!["size"]!.AsValue().GetValue<long>(), | ||||||
|                         }) |                         }) | ||||||
|                         .Where(f => f.Name == "database.sqlite3.zip") |                         .Where(f => f.Name.StartsWith("database.") && f.Name.EndsWith(".zip")) | ||||||
|                         .FirstOrDefault(); |                         .OrderBy(f => f.Size) | ||||||
|  |                         .ToList(); | ||||||
|  |  | ||||||
|                     if (file == null) { |                     if (files.Count == 0) { | ||||||
|                         MessageBox.Show("Die Datenbank wurde noch nicht vom Hauptgerät hochgeladen!", "Datenbank herunterladen", |                         MessageBox.Show("Die Datenbank wurde noch nicht vom Hauptgerät hochgeladen!", "Datenbank herunterladen", | ||||||
|                             MessageBoxButton.OK, MessageBoxImage.Error); |                             MessageBoxButton.OK, MessageBoxImage.Error); | ||||||
|                         return; |                         return; | ||||||
|                     } |                     } | ||||||
|  |                     var file = files[0]; | ||||||
|  |  | ||||||
|                     var res = MessageBox.Show($"Es wurde eine komprimierte Datenbank (ca. {file.Size / 1024 / 1024} MB) vom {file.Timestamp:dd.MM.yyyy, HH:mm} gefunden.\n\nWollen Sie wirklich die aktuelle Datenbank unwiederruflich\nlöschen und durch die gefundene ersetzen?\n\nDas kann zu Datenverlust führen!", "Datenbank herunterladen", |                     var res = MessageBox.Show($"Es wurde eine komprimierte Datenbank (ca. {file.Size / 1024 / 1024} MB) vom {file.Timestamp:dd.MM.yyyy, HH:mm} gefunden.\n\nWollen Sie wirklich die aktuelle Datenbank unwiederruflich\nlöschen und durch die gefundene ersetzen?\n\nDas kann zu Datenverlust führen!", "Datenbank herunterladen", | ||||||
|                         MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); |                         MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel); | ||||||
| @@ -301,8 +345,8 @@ namespace Elwig.Windows { | |||||||
|             Mouse.OverrideCursor = Cursors.Wait; |             Mouse.OverrideCursor = Cursors.Wait; | ||||||
|             await Task.Run(async () => { |             await Task.Run(async () => { | ||||||
|                 try { |                 try { | ||||||
|                     var path = Path.Combine(App.TempPath, "database.sqlite3.zip"); |                     var path = Path.Combine(App.TempPath, "database.sql.zip"); | ||||||
|                     ElwigData.ExportDatabase(path); |                     await Database.ExportSql(path, true); | ||||||
|                     await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); |                     await Utils.UploadExportData(path, App.Config.SyncUrl, App.Config.SyncUsername, App.Config.SyncPassword); | ||||||
|                     MessageBox.Show($"Hochladen der gesamten Datenbank erfolgreich!", "Datenbank hochladen", |                     MessageBox.Show($"Hochladen der gesamten Datenbank erfolgreich!", "Datenbank hochladen", | ||||||
|                         MessageBoxButton.OK, MessageBoxImage.Information); |                         MessageBoxButton.OK, MessageBoxImage.Information); | ||||||
|   | |||||||
| @@ -38,7 +38,7 @@ namespace Elwig.Windows { | |||||||
|             IList<DbColumn> header; |             IList<DbColumn> header; | ||||||
|  |  | ||||||
|             using (var cnx = await AppDbContext.ConnectAsync()) { |             using (var cnx = await AppDbContext.ConnectAsync()) { | ||||||
|                 var cmd = cnx.CreateCommand(); |                 using var cmd = cnx.CreateCommand(); | ||||||
|                 cmd.CommandText = sqlQuery; |                 cmd.CommandText = sqlQuery; | ||||||
|                 using var reader = await cmd.ExecuteReaderAsync(); |                 using var reader = await cmd.ExecuteReaderAsync(); | ||||||
|                 header = await reader.GetColumnSchemaAsync(); |                 header = await reader.GetColumnSchemaAsync(); | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ | |||||||
|   </Target> |   </Target> | ||||||
|   <ItemGroup> |   <ItemGroup> | ||||||
|     <ProjectReference Include="..\Installer\Installer.wixproj" /> |     <ProjectReference Include="..\Installer\Installer.wixproj" /> | ||||||
|     <PackageReference Include="WixToolset.Bal.wixext" Version="6.0.1" /> |     <PackageReference Include="WixToolset.Bal.wixext" Version="6.0.2" /> | ||||||
|     <PackageReference Include="WixToolset.Util.wixext" Version="6.0.1" /> |     <PackageReference Include="WixToolset.Util.wixext" Version="6.0.2" /> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
| </Project> | </Project> | ||||||
		Reference in New Issue
	
	Block a user