Compare commits
	
		
			8 Commits
		
	
	
		
			v0.13.2
			...
			ebf0c20a90
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ebf0c20a90 | |||
| 2ee0d56dcc | |||
| 0a9731af09 | |||
| 6718ad4c8d | |||
| a1d84dd988 | |||
| f4fa549130 | |||
| c5453c2fe6 | |||
| 54deccf021 | 
							
								
								
									
										32
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -3,12 +3,36 @@ Changelog | ||||
| ========= | ||||
|  | ||||
|  | ||||
| [v0.13.3][v0.13.3] (2024-11-13) {#v0.13.3} | ||||
| ------------------------------------------ | ||||
|  | ||||
| ### Neue Funktionen {#0.13.3-features} | ||||
|  | ||||
| * Im Haupt-Fenster (`MainWindow`) unter _Leseabschluss_ eine Statistik-Tabelle (Gebunden/Ungeb., Mitglieder/Gewicht/Fläche) hinzugefügt. (54deccf021) | ||||
| * Im Haupt-Fenster (`MainWindow`) unter _Leseabschluss_ zwei Exportmöglichkeiten (_Flächenbindungen_, _Liefermenge/Ertrag_) hinzugefügt. (c5453c2fe6) | ||||
| * Ausgangs-Protokoll-Fenster (`MailLogWindow`) zum Ansehen aller ausgehenden E-Mails oder ausgedruckten Rundschreiben hinzugefügt (_Rundschreiben_ -> _Hilfe_). (2ee0d56dcc) | ||||
|  | ||||
| ### Behobene Fehler {#0.13.3-bugfixes} | ||||
|  | ||||
| * Im Rundschreiben-Fenster (`MailWindow`) kleinere Fehler behoben und alle Einstellungen werden nun gespeichert. (0a9731af09) | ||||
|  | ||||
| ### Sonstiges {#0.13.3-misc} | ||||
|  | ||||
| * In allen Fenstern an passenden Stellen Symbole/Icons hinzugefügt. (f4fa549130) | ||||
| * Im Mitglieder-Fenster (`MemberAdminWindow`) Filter `Flächenbindung` (Mitglieder mit irgendeiner aktiven Flächenbindung) hinzugefügt. (a1d84dd988) | ||||
| * Im Flächenbindungen-Fenster (`AreaComAdminWindow`) Filter für explizite Saisons hinzugefügt. (6718ad4c8d) | ||||
|  | ||||
| [v0.13.3]: https://git.necronda.net/winzer/elwig/releases/tag/v0.13.3 | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| [v0.13.2][v0.13.2] (2024-10-13) {#v0.13.2} | ||||
| ------------------------------------------ | ||||
|  | ||||
| ### Neue Funktionen {#0.13.2-features} | ||||
|  | ||||
| * Im Lieferungen-Fenster den Menüpunkt _Abwerteliste_ (`DeliveryDepreciationList`) hinzugefügt. (3cbffdbf27) | ||||
| * Im Lieferungen-Fenster den Menüpunkt _Abwertungsliste_ (`DeliveryDepreciationList`) hinzugefügt. (3cbffdbf27) | ||||
|  | ||||
| ### Behobene Fehler {#0.13.2-bugfixes} | ||||
|  | ||||
| @@ -132,7 +156,7 @@ Changelog | ||||
| ### Neue Funktionen {#v0.11.2-features} | ||||
|  | ||||
| * In der Anmeldeliste (`DeliveryAncmtList`) wird die Stamm-KG des Mitgliedes angegeben. (165770fa37) | ||||
| * Im Hauptmenü wurde im Menüpunkt _Hilfe_ ein Fehler-Protokoll-Fenster (`LogWindow`) hinzugefügt. (526e951029) | ||||
| * Im Haupt-Fenster (`MainWindow`) wurde im Menüpunkt _Hilfe_ ein Fehler-Protokoll-Fenster (`LogWindow`) hinzugefügt. (526e951029) | ||||
|  | ||||
| ### Behobene Fehler {#v0.11.2-bugfixes} | ||||
|  | ||||
| @@ -239,7 +263,7 @@ Changelog | ||||
|  | ||||
| ### Behobene Fehler {#v0.10.6-bugfixes} | ||||
|  | ||||
| * Der Titel des Flächenbindungs-Fensters (`AreaComAdminWindow`) ist jetzt _Flächenbindungen_, nicht mehr _Lieferungen_. (ee1315929c) | ||||
| * Der Titel des Flächenbindungen-Fensters (`AreaComAdminWindow`) ist jetzt _Flächenbindungen_, nicht mehr _Lieferungen_. (ee1315929c) | ||||
| * Im Auszahlungsvariante-Fenster (`ChartWindow`) einen Skalierungs-Fehler behoben. ([#33][i33]) | ||||
| * Versuch: Fehler bei automatischer Daten-Erneuerung bei längerer Benutzung. (8c8c0a8c2b) | ||||
|  | ||||
| @@ -556,7 +580,7 @@ Changelog | ||||
|  | ||||
| ### Behobene Fehler {#v0.8.4-bugfixes} | ||||
|  | ||||
| * Falls beim Schließen des Hauptmenüs ein anderes Fenster im Bearbeiten-/Erstellen-Modus war führte das zu einem Absturz. (70f8276808) | ||||
| * Falls beim Schließen des Haupt-Fensters (`MainWindow`) ein anderes Fenster im Bearbeiten-/Erstellen-Modus war führte das zu einem Absturz. (70f8276808) | ||||
|  | ||||
| ### Sonstiges {#v0.8.4-misc} | ||||
|  | ||||
|   | ||||
| @@ -26,6 +26,7 @@ namespace Elwig { | ||||
|         private readonly DispatcherTimer _autoUpdateTimer = new() { Interval = TimeSpan.FromHours(1) }; | ||||
|  | ||||
|         public static readonly string DataPath = @"C:\ProgramData\Elwig\"; | ||||
|         public static readonly string MailsPath = Path.Combine(DataPath, "mails"); | ||||
|         public static readonly string ConfigPath = Path.Combine(DataPath, "config.ini"); | ||||
|         public static readonly string ExePath = @"C:\Program Files\Elwig\"; | ||||
|         public static readonly string TempPath = Path.Combine(Path.GetTempPath(), "Elwig"); | ||||
| @@ -56,6 +57,7 @@ namespace Elwig { | ||||
|             Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); | ||||
|             Directory.CreateDirectory(TempPath); | ||||
|             Directory.CreateDirectory(DataPath); | ||||
|             Directory.CreateDirectory(MailsPath); | ||||
|             MainDispatcher = Dispatcher; | ||||
|             Scales = []; | ||||
|             CurrentApp = this; | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <UseWPF>true</UseWPF> | ||||
|     <PreserveCompilationContext>true</PreserveCompilationContext> | ||||
|     <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon> | ||||
|     <Version>0.13.2</Version> | ||||
|     <Version>0.13.3</Version> | ||||
|     <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> | ||||
|     <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||||
|     <ApplicationManifest>app.manifest</ApplicationManifest> | ||||
|   | ||||
| @@ -63,10 +63,12 @@ namespace Elwig.Helpers { | ||||
|         public DbSet<PaymentDeliveryPart> PaymentDeliveryParts { get; private set; } | ||||
|         public DbSet<PaymentCustom> CustomPayments { get; private set; } | ||||
|         public DbSet<Credit> Credits { get; private set; } | ||||
|         public DbSet<DeliveryPartBucket> DeliveryPartBuckets { get; private set; } | ||||
|  | ||||
|         public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; } | ||||
|         public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; } | ||||
|         public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; } | ||||
|         public DbSet<MemberAreaComsRowSingle> MemberAreaComsRows { get; private set; } | ||||
|         public DbSet<CreditNoteDeliveryRowSingle> CreditNoteDeliveryRows { get; private set; } | ||||
|         public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; } | ||||
|         public DbSet<WeightBreakdownRow> WeightBreakDownRows { get; private set; } | ||||
|   | ||||
| @@ -67,6 +67,12 @@ namespace Elwig.Helpers { | ||||
|         public string? TextEmailSubject; | ||||
|         public string? TextEmailBody; | ||||
|  | ||||
|         public bool MailIncludeNonDeliverers; | ||||
|         public bool MailDoublePaged; | ||||
|         public int MailSendPostal; | ||||
|         public int MailSendEmail; | ||||
|         public int MailOrdering; | ||||
|  | ||||
|         public int ExportEbicsVersion; | ||||
|         public int ExportEbicsAddress; | ||||
|  | ||||
| @@ -117,7 +123,7 @@ namespace Elwig.Helpers { | ||||
|                     case "KMW/5": ModeWineQualityStatistics = 3; break; | ||||
|                     case "KMW/10": ModeWineQualityStatistics = 4; break; | ||||
|                 } | ||||
|                 switch (parameters.GetValueOrDefault("ORDERING_MEMBERLIST", "")?.ToUpper()) { | ||||
|                 switch (parameters.GetValueOrDefault("ORDERING_MEMBERLIST", "MGNR")?.ToUpper()) { | ||||
|                     case "MGNR": OrderingMemberList = 0; break; | ||||
|                     case "NAME": OrderingMemberList = 1; break; | ||||
|                     case "KG": OrderingMemberList = 2; break; | ||||
| @@ -135,6 +141,31 @@ namespace Elwig.Helpers { | ||||
|                 TextEmailBody = parameters.GetValueOrDefault("TEXT_EMAIL_BODY"); | ||||
|                 if (TextEmailBody == "") TextEmailBody = null; | ||||
|  | ||||
|                 MailIncludeNonDeliverers = (parameters.GetValueOrDefault("MAIL_INCLUDE_NON_DELIVERERS")?.ToUpper()) switch { | ||||
|                     "1" or "TRUE" or "YES" or "JA" => true, | ||||
|                     _ => false, | ||||
|                 }; | ||||
|                 MailDoublePaged = (parameters.GetValueOrDefault("MAIL_DOUBLE_PAGED")?.ToUpper()) switch { | ||||
|                     "1" or "TRUE" or "YES" or "JA" => true, | ||||
|                     _ => false, | ||||
|                 }; | ||||
|                 switch (parameters.GetValueOrDefault("MAIL_SEND_POSTAL", "WISH")?.ToUpper()) { | ||||
|                     case "ALL": MailSendPostal = 3; break; | ||||
|                     case "WISH": MailSendPostal = 2; break; | ||||
|                     case "NO_EMAIL": MailSendPostal = 1; break; | ||||
|                     case "NONE": MailSendPostal = 0; break; | ||||
|                 } | ||||
|                 switch (parameters.GetValueOrDefault("MAIL_SEND_EMAIL", "WISH")?.ToUpper()) { | ||||
|                     case "ALL": MailSendEmail = 2; break; | ||||
|                     case "WISH": MailSendEmail = 1; break; | ||||
|                     case "NONE": MailSendEmail = 0; break; | ||||
|                 } | ||||
|                 switch (parameters.GetValueOrDefault("MAIL_ORDERING", "MGNR")?.ToUpper()) { | ||||
|                     case "MGNR": MailOrdering = 0; break; | ||||
|                     case "NAME": MailOrdering = 1; break; | ||||
|                     case "PLZ": MailOrdering = 2; break; | ||||
|                 } | ||||
|  | ||||
|                 ExportEbicsVersion = int.TryParse(parameters.GetValueOrDefault("EXPORT_EBICS_VERSION"), out var v) ? v : 9; | ||||
|                 switch (parameters.GetValueOrDefault("EXPORT_EBICS_ADDRESS", "FULL")?.ToUpper()) { | ||||
|                     case "OMIT": ExportEbicsAddress = 0; break; | ||||
| @@ -177,6 +208,25 @@ namespace Elwig.Helpers { | ||||
|                 case 1: orderingMemberList = "NAME"; break; | ||||
|                 case 2: orderingMemberList = "KG"; break; | ||||
|             } | ||||
|             string mailSendPostal = "MGNR"; | ||||
|             switch (MailOrdering) { | ||||
|                 case 0: mailSendPostal = "NONE"; break; | ||||
|                 case 1: mailSendPostal = "NO_EMAIL"; break; | ||||
|                 case 2: mailSendPostal = "WISH"; break; | ||||
|                 case 3: mailSendPostal = "ALL"; break; | ||||
|             } | ||||
|             string mailSendEmail = "MGNR"; | ||||
|             switch (MailOrdering) { | ||||
|                 case 0: mailSendEmail = "NONE"; break; | ||||
|                 case 1: mailSendEmail = "WISH"; break; | ||||
|                 case 2: mailSendEmail = "ALL"; break; | ||||
|             } | ||||
|             string mailOrdering = "MGNR"; | ||||
|             switch (MailOrdering) { | ||||
|                 case 0: mailOrdering = "MGNR"; break; | ||||
|                 case 1: mailOrdering = "NAME"; break; | ||||
|                 case 2: mailOrdering = "PLZ"; break; | ||||
|             } | ||||
|             string exportEbicsAddress = "FULL"; | ||||
|             switch (ExportEbicsAddress) { | ||||
|                 case 0: exportEbicsAddress = "OMIT"; break; | ||||
| @@ -212,6 +262,11 @@ namespace Elwig.Helpers { | ||||
|                 ("TEXT_CREDITNOTE", TextCreditNote), | ||||
|                 ("TEXT_EMAIL_SUBJECT", TextEmailSubject), | ||||
|                 ("TEXT_EMAIL_BODY", TextEmailBody), | ||||
|                 ("MAIL_INCLUDE_NON_DELIVERERS", MailIncludeNonDeliverers ? "YES" : "NO"), | ||||
|                 ("MAIL_DOUBLE_PAGED", MailDoublePaged ? "YES" : "NO"), | ||||
|                 ("MAIL_SEND_POSTAL", mailSendPostal), | ||||
|                 ("MAIL_SEND_EMAIL", mailSendEmail), | ||||
|                 ("MAIL_ORDERING", mailOrdering), | ||||
|                 ("EXPORT_EBICS_VERSION", ExportEbicsVersion.ToString()), | ||||
|                 ("EXPORT_EBICS_ADDRESS", exportEbicsAddress), | ||||
|                 ("AUTOADJUST_BUSINESSSHARES", autoAdjust), | ||||
|   | ||||
| @@ -5,6 +5,7 @@ using System.Linq; | ||||
| using System.Windows; | ||||
| using System.Windows.Controls; | ||||
| using System.Windows.Controls.Primitives; | ||||
| using System.Windows.Threading; | ||||
| using Brush = System.Windows.Media.Brush; | ||||
| using Brushes = System.Windows.Media.Brushes; | ||||
|  | ||||
| @@ -234,5 +235,21 @@ namespace Elwig.Helpers { | ||||
|                 return null; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static void InitializeDelayTimer(TextBox tb, Action<object, TextChangedEventArgs> handler) { | ||||
|             var timer = new DispatcherTimer { | ||||
|                 Interval = TimeSpan.FromMilliseconds(250) | ||||
|             }; | ||||
|             timer.Tick += (object? sender, EventArgs evt) => { | ||||
|                 timer.Stop(); | ||||
|                 var (oSender, oEvent) = ((object, TextChangedEventArgs))timer.Tag; | ||||
|                 handler(oSender, oEvent); | ||||
|             }; | ||||
|             tb.TextChanged += (object sender, TextChangedEventArgs evt) => { | ||||
|                 timer.Stop(); | ||||
|                 timer.Tag = (sender, evt); | ||||
|                 timer.Start(); | ||||
|             }; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -594,5 +594,76 @@ namespace Elwig.Helpers { | ||||
|         public static IEnumerable<AreaCom> ActiveAreaCommitments(IEnumerable<AreaCom> query) => ActiveAreaCommitments(query, CurrentYear); | ||||
|         public static IEnumerable<AreaCom> ActiveAreaCommitments(IEnumerable<AreaCom> query, int year) => | ||||
|             query.Where(c => ActiveAreaCommitments(year).Invoke(c)); | ||||
|  | ||||
|         public static async Task<(DateTime DateTime, string Type, int MgNr, string Name, string[] Addresses, string Subject, string[] Attachments)[]> GetSentMails(DateOnly? fromDate = null, DateOnly? toDate = null) { | ||||
|             var f = $"{fromDate:yyyy-MM-dd}"; | ||||
|             var t = $"{toDate:yyyy-MM-dd}"; | ||||
|             try { | ||||
|                 var rows = new List<(DateTime, string, int, string, string[], string, string[])>(); | ||||
|                 var filenames = Directory.GetFiles(App.MailsPath, "????.csv") | ||||
|                     .Where(n => fromDate == null || Path.GetFileName(n).CompareTo($"{fromDate.Value.Year}.csv") >= 0) | ||||
|                     .Where(n => toDate   == null || Path.GetFileName(n).CompareTo($"{toDate.Value.Year}.csv")   <= 0) | ||||
|                     .Order(); | ||||
|                 foreach (var filename in filenames) { | ||||
|                     using var reader = new StreamReader(filename, Utils.UTF8); | ||||
|                     string? line; | ||||
|                     while ((line = await reader.ReadLineAsync()) != null) { | ||||
|                         try { | ||||
|                             if (line.Length < 20 || line[10] != ';' || line[19] != ';') | ||||
|                                 continue; | ||||
|                             var date = line[..10]; | ||||
|                             if (fromDate != null && date.CompareTo(f) < 0) { | ||||
|                                 continue; | ||||
|                             } else if (toDate != null && date.CompareTo(t) > 0) { | ||||
|                                 break; | ||||
|                             } | ||||
|                             var p = line.Split(';'); | ||||
|                             rows.Add(( | ||||
|                                 DateOnly.ParseExact(p[0], "yyyy-MM-dd").ToDateTime(TimeOnly.ParseExact(p[1], "HH:mm:ss")), | ||||
|                                 p[2], | ||||
|                                 int.Parse(p[3]), | ||||
|                                 p[4], | ||||
|                                 p[5].Split(',').Select(a => a.Replace(" | ", "\n")).ToArray(), | ||||
|                                 p[6], | ||||
|                                 p[7].Split(',') | ||||
|                             )); | ||||
|                         } catch { | ||||
|                             continue; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 return [.. rows]; | ||||
|             } catch { | ||||
|                 return []; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         public static async Task AddSentMails(IEnumerable<(string Type, int MgNr, string Name, string[] Addresses, string Subject, string[] Attachments)> data) { | ||||
|             var now = DateTime.Now; | ||||
|             var filename = Path.Combine(App.MailsPath, $"{now.Year}.csv"); | ||||
|             await File.AppendAllLinesAsync(filename, data.Select(d => | ||||
|                 $"{now:yyyy-MM-dd;HH:mm:ss};{d.Type};" + | ||||
|                 $"{d.MgNr};{d.Name.Replace(';', ' ')};" + | ||||
|                 $"{string.Join(',', d.Addresses.Select(a => a.Replace(';', ' ').Replace(',', ' ').Replace("\n", " | ")))};" + | ||||
|                 $"{d.Subject.Replace(';', ' ')};" + | ||||
|                 $"{string.Join(',', d.Attachments.Select(a => a.Replace(';', ' ').Replace(',', ' ')))}" | ||||
|             ), Utils.UTF8); | ||||
|         } | ||||
|  | ||||
|         public static async Task<string?> FindSentMailBody(DateTime target) { | ||||
|             var dt = $"{target:yyyy-MM-dd_HH-mm-ss}_"; | ||||
|             var filename = Directory.GetFiles(App.MailsPath, "????-??-??_??-??-??_*.txt") | ||||
|                 .Where(n => Path.GetFileName(n).CompareTo(dt) <= 0) | ||||
|                 .Order() | ||||
|                 .LastOrDefault(); | ||||
|             if (filename == null) | ||||
|                 return null; | ||||
|             return await File.ReadAllTextAsync(filename, Utils.UTF8); | ||||
|         } | ||||
|  | ||||
|         public static async Task AddSentMailBody(string subject, string body, int recipients) { | ||||
|             var filename = Path.Combine(App.MailsPath, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}_{NormalizeFileName(subject)}.txt"); | ||||
|             await File.WriteAllTextAsync(filename, $"# {subject}\r\n# Vorgesehene Empfänger: {recipients}\r\n\r\n" + body, Utils.UTF8); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										105
									
								
								Elwig/Models/Dtos/MemberAreaComsData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								Elwig/Models/Dtos/MemberAreaComsData.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| using Microsoft.EntityFrameworkCore; | ||||
| using System.Collections.Generic; | ||||
| using System.ComponentModel.DataAnnotations.Schema; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
|  | ||||
| namespace Elwig.Models.Dtos { | ||||
|     class MemberAreaComsData : DataTable<MemberAreaComsRow> { | ||||
|  | ||||
|         private static readonly (string, string, string?, int)[] FieldNames = [ | ||||
|             ("MgNr", "MgNr.", null, 12), | ||||
|             ("Name1", "Name", null, 40), | ||||
|             ("Name2", "Vorname", null, 40), | ||||
|             ("Address", "Adresse", null, 60), | ||||
|             ("Plz", "PLZ", null, 10), | ||||
|             ("Locality", "Ort", null, 60), | ||||
|             ("SortIds", "Sorte", null, 12), | ||||
|             ("AttrIds", "Attribut", null, 16), | ||||
|             ("Areas", "Fläche", "m²", 22), | ||||
|             ("DeliveryObligations", "Lieferpflicht", "kg", 22), | ||||
|             ("DeliveryRights", "Lieferrecht", "kg", 22), | ||||
|         ]; | ||||
|  | ||||
|         public MemberAreaComsData(IEnumerable<MemberAreaComsRow> rows, int year) : | ||||
|             base($"Flächenbindungen", $"Flächenbindungen pro Mitglied {year}", rows, FieldNames) { | ||||
|         } | ||||
|  | ||||
|         public static async Task<MemberAreaComsData> ForSeason(DbSet<MemberAreaComsRowSingle> table, int year) { | ||||
|             return new MemberAreaComsData( | ||||
|                (await FromDbSet(table, year)).GroupBy( | ||||
|                    r => r.MgNr, | ||||
|                    (k, g) => new MemberAreaComsRow(g) | ||||
|              ), year); | ||||
|         } | ||||
|  | ||||
|         private static async Task<IEnumerable<MemberAreaComsRowSingle>> FromDbSet(DbSet<MemberAreaComsRowSingle> table, int year) { | ||||
|             return await table.FromSql($""" | ||||
|                     SELECT m.mgnr, m.name AS name_1, | ||||
|                            COALESCE(m.prefix || ' ', '') || m.given_name || | ||||
|                            COALESCE(' ' || m.middle_names, '') || COALESCE(' ' || m.suffix, '') AS name_2, | ||||
|                            p.plz, o.name AS ort, m.address, | ||||
|                            c.bucket, c.area, c.min_kg, c.max_kg | ||||
|                     FROM v_area_commitment_bucket_strict c | ||||
|                         LEFT JOIN member m ON m.mgnr = c.mgnr | ||||
|                         LEFT JOIN AT_plz_dest p ON p.id = m.postal_dest | ||||
|                         LEFT JOIN AT_ort o ON o.okz = p.okz | ||||
|                     WHERE c.year = {year} | ||||
|                     ORDER BY m.mgnr, c.bucket | ||||
|                     """).ToListAsync(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public class MemberAreaComsRow { | ||||
|         public int MgNr; | ||||
|         public string Name1; | ||||
|         public string? Name2; | ||||
|         public string Address; | ||||
|         public int Plz; | ||||
|         public string Locality; | ||||
|         public string[] SortIds; | ||||
|         public string[] AttrIds; | ||||
|         public int[] Areas; | ||||
|         public int[] DeliveryObligations; | ||||
|         public int[] DeliveryRights; | ||||
|  | ||||
|         public MemberAreaComsRow(IEnumerable<MemberAreaComsRowSingle> rows) { | ||||
|             var f = rows.First(); | ||||
|             MgNr = f.MgNr; | ||||
|             Name1 = f.Name1; | ||||
|             Name2 = f.Name2; | ||||
|             Address = f.Address; | ||||
|             Plz = f.Plz; | ||||
|             Locality = f.Locality.Split(",")[0]; | ||||
|             SortIds = rows.Select(r => r.VtrgId[..2]).ToArray(); | ||||
|             AttrIds = rows.Select(r => r.VtrgId[2..]).ToArray(); | ||||
|             Areas = rows.Select(r => r.Area).ToArray(); | ||||
|             DeliveryObligations = rows.Select(r => r.MinKg).ToArray(); | ||||
|             DeliveryRights = rows.Select(r => r.MaxKg).ToArray(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     [Keyless] | ||||
|     public class MemberAreaComsRowSingle { | ||||
|         [Column("mgnr")] | ||||
|         public int MgNr { get; set; } | ||||
|         [Column("name_1")] | ||||
|         public required string Name1 { get; set; } | ||||
|         [Column("name_2")] | ||||
|         public string? Name2 { get; set; } | ||||
|         [Column("address")] | ||||
|         public required string Address { get; set; } | ||||
|         [Column("plz")] | ||||
|         public int Plz { get; set; } | ||||
|         [Column("ort")] | ||||
|         public required string Locality { get; set; } | ||||
|         [Column("bucket")] | ||||
|         public required string VtrgId { get; set; } | ||||
|         [Column("area")] | ||||
|         public int Area { get; set; } | ||||
|         [Column("min_kg")] | ||||
|         public int MinKg { get; set; } | ||||
|         [Column("max_kg")] | ||||
|         public int MaxKg { get; set; } | ||||
|     } | ||||
| } | ||||
| @@ -6,7 +6,7 @@ using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace Elwig.Models.Dtos { | ||||
|     public class MemberDeliveryPerVariantData : DataTable<MemberDeliveryPerVariantRow> { | ||||
|     public class MemberDeliveryPerVarietyData : DataTable<MemberDeliveryPerVariantRow> { | ||||
| 
 | ||||
|         private static readonly (string, string, string?, int)[] FieldNames = [ | ||||
|             ("MgNr", "MgNr.", null, 12), | ||||
| @@ -22,13 +22,12 @@ namespace Elwig.Models.Dtos { | ||||
|             ("Yields", "Ertrag", "kg/ha", 22), | ||||
|         ]; | ||||
| 
 | ||||
| 
 | ||||
|         public MemberDeliveryPerVariantData(IEnumerable<MemberDeliveryPerVariantRow> rows, int year) : | ||||
|         public MemberDeliveryPerVarietyData(IEnumerable<MemberDeliveryPerVariantRow> rows, int year) : | ||||
|             base($"Liefermengen", $"Liefermengen pro Mitglied, Sorte und Attribut {year}", rows, FieldNames) { | ||||
|         } | ||||
| 
 | ||||
|         public static async Task<MemberDeliveryPerVariantData> ForSeason(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) { | ||||
|             return new MemberDeliveryPerVariantData( | ||||
|         public static async Task<MemberDeliveryPerVarietyData> ForSeason(DbSet<MemberDeliveryPerVariantRowSingle> table, int year) { | ||||
|             return new MemberDeliveryPerVarietyData( | ||||
|                (await FromDbSet(table, year)).GroupBy( | ||||
|                    r => r.MgNr, | ||||
|                    (k, g) => new MemberDeliveryPerVariantRow(g) | ||||
| @@ -48,6 +48,7 @@ namespace Elwig.Services { | ||||
|             var filterNotVar = new List<string>(); | ||||
|             var filterAttr = new List<string>(); | ||||
|             var filterNotAttr = new List<string>(); | ||||
|             var filterSeasons = new List<int>(); | ||||
|  | ||||
|             var filter = vm.TextFilter; | ||||
|             if (filter.Count > 0) { | ||||
| @@ -87,6 +88,10 @@ namespace Elwig.Services { | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"ohne {var[e[1..3].ToUpper()].Name}"); | ||||
|                         filterNames.Add($"ohne Attribut {attrId[e[3..].ToUpper()].Name}"); | ||||
|                     } else if (e.Length == 4 && int.TryParse(e, out var year)) { | ||||
|                         filterSeasons.Add(year); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"laufend {e}"); | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
| @@ -94,6 +99,7 @@ namespace Elwig.Services { | ||||
|                 if (filterNotVar.Count > 0) areaComQuery = areaComQuery.Where(a => !filterNotVar.Contains(a.AreaComType.WineVar.SortId)); | ||||
|                 if (filterAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId != null && filterAttr.Contains(a.AreaComType.WineAttr.AttrId)); | ||||
|                 if (filterNotAttr.Count > 0) areaComQuery = areaComQuery.Where(a => a.AreaComType.WineAttr!.AttrId == null || !filterNotAttr.Contains(a.AreaComType.WineAttr.AttrId)); | ||||
|                 foreach (var year in filterSeasons) areaComQuery = Utils.ActiveAreaCommitments(areaComQuery, year); | ||||
|             } | ||||
|  | ||||
|             return (filterNames, areaComQuery, filter); | ||||
|   | ||||
| @@ -212,6 +212,7 @@ namespace Elwig.Services { | ||||
|             var filterLfbisNr = new List<string>(); | ||||
|             var filterUstIdNr = new List<string>(); | ||||
|             var filterAreaCom = new List<string>(); | ||||
|             var filterNotAreaCom = new List<string>(); | ||||
|  | ||||
|             var filter = vm.TextFilter; | ||||
|             if (filter.Count > 0) { | ||||
| @@ -314,10 +315,22 @@ namespace Elwig.Services { | ||||
|                         memberQuery = memberQuery.Where(m => m.TelephoneNumbers.Any(t => t.Number.Replace(" ", "").StartsWith(e))); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"Tel.-Nr. {e}"); | ||||
|                     } else if (e.Length >= 5 && e.Length <= 14 && "flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) { | ||||
|                         filterAreaCom.AddRange(areaComs.Keys); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"Flächenbindung"); | ||||
|                     } else if (e.Length >= 6 && e.Length <= 15 && "!flächenbindung".StartsWith(e, StringComparison.CurrentCultureIgnoreCase)) { | ||||
|                         filterNotAreaCom.AddRange(areaComs.Keys); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"keine Flächenbindung"); | ||||
|                     } else if (areaComs.ContainsKey(e.ToUpper())) { | ||||
|                         filterAreaCom.Add(e.ToUpper()); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"Flächenbindung {e.ToUpper()}"); | ||||
|                     } else if (e.Length >= 3 && e[0] == '!' && areaComs.ContainsKey(e[1..].ToUpper())) { | ||||
|                         filterNotAreaCom.Add(e[1..].ToUpper()); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add($"ohne Flächenbindung {e[1..].ToUpper()}"); | ||||
|                     } else if (Validator.CheckLfbisNr(e)) { | ||||
|                         filterLfbisNr.Add(e); | ||||
|                         filter.RemoveAt(i--); | ||||
| @@ -337,6 +350,7 @@ namespace Elwig.Services { | ||||
|                 if (filterKgNr.Count > 0) memberQuery = memberQuery.Where(m => m.DefaultKgNr != null && filterKgNr.Contains((int)m.DefaultKgNr)); | ||||
|                 if (filterZwst.Count > 0) memberQuery = memberQuery.Where(m => m.ZwstId != null && filterZwst.Contains(m.ZwstId)); | ||||
|                 if (filterAreaCom.Count > 0) memberQuery = memberQuery.Where(m => m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments()).Any(c => filterAreaCom.Contains(c.VtrgId))); | ||||
|                 if (filterNotAreaCom.Count > 0) memberQuery = memberQuery.Where(m => !m.AreaCommitments.AsQueryable().Where(Utils.ActiveAreaCommitments()).All(c => filterNotAreaCom.Contains(c.VtrgId))); | ||||
|                 if (filterLfbisNr.Count > 0) memberQuery = memberQuery.Where(m => m.LfbisNr != null && filterLfbisNr.Contains(m.LfbisNr)); | ||||
|                 if (filterUstIdNr.Count > 0) memberQuery = memberQuery.Where(m => m.UstIdNr != null && filterUstIdNr.Contains(m.UstIdNr)); | ||||
|             } | ||||
|   | ||||
| @@ -8,7 +8,6 @@ using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using System.Windows; | ||||
| using System.Windows.Controls; | ||||
| using System.Windows.Threading; | ||||
| using System.Windows.Input; | ||||
|  | ||||
| namespace Elwig.Windows { | ||||
| @@ -358,22 +357,6 @@ namespace Elwig.Windows { | ||||
|             UpdateComboBox(ortInput); | ||||
|         } | ||||
|  | ||||
|         protected static void InitializeDelayTimer(TextBox tb, Action<object, TextChangedEventArgs> handler) { | ||||
|             var timer = new DispatcherTimer { | ||||
|                 Interval = TimeSpan.FromMilliseconds(250) | ||||
|             }; | ||||
|             timer.Tick += (object? sender, EventArgs evt) => { | ||||
|                 timer.Stop(); | ||||
|                 var (oSender, oEvent) = ((object, TextChangedEventArgs))timer.Tag; | ||||
|                 handler(oSender, oEvent); | ||||
|             }; | ||||
|             tb.TextChanged += (object sender, TextChangedEventArgs evt) => { | ||||
|                 timer.Stop(); | ||||
|                 timer.Tag = (sender, evt); | ||||
|                 timer.Start(); | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         protected bool InputTextChanged(TextBox input) { | ||||
|             return InputTextChanged(input, new ValidationResult(true, null)); | ||||
|         } | ||||
|   | ||||
| @@ -88,8 +88,9 @@ | ||||
|                         <LineBreak/> | ||||
|                         Filtern nach:<LineBreak/> | ||||
|                         <Bold>Sorte</Bold>: z.B. GV, zw, RR, ...<LineBreak/> | ||||
|                         <Bold>Attribut</Bold>: z.B. Kabinett, dac, ... <LineBreak/> | ||||
|                         <Bold>Flächenbindung</Bold>: z.B. GVK, GVD, ... | ||||
|                         <Bold>Attribut</Bold>: z.B. Kabinett, dac, ...<LineBreak/> | ||||
|                         <Bold>Flächenbindung</Bold>: z.B. GVK, GVD, ...<LineBreak/> | ||||
|                         <Bold>Saison</Bold>: z.B. 2020, 2019... (in dieser Saison aktiv) | ||||
|                     </TextBlock> | ||||
|                 </TextBox.ToolTip> | ||||
|             </TextBox> | ||||
|   | ||||
| @@ -33,7 +33,7 @@ namespace Elwig.Windows { | ||||
|                 GstNrInput, AreaInput, AreaComTypeInput, WineCultivationInput | ||||
|             ]; | ||||
|  | ||||
|             InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             SearchInput.TextChanged -= SearchInput_TextChanged; | ||||
|             ActiveAreaCommitmentInput.Content = ((string)ActiveAreaCommitmentInput.Content).Replace("2020", $"{Utils.CurrentLastSeason}"); | ||||
|         } | ||||
|   | ||||
| @@ -67,13 +67,29 @@ | ||||
|         <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Lieferschein"> | ||||
|                 <MenuItem x:Name="Menu_DeliveryNote_Show" Header="...anzeigen (PDF)" IsEnabled="False" | ||||
|                           Click="Menu_DeliveryNote_Show_Click" InputGestureText="Strg+P"/> | ||||
|                           Click="Menu_DeliveryNote_Show_Click" InputGestureText="Strg+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_DeliveryNote_SavePdf" Header="...speichern... (PDF)" IsEnabled="False" | ||||
|                           Click="Menu_DeliveryNote_SavePdf_Click"/> | ||||
|                           Click="Menu_DeliveryNote_SavePdf_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_DeliveryNote_Print" Header="...drucken" IsEnabled="False" | ||||
|                           Click="Menu_DeliveryNote_Print_Click" InputGestureText="Strg+Shift+P"/> | ||||
|                           Click="Menu_DeliveryNote_Print_Click" InputGestureText="Strg+Shift+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_DeliveryNote_Email" Header="...per E-Mail schicken" IsEnabled="False" | ||||
|                           Click="Menu_DeliveryNote_Email_Click"/> | ||||
|                           Click="Menu_DeliveryNote_Email_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Lieferjournal"> | ||||
|                 <MenuItem x:Name="Menu_DeliveryJournal_SaveFilters" Header="...aus Filtern speichern... (Excel)" | ||||
|   | ||||
| @@ -66,7 +66,7 @@ namespace Elwig.Windows { | ||||
|             SecondsTimer.Tick += new EventHandler(OnSecondPassed); | ||||
|             SecondsTimer.Interval = new TimeSpan(0, 0, 1); | ||||
|  | ||||
|             InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             SearchInput.TextChanged -= SearchInput_TextChanged; | ||||
|             ViewModel.FilterSeason = Utils.CurrentLastSeason; | ||||
|  | ||||
|   | ||||
| @@ -69,13 +69,29 @@ | ||||
|         <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Anmeldeliste"> | ||||
|                 <MenuItem x:Name="Menu_DeliveryAncmtList_SaveSelected" Header="...von ausgewähltem Leseplan speichern... (Excel)" | ||||
|                           Click="Menu_DeliveryAncmtList_SaveSelected_Click"/> | ||||
|                           Click="Menu_DeliveryAncmtList_SaveSelected_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_DeliveryAncmtList_ShowSelected" Header="...von ausgewähltem Leseplan anzeigen (PDF)" | ||||
|                           Click="Menu_DeliveryAncmtList_ShowSelected_Click" InputGestureText="Strg+P"/> | ||||
|                           Click="Menu_DeliveryAncmtList_ShowSelected_Click" InputGestureText="Strg+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_DeliveryAncmtList_SavePdfSelected" Header="...von ausgewähltem Leseplan speichern... (PDF)" | ||||
|                           Click="Menu_DeliveryAncmtList_SavePdfSelected_Click"/> | ||||
|                           Click="Menu_DeliveryAncmtList_SavePdfSelected_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_DeliveryAncmtList_PrintSelected" Header="...von ausgewähltem Leseplan drucken" | ||||
|                           Click="Menu_DeliveryAncmtList_PrintSelected_Click" InputGestureText="Strg+Shift+P"/> | ||||
|                           Click="Menu_DeliveryAncmtList_PrintSelected_Click" InputGestureText="Strg+Shift+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|         </Menu> | ||||
|  | ||||
|   | ||||
| @@ -33,7 +33,7 @@ namespace Elwig.Windows { | ||||
|  | ||||
|             DoShowWarningWindows = false; | ||||
|  | ||||
|             InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             SearchInput.TextChanged -= SearchInput_TextChanged; | ||||
|             ViewModel.FilterSeason = Utils.CurrentLastSeason; | ||||
|         } | ||||
|   | ||||
| @@ -27,7 +27,7 @@ namespace Elwig.Windows { | ||||
|                 DateInput, BranchInput, DescriptionInput, MainWineVarietiesInput, | ||||
|             ]; | ||||
|  | ||||
|             InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             SearchInput.TextChanged -= SearchInput_TextChanged; | ||||
|             ViewModel.FilterSeason = Utils.CurrentLastSeason; | ||||
|         } | ||||
|   | ||||
| @@ -36,9 +36,10 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void EventList_SelectionChanged(object sender, RoutedEventArgs evt) { | ||||
|             var t = EventList.SelectedItem.GetType(); | ||||
|             var item = EventList.SelectedItem; | ||||
|             var t = item.GetType(); | ||||
|             var p = t.GetProperty("Event")!; | ||||
|             EventData.Text = ((EventLogEntry)p.GetValue(EventList.SelectedItem)!).Message; | ||||
|             EventData.Text = ((EventLogEntry)p.GetValue(item)!).Message; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
							
								
								
									
										54
									
								
								Elwig/Windows/MailLogWindow.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								Elwig/Windows/MailLogWindow.xaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| <Window x:Class="Elwig.Windows.MailLogWindow" | ||||
|         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | ||||
|         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | ||||
|         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | ||||
|         xmlns:local="clr-namespace:Elwig.Windows" | ||||
|         Title="Ausgangs-Protokoll - Rundschreiben - Elwig" Height="600" Width="1000"> | ||||
|     <Grid> | ||||
|         <Grid.ColumnDefinitions> | ||||
|             <ColumnDefinition Width="3*"/> | ||||
|             <ColumnDefinition Width="5"/> | ||||
|             <ColumnDefinition Width="2*"/> | ||||
|         </Grid.ColumnDefinitions> | ||||
|  | ||||
|         <TextBox x:Name="FilterInput" Margin="10,10,300,10" Height="25" FontSize="14" Padding="2" TextWrapping="NoWrap" | ||||
|                  HorizontalAlignment="Stretch" VerticalAlignment="Top" | ||||
|                  TextChanged="FilterInput_TextChanged"/> | ||||
|  | ||||
|         <ComboBox x:Name="TypeInput" Margin="10,10,165,10" Width="130" Height="25" FontSize="14" | ||||
|                   HorizontalAlignment="Right" VerticalAlignment="Top" | ||||
|                   SelectionChanged="TypeInput_SelectionChanged"> | ||||
|             <ComboBoxItem Content="Post & E-Mail" IsSelected="True"/> | ||||
|             <ComboBoxItem Content="Nur Post"/> | ||||
|             <ComboBoxItem Content="Nur E-Mail"/> | ||||
|         </ComboBox> | ||||
|  | ||||
|         <ComboBox x:Name="TimeSpanInput" Margin="10,10,10,10" Width="150" Height="25" FontSize="14" | ||||
|                   HorizontalAlignment="Right" VerticalAlignment="Top" | ||||
|                   SelectionChanged="TimeSpanInput_SelectionChanged"> | ||||
|             <ComboBoxItem Content="letzten 7 Tage" IsSelected="True"/> | ||||
|             <ComboBoxItem Content="letzten 6 Monate"/> | ||||
|             <ComboBoxItem Content="Immer"/> | ||||
|         </ComboBox> | ||||
|  | ||||
|         <DataGrid x:Name="MailList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single" | ||||
|                   CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False" | ||||
|                   SelectionChanged="MailList_SelectionChanged" | ||||
|                   Margin="10,40,5,10"> | ||||
|             <DataGrid.Columns> | ||||
|                 <DataGridTextColumn Header="Zeitpunkt" Binding="{Binding DateTime, StringFormat='{}{0:dd.MM.yyyy HH:mm:ss}'}" Width="120"/> | ||||
|                 <DataGridTextColumn Header="Typ" Binding="{Binding Type}" Width="50"/> | ||||
|                 <DataGridTextColumn Header="MgNr." Binding="{Binding MgNr}" Width="50"/> | ||||
|                 <DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="200"/> | ||||
|                 <DataGridTextColumn Header="Adressen" Binding="{Binding Addresses}" Width="200"/> | ||||
|                 <DataGridTextColumn Header="Betreff" Binding="{Binding Subject}" Width="250"/> | ||||
|                 <DataGridTextColumn Header="Anhänge" Binding="{Binding Attachments}" Width="200"/> | ||||
|             </DataGrid.Columns> | ||||
|         </DataGrid> | ||||
|  | ||||
|         <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/> | ||||
|  | ||||
|         <TextBox x:Name="MailData" Grid.Column="2" Margin="5,10,10,10" IsReadOnly="True" | ||||
|                  HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible"/> | ||||
|     </Grid> | ||||
| </Window> | ||||
							
								
								
									
										83
									
								
								Elwig/Windows/MailLogWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								Elwig/Windows/MailLogWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,83 @@ | ||||
| using Elwig.Helpers; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Windows; | ||||
|  | ||||
| namespace Elwig.Windows { | ||||
|     public partial class MailLogWindow : Window { | ||||
|  | ||||
|         record struct Row (DateTime DateTime, string Type, int MgNr, string Name, string Addresses, string Subject, string Attachments); | ||||
|  | ||||
|         private List<Row> Data = []; | ||||
|  | ||||
|         public MailLogWindow() { | ||||
|             InitializeComponent(); | ||||
|             WindowState = WindowState.Maximized; | ||||
|             ControlUtils.InitializeDelayTimer(FilterInput, FilterInput_TextChanged); | ||||
|             FilterInput.TextChanged -= FilterInput_TextChanged; | ||||
|         } | ||||
|  | ||||
|         private async void TimeSpanInput_SelectionChanged(object sender, RoutedEventArgs evt) { | ||||
|             DateTime? fromDate = DateTime.Now; | ||||
|             if (TimeSpanInput.SelectedIndex == 0) { | ||||
|                 fromDate = fromDate.Value.AddDays(-7); | ||||
|             } else if (TimeSpanInput.SelectedIndex == 1) { | ||||
|                 fromDate = fromDate.Value.AddMonths(-6); | ||||
|             } else { | ||||
|                 fromDate = null; | ||||
|             } | ||||
|             var mails = await Utils.GetSentMails(fromDate: fromDate == null ? null : DateOnly.FromDateTime(fromDate.Value)); | ||||
|             Data = mails.Reverse().Select(m => new Row( | ||||
|                 m.DateTime, | ||||
|                 m.Type == "email" ? "E-Mail" : m.Type == "postal" ? "Post" : "?", | ||||
|                 m.MgNr, | ||||
|                 m.Name, | ||||
|                 string.Join("\n", m.Addresses), | ||||
|                 m.Subject, | ||||
|                 string.Join("\n", m.Attachments) | ||||
|             )).ToList(); | ||||
|             MailList.ItemsSource = Data; | ||||
|             ApplyFilters(); | ||||
|         } | ||||
|  | ||||
|         private void FilterInput_TextChanged(object sender, RoutedEventArgs evt) { | ||||
|             ApplyFilters(); | ||||
|         } | ||||
|  | ||||
|         private void TypeInput_SelectionChanged(object sender, RoutedEventArgs evt) { | ||||
|             ApplyFilters(); | ||||
|         } | ||||
|  | ||||
|         private void ApplyFilters() { | ||||
|             var filters = FilterInput.Text.Split(' '); | ||||
|             IEnumerable<Row> data = Data; | ||||
|             switch (TypeInput.SelectedIndex) { | ||||
|                 case 1: data = data.Where(d => d.Type == "Post"); break; | ||||
|                 case 2: data = data.Where(d => d.Type == "E-Mail"); break; | ||||
|             } | ||||
|             foreach (var filter in filters) { | ||||
|                 if (int.TryParse(filter, out var mgnr)) { | ||||
|                     data = data.Where(d => d.MgNr == mgnr); | ||||
|                 } else { | ||||
|                     var f = filter.ToLower(); | ||||
|                     data = data.Where(d => d.Name.Contains(f, StringComparison.CurrentCultureIgnoreCase) || | ||||
|                                            d.Addresses.Contains(f, StringComparison.CurrentCultureIgnoreCase) || | ||||
|                                            d.Subject.Contains(f, StringComparison.CurrentCultureIgnoreCase) || | ||||
|                                            d.Attachments.Contains(f, StringComparison.CurrentCultureIgnoreCase)); | ||||
|                 } | ||||
|             } | ||||
|             if (IsLoaded) | ||||
|                 MailList.ItemsSource = data.ToList(); | ||||
|         } | ||||
|  | ||||
|         private async void MailList_SelectionChanged(object sender, RoutedEventArgs evt) { | ||||
|             if (MailList.SelectedItem is not Row item) return; | ||||
|             if (item.Type == "E-Mail") { | ||||
|                 MailData.Text = await Utils.FindSentMailBody(item.DateTime); | ||||
|             } else { | ||||
|                 MailData.Text = ""; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -27,281 +27,334 @@ | ||||
|             <Setter Property="TextWrapping" Value="NoWrap"/> | ||||
|         </Style> | ||||
|     </Window.Resources> | ||||
|     <TabControl x:Name="TabControl" BorderThickness="0" PreviewDragOver="Document_PreviwDragOver" AllowDrop="True" Drop="Document_Drop"> | ||||
|         <TabItem Header="Dokumente" Visibility="Collapsed"> | ||||
|             <Grid> | ||||
|                 <Grid.ColumnDefinitions> | ||||
|                     <ColumnDefinition Width="*"/> | ||||
|                     <ColumnDefinition Width="320"/> | ||||
|                 </Grid.ColumnDefinitions> | ||||
|     <Grid> | ||||
|         <Grid.RowDefinitions> | ||||
|             <RowDefinition Height="19"/> | ||||
|             <RowDefinition Height="1*"/> | ||||
|             <RowDefinition Height="24"/> | ||||
|         </Grid.RowDefinitions> | ||||
|  | ||||
|                 <Grid Height="200" VerticalAlignment="Top" HorizontalAlignment="Stretch"> | ||||
|         <Menu BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Hilfe"> | ||||
|                 <MenuItem x:Name="Menu_Help_Log" Header="Ausgangs-Protokoll anzeigen" | ||||
|                           Click="Menu_Help_Log_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|         </Menu> | ||||
|  | ||||
|         <TabControl x:Name="TabControl" BorderThickness="0" Grid.Row="1" | ||||
|                     PreviewDragOver="Document_PreviwDragOver" AllowDrop="True" Drop="Document_Drop"> | ||||
|             <TabItem Header="Dokumente" Visibility="Collapsed"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                         <ColumnDefinition Width="25"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                         <ColumnDefinition Width="320"/> | ||||
|                     </Grid.ColumnDefinitions> | ||||
|                     <Grid.RowDefinitions> | ||||
|                         <RowDefinition Height="*"/> | ||||
|                         <RowDefinition Height="30"/> | ||||
|                     </Grid.RowDefinitions> | ||||
|  | ||||
|                     <Label Content="Verfügbare Dokumente" | ||||
|                            Grid.Column="0" Margin="10,8,10,10"/> | ||||
|                     <ListBox x:Name="AvaiableDocumentsList" | ||||
|                              Grid.Column="0" Margin="10,30,10,10" | ||||
|                              SelectionChanged="AvaiableDocumentsList_SelectionChanged"/> | ||||
|  | ||||
|                     <Button x:Name="DocumentAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" | ||||
|                             Grid.Column="1" Margin="0,0,0,30" VerticalAlignment="Center" Height="25" IsEnabled="False" | ||||
|                             Click="DocumentAddButton_Click"/> | ||||
|                     <Button x:Name="DocumentRemoveButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="1.5,0,0,0" | ||||
|                             Grid.Column="1" Margin="0,30,0,0" VerticalAlignment="Center" Height="25" IsEnabled="False" | ||||
|                             Click="DocumentRemoveButton_Click"/> | ||||
|  | ||||
|                     <Label Content="Ausgewählte Dokumente" | ||||
|                            Grid.Column="2" Margin="10,8,10,10"/> | ||||
|                     <ListBox x:Name="SelectedDocumentsList" DisplayMemberPath="Name" | ||||
|                              Grid.Column="2" Margin="10,30,10,37" | ||||
|                              SelectionChanged="SelectedDocumentsList_SelectionChanged"> | ||||
|                         <ListBox.InputBindings> | ||||
|                             <KeyBinding Key="Delete" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/> | ||||
|                         </ListBox.InputBindings> | ||||
|                     </ListBox> | ||||
|                     <Button x:Name="SelectDocumentButton" Content="Durchsuchen..." | ||||
|                             Grid.Column="2" VerticalAlignment="Bottom" Margin="10,10,10,10" Height="22" | ||||
|                             Click="SelectDocumentButton_Click"/> | ||||
|                 </Grid> | ||||
|  | ||||
|                 <GroupBox x:Name="DocumentBox" Header="Dokument" Margin="10,170,10,47" HorizontalAlignment="Stretch"> | ||||
|                     <Grid> | ||||
|                     <Grid Height="200" VerticalAlignment="Top" HorizontalAlignment="Stretch"> | ||||
|                         <Grid.ColumnDefinitions> | ||||
|                             <ColumnDefinition Width="70"/> | ||||
|                             <ColumnDefinition Width="*"/> | ||||
|                             <ColumnDefinition Width="25"/> | ||||
|                             <ColumnDefinition Width="*"/> | ||||
|                         </Grid.ColumnDefinitions> | ||||
|                         <Grid.RowDefinitions> | ||||
|                             <RowDefinition Height="*"/> | ||||
|                             <RowDefinition Height="30"/> | ||||
|                         </Grid.RowDefinitions> | ||||
|  | ||||
|                         <CheckBox x:Name="DocumentNonDeliverersInput" Content="Auch Nicht-Lieferanten miteinbeziehen" | ||||
|                                   Margin="10,10,10,10" Grid.Column="1"/> | ||||
|                         <Label Content="Verfügbare Dokumente" | ||||
|                                Grid.Column="0" Margin="10,8,10,10"/> | ||||
|                         <ListBox x:Name="AvaiableDocumentsList" | ||||
|                                  Grid.Column="0" Margin="10,30,10,10" | ||||
|                                  SelectionChanged="AvaiableDocumentsList_SelectionChanged"/> | ||||
|  | ||||
|                         <Label x:Name="DocumentFooterLabel" Content="Fußtext:" Margin="10,40,0,10"/> | ||||
|                         <TextBox x:Name="DeliveryConfirmationFooterInput" Grid.Column="1" | ||||
|                                  Margin="0,40,10,10" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" | ||||
|                                  AcceptsReturn="True" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" | ||||
|                                  TextChanged="DocumentInput_TextChanged"/> | ||||
|                         <TextBox x:Name="CreditNoteFooterInput" Grid.Column="1" | ||||
|                                  Margin="0,10,10,10" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" | ||||
|                                  AcceptsReturn="True" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" | ||||
|                                  TextChanged="DocumentInput_TextChanged"/> | ||||
|                         <Button x:Name="DocumentAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" | ||||
|                                 Grid.Column="1" Margin="0,0,0,30" VerticalAlignment="Center" Height="25" IsEnabled="False" | ||||
|                                 Click="DocumentAddButton_Click"/> | ||||
|                         <Button x:Name="DocumentRemoveButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="1.5,0,0,0" | ||||
|                                 Grid.Column="1" Margin="0,30,0,0" VerticalAlignment="Center" Height="25" IsEnabled="False" | ||||
|                                 Click="DocumentRemoveButton_Click"/> | ||||
|  | ||||
|                         <Label Content="Ausgewählte Dokumente" | ||||
|                                Grid.Column="2" Margin="10,8,10,10"/> | ||||
|                         <ListBox x:Name="SelectedDocumentsList" DisplayMemberPath="Name" | ||||
|                                  Grid.Column="2" Margin="10,30,10,37" | ||||
|                                  SelectionChanged="SelectedDocumentsList_SelectionChanged"> | ||||
|                             <ListBox.InputBindings> | ||||
|                                 <KeyBinding Key="Delete" Command="{Binding Path=DeleteCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/> | ||||
|                             </ListBox.InputBindings> | ||||
|                         </ListBox> | ||||
|                         <Button x:Name="SelectDocumentButton" Content="Durchsuchen..." | ||||
|                                 Grid.Column="2" VerticalAlignment="Bottom" Margin="10,10,10,10" Height="22" | ||||
|                                 Click="SelectDocumentButton_Click"/> | ||||
|                     </Grid> | ||||
|                 </GroupBox> | ||||
|  | ||||
|                 <TextBox x:Name="PostalLocation" Grid.Column="1" TextChanged="PostalLocation_TextChanged" | ||||
|                          Margin="10,30,10,10" Width="120" HorizontalAlignment="Left"/> | ||||
|                 <Label Content=", am" Margin="130,30,10,10" FontSize="14" Grid.Column="1"/> | ||||
|                 <TextBox x:Name="PostalDate" Grid.Column="1" Text="01.01.2020" | ||||
|                          Margin="162,30,10,10" Width="78" HorizontalAlignment="Left" | ||||
|                          TextChanged="Date_TextChanged" LostFocus="Date_LostFocus"/> | ||||
|                     <GroupBox x:Name="DocumentBox" Header="Dokument" Margin="10,170,10,47" HorizontalAlignment="Stretch"> | ||||
|                         <Grid> | ||||
|                             <Grid.ColumnDefinitions> | ||||
|                                 <ColumnDefinition Width="70"/> | ||||
|                                 <ColumnDefinition Width="*"/> | ||||
|                             </Grid.ColumnDefinitions> | ||||
|  | ||||
|                 <GroupBox Header="Adressaten" Margin="10,70,10,47" Grid.Column="1"> | ||||
|                     <Grid> | ||||
|                         <RadioButton GroupName="Recipients" x:Name="RecipientsActiveMembersInput" Content="aktive Mitglieder" | ||||
|                                      Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                         <RadioButton GroupName="Recipients" x:Name="RecipientsAreaComMembersInput" Content="Mitglieder mit Flächenbindung" | ||||
|                                      Margin="10,30,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                         <RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryAncmtMembersInput" Content="Mitglieder mit Anmeldung" | ||||
|                                      Margin="10,50,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                         <RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryMembersInput" Content="Lieferanten der Saison" | ||||
|                                      Margin="10,70,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                         <RadioButton GroupName="Recipients" x:Name="RecipientsNonDeliveryMembersInput" Content="Nicht-Lieferanten der Saison" | ||||
|                                      Margin="10,90,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                         <RadioButton GroupName="Recipients" x:Name="RecipientsCustomInput" Content="Benutzerdefiniert" | ||||
|                                      Margin="10,110,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                             <CheckBox x:Name="DocumentNonDeliverersInput" Content="Auch Nicht-Lieferanten miteinbeziehen" | ||||
|                                       Margin="10,10,10,10" Grid.Column="1"/> | ||||
|  | ||||
|                         <Label Content="Zwst.:" x:Name="MemberBranchLabel" Margin="10,140,0,10"/> | ||||
|                         <ctrl:CheckComboBox x:Name="MemberBranchInput" AllItemsSelectedContent="Alle Stammzweigstellen" Delimiter=", " DisplayMemberPath="Name" | ||||
|                                             Margin="50,140,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                             SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|                             <Label x:Name="DocumentFooterLabel" Content="Fußtext:" Margin="10,40,0,10"/> | ||||
|                             <TextBox x:Name="DeliveryConfirmationFooterInput" Grid.Column="1" | ||||
|                                      Margin="0,40,10,10" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" | ||||
|                                      AcceptsReturn="True" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" | ||||
|                                      TextChanged="DocumentInput_TextChanged"/> | ||||
|                             <TextBox x:Name="CreditNoteFooterInput" Grid.Column="1" | ||||
|                                      Margin="0,10,10,10" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" | ||||
|                                      AcceptsReturn="True" VerticalScrollBarVisibility="Visible" TextWrapping="Wrap" | ||||
|                                      TextChanged="DocumentInput_TextChanged"/> | ||||
|                         </Grid> | ||||
|                     </GroupBox> | ||||
|  | ||||
|                         <Label Content="Gem.:" x:Name="MemberKgLabel" Margin="10,170,0,10"/> | ||||
|                         <ctrl:CheckComboBox x:Name="MemberKgInput" AllItemsSelectedContent="Alle Stammgemeinden" Delimiter=", " DisplayMemberPath="Name" | ||||
|                                             IsSelectAllActive="True" SelectAllContent="Alle Stammgemeinden" | ||||
|                                             Margin="50,170,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                             SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|                     <TextBox x:Name="PostalLocation" Grid.Column="1" TextChanged="PostalLocation_TextChanged" | ||||
|                              Margin="10,30,10,10" Width="120" HorizontalAlignment="Left"/> | ||||
|                     <Label Content=", am" Margin="130,30,10,10" FontSize="14" Grid.Column="1"/> | ||||
|                     <TextBox x:Name="PostalDate" Grid.Column="1" Text="01.01.2020" | ||||
|                              Margin="162,30,10,10" Width="78" HorizontalAlignment="Left" | ||||
|                              TextChanged="Date_TextChanged" LostFocus="Date_LostFocus"/> | ||||
|  | ||||
|                         <Label Content="Bio-Betrieb:" x:Name="MemberOrganicLabel" Margin="10,200,0,10"/> | ||||
|                         <RadioButton x:Name="MemberOrganicYesInput" Content="Ja" GroupName="MemberOrganic" | ||||
|                                      Margin="80,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="MemberInput_Checked"/> | ||||
|                         <RadioButton x:Name="MemberOrganicNoInput" Content="Nein" GroupName="MemberOrganic" | ||||
|                                      Margin="125,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="MemberInput_Checked"/> | ||||
|                         <RadioButton x:Name="MemberOrganicIndifferentInput" Content="Egal" GroupName="MemberOrganic" | ||||
|                                      Margin="180,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="MemberInput_Checked"/> | ||||
|                     <GroupBox Header="Adressaten" Margin="10,70,10,47" Grid.Column="1"> | ||||
|                         <Grid> | ||||
|                             <RadioButton GroupName="Recipients" x:Name="RecipientsActiveMembersInput" Content="aktive Mitglieder" | ||||
|                                          Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                             <RadioButton GroupName="Recipients" x:Name="RecipientsAreaComMembersInput" Content="Mitglieder mit Flächenbindung" | ||||
|                                          Margin="10,30,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                             <RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryAncmtMembersInput" Content="Mitglieder mit Anmeldung" | ||||
|                                          Margin="10,50,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                             <RadioButton GroupName="Recipients" x:Name="RecipientsDeliveryMembersInput" Content="Lieferanten der Saison" | ||||
|                                          Margin="10,70,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                             <RadioButton GroupName="Recipients" x:Name="RecipientsNonDeliveryMembersInput" Content="Nicht-Lieferanten der Saison" | ||||
|                                          Margin="10,90,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|                             <RadioButton GroupName="Recipients" x:Name="RecipientsCustomInput" Content="Benutzerdefiniert" | ||||
|                                          Margin="10,110,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="RecipientsInput_Changed" Unchecked="RecipientsInput_Changed"/> | ||||
|  | ||||
|                         <Label Content="Funktionär:" x:Name="MemberFunktionärLabel" Margin="10,230,0,10"/> | ||||
|                         <RadioButton x:Name="MemberFunktionärYesInput" Content="Ja" GroupName="MemberFunktionär" | ||||
|                                      Margin="80,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="MemberInput_Checked"/> | ||||
|                         <RadioButton x:Name="MemberFunktionärNoInput" Content="Nein" GroupName="MemberFunktionär" | ||||
|                                      Margin="125,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="MemberInput_Checked"/> | ||||
|                         <RadioButton x:Name="MemberFunktionärIndifferentInput" Content="Egal" GroupName="MemberFunktionär" | ||||
|                                      Margin="180,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                      Checked="MemberInput_Checked"/> | ||||
|                             <Label Content="Zwst.:" x:Name="MemberBranchLabel" Margin="10,140,0,10"/> | ||||
|                             <ctrl:CheckComboBox x:Name="MemberBranchInput" AllItemsSelectedContent="Alle Stammzweigstellen" Delimiter=", " DisplayMemberPath="Name" | ||||
|                                                 Margin="50,140,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                                 SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|  | ||||
|                         <Label Content="Vtrg.:" x:Name="MemberAreaComLabel" Margin="10,260,0,10"/> | ||||
|                         <ctrl:CheckComboBox x:Name="MemberAreaComInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId" | ||||
|                                             IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten" | ||||
|                                             Margin="50,260,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                             SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|                             <Label Content="Gem.:" x:Name="MemberKgLabel" Margin="10,170,0,10"/> | ||||
|                             <ctrl:CheckComboBox x:Name="MemberKgInput" AllItemsSelectedContent="Alle Stammgemeinden" Delimiter=", " DisplayMemberPath="Name" | ||||
|                                                 IsSelectAllActive="True" SelectAllContent="Alle Stammgemeinden" | ||||
|                                                 Margin="50,170,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                                 SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|  | ||||
|                         <Label Content="Tag:" x:Name="MemberDeliveryAncmtLabel" Margin="10,260,0,10"/> | ||||
|                         <ctrl:CheckComboBox x:Name="MemberDeliveryAncmtInput" AllItemsSelectedContent="Alle Lesepläne" Delimiter=", " DisplayMemberPath="Identifier" | ||||
|                                             IsSelectAllActive="True" SelectAllContent="Alle Lesepläne" | ||||
|                                             Margin="50,260,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                             SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|                             <Label Content="Bio-Betrieb:" x:Name="MemberOrganicLabel" Margin="10,200,0,10"/> | ||||
|                             <RadioButton x:Name="MemberOrganicYesInput" Content="Ja" GroupName="MemberOrganic" | ||||
|                                          Margin="80,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="MemberInput_Checked"/> | ||||
|                             <RadioButton x:Name="MemberOrganicNoInput" Content="Nein" GroupName="MemberOrganic" | ||||
|                                          Margin="125,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="MemberInput_Checked"/> | ||||
|                             <RadioButton x:Name="MemberOrganicIndifferentInput" Content="Egal" GroupName="MemberOrganic" | ||||
|                                          Margin="180,205,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="MemberInput_Checked"/> | ||||
|  | ||||
|                         <ctrl:CheckComboBox x:Name="MemberCustomInput" AllItemsSelectedContent="Alle Mitglieder" Delimiter=", " DisplayMemberPath="AdministrativeName" | ||||
|                                             IsSelectAllActive="True" SelectAllContent="Alle Mitglieder" | ||||
|                                             Margin="10,140,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                             SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|                     </Grid> | ||||
|                 </GroupBox> | ||||
|                             <Label Content="Funktionär:" x:Name="MemberFunktionärLabel" Margin="10,230,0,10"/> | ||||
|                             <RadioButton x:Name="MemberFunktionärYesInput" Content="Ja" GroupName="MemberFunktionär" | ||||
|                                          Margin="80,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="MemberInput_Checked"/> | ||||
|                             <RadioButton x:Name="MemberFunktionärNoInput" Content="Nein" GroupName="MemberFunktionär" | ||||
|                                          Margin="125,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="MemberInput_Checked"/> | ||||
|                             <RadioButton x:Name="MemberFunktionärIndifferentInput" Content="Egal" GroupName="MemberFunktionär" | ||||
|                                          Margin="180,235,10,10" VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                          Checked="MemberInput_Checked"/> | ||||
|  | ||||
|                 <Button x:Name="ContinueButton" Content="Weiter" Grid.Column="1" | ||||
|                         Margin="10,10,10,10" Height="27" Width="100" Padding="9,3" FontSize="14" | ||||
|                         VerticalAlignment="Bottom" HorizontalAlignment="Right" | ||||
|                         Click="ContinueButton_Click"/> | ||||
|             </Grid> | ||||
|         </TabItem> | ||||
|                             <Label Content="Vtrg.:" x:Name="MemberAreaComLabel" Margin="10,260,0,10"/> | ||||
|                             <ctrl:CheckComboBox x:Name="MemberAreaComInput" AllItemsSelectedContent="Alle Vertragsarten" Delimiter=", " DisplayMemberPath="VtrgId" | ||||
|                                                 IsSelectAllActive="True" SelectAllContent="Alle Vertragsarten" | ||||
|                                                 Margin="50,260,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                                 SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|  | ||||
|         <TabItem Header="Absenden" Visibility="Collapsed"> | ||||
|             <Grid> | ||||
|                 <Grid.ColumnDefinitions> | ||||
|                     <ColumnDefinition Width="*"/> | ||||
|                     <ColumnDefinition Width="1.5*"/> | ||||
|                 </Grid.ColumnDefinitions> | ||||
|                 <Grid.RowDefinitions> | ||||
|                     <RowDefinition Height="*"/> | ||||
|                     <RowDefinition Height="80"/> | ||||
|                 </Grid.RowDefinitions> | ||||
|                             <Label Content="Tag:" x:Name="MemberDeliveryAncmtLabel" Margin="10,260,0,10"/> | ||||
|                             <ctrl:CheckComboBox x:Name="MemberDeliveryAncmtInput" AllItemsSelectedContent="Alle Lesepläne" Delimiter=", " DisplayMemberPath="Identifier" | ||||
|                                                 IsSelectAllActive="True" SelectAllContent="Alle Lesepläne" | ||||
|                                                 Margin="50,260,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                                 SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|  | ||||
|                 <GroupBox Header="Post" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,5,10" Grid.Column="0"> | ||||
|                     <Grid> | ||||
|                         <GroupBox Header="Zusenden an..." Margin="10,10,10,10" Height="150" Width="220" VerticalAlignment="Top" HorizontalAlignment="Left"> | ||||
|                             <StackPanel> | ||||
|                                 <RadioButton x:Name="PostalAllInput" Margin="10,10,10,2.5" Click="PostalInput_Changed"> | ||||
|                                     <TextBlock> | ||||
|                                         ...alle (<Run Text="{Binding Path=PostalAllCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                     </TextBlock> | ||||
|                                 </RadioButton> | ||||
|                                 <RadioButton x:Name="PostalWishInput" Margin="10,2.5,10,2.5" Click="PostalInput_Changed" IsChecked="True"> | ||||
|                                     <TextBlock> | ||||
|                                         ...Mitglieder, die Zusendung<LineBreak/> | ||||
|                                         per Post wünschen (<Run Text="{Binding Path=PostalWishCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                     </TextBlock> | ||||
|                                 </RadioButton> | ||||
|                                 <RadioButton x:Name="PostalNoEmailInput" Margin="10,2.5,10,2.5" Click="PostalInput_Changed"> | ||||
|                                     <TextBlock> | ||||
|                                         ...Mitglieder, die keine<LineBreak/> | ||||
|                                         E-Mail erhalten würden (<Run Text="{Binding Path=PostalNoEmailCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                     </TextBlock> | ||||
|                                 </RadioButton> | ||||
|                                 <RadioButton x:Name="PostalNobodyInput" Margin="10,2.5,10,10" Content="...niemanden (0)"  Click="PostalInput_Changed"/> | ||||
|                             </StackPanel> | ||||
|                         </GroupBox> | ||||
|                             <ctrl:CheckComboBox x:Name="MemberCustomInput" AllItemsSelectedContent="Alle Mitglieder" Delimiter=", " DisplayMemberPath="AdministrativeName" | ||||
|                                                 IsSelectAllActive="True" SelectAllContent="Alle Mitglieder" | ||||
|                                                 Margin="10,140,10,10" VerticalAlignment="Top" HorizontalAlignment="Stretch" Height="25" | ||||
|                                                 SelectionChanged="MemberInput_SelectionChanged"/> | ||||
|                         </Grid> | ||||
|                     </GroupBox> | ||||
|  | ||||
|                         <GroupBox Header="Sortieren nach" Margin="10,180,10,10" Width="180" Height="80" VerticalAlignment="Top" HorizontalAlignment="Left"> | ||||
|                             <StackPanel Margin="5,5,0,5"> | ||||
|                                 <RadioButton GroupName="Order" x:Name="OrderMgNrInput" Content="Mitgliedsnummer" Click="OrderInput_Changed" IsChecked="True"/> | ||||
|                                 <RadioButton GroupName="Order" x:Name="OrderNameInput" Content="Name" Click="OrderInput_Changed"/> | ||||
|                                 <RadioButton GroupName="Order" x:Name="OrderPlzInput" Content="PLZ, Ort, Name" Click="OrderInput_Changed"/> | ||||
|                             </StackPanel> | ||||
|                         </GroupBox> | ||||
|                     <Button x:Name="ContinueButton" Content="Weiter" Grid.Column="1" | ||||
|                             Margin="10,10,10,10" Height="27" Width="100" Padding="9,3" FontSize="14" | ||||
|                             VerticalAlignment="Bottom" HorizontalAlignment="Right" | ||||
|                             Click="ContinueButton_Click"/> | ||||
|                 </Grid> | ||||
|             </TabItem> | ||||
|  | ||||
|                         <CheckBox x:Name="DoublePagedInput" Margin="20,270,10,10" Content="Doppelseitig drucken" | ||||
|                                   VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                   Checked="DoublePagedInput_Changed" Unchecked="DoublePagedInput_Changed"/> | ||||
|  | ||||
|                         <TextBox x:Name="PostalSender1" TextChanged="PostalSender_TextChanged" IsEnabled="False" | ||||
|                                  Margin="10,300,10,10"/> | ||||
|                         <TextBox x:Name="PostalSender2" TextChanged="PostalSender_TextChanged" | ||||
|                                  Margin="10,330,10,10"/> | ||||
|                     </Grid> | ||||
|                 </GroupBox> | ||||
|  | ||||
|                 <GroupBox Header="E-Mail" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,10,10,10" Grid.Column="1"> | ||||
|                     <Grid> | ||||
|                         <GroupBox Header="Zusenden an..." Margin="80,10,10,10" Width="220" Height="110" VerticalAlignment="Top" HorizontalAlignment="Left"> | ||||
|                             <StackPanel> | ||||
|                                 <RadioButton x:Name="EmailAllInput" Margin="10,10,10,2.5" Checked="EmailInput_Changed"> | ||||
|                                     <TextBlock> | ||||
|                                         ...alle mit E-Mail-Adressen (<Run Text="{Binding Path=EmailAllCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                     </TextBlock> | ||||
|                                 </RadioButton> | ||||
|                                 <RadioButton x:Name="EmailWishInput" Margin="10,2.5,10,2.5" IsChecked="True" Checked="EmailInput_Changed"> | ||||
|                                     <TextBlock> | ||||
|                                             ...Mitglieder, die Zusendung<LineBreak/> | ||||
|                                             per E-Mail wünschen (<Run Text="{Binding Path=EmailWishCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                     </TextBlock> | ||||
|                                 </RadioButton> | ||||
|                                 <RadioButton x:Name="EmailNobodyInput" Margin="10,2.5,10,10" Content="...niemanden (0)"  Checked="EmailInput_Changed"/> | ||||
|                             </StackPanel> | ||||
|                         </GroupBox> | ||||
|  | ||||
|                         <Label Content="Betreff:" Margin="10,130,10,10"/> | ||||
|                         <TextBox x:Name="EmailSubjectInput" Margin="80,130,10,10"/> | ||||
|  | ||||
|                         <Label Content="Nachricht:" Margin="10,160,10,10"/> | ||||
|                         <TextBox x:Name="EmailBodyInput" | ||||
|                                  Margin="80,160,10,10" VerticalAlignment="Stretch" Height="Auto" | ||||
|                                  TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"/> | ||||
|                     </Grid> | ||||
|                 </GroupBox> | ||||
|  | ||||
|                 <Grid Grid.Row="1" Grid.ColumnSpan="2" Width="400" Height="59"> | ||||
|             <TabItem Header="Absenden" Visibility="Collapsed"> | ||||
|                 <Grid> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="0.7*"/> | ||||
|                         <ColumnDefinition Width="10"/> | ||||
|                         <ColumnDefinition Width="0.4*"/> | ||||
|                         <ColumnDefinition Width="5"/> | ||||
|                         <ColumnDefinition Width="0.6*"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                         <ColumnDefinition Width="1.5*"/> | ||||
|                     </Grid.ColumnDefinitions> | ||||
|                     <Grid.RowDefinitions> | ||||
|                         <RowDefinition Height="*"/> | ||||
|                         <RowDefinition Height="5"/> | ||||
|                         <RowDefinition Height="*"/> | ||||
|                         <RowDefinition Height="80"/> | ||||
|                     </Grid.RowDefinitions> | ||||
|  | ||||
|                     <Button x:Name="GenerateButton" Content="Generieren" | ||||
|                             Grid.Row="0" Grid.Column="0" FontSize="14" | ||||
|                             Click="GenerateButton_Click"/> | ||||
|                     <ProgressBar x:Name="ProgressBar" | ||||
|                                  Grid.Row="2" Grid.Column="0" SnapsToDevicePixels="True"/> | ||||
|                     <GroupBox Header="Post" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,10,5,10" Grid.Column="0"> | ||||
|                         <Grid> | ||||
|                             <GroupBox Header="Zusenden an..." Margin="10,10,10,10" Height="150" Width="220" VerticalAlignment="Top" HorizontalAlignment="Left"> | ||||
|                                 <StackPanel> | ||||
|                                     <RadioButton x:Name="PostalAllInput" Margin="10,10,10,2.5" Click="PostalInput_Changed"> | ||||
|                                         <TextBlock> | ||||
|                                             ...alle (<Run Text="{Binding Path=PostalAllCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                         </TextBlock> | ||||
|                                     </RadioButton> | ||||
|                                     <RadioButton x:Name="PostalWishInput" Margin="10,2.5,10,2.5" Click="PostalInput_Changed" IsChecked="True"> | ||||
|                                         <TextBlock> | ||||
|                                             ...Mitglieder, die Zusendung<LineBreak/> | ||||
|                                             per Post wünschen (<Run Text="{Binding Path=PostalWishCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                         </TextBlock> | ||||
|                                     </RadioButton> | ||||
|                                     <RadioButton x:Name="PostalNoEmailInput" Margin="10,2.5,10,2.5" Click="PostalInput_Changed"> | ||||
|                                         <TextBlock> | ||||
|                                             ...Mitglieder, die keine<LineBreak/> | ||||
|                                             E-Mail erhalten würden (<Run Text="{Binding Path=PostalNoEmailCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                         </TextBlock> | ||||
|                                     </RadioButton> | ||||
|                                     <RadioButton x:Name="PostalNobodyInput" Margin="10,2.5,10,10" Content="...niemanden (0)"  Click="PostalInput_Changed"/> | ||||
|                                 </StackPanel> | ||||
|                             </GroupBox> | ||||
|  | ||||
|                     <Button x:Name="PreviewButton" Content="Vorschau" IsEnabled="False" | ||||
|                             Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3" FontSize="14" | ||||
|                             Click="PreviewButton_Click"/> | ||||
|                     <Button x:Name="PrintButton" Content="Drucken" IsEnabled="False" | ||||
|                             Grid.Row="2" Grid.Column="2" FontSize="14" | ||||
|                             Click="PrintButton_Click"/> | ||||
|                     <Button x:Name="EmailButton" Content="E-Mails verschicken" IsEnabled="False" | ||||
|                             Grid.Row="2" Grid.Column="4" FontSize="14" | ||||
|                             Click="EmailButton_Click"/> | ||||
|                             <GroupBox Header="Sortieren nach" Margin="10,180,10,10" Width="180" Height="80" VerticalAlignment="Top" HorizontalAlignment="Left"> | ||||
|                                 <StackPanel Margin="5,5,0,5"> | ||||
|                                     <RadioButton GroupName="Order" x:Name="OrderMgNrInput" Content="Mitgliedsnummer" Click="OrderInput_Changed" IsChecked="True"/> | ||||
|                                     <RadioButton GroupName="Order" x:Name="OrderNameInput" Content="Name" Click="OrderInput_Changed"/> | ||||
|                                     <RadioButton GroupName="Order" x:Name="OrderPlzInput" Content="PLZ, Ort, Name" Click="OrderInput_Changed"/> | ||||
|                                 </StackPanel> | ||||
|                             </GroupBox> | ||||
|  | ||||
|                             <CheckBox x:Name="DoublePagedInput" Margin="20,270,10,10" Content="Doppelseitig drucken" | ||||
|                                       VerticalAlignment="Top" HorizontalAlignment="Left" | ||||
|                                       Checked="DoublePagedInput_Changed" Unchecked="DoublePagedInput_Changed"/> | ||||
|  | ||||
|                             <TextBox x:Name="PostalSender1" TextChanged="PostalSender_TextChanged" IsEnabled="False" | ||||
|                                      Margin="10,300,10,10"/> | ||||
|                             <TextBox x:Name="PostalSender2" TextChanged="PostalSender_TextChanged" | ||||
|                                      Margin="10,330,10,10"/> | ||||
|                         </Grid> | ||||
|                     </GroupBox> | ||||
|  | ||||
|                     <GroupBox Header="E-Mail" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="5,10,10,10" Grid.Column="1"> | ||||
|                         <Grid> | ||||
|                             <GroupBox Header="Zusenden an..." Margin="80,10,10,10" Width="220" Height="110" VerticalAlignment="Top" HorizontalAlignment="Left"> | ||||
|                                 <StackPanel> | ||||
|                                     <RadioButton x:Name="EmailAllInput" Margin="10,10,10,2.5" Checked="EmailInput_Changed"> | ||||
|                                         <TextBlock> | ||||
|                                             ...alle mit E-Mail-Adressen (<Run Text="{Binding Path=EmailAllCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                         </TextBlock> | ||||
|                                     </RadioButton> | ||||
|                                     <RadioButton x:Name="EmailWishInput" Margin="10,2.5,10,2.5" IsChecked="True" Checked="EmailInput_Changed"> | ||||
|                                         <TextBlock> | ||||
|                                             ...Mitglieder, die Zusendung<LineBreak/> | ||||
|                                             per E-Mail wünschen (<Run Text="{Binding Path=EmailWishCount, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type local:MailWindow}}}"/>) | ||||
|                                         </TextBlock> | ||||
|                                     </RadioButton> | ||||
|                                     <RadioButton x:Name="EmailNobodyInput" Margin="10,2.5,10,10" Content="...niemanden (0)"  Checked="EmailInput_Changed"/> | ||||
|                                 </StackPanel> | ||||
|                             </GroupBox> | ||||
|  | ||||
|                             <Label Content="Betreff:" Margin="10,130,10,10"/> | ||||
|                             <TextBox x:Name="EmailSubjectInput" Margin="80,130,10,10"/> | ||||
|  | ||||
|                             <Label Content="Nachricht:" Margin="10,160,10,10"/> | ||||
|                             <TextBox x:Name="EmailBodyInput" | ||||
|                                      Margin="80,160,10,10" VerticalAlignment="Stretch" Height="Auto" | ||||
|                                      TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"/> | ||||
|                         </Grid> | ||||
|                     </GroupBox> | ||||
|  | ||||
|                     <Grid Grid.Row="1" Grid.ColumnSpan="2" Width="400" Height="59"> | ||||
|                         <Grid.ColumnDefinitions> | ||||
|                             <ColumnDefinition Width="0.7*"/> | ||||
|                             <ColumnDefinition Width="10"/> | ||||
|                             <ColumnDefinition Width="0.4*"/> | ||||
|                             <ColumnDefinition Width="5"/> | ||||
|                             <ColumnDefinition Width="0.6*"/> | ||||
|                         </Grid.ColumnDefinitions> | ||||
|                         <Grid.RowDefinitions> | ||||
|                             <RowDefinition Height="*"/> | ||||
|                             <RowDefinition Height="5"/> | ||||
|                             <RowDefinition Height="*"/> | ||||
|                         </Grid.RowDefinitions> | ||||
|  | ||||
|                         <Button x:Name="GenerateButton" Content="Generieren" | ||||
|                                 Grid.Row="0" Grid.Column="0" FontSize="14" | ||||
|                                 Click="GenerateButton_Click"/> | ||||
|                         <ProgressBar x:Name="ProgressBar" | ||||
|                                      Grid.Row="2" Grid.Column="0" SnapsToDevicePixels="True"/> | ||||
|  | ||||
|                         <Button x:Name="PreviewButton" Content="Vorschau" IsEnabled="False" | ||||
|                                 Grid.Row="0" Grid.Column="2" Grid.ColumnSpan="3" FontSize="14" | ||||
|                                 Click="PreviewButton_Click"/> | ||||
|                         <Button x:Name="PrintButton" Content="Drucken" IsEnabled="False" | ||||
|                                 Grid.Row="2" Grid.Column="2" FontSize="14" | ||||
|                                 Click="PrintButton_Click"/> | ||||
|                         <Button x:Name="EmailButton" Content="E-Mails verschicken" IsEnabled="False" | ||||
|                                 Grid.Row="2" Grid.Column="4" FontSize="14" | ||||
|                                 Click="EmailButton_Click"/> | ||||
|                     </Grid> | ||||
|  | ||||
|                     <Button x:Name="BackButton" Content="Zurück" Grid.Row="1" | ||||
|                             Margin="10,10,10,10" Height="27" Width="100" Padding="9,3" FontSize="14" | ||||
|                             VerticalAlignment="Bottom" HorizontalAlignment="Left" | ||||
|                             Click="BackButton_Click"/> | ||||
|                 </Grid> | ||||
|             </TabItem> | ||||
|         </TabControl> | ||||
|  | ||||
|                 <Button x:Name="BackButton" Content="Zurück" Grid.Row="1" | ||||
|                         Margin="10,10,10,10" Height="27" Width="100" Padding="9,3" FontSize="14" | ||||
|                         VerticalAlignment="Bottom" HorizontalAlignment="Left" | ||||
|                         Click="BackButton_Click"/> | ||||
|             </Grid> | ||||
|         </TabItem> | ||||
|     </TabControl> | ||||
|         <StatusBar Grid.Row="2" BorderThickness="0,1,0,0" BorderBrush="Gray"> | ||||
|             <StatusBar.ItemsPanel> | ||||
|                 <ItemsPanelTemplate> | ||||
|                     <Grid> | ||||
|                         <Grid.ColumnDefinitions> | ||||
|                             <ColumnDefinition Width="1*"/> | ||||
|                             <ColumnDefinition Width="Auto"/> | ||||
|                             <ColumnDefinition Width="1*"/> | ||||
|                             <ColumnDefinition Width="Auto"/> | ||||
|                             <ColumnDefinition Width="1*"/> | ||||
|                         </Grid.ColumnDefinitions> | ||||
|                     </Grid> | ||||
|                 </ItemsPanelTemplate> | ||||
|             </StatusBar.ItemsPanel> | ||||
|             <StatusBarItem> | ||||
|                 <TextBlock> | ||||
|                     Adressaten: <Run x:Name="StatusRecipients" Text="0"/> | ||||
|                 </TextBlock> | ||||
|             </StatusBarItem> | ||||
|             <Separator Grid.Column="1"/> | ||||
|             <StatusBarItem Grid.Column="2"> | ||||
|                 <TextBlock> | ||||
|                     Adressaten (Post): <Run x:Name="StatusPostalRecipients" Text="0"/> | ||||
|                 </TextBlock> | ||||
|             </StatusBarItem> | ||||
|             <Separator Grid.Column="3"/> | ||||
|             <StatusBarItem Grid.Column="4"> | ||||
|                 <TextBlock> | ||||
|                     Adressaten (E-Mail): <Run x:Name="StatusEmailRecipients" Text="0"/> | ||||
|                 </TextBlock> | ||||
|             </StatusBarItem> | ||||
|         </StatusBar> | ||||
|     </Grid> | ||||
| </local:ContextWindow> | ||||
|   | ||||
| @@ -58,6 +58,7 @@ namespace Elwig.Windows { | ||||
|         public IEnumerable<Member> Recipients = []; | ||||
|  | ||||
|         protected Document? PrintDocument; | ||||
|         protected Dictionary<Member, List<Document>>? PrintMemberDocuments; | ||||
|         protected Dictionary<Member, List<Document>>? EmailDocuments; | ||||
|  | ||||
|         public static readonly DependencyProperty PostalAllCountProperty = DependencyProperty.Register(nameof(PostalAllCount), typeof(int), typeof(MailWindow)); | ||||
| @@ -122,6 +123,26 @@ namespace Elwig.Windows { | ||||
|             DeliveryConfirmationFooterInput.Text = App.Client.TextDeliveryConfirmation; | ||||
|             CreditNoteFooterInput.Text = App.Client.TextCreditNote; | ||||
|  | ||||
|             DocumentNonDeliverersInput.IsChecked = App.Client.MailIncludeNonDeliverers; | ||||
|             DoublePagedInput.IsChecked = App.Client.MailDoublePaged; | ||||
|  | ||||
|             switch (App.Client.MailSendPostal) { | ||||
|                 case 0: PostalNobodyInput.IsChecked = true; break; | ||||
|                 case 1: PostalNoEmailInput.IsChecked = true; break; | ||||
|                 case 2: PostalWishInput.IsChecked = true; break; | ||||
|                 case 3: PostalAllInput.IsChecked = true; break; | ||||
|             } | ||||
|             switch (App.Client.MailSendEmail) { | ||||
|                 case 0: EmailNobodyInput.IsChecked = true; break; | ||||
|                 case 1: EmailWishInput.IsChecked = true; break; | ||||
|                 case 2: EmailAllInput.IsChecked = true; break; | ||||
|             } | ||||
|             switch (App.Client.MailOrdering) { | ||||
|                 case 0: OrderMgNrInput.IsChecked = true; break; | ||||
|                 case 1: OrderNameInput.IsChecked = true; break; | ||||
|                 case 2: OrderPlzInput.IsChecked = true; break; | ||||
|             } | ||||
|  | ||||
|             PostalSender1.Text = App.Client.Sender1; | ||||
|             PostalSender2.Text = App.Client.Sender2; | ||||
|             PostalLocation.Text = App.BranchLocation; | ||||
| @@ -242,6 +263,11 @@ namespace Elwig.Windows { | ||||
|                 rb.IsEnabled = true; | ||||
|         } | ||||
|  | ||||
|         private void Menu_Help_Log_Click(object sender, RoutedEventArgs evt) { | ||||
|             var w = new MailLogWindow(); | ||||
|             w.Show(); | ||||
|         } | ||||
|  | ||||
|         private void ContinueButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             TabControl.SelectedIndex = 1; | ||||
|             TabControl.AllowDrop = false; | ||||
| @@ -312,7 +338,7 @@ namespace Elwig.Windows { | ||||
|             if (idx == 0) { | ||||
|                 SelectedDocs.Add(new(DocType.MemberDataSheet, s, null)); | ||||
|             } else if (idx == 1) { | ||||
|                 SelectedDocs.Add(new(DocType.DeliveryConfirmation, s, (Year, DocumentNonDeliverersInput.IsChecked == true))); | ||||
|                 SelectedDocs.Add(new(DocType.DeliveryConfirmation, s, Year)); | ||||
|                 RecipientsDeliveryMembersInput.IsChecked = true; | ||||
|             } else if (idx >= 2) { | ||||
|                 var name = s.Split(" – ")[^1]; | ||||
| @@ -449,18 +475,32 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void UpdatePostalEmailRecipients() { | ||||
|             var modeEmail = EmailAllInput.IsChecked == true ? 2 : EmailWishInput.IsChecked == true ? 1 : 0; | ||||
|             var modePostal = PostalAllInput.IsChecked == true ? 3 : PostalWishInput.IsChecked == true ? 2 : PostalNoEmailInput.IsChecked == true ? 1 : 0; | ||||
|             EmailAllCount = Recipients.Count(m => m.EmailAddresses.Count > 0); | ||||
|             EmailWishCount = Recipients.Count(m => m.EmailAddresses.Count > 0 && m.ContactViaEmail); | ||||
|             PostalAllCount = Recipients.Count(); | ||||
|             PostalWishCount = Recipients.Count(m => m.ContactViaPost); | ||||
|             var m = EmailAllInput.IsChecked == true ? 3 : EmailWishInput.IsChecked == true ? 2 : 1; | ||||
|             PostalNoEmailCount = PostalAllCount - (m == 3 ? EmailAllCount : m == 2 ? EmailWishCount : 0); | ||||
|             var countEmail = (modeEmail == 2 ? EmailAllCount : modeEmail == 1 ? EmailWishCount : 0); | ||||
|             PostalNoEmailCount = PostalAllCount - countEmail; | ||||
|             var countPostal = (modePostal == 3 ? PostalAllCount : modePostal == 2 ? PostalWishCount : modePostal == 1 ? PostalNoEmailCount : 0); | ||||
|             if (IsLoaded) { | ||||
|                 StatusRecipients.Text = $"{Recipients.Count():N0}"; | ||||
|                 StatusPostalRecipients.Text = $"{countPostal:N0}"; | ||||
|                 StatusEmailRecipients.Text = $"{countEmail:N0}"; | ||||
|             } | ||||
|             ResetDocuments(); | ||||
|         } | ||||
|  | ||||
|         private async Task UpdateTextParameters() { | ||||
|         private async Task UpdateClientParameters() { | ||||
|             var changed = false; | ||||
|  | ||||
|             var dcInclude = DocumentNonDeliverersInput.IsChecked ?? false; | ||||
|             if (dcInclude != App.Client.MailIncludeNonDeliverers) { | ||||
|                 App.Client.MailIncludeNonDeliverers = dcInclude; | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var dcText = DeliveryConfirmationFooterInput.Text.Trim(); | ||||
|             if (dcText.Length == 0) dcText = null; | ||||
|             if (dcText != App.Client.TextDeliveryConfirmation) { | ||||
| @@ -475,6 +515,53 @@ namespace Elwig.Windows { | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var sendPostal = 0; | ||||
|             if (PostalAllInput.IsChecked ?? false) { | ||||
|                 sendPostal = 3; | ||||
|             } else if (PostalWishInput.IsChecked ?? false) { | ||||
|                 sendPostal = 2; | ||||
|             } else if (PostalNoEmailInput.IsChecked ?? false) { | ||||
|                 sendPostal = 1; | ||||
|             } | ||||
|             if (sendPostal != App.Client.MailSendPostal) { | ||||
|                 App.Client.MailSendPostal = sendPostal; | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var sendEmail = 0; | ||||
|             if (EmailAllInput.IsChecked ?? false) { | ||||
|                 sendEmail = 2; | ||||
|             } else if (EmailWishInput.IsChecked ?? false) { | ||||
|                 sendEmail = 1; | ||||
|             } | ||||
|             if (sendEmail != App.Client.MailSendEmail) { | ||||
|                 App.Client.MailSendEmail = sendEmail; | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var ordering = 0; | ||||
|             if (OrderNameInput.IsChecked ?? false) { | ||||
|                 ordering = 1; | ||||
|             } else if (OrderPlzInput.IsChecked ?? false) { | ||||
|                 ordering = 2; | ||||
|             } | ||||
|             if (ordering != App.Client.MailOrdering) { | ||||
|                 App.Client.MailOrdering = ordering; | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var mailDoublePaged = DoublePagedInput.IsChecked ?? false; | ||||
|             if (mailDoublePaged != App.Client.MailDoublePaged) { | ||||
|                 App.Client.MailDoublePaged = mailDoublePaged; | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var sender2 = PostalSender2.Text.Trim(); | ||||
|             if (sender2 != App.Client.Sender2) { | ||||
|                 App.Client.Sender2 = sender2; | ||||
|                 changed = true; | ||||
|             } | ||||
|  | ||||
|             var emailSubject = EmailSubjectInput.Text.Trim(); | ||||
|             if (emailSubject.Length == 0) emailSubject = null; | ||||
|             if (emailSubject != App.Client.TextEmailSubject) { | ||||
| @@ -519,7 +606,7 @@ namespace Elwig.Windows { | ||||
|             GenerateButton.IsEnabled = false; | ||||
|  | ||||
|             DisposeDocs(); | ||||
|             await UpdateTextParameters(); | ||||
|             await UpdateClientParameters(); | ||||
|  | ||||
|             using var ctx = new AppDbContext(); | ||||
|  | ||||
| @@ -562,8 +649,7 @@ namespace Elwig.Windows { | ||||
|             Dictionary<(int, int), (IDictionary<int, CreditNoteDeliveryData>, IDictionary<int, PaymentMember>, BillingData)> cnData = []; | ||||
|             foreach (var doc in docs) { | ||||
|                 if (doc.Type == DocType.DeliveryConfirmation) { | ||||
|                     var details = ((int, bool))doc.Details!; | ||||
|                     var year = details.Item1; | ||||
|                     var year = (int)doc.Details!; | ||||
|  | ||||
|                     try { | ||||
|                         var b = new Billing(year); | ||||
| @@ -610,13 +696,11 @@ namespace Elwig.Windows { | ||||
|                         } else if (doc.Type == DocType.MemberDataSheet) { | ||||
|                             return [new GeneratedDoc(new MemberDataSheet(m, ctx) { Date = postalDate })]; | ||||
|                         } else if (doc.Type == DocType.DeliveryConfirmation) { | ||||
|                             var details = ((int, bool))doc.Details!; | ||||
|                             var year = details.Item1; | ||||
|                             var include = details.Item2; | ||||
|                             var year = (int)doc.Details!; | ||||
|                             DeliveryConfirmationDeliveryData data; | ||||
|                             if (dcData[year].TryGetValue(m.MgNr, out var d)) { | ||||
|                                 data = d; | ||||
|                             } else if (include) { | ||||
|                             } else if (App.Client.MailIncludeNonDeliverers) { | ||||
|                                 data = DeliveryConfirmationDeliveryData.CreateEmpty(year, m); | ||||
|                             } else { | ||||
|                                 return []; | ||||
| @@ -691,11 +775,13 @@ namespace Elwig.Windows { | ||||
|                 EmailDocuments = email; | ||||
|             } | ||||
|  | ||||
|             var printDocs = memberDocs | ||||
|             var printMemberDocs = memberDocs | ||||
|                 .Where(d => | ||||
|                     printMode == 3 || | ||||
|                     (printMode == 2 && d.Member.ContactViaPost) || | ||||
|                     (printMode == 1 && !emailRecipients.Contains(d.Member.MgNr))) | ||||
|                 .ToList(); | ||||
|             var printDocs = printMemberDocs | ||||
|                 .SelectMany(m => { | ||||
|                     var docs = m.Docs.Select(d => d.Doc).ToList(); | ||||
|                     if (docs.Count == 0 || m.Docs[0].Type == DocType.Custom) { | ||||
| @@ -720,6 +806,7 @@ namespace Elwig.Windows { | ||||
|                         ProgressBar.Value = 100.0 * emailNum / totalNum + v * printNum / totalNum; | ||||
|                     })); | ||||
|                     PrintDocument = print; | ||||
|                     PrintMemberDocuments = printMemberDocs.ToDictionary(m => m.Member, m => m.Docs.Select(d => d.Doc).ToList()); | ||||
|                 } catch (Exception exc) { | ||||
|                     MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|                     UnlockInputs(); | ||||
| @@ -727,6 +814,9 @@ namespace Elwig.Windows { | ||||
|                     Mouse.OverrideCursor = null; | ||||
|                     return; | ||||
|                 } | ||||
|             } else { | ||||
|                 PrintDocument = null; | ||||
|                 PrintMemberDocuments = null; | ||||
|             } | ||||
|             ProgressBar.Value = 100.0; | ||||
|  | ||||
| @@ -763,7 +853,7 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private async void PrintButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (PrintDocument == null) return; | ||||
|             if (PrintDocument == null || PrintMemberDocuments == null) return; | ||||
|  | ||||
|             PrintButton.IsEnabled = false; | ||||
|             GenerateButton.IsEnabled = false; | ||||
| @@ -777,6 +867,14 @@ namespace Elwig.Windows { | ||||
|                     PrintDocument.Show(); | ||||
|                 } else { | ||||
|                     await PrintDocument.Print(); | ||||
|                     await Utils.AddSentMails( | ||||
|                         PrintMemberDocuments.Select(d => ( | ||||
|                             "postal", d.Key.MgNr, d.Key.AdministrativeName, | ||||
|                             new string[] { d.Value.Select(d => (d as BusinessDocument)?.Address).FirstOrDefault(a => a != null) ?? d.Key.FullAddress }, | ||||
|                             d.Value.Select(d => d.Title).FirstOrDefault("Briefkopf"), | ||||
|                             d.Value.Select(d => d.Title).ToArray() | ||||
|                         )) | ||||
|                     ); | ||||
|                 } | ||||
|                 Mouse.OverrideCursor = null; | ||||
|             } | ||||
| @@ -808,6 +906,7 @@ namespace Elwig.Windows { | ||||
|                 Mouse.OverrideCursor = Cursors.AppStarting; | ||||
|                 var subject = EmailSubjectInput.Text; | ||||
|                 var text = EmailBodyInput.Text; | ||||
|                 await Utils.AddSentMailBody(subject, text, EmailDocuments.Count); | ||||
|                 foreach (var (m, docs) in EmailDocuments) { | ||||
|                     using var msg = new MimeMessage(); | ||||
|                     msg.From.Add(new MailboxAddress(App.Client.NameFull, App.Config.Smtp.Value.From)); | ||||
| @@ -822,6 +921,12 @@ namespace Elwig.Windows { | ||||
|                     } | ||||
|                     msg.Body = body; | ||||
|                     await client!.SendAsync(msg); | ||||
|                     await Utils.AddSentMails([( | ||||
|                         "email", m.MgNr, m.AdministrativeName, | ||||
|                         m.EmailAddresses.OrderBy(a => a.Nr).Select(a => a.Address).ToArray(), | ||||
|                         subject, | ||||
|                         docs.Select(d => d.Title).ToArray() | ||||
|                     )]); | ||||
|                 } | ||||
|  | ||||
|                 MessageBox.Show("Erfolgreich alle E-Mails verschickt!", "Rundschreiben verschicken", MessageBoxButton.OK, MessageBoxImage.Information); | ||||
| @@ -870,7 +975,7 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void PostalInput_Changed(object sender, RoutedEventArgs evt) { | ||||
|             ResetDocuments(); | ||||
|             UpdatePostalEmailRecipients(); | ||||
|         } | ||||
|  | ||||
|         private void OrderInput_Changed(object sender, RoutedEventArgs evt) { | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
|         <Style TargetType="Button"> | ||||
|             <Setter Property="VerticalAlignment" Value="Top"/> | ||||
|             <Setter Property="HorizontalAlignment" Value="Center"/> | ||||
|             <Setter Property="HorizontalContentAlignment" Value="Stretch"/> | ||||
|             <Setter Property="FontSize" Value="14"/> | ||||
|             <Setter Property="Padding" Value="9,3"/> | ||||
|             <Setter Property="Height" Value="35"/> | ||||
| @@ -19,23 +20,67 @@ | ||||
|     <Grid> | ||||
|         <Menu BorderThickness="0,0,0,1" VerticalAlignment="Top" Height="19" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Datenbank"> | ||||
|                 <MenuItem Header="Daten exportieren..." Click="Menu_Database_Export_Click" IsEnabled="False"/> | ||||
|                 <MenuItem Header="Daten importieren..." Click="Menu_Database_Import_Click"/> | ||||
|                 <MenuItem Header="Daten exportieren..." Click="Menu_Database_Export_Click" IsEnabled="False"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem Header="Daten importieren..." Click="Menu_Database_Import_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="Speicherort öffnen..." Click="Menu_Database_Open_Click"/> | ||||
|                 <MenuItem Header="Abfragen stellen" Click="Menu_Database_Query_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem Header="Speicherort öffnen..." Click="Menu_Database_Open_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Waage"> | ||||
|                 <MenuItem Header="Datum und Uhrzeit setzen" Click="Menu_Scale_SetDateTime_Click"/> | ||||
|                 <MenuItem Header="Datum und Uhrzeit setzen" Click="Menu_Scale_SetDateTime_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem x:Name="HelpMenu" Header="Hilfe"> | ||||
|                 <MenuItem Header="Über"/> | ||||
|                 <MenuItem x:Name="Menu_Help_Update" Header="Nach Updates suchen" Click="Menu_Help_Update_Click"/> | ||||
|                 <MenuItem x:Name="Menu_Help_Smtp" Header="E-Mail-Einstellungen testen" Click="Menu_Help_Smtp_Click"/> | ||||
|                 <MenuItem x:Name="Menu_Help_Log" Header="Fehler-Protokoll anzeigen" Click="Menu_Help_Log_Click"/> | ||||
|                 <MenuItem Header="Über"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_Help_Update" Header="Nach Updates suchen" Click="Menu_Help_Update_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_Help_Smtp" Header="E-Mail-Einstellungen testen" Click="Menu_Help_Smtp_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_Help_Log" Header="Fehler-Protokoll anzeigen" Click="Menu_Help_Log_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <Separator/> | ||||
|                 <MenuItem x:Name="Menu_Help_Config" Header="Konfigurationsdatei öffnen..." Click="Menu_Help_Config_Click"/> | ||||
|                 <MenuItem x:Name="Menu_Help_Directory" Header="Konfigurationsspeicherort öffnen..." Click="Menu_Help_Directory_Click"/> | ||||
|                 <MenuItem x:Name="Menu_Help_Config" Header="Konfigurationsdatei öffnen..." Click="Menu_Help_Config_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_Help_Directory" Header="Konfigurationsspeicherort öffnen..." Click="Menu_Help_Directory_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|         </Menu> | ||||
|  | ||||
| @@ -58,26 +103,64 @@ | ||||
|             </TextBlock> | ||||
|         </Grid> | ||||
|  | ||||
|         <Button x:Name="MemberAdminButton" Content="Mitglieder" Click="MemberAdminButton_Click" | ||||
|                 Margin="0,170,205,0"/> | ||||
|         <Button x:Name="MailButton" Content="Rundschreiben" Click="MailButton_Click" | ||||
|                 Margin="205,170,0,0"/> | ||||
|         <Button x:Name="DeliveryAdminButton" Content="Lieferungen" Click="DeliveryAdminButton_Click" | ||||
|                 Margin="0,210,205,0"/> | ||||
|         <Button x:Name="ReceiptButton" Content="Übernahme" Click="ReceiptButton_Click" | ||||
|                 Margin="205,210,0,0"/> | ||||
|         <Button x:Name="BaseDataButton" Content="Stammdaten" Click="BaseDataButton_Click" | ||||
|                 Margin="0,250,205,0"/> | ||||
|         <Button x:Name="DeliveryAncmtButton" Content="Anmeldungen" Click="DeliveryAncmtButton_Click" | ||||
|                 Margin="205,250,0,0"/> | ||||
|         <Button x:Name="MemberAdminButton" Click="MemberAdminButton_Click" | ||||
|                 Margin="0,170,205,0"> | ||||
|             <Grid> | ||||
|                 <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                            TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                 <TextBlock TextAlignment="Center">Mitglieder</TextBlock> | ||||
|             </Grid> | ||||
|         </Button> | ||||
|         <Button x:Name="MailButton" Click="MailButton_Click" | ||||
|                 Margin="205,170,0,0"> | ||||
|             <Grid> | ||||
|                 <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                            TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                 <TextBlock TextAlignment="Center">Rundschreiben</TextBlock> | ||||
|             </Grid> | ||||
|         </Button> | ||||
|         <Button x:Name="DeliveryAdminButton" Click="DeliveryAdminButton_Click" | ||||
|                 Margin="0,210,205,0"> | ||||
|             <Grid> | ||||
|                 <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                            TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                 <TextBlock TextAlignment="Center">Lieferungen</TextBlock> | ||||
|             </Grid> | ||||
|         </Button> | ||||
|         <Button x:Name="ReceiptButton" Click="ReceiptButton_Click" | ||||
|                 Margin="205,210,0,0"> | ||||
|             <Grid> | ||||
|                 <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                            TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                 <TextBlock TextAlignment="Center">Übernahme</TextBlock> | ||||
|             </Grid> | ||||
|         </Button> | ||||
|         <Button x:Name="BaseDataButton" Click="BaseDataButton_Click" | ||||
|                 Margin="0,250,205,0"> | ||||
|             <Grid> | ||||
|                 <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                            TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                 <TextBlock TextAlignment="Center">Stammdaten</TextBlock> | ||||
|             </Grid> | ||||
|         </Button> | ||||
|         <Button x:Name="DeliveryAncmtButton" Click="DeliveryAncmtButton_Click" | ||||
|                 Margin="205,250,0,0"> | ||||
|             <Grid> | ||||
|                 <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                            TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                 <TextBlock TextAlignment="Center">Anmeldungen</TextBlock> | ||||
|             </Grid> | ||||
|         </Button> | ||||
|  | ||||
|         <Button x:Name="DownloadButton" Click="DownloadButton_Click" | ||||
|                 Margin="310,135,0,0" Padding="1.5,0,0,0" Height="30" Width="30" | ||||
|                 Margin="310,135,0,0" Padding="0.375,0.5,0,0" Height="30" Width="30" | ||||
|                 Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" | ||||
|                 HorizontalContentAlignment="Center" | ||||
|                 ToolTip="Lieferungen und Mitgliederdaten anderer Zweigstellen herunterladen"/> | ||||
|         <Button x:Name="UploadButton" Click="UploadButton_Click" | ||||
|                 Margin="375,135,0,0" Padding="1.5,0,0,0" Height="30" Width="30" | ||||
|                 Margin="375,135,0,0" Padding="1.0,0.5,0,0" Height="30" Width="30" | ||||
|                 Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" | ||||
|                 HorizontalContentAlignment="Center" | ||||
|                 ToolTip="Lieferungen dieser Zweigstelle hochladen"/> | ||||
|  | ||||
|         <Expander x:Name="SeasonFinish" Header="Leseabschluss" SnapsToDevicePixels="True" | ||||
| @@ -90,21 +173,104 @@ | ||||
|                                     Margin="0,13,0,0" VerticalAlignment="Top" HorizontalAlignment="Center" | ||||
|                                     TextChanged="SeasonInput_TextChanged"/> | ||||
|  | ||||
|                 <Button x:Name="OverUnderDeliveryButton" Content="Über-/Unterlieferungen" | ||||
|                         Click="OverUnderDeliveryButton_Click" | ||||
|                         Margin="0,50,195,10" Width="190"/> | ||||
|  | ||||
|                 <Button x:Name="DeliveryConfirmationButton" Content="Anlieferungsbestätigung" | ||||
|                 <Button x:Name="DeliveryConfirmationButton" | ||||
|                         Click="DeliveryConfirmationButton_Click" | ||||
|                         Margin="195,50,0,10" Width="190"/> | ||||
|                         Margin="0,50,195,10" Width="190"> | ||||
|                     <Grid> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                    TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,0.5,0,0"/> | ||||
|                         <TextBlock FontSize="12" Margin="18,1,0,0" TextAlignment="Center">Anlieferungsbestätigung</TextBlock> | ||||
|                     </Grid> | ||||
|                 </Button> | ||||
|  | ||||
|                 <Button x:Name="BreakdownButton" Content="Sorten-/Qual.aufteilung" | ||||
|                         Click="BreakdownButton_Click" | ||||
|                         Margin="0,90,195,10" Width="190"/> | ||||
|  | ||||
|                 <Button x:Name="PaymentButton" Content="Auszahlung" | ||||
|                 <Button x:Name="PaymentButton" | ||||
|                         Click="PaymentButton_Click" | ||||
|                         Margin="195,90,0,10" Width="190"/> | ||||
|                         Margin="195,50,0,10" Width="190"> | ||||
|                     <Grid> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                   TextAlignment="Left" HorizontalAlignment="Left" Padding="0.5,1.5,0,0"/> | ||||
|                         <TextBlock TextAlignment="Center">Auszahlung</TextBlock> | ||||
|                     </Grid> | ||||
|                 </Button> | ||||
|  | ||||
|                 <Button x:Name="OverUnderDeliveryButton" | ||||
|                         Click="OverUnderDeliveryButton_Click" | ||||
|                         Margin="0,90,195,10" Width="190" Padding="3,5,5,5" | ||||
|                         ToolTip="Über-/Unterlieferungen laut gezeichneten Geschäftsanteilen und Unterlieferungen nach Flächenbindungen"> | ||||
|                     <Grid> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                    TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,0.5,0,0"/> | ||||
|                         <TextBlock FontSize="12" Margin="18,1,0,0" TextAlignment="Center">Über-/Unterlieferungen</TextBlock> | ||||
|                     </Grid> | ||||
|                 </Button> | ||||
|  | ||||
|                 <Button x:Name="BreakdownButton" | ||||
|                         Click="BreakdownButton_Click" | ||||
|                         Margin="195,90,0,10" Width="190" Padding="3,5,5,5" | ||||
|                         ToolTip="Aufschlüsselung des Gewichts nach Zweigstelle, Mitglied, Sorte, Attribut/Bewirt., Qualitätsstufe, gebunden/ungebunden"> | ||||
|                     <Grid> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                    TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,0.5,0,0"/> | ||||
|                         <TextBlock FontSize="12" Margin="18,1,0,0" TextAlignment="Center">Sorten-/Qual.aufschlüssel.</TextBlock> | ||||
|                     </Grid> | ||||
|                 </Button> | ||||
|  | ||||
|                 <Button x:Name="AreaCommitmentsButton" | ||||
|                         Click="AreaCommitmentsButton_Click" | ||||
|                         Margin="0,130,195,10" Width="190" Padding="3,5,5,5" | ||||
|                         ToolTip="Aktive Flächenbindungen der Saison pro Mitglied und Sorte/Attribut"> | ||||
|                     <Grid> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                    TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,1.5,0,0"/> | ||||
|                         <TextBlock Margin="18,0,0,0" TextAlignment="Center">Flächenbindungen</TextBlock> | ||||
|                     </Grid> | ||||
|                 </Button> | ||||
|  | ||||
|                 <Button x:Name="BreakdownMemberVarietyButton" | ||||
|                         Click="BreakdownMemberVarietyButton_Click" | ||||
|                         Margin="195,130,0,10" Width="190" Padding="3,5,5,5" | ||||
|                         ToolTip="Liefermengen und Ertrag (kg/ha) pro Mitglied"> | ||||
|                     <Grid> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                    TextAlignment="Left" HorizontalAlignment="Left" Padding="6.5,1.5,0,0"/> | ||||
|                         <TextBlock Margin="18,0,0,0" TextAlignment="Center">Liefermengen/Ertrag</TextBlock> | ||||
|                     </Grid> | ||||
|                 </Button> | ||||
|  | ||||
|                 <Grid VerticalAlignment="Bottom" Margin="50,175,50,15"> | ||||
|                     <Grid.ColumnDefinitions> | ||||
|                         <ColumnDefinition Width="60"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                         <ColumnDefinition Width="*"/> | ||||
|                     </Grid.ColumnDefinitions> | ||||
|                     <Grid.RowDefinitions> | ||||
|                         <RowDefinition Height="20"/> | ||||
|                         <RowDefinition Height="20"/> | ||||
|                         <RowDefinition Height="20"/> | ||||
|                         <RowDefinition Height="20"/> | ||||
|                     </Grid.RowDefinitions> | ||||
|  | ||||
|                     <TextBlock Grid.Row="0" Grid.Column="1" TextAlignment="Right"><Bold>Mitglieder</Bold></TextBlock> | ||||
|                     <TextBlock Grid.Row="0" Grid.Column="2" TextAlignment="Right"><Bold>Gewicht</Bold></TextBlock> | ||||
|                     <TextBlock Grid.Row="0" Grid.Column="3" TextAlignment="Right"><Bold>Fläche</Bold></TextBlock> | ||||
|  | ||||
|                     <TextBlock Grid.Row="1" Grid.Column="0">Gesamt:</TextBlock> | ||||
|                     <TextBlock Grid.Row="2" Grid.Column="0">Gebunden:</TextBlock> | ||||
|                     <TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2">Ungebunden:</TextBlock> | ||||
|  | ||||
|                     <TextBlock Grid.Row="1" Grid.Column="1" TextAlignment="Right" x:Name="SeasonStatMembersTotal">-</TextBlock> | ||||
|                     <TextBlock Grid.Row="2" Grid.Column="1" TextAlignment="Right" x:Name="SeasonStatMembersGeb">-</TextBlock> | ||||
|                     <TextBlock Grid.Row="3" Grid.Column="1" TextAlignment="Right">-</TextBlock> | ||||
|  | ||||
|                     <TextBlock Grid.Row="1" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightTotal">-</TextBlock> | ||||
|                     <TextBlock Grid.Row="2" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightGeb">-</TextBlock> | ||||
|                     <TextBlock Grid.Row="3" Grid.Column="2" TextAlignment="Right" x:Name="SeasonStatWeightUngeb">-</TextBlock> | ||||
|  | ||||
|                     <TextBlock Grid.Row="1" Grid.Column="3" TextAlignment="Right">-</TextBlock> | ||||
|                     <TextBlock Grid.Row="2" Grid.Column="3" TextAlignment="Right" x:Name="SeasonStatArea">-</TextBlock> | ||||
|                     <TextBlock Grid.Row="3" Grid.Column="3" TextAlignment="Right">-</TextBlock> | ||||
|                 </Grid> | ||||
|             </Grid> | ||||
|         </Expander> | ||||
|     </Grid> | ||||
|   | ||||
| @@ -251,7 +251,7 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void SeasonFinish_Expanded(object sender, RoutedEventArgs evt) { | ||||
|             Height = 530; | ||||
|             Height = 660; | ||||
|         } | ||||
|  | ||||
|         private void SeasonFinish_Collapsed(object sender, RoutedEventArgs evt) { | ||||
| @@ -260,12 +260,34 @@ namespace Elwig.Windows { | ||||
|  | ||||
|         private async void SeasonInput_TextChanged(object? sender, TextChangedEventArgs? evt) { | ||||
|             using var ctx = new AppDbContext(); | ||||
|             var s0 = await ctx.Seasons.FindAsync(SeasonInput.Value); | ||||
|             var year = SeasonInput.Value; | ||||
|             var s0 = await ctx.Seasons.FindAsync(year); | ||||
|             var valid = (s0 != null); | ||||
|             DeliveryConfirmationButton.IsEnabled = valid; | ||||
|             OverUnderDeliveryButton.IsEnabled = valid; | ||||
|             PaymentButton.IsEnabled = valid; | ||||
|             OverUnderDeliveryButton.IsEnabled = valid; | ||||
|             BreakdownButton.IsEnabled = valid; | ||||
|             AreaCommitmentsButton.IsEnabled = valid; | ||||
|             BreakdownMemberVarietyButton.IsEnabled = valid; | ||||
|  | ||||
|             if (valid) { | ||||
|                 var areaComs = Utils.ActiveAreaCommitments(ctx.AreaCommitments, year!.Value); | ||||
|                 var weightTotal = await ctx.DeliveryParts.Where(p => p.Year == year).SumAsync(p => p.Weight); | ||||
|                 var gebWeight = await ctx.DeliveryPartBuckets.Where(b => b.Year == year && b.Discr != "_").SumAsync(b => b.Value); | ||||
|                 SeasonStatMembersTotal.Text = $"{await ctx.Deliveries.Where(d => d.Year == year).Select(d => d.Member).Distinct().CountAsync():N0}"; | ||||
|                 SeasonStatMembersGeb.Text = $"{await areaComs.Select(c => c.Member).Distinct().CountAsync():N0}"; | ||||
|                 SeasonStatWeightTotal.Text = $"{weightTotal:N0} kg"; | ||||
|                 SeasonStatWeightGeb.Text = $"{gebWeight:N0} kg"; | ||||
|                 SeasonStatWeightUngeb.Text = $"{weightTotal - gebWeight:N0} kg"; | ||||
|                 SeasonStatArea.Text = $"{await areaComs.SumAsync(c => c.Area):N0} m²"; | ||||
|             } else { | ||||
|                 SeasonStatMembersTotal.Text = "-"; | ||||
|                 SeasonStatMembersGeb.Text = "-"; | ||||
|                 SeasonStatWeightTotal.Text = "-"; | ||||
|                 SeasonStatWeightGeb.Text = "-"; | ||||
|                 SeasonStatWeightUngeb.Text = "-"; | ||||
|                 SeasonStatArea.Text = "-"; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) { | ||||
| @@ -275,6 +297,12 @@ namespace Elwig.Windows { | ||||
|             w.AddDeliveryConfirmation(); | ||||
|         } | ||||
|  | ||||
|         private void PaymentButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (SeasonInput.Value is not int year) | ||||
|                 return; | ||||
|             App.FocusPaymentVariants(year); | ||||
|         } | ||||
|  | ||||
|         private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (SeasonInput.Value is not int year) | ||||
|                 return; | ||||
| @@ -297,23 +325,15 @@ namespace Elwig.Windows { | ||||
|                 using var ctx = new AppDbContext(); | ||||
|                 var tbl1 = await OverUnderDeliveryData.ForSeason(ctx.OverUnderDeliveryRows, year); | ||||
|                 var tbl2 = await AreaComUnderDeliveryData.ForSeason(ctx.AreaComUnderDeliveryRows, year); | ||||
|                 var tbl3 = await MemberDeliveryPerVariantData.ForSeason(ctx.MemberDeliveryPerVariantRows, year); | ||||
|                 using var ods = new OdsFile(d.FileName); | ||||
|                 await ods.AddTable(tbl1); | ||||
|                 await ods.AddTable(tbl2); | ||||
|                 await ods.AddTable(tbl3); | ||||
|             } catch (Exception exc) { | ||||
|                 MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|             } | ||||
|             Mouse.OverrideCursor = null; | ||||
|         } | ||||
|  | ||||
|         private void PaymentButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (SeasonInput.Value is not int year) | ||||
|                 return; | ||||
|             App.FocusPaymentVariants(year); | ||||
|         } | ||||
|  | ||||
|         private async void BreakdownButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (SeasonInput.Value is not int year) | ||||
|                 return; | ||||
| @@ -346,5 +366,63 @@ namespace Elwig.Windows { | ||||
|             } | ||||
|             Mouse.OverrideCursor = null; | ||||
|         } | ||||
|  | ||||
|         private async void AreaCommitmentsButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (SeasonInput.Value is not int year) | ||||
|                 return; | ||||
|             var d = new SaveFileDialog() { | ||||
|                 FileName = $"Flächenbindungen-{year}.ods", | ||||
|                 DefaultExt = "ods", | ||||
|                 Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", | ||||
|                 Title = $"Flächenbindungen {year} speichern unter - Elwig" | ||||
|             }; | ||||
|             if (d.ShowDialog() == false) | ||||
|                 return; | ||||
|  | ||||
|             Mouse.OverrideCursor = Cursors.AppStarting; | ||||
|             try { | ||||
|                 var b = new Billing(year); | ||||
|                 await b.FinishSeason(); | ||||
|                 await b.CalculateBuckets(); | ||||
|                 App.HintContextChange(); | ||||
|  | ||||
|                 using var ctx = new AppDbContext(); | ||||
|                 var tbl = await MemberAreaComsData.ForSeason(ctx.MemberAreaComsRows, year); | ||||
|                 using var ods = new OdsFile(d.FileName); | ||||
|                 await ods.AddTable(tbl); | ||||
|             } catch (Exception exc) { | ||||
|                 MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|             } | ||||
|             Mouse.OverrideCursor = null; | ||||
|         } | ||||
|  | ||||
|         private async void BreakdownMemberVarietyButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             if (SeasonInput.Value is not int year) | ||||
|                 return; | ||||
|             var d = new SaveFileDialog() { | ||||
|                 FileName = $"Liefermengen-Ertrag-{year}.ods", | ||||
|                 DefaultExt = "ods", | ||||
|                 Filter = "OpenDocument Format Spreadsheet (*.ods)|*.ods", | ||||
|                 Title = $"Liefermengen/Ertrag {year} speichern unter - Elwig" | ||||
|             }; | ||||
|             if (d.ShowDialog() == false) | ||||
|                 return; | ||||
|  | ||||
|             Mouse.OverrideCursor = Cursors.AppStarting; | ||||
|             try { | ||||
|                 var b = new Billing(year); | ||||
|                 await b.FinishSeason(); | ||||
|                 await b.CalculateBuckets(); | ||||
|                 App.HintContextChange(); | ||||
|  | ||||
|                 using var ctx = new AppDbContext(); | ||||
|                 var tbl = await MemberDeliveryPerVarietyData.ForSeason(ctx.MemberDeliveryPerVariantRows, year); | ||||
|                 using var ods = new OdsFile(d.FileName); | ||||
|                 await ods.AddTable(tbl); | ||||
|             } catch (Exception exc) { | ||||
|                 MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error); | ||||
|             } | ||||
|             Mouse.OverrideCursor = null; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -52,19 +52,43 @@ | ||||
|         <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Kontaktieren"> | ||||
|                 <MenuItem x:Name="Menu_Contact_Email" Header="E-Mail senden..." IsEnabled="{Binding MemberHasEmail}" | ||||
|                           Click="Menu_Contact_Email_Click"/> | ||||
|                           Click="Menu_Contact_Email_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_Contact_Letterhead" Header="Briefkopf drucken" IsEnabled="{Binding IsMemberSelected}" | ||||
|                           Click="Menu_Contact_Letterhead_Click"/> | ||||
|                           Click="Menu_Contact_Letterhead_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Stammdatenblatt"> | ||||
|                 <MenuItem x:Name="Menu_MemberDataSheet_Show" Header="...anzeigen (PDF)" IsEnabled="{Binding IsMemberSelected}" | ||||
|                           Click="Menu_MemberDataSheet_Show_Click" InputGestureText="Strg+P"/> | ||||
|                           Click="Menu_MemberDataSheet_Show_Click" InputGestureText="Strg+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_MemberDataSheet_SavePdf" Header="...speichern... (PDF)" IsEnabled="{Binding IsMemberSelected}" | ||||
|                           Click="Menu_MemberDataSheet_SavePdf_Click"/> | ||||
|                           Click="Menu_MemberDataSheet_SavePdf_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_MemberDataSheet_Print" Header="...drucken" IsEnabled="{Binding IsMemberSelected}" | ||||
|                           Click="Menu_MemberDataSheet_Print_Click" InputGestureText="Strg+Shift+P"/> | ||||
|                           Click="Menu_MemberDataSheet_Print_Click" InputGestureText="Strg+Shift+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_MemberDataSheet_Email" Header="...per E-Mail schicken" IsEnabled="{Binding MemberCanSendEmail}" | ||||
|                           Click="Menu_MemberDataSheet_Email_Click"/> | ||||
|                           Click="Menu_MemberDataSheet_Email_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Anlieferungsbestätigung" x:Name="Menu_DeliveryConfirmation"> | ||||
|                 <MenuItem x:Name="Menu_DeliveryConfirmation_Show" Header="...anzeigen (PDF)" IsEnabled="False" | ||||
| @@ -177,7 +201,7 @@ | ||||
|                         <Bold>Telefon-Nr.</Bold>: z.B. +436641234, ....<LineBreak/> | ||||
|                         <Bold>Kontaktdaten</Bold>: email (mind. 1 E-Mail-Adr.), telnr (mind. 1 Tel.-Nr.), !email (keine E-Mail-Adr.), !telnr (keine Tel.-Nr.)<LineBreak/> | ||||
|                         <Bold>Kontaktart</Bold>: kontakt:email, kontakt:post, !kontakt:email, !kontakt:post<LineBreak/> | ||||
|                         <Bold>Flächenbindungen</Bold>: z.B. zw, GVK, WRB, ... (Mitglieder mit aktiven Flächenbindungen)<LineBreak/> | ||||
|                         <Bold>Flächenbindungen</Bold>: z.B. zw, GVK, WRB, Fläch[enbindung], !GVK, ... (Mitglieder mit aktiven Flächenbindungen)<LineBreak/> | ||||
|                         <Bold>Freitext</Bold>: z.B. Rechnungsaddresse, Anmerkung, "matzen" (sucht nach dem Text "matzen") | ||||
|                     </TextBlock> | ||||
|                 </TextBox.ToolTip> | ||||
|   | ||||
| @@ -68,7 +68,7 @@ namespace Elwig.Windows { | ||||
|                 (PhoneNr9TypeInput, PhoneNr9Input, PhoneNr9CommentInput), | ||||
|             ]; | ||||
|  | ||||
|             InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             ControlUtils.InitializeDelayTimer(SearchInput, SearchInput_TextChanged); | ||||
|             SearchInput.TextChanged -= SearchInput_TextChanged; | ||||
|  | ||||
|             ViewModel.MemberListOrderByMgNr = false; | ||||
| @@ -187,49 +187,80 @@ namespace Elwig.Windows { | ||||
|             ControlUtils.RenewItemsSource(BranchInput, await ctx.Branches.OrderBy(b => b.Name).ToListAsync()); | ||||
|             ControlUtils.RenewItemsSource(DefaultKgInput, await ctx.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync()); | ||||
|  | ||||
|             var font = new System.Windows.Media.FontFamily("Segoe MDL2 Assets"); | ||||
|             MenuItem? temp = null; | ||||
|             var seasons = await ctx.Seasons.OrderByDescending(s => s.Year).ToListAsync(); | ||||
|             Menu_DeliveryConfirmation.Items.Clear(); | ||||
|             foreach (var s in seasons) { | ||||
|                 var i = new MenuItem { Header = $"Saison {s.Year}...", Tag = s.Year }; | ||||
|                 var i = new MenuItem { | ||||
|                     Header = $"Saison {s.Year}...", | ||||
|                     Tag = s.Year, | ||||
|                     Icon = s.Year == seasons[0].Year ? new TextBlock { FontSize = 16, Text = "\uE734", FontFamily = font } : null, | ||||
|                 }; | ||||
|                 i.SetBinding(IsEnabledProperty, new Binding() { Path = new("IsMemberSelected") }); | ||||
|                 var show = new MenuItem { Header = "...anzeigen (PDF)" }; | ||||
|                 var show = new MenuItem { Header = "...anzeigen (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uE8FF", FontFamily = font } }; | ||||
|                 show.Click += Menu_DeliveryConfirmation_Show_Click; | ||||
|                 i.Items.Add(show); | ||||
|                 var pdf = new MenuItem { Header = "...speichern... (PDF)" }; | ||||
|                 var pdf = new MenuItem { Header = "...speichern... (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uEA90", FontFamily = font } }; | ||||
|                 pdf.Click += Menu_DeliveryConfirmation_SavePdf_Click; | ||||
|                 i.Items.Add(pdf); | ||||
|                 var print = new MenuItem { Header = "...drucken" }; | ||||
|                 var print = new MenuItem { Header = "...drucken", Icon = new TextBlock { FontSize = 16, Text = "\uE749", FontFamily = font } }; | ||||
|                 print.Click += Menu_DeliveryConfirmation_Print_Click; | ||||
|                 i.Items.Add(print); | ||||
|                 var email = new MenuItem { Header = "...per E-Mail schicken" }; | ||||
|                 var email = new MenuItem { Header = "...per E-Mail schicken", Icon = new TextBlock { FontSize = 16, Text = "\uE89C", FontFamily = font } }; | ||||
|                 email.Click += Menu_DeliveryConfirmation_Email_Click; | ||||
|                 email.SetBinding(IsEnabledProperty, new Binding() { Path = new("MemberCanSendEmail") }); | ||||
|                 i.Items.Add(email); | ||||
|                 Menu_DeliveryConfirmation.Items.Add(i); | ||||
|                 var decade = s.Year / 10; | ||||
|                 if (seasons[0].Year / 10 != decade) { | ||||
|                     if (temp == null || !temp.Header.ToString()!.Contains($"{decade}0er")) { | ||||
|                         temp = new MenuItem { Header = $"Saisons {decade}0er..." }; | ||||
|                         Menu_DeliveryConfirmation.Items.Add(temp); | ||||
|                     } | ||||
|                     temp?.Items.Add(i); | ||||
|                 } else { | ||||
|                     Menu_DeliveryConfirmation.Items.Add(i); | ||||
|                 } | ||||
|             } | ||||
|             temp = null; | ||||
|             Menu_CreditNote.Items.Clear(); | ||||
|             foreach (var s in seasons) { | ||||
|                 var i1 = new MenuItem { Header = $"Saison {s.Year}...", Tag = s.Year, IsEnabled = MemberList.SelectedItem != null }; | ||||
|                 var i1 = new MenuItem { | ||||
|                     Header = $"Saison {s.Year}...", | ||||
|                     Tag = s.Year, | ||||
|                     IsEnabled = MemberList.SelectedItem != null, | ||||
|                     Icon = s.Year == seasons[0].Year ? new TextBlock { FontSize = 16, Text = "\uE734", FontFamily = font } : null, | ||||
|                 }; | ||||
|                 i1.SetBinding(IsEnabledProperty, new Binding() { Path = new($"MemberHasDeliveries[{s.Year}]") }); | ||||
|                 foreach (var v in s.PaymentVariants.OrderByDescending(v => v.AvNr)) { | ||||
|                     var i2 = new MenuItem { Header = $"...{v.Name}...", Tag = v.AvNr }; | ||||
|                     var show = new MenuItem { Header = "...anzeigen (PDF)" }; | ||||
|                     var show = new MenuItem { Header = "...anzeigen (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uE8FF", FontFamily = font } }; | ||||
|                     show.Click += Menu_CreditNote_Show_Click; | ||||
|                     i2.Items.Add(show); | ||||
|                     var pdf = new MenuItem { Header = "...speichern... (PDF)" }; | ||||
|                     var pdf = new MenuItem { Header = "...speichern... (PDF)", Icon = new TextBlock { FontSize = 16, Text = "\uEA90", FontFamily = font } }; | ||||
|                     pdf.Click += Menu_CreditNote_SavePdf_Click; | ||||
|                     i2.Items.Add(pdf); | ||||
|                     var print = new MenuItem { Header = "...drucken" }; | ||||
|                     var print = new MenuItem { Header = "...drucken", Icon = new TextBlock { FontSize = 16, Text = "\uE749", FontFamily = font } }; | ||||
|                     print.Click += Menu_CreditNote_Print_Click; | ||||
|                     i2.Items.Add(print); | ||||
|                     var email = new MenuItem { Header = "...per E-Mail schicken" }; | ||||
|                     var email = new MenuItem { Header = "...per E-Mail schicken", Icon = new TextBlock { FontSize = 16, Text = "\uE89C", FontFamily = font } }; | ||||
|                     email.SetBinding(IsEnabledProperty, new Binding { Path = new("MemberCanSendEmail") }); | ||||
|                     email.Click += Menu_CreditNote_Email_Click; | ||||
|                     i2.Items.Add(email); | ||||
|                     i1.Items.Add(i2); | ||||
|                 } | ||||
|                 Menu_CreditNote.Items.Add(i1); | ||||
|                 var decade = s.Year / 10; | ||||
|                 if (seasons[0].Year / 10 != decade) { | ||||
|                     if (temp == null || !temp.Header.ToString()!.Contains($"{decade}0er")) { | ||||
|                         temp = new MenuItem { Header = $"Saisons {decade}0er..." }; | ||||
|                         Menu_CreditNote.Items.Add(temp); | ||||
|                     } | ||||
|                     temp?.Items.Add(i1); | ||||
|                 } else { | ||||
|                     Menu_CreditNote.Items.Add(i1); | ||||
|                 } | ||||
|             } | ||||
|             temp = null; | ||||
|  | ||||
|             await RefreshList(); | ||||
|  | ||||
|   | ||||
| @@ -56,21 +56,45 @@ | ||||
|         <Menu Grid.ColumnSpan="2" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Variantendaten"> | ||||
|                 <MenuItem x:Name="Menu_SummaryShow" Header="...anzeigen (PDF)" IsEnabled="False" | ||||
|                           Click="Menu_SummaryShow_Click" InputGestureText="Strg+P"/> | ||||
|                           Click="Menu_SummaryShow_Click" InputGestureText="Strg+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_SummarySave" Header="...speichern... (PDF)" IsEnabled="False" | ||||
|                           Click="Menu_SummarySave_Click"/> | ||||
|                           Click="Menu_SummarySave_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_SummaryExport" Header="...speichern... (Excel)" IsEnabled="False" | ||||
|                           Click="Menu_SummaryExport_Click"/> | ||||
|                           Click="Menu_SummaryExport_Click"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|                 <MenuItem x:Name="Menu_SummaryPrint" Header="...drucken" IsEnabled="False" | ||||
|                           Click="Menu_SummaryPrint_Click" InputGestureText="Strg+Shift+P"/> | ||||
|                           Click="Menu_SummaryPrint_Click" InputGestureText="Strg+Shift+P"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Buchungsliste"> | ||||
|                 <MenuItem x:Name="Menu_ExportSave" Header="...speichern... (Excel)" IsEnabled="False" | ||||
|                           Click="Menu_ExportSave_Click" InputGestureText="Strg+L"/> | ||||
|                           Click="Menu_ExportSave_Click" InputGestureText="Strg+L"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Überweisungsdaten"> | ||||
|                 <MenuItem x:Name="Menu_EbicsSave" Header="...exportieren... (EBICS)" IsEnabled="False" | ||||
|                           Click="Menu_EbicsSave_Click" InputGestureText="Strg+Ü"/> | ||||
|                           Click="Menu_EbicsSave_Click" InputGestureText="Strg+Ü"> | ||||
|                     <MenuItem.Icon> | ||||
|                         <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text=""/> | ||||
|                     </MenuItem.Icon> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|         </Menu> | ||||
|  | ||||
| @@ -215,10 +239,16 @@ | ||||
|                         Click="SaveButton_Click"/> | ||||
|             </Grid> | ||||
|  | ||||
|             <Button x:Name="MailButton" Content="Traubengutschriften" | ||||
|                     FontSize="14" Width="160" Margin="10,10,10,10" Height="27" IsEnabled="False" | ||||
|             <Button x:Name="MailButton" | ||||
|                     FontSize="14" Width="180" Margin="10,10,10,10" Height="30" IsEnabled="False" | ||||
|                     Click="MailButton_Click" | ||||
|                     VerticalAlignment="Bottom" HorizontalAlignment="Right" Grid.Column="1"/> | ||||
|                     VerticalAlignment="Bottom" HorizontalAlignment="Right" HorizontalContentAlignment="Stretch" Grid.Column="1"> | ||||
|                 <Grid> | ||||
|                     <TextBlock FontFamily="Segoe MDL2 Assets" FontSize="16" Text="" | ||||
|                                TextAlignment="Left" HorizontalAlignment="Left" Padding="0,1.5,0,0" Margin="0,0,10,0"/> | ||||
|                     <TextBlock Margin="18,0,0,0" TextAlignment="Center">Traubengutschriften</TextBlock> | ||||
|                 </Grid> | ||||
|             </Button> | ||||
|         </Grid> | ||||
|  | ||||
|         <StatusBar Grid.Row="2" Grid.ColumnSpan="2" BorderThickness="0,1,0,0" BorderBrush="Gray"> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user