Compare commits
	
		
			17 Commits
		
	
	
		
			0938e33fe1
			...
			v0.3.3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7347439034 | |||
| 51ad8f99fd | |||
| 39279a5dda | |||
| 5271f357f5 | |||
| 13ba3f90f6 | |||
| 43be8bf391 | |||
| 826a76c56c | |||
| efaae5f490 | |||
| 3a73265a75 | |||
| a6fef7fd9b | |||
| a08df4c3ed | |||
| 9701af9e36 | |||
| b4f1eeee84 | |||
| 2922fe0138 | |||
| 704facbc6b | |||
| 404e8a0c27 | |||
| ef621fab2d | 
| @@ -82,7 +82,7 @@ namespace Elwig { | ||||
|  | ||||
|             Dictionary<string, (string, string, int?, string?, string?, string?, string?, string?)> branches = new(); | ||||
|             using (var ctx = new AppDbContext()) { | ||||
|                 branches = ctx.Branches.ToDictionary(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Dest, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr)); | ||||
|                 branches = ctx.Branches.ToDictionary(b => b.Name.ToLower(), b => (b.ZwstId, b.Name, b.PostalDest?.AtPlz?.Plz, b.PostalDest?.AtPlz?.Ort.Name, b.Address, b.PhoneNr, b.FaxNr, b.MobileNr)); | ||||
|                 try { | ||||
|                     Client = new(ctx); | ||||
|                 } catch (Exception e) { | ||||
|   | ||||
							
								
								
									
										67
									
								
								Elwig/Documents/DeliveryJournal.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								Elwig/Documents/DeliveryJournal.cshtml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| @using RazorLight | ||||
| @inherits TemplatePage<Elwig.Documents.DeliveryJournal> | ||||
| @model Elwig.Documents.DeliveryJournal | ||||
| @{ Layout = "Document"; } | ||||
| <link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\style-deliveryjournal.css"/> | ||||
| <main> | ||||
|     <h1>Lieferjournal</h1> | ||||
|     <h2>@Model.Filter</h2> | ||||
|     <table class="journal"> | ||||
|         <colgroup> | ||||
|             <col style="width: 25mm;"/> | ||||
|             <col style="width: 5mm;"/> | ||||
|             <col style="width: 17mm;"/> | ||||
|             <col style="width: 10mm;"/> | ||||
|             <col style="width: 8mm;"/> | ||||
|             <col style="width: 38mm;"/> | ||||
|             <col style="width: 28mm;"/> | ||||
|             <col style="width: 10mm;"/> | ||||
|             <col style="width: 10mm;"/> | ||||
|             <col style="width: 14mm;"/> | ||||
|         </colgroup> | ||||
|         <thead> | ||||
|             <tr> | ||||
|                 <th rowspan="2" style="text-align: left;">Lieferschein-Nr.</th> | ||||
|                 <th rowspan="2">Pos.</th> | ||||
|                 <th rowspan="2">Datum</th> | ||||
|                 <th rowspan="2">Zeit</th> | ||||
|                 <th colspan="2" rowspan="2" style="text-align: left;">Mitglied</th> | ||||
|                 <th rowspan="2" style="text-align: left;">Sorte</th> | ||||
|                 <th colspan="2">Gradation</th> | ||||
|                 <th>Gewicht</th> | ||||
|             </tr> | ||||
|             <tr> | ||||
|                 <th>[°Oe]</th> | ||||
|                 <th>[°KMW]</th> | ||||
|                 <th>[kg]</th> | ||||
|             </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|             @foreach (var p in Model.Deliveries) { | ||||
|                 <tr> | ||||
|                     <td>@p.Delivery.LsNr</td> | ||||
|                     <td>@p.DPNr</td> | ||||
|                     <td>@($"{p.Delivery.Date:dd.MM.yyyy}")</td> | ||||
|                     <td>@($"{p.Delivery.Time:HH:mm}")</td> | ||||
|                     <td class="mgnr">@p.Delivery.Member.MgNr</td> | ||||
|                     <td>@p.Delivery.Member.AdministrativeName</td> | ||||
|                     <td>@p.Variant.Name</td> | ||||
|                     <td class="grad">@($"{p.Oe:N0}")</td> | ||||
|                     <td class="grad">@($"{p.Kmw:N1}")</td> | ||||
|                     <td class="weight">@($"{p.Weight:N0}")</td> | ||||
|                 </tr> | ||||
|             } | ||||
|             <tr class="sum"> | ||||
|                 @{ | ||||
|                     var kmw = Elwig.Helpers.Utils.AggregateDeliveryPartsKmw(Model.Deliveries); | ||||
|                     var oe = Elwig.Helpers.Utils.KmwToOe(kmw); | ||||
|                 } | ||||
|                 <td colspan="2">Gesamt:</td> | ||||
|                 <td colspan="5">(Teil-)Lieferungen: @($"{Model.Deliveries.DistinctBy(p => p.Delivery).Count():N0}") (@($"{Model.Deliveries.Count():N0}"))</td> | ||||
|                 <td class="grad">@($"{oe:N0}")</td> | ||||
|                 <td class="grad">@($"{kmw:N1}")</td> | ||||
|                 <td class="weight">@($"{Model.Deliveries.Sum(p => p.Weight):N0}")</td> | ||||
|             </tr> | ||||
|         </tbody> | ||||
|     </table> | ||||
| </main> | ||||
							
								
								
									
										25
									
								
								Elwig/Documents/DeliveryJournal.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								Elwig/Documents/DeliveryJournal.cshtml.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| using Elwig.Helpers; | ||||
| using Elwig.Models; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
|  | ||||
| namespace Elwig.Documents { | ||||
|     public class DeliveryJournal : Document { | ||||
|  | ||||
|         public string Filter; | ||||
|         public IEnumerable<DeliveryPart> Deliveries; | ||||
|  | ||||
|         public DeliveryJournal(string filter, IEnumerable<DeliveryPart> deliveries) : base($"Lieferjournal {filter}") { | ||||
|             Filter = filter; | ||||
|             Deliveries = deliveries; | ||||
|         } | ||||
|  | ||||
|         public DeliveryJournal(AppDbContext ctx, DateOnly date) : | ||||
|             this(date.ToString("dd.MM.yyyy"), ctx.DeliveryParts | ||||
|                 .Where(p => p.Delivery.DateString == date.ToString("yyy-MM-dd")) | ||||
|                 .OrderBy(p => p.Delivery.LsNr) | ||||
|                 .ThenBy(p => p.DPNr) | ||||
|                 .ToList()) { } | ||||
|     } | ||||
| } | ||||
| @@ -53,6 +53,8 @@ namespace Elwig.Documents { | ||||
|                 name = "DeliveryNote"; | ||||
|             } else if (this is CreditNote) { | ||||
|                 name = "CreditNote"; | ||||
|             } else if (this is DeliveryJournal) { | ||||
|                 name = "DeliveryJournal"; | ||||
|             } else { | ||||
|                 throw new InvalidOperationException("Invalid document object"); | ||||
|             } | ||||
|   | ||||
| @@ -19,6 +19,7 @@ namespace Elwig.Documents { | ||||
|             await e.CompileTemplateAsync("BusinessLetter"); | ||||
|             await e.CompileTemplateAsync("DeliveryNote"); | ||||
|             await e.CompileTemplateAsync("CreditNote"); | ||||
|             await e.CompileTemplateAsync("DeliveryJournal"); | ||||
|  | ||||
|             Engine = e; | ||||
|             evtHandler(); | ||||
|   | ||||
							
								
								
									
										47
									
								
								Elwig/Documents/style-deliveryjournal.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								Elwig/Documents/style-deliveryjournal.css
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,47 @@ | ||||
|  | ||||
| h1 { | ||||
|     text-align: center; | ||||
|     font-size: 24pt; | ||||
|     margin-bottom: 2mm; | ||||
| } | ||||
|  | ||||
| h2 { | ||||
|     text-align: center; | ||||
|     font-size: 14pt; | ||||
|     margin-top: 2mm; | ||||
| } | ||||
|  | ||||
| table.journal { | ||||
|     font-size: 10pt; | ||||
| } | ||||
|  | ||||
| table.journal thead { | ||||
|     font-size: 8pt; | ||||
| } | ||||
|  | ||||
| table.journal th { | ||||
|     font-weight: normal; | ||||
|     font-style: italic; | ||||
| } | ||||
|  | ||||
| table.journal td { | ||||
|     overflow: hidden; | ||||
|     white-space: nowrap; | ||||
| } | ||||
|  | ||||
| table.journal .mgnr, | ||||
| table.journal .weight { | ||||
|     text-align: right; | ||||
| } | ||||
|  | ||||
| table.journal .grad { | ||||
|     text-align: center; | ||||
| } | ||||
|  | ||||
| table.journal tr.sum { | ||||
|     font-weight: bold; | ||||
| } | ||||
|  | ||||
| table.journal tr.sum td { | ||||
|     border-top: 0.5pt solid black; | ||||
| } | ||||
| @@ -7,7 +7,7 @@ | ||||
|     <UseWPF>true</UseWPF> | ||||
|     <PreserveCompilationContext>true</PreserveCompilationContext> | ||||
|     <ApplicationIcon>elwig.ico</ApplicationIcon> | ||||
|     <Version>0.3.0</Version> | ||||
|     <Version>0.3.3</Version> | ||||
|     <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages> | ||||
|   </PropertyGroup> | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,7 @@ using System; | ||||
| namespace Elwig.Helpers { | ||||
|     public static class AppDbUpdater { | ||||
|  | ||||
|         public static readonly int RequiredSchemaVersion = 1; | ||||
|         public static readonly int RequiredSchemaVersion = 2; | ||||
|  | ||||
|         private static int _versionOffset = 0; | ||||
|         private static readonly Action<SqliteConnection>[] _updaters = new[] { | ||||
| @@ -42,7 +42,10 @@ namespace Elwig.Helpers { | ||||
|             var minor = (userVers >> 16) & 0xFF; | ||||
|             var patch = userVers & 0xFFFF; | ||||
|  | ||||
|             if (App.VersionMajor > major || App.VersionMinor > minor || App.VersionPatch > patch) { | ||||
|             if (App.VersionMajor > major || | ||||
|                 (App.VersionMajor == major && App.VersionMinor > minor) || | ||||
|                 (App.VersionMajor == major && App.VersionMinor == minor && App.VersionPatch > patch)) | ||||
|             { | ||||
|                 long vers = (App.VersionMajor << 24) | (App.VersionMinor << 16) | App.VersionPatch; | ||||
|                 ExecuteNonQuery(cnx, $"PRAGMA user_version = {vers}"); | ||||
|             } | ||||
| @@ -71,7 +74,11 @@ namespace Elwig.Helpers { | ||||
|             ExecuteNonQuery(cnx, $"PRAGMA schema_version = {toVersion * 100 + _versionOffset}"); | ||||
|         } | ||||
|  | ||||
|         private static void UpdateDbSchema_1_To_2(SqliteConnection cnx) { } | ||||
|         private static void UpdateDbSchema_1_To_2(SqliteConnection cnx) { | ||||
|             ExecuteNonQuery(cnx, "DROP VIEW v_area_commitment"); | ||||
|             ExecuteNonQuery(cnx, "ALTER TABLE delivery_part DROP COLUMN weighing_reason"); | ||||
|             ExecuteNonQuery(cnx, "ALTER TABLE delivery_part ADD COLUMN weighing_reason TEXT CHECK(NOT (manual_weighing = FALSE AND weighing_reason IS NOT NULL))"); | ||||
|         } | ||||
|  | ||||
|         private static void UpdateDbSchema_2_To_3(SqliteConnection cnx) { } | ||||
|     } | ||||
|   | ||||
| @@ -193,28 +193,27 @@ namespace Elwig.Helpers { | ||||
|             if (!searchKeywords.Any()) | ||||
|                 return 0; | ||||
|  | ||||
|             return words | ||||
|                 .Select(w => { | ||||
|                     w = w?.ToLower(); | ||||
|                     var p = w?.ToLower()?.Split(" "); | ||||
|                     if (w == null || p == null) | ||||
|                         return 0; | ||||
|  | ||||
|                     var t1 = searchKeywords.Where(f => w == f).Select(f => f.Length).OrderDescending().FirstOrDefault(0); | ||||
|                     var t2 = searchKeywords.Where(f => p.Any(a => a == f)).Select(f => f.Length).OrderDescending().FirstOrDefault(0); | ||||
|                     var t3 = searchKeywords.Where(f => p.Any(a => a.StartsWith(f))).Select(f => f.Length).OrderDescending().FirstOrDefault(0); | ||||
|                     var t4 = searchKeywords.Where(f => w.Contains(f)).Select(f => f.Length).OrderDescending().FirstOrDefault(0); | ||||
|                     if (t1 > 0) { | ||||
|                         return 4 + t1; | ||||
|                     } else if (t2 > 0) { | ||||
|                         return 3 + t2; | ||||
|                     } else if (t3 > 0) { | ||||
|                         return 2 + t3; | ||||
|                     } else if (t4 > 0) { | ||||
|                         return 1 + t4; | ||||
|                     } else { | ||||
|                         return 0; | ||||
|                     } | ||||
|             return searchKeywords | ||||
|                 .Select(k => { | ||||
|                     k = k.ToLower(); | ||||
|                     var scores = words.Select(w => { | ||||
|                         w = w?.ToLower(); | ||||
|                         var p = w?.ToLower()?.Split(" "); | ||||
|                         if (w == null || p == null) { | ||||
|                             return 0; | ||||
|                         } else if (k == w) { | ||||
|                             return 4 + k.Length; | ||||
|                         } else if (p.Any(a => a == k)) { | ||||
|                             return 3 + k.Length; | ||||
|                         } else if (p.Any(a => a.StartsWith(k))) { | ||||
|                             return 2 + k.Length; | ||||
|                         } else if (w.Contains(k)) { | ||||
|                             return 1 + k.Length; | ||||
|                         } else { | ||||
|                             return 0; | ||||
|                         } | ||||
|                     }); | ||||
|                     return scores.Max() + scores.Count(s => s > 0); | ||||
|                 }) | ||||
|                 .Sum(); | ||||
|         } | ||||
|   | ||||
| @@ -70,9 +70,9 @@ namespace Elwig.Helpers { | ||||
|             for (int i = 0; i < input.Text.Length; i++) { | ||||
|                 char ch = input.Text[i]; | ||||
|                 if (char.IsAsciiDigit(ch)) { | ||||
|                     if (v2 == -1 && v1 < maxLen) { | ||||
|                     if (v2 == -1 && (maxLen == -1 || v1 < maxLen)) { | ||||
|                         text += ch; v1++; | ||||
|                     } else if (v2 != -1 && v2 < maxDecimal) { | ||||
|                     } else if (v2 != -1 && (maxDecimal == -1 || v2 < maxDecimal)) { | ||||
|                         text += ch; v2++; | ||||
|                     } | ||||
|                 } else if (v2 == 0-1 && ch == ',' || ch == '.') { | ||||
|   | ||||
| @@ -16,20 +16,20 @@ namespace Elwig.Windows { | ||||
|         protected Control[] ExemptInputs { private get; set; } | ||||
|         protected Control[] RequiredInputs { private get; set; } | ||||
|  | ||||
|         private bool _IsEditing; | ||||
|         private bool _IsCreating; | ||||
|         private bool _isEditing; | ||||
|         private bool _isCreating; | ||||
|         protected bool IsEditing { | ||||
|             get { return _IsEditing; } | ||||
|             get { return _isEditing; } | ||||
|             set { | ||||
|                 _IsEditing = value; | ||||
|                 LockContext = IsEditing; | ||||
|                 _isEditing = value; | ||||
|                 LockContext = IsEditing || IsCreating; | ||||
|             } | ||||
|         } | ||||
|         protected bool IsCreating { | ||||
|             get { return _IsCreating; } | ||||
|             get { return _isCreating; } | ||||
|             set { | ||||
|                 _IsCreating = value; | ||||
|                 LockContext = IsEditing; | ||||
|                 _isCreating = value; | ||||
|                 LockContext = IsEditing || IsCreating; | ||||
|             } | ||||
|         } | ||||
|         protected bool DoShowWarningWindows = true; | ||||
| @@ -99,7 +99,7 @@ namespace Elwig.Windows { | ||||
|  | ||||
|         abstract protected void UpdateButtons(); | ||||
|  | ||||
|         protected override async Task RenewContext() { | ||||
|         protected override async Task OnRenewContext() { | ||||
|             for (int i = 0; i < PlzInputs.Length; i++) | ||||
|                 UpdatePlz(PlzInputs[i], PlzOrtInputs[i]); | ||||
|         } | ||||
| @@ -462,6 +462,10 @@ namespace Elwig.Windows { | ||||
|             InputTextChanged((TextBox)sender, Validator.CheckInteger); | ||||
|         } | ||||
|  | ||||
|         protected void DecimalInput_TextChanged(object sender, RoutedEventArgs evt) { | ||||
|             InputTextChanged((TextBox)sender, Validator.CheckDecimal); | ||||
|         } | ||||
|  | ||||
|         protected void PartialDateInput_TextChanged(object sender, RoutedEventArgs evt) { | ||||
|             InputTextChanged((TextBox)sender, Validator.CheckPartialDate); | ||||
|         } | ||||
|   | ||||
| @@ -95,8 +95,8 @@ namespace Elwig.Windows { | ||||
|             ValidateRequiredInputs(); | ||||
|         } | ||||
|  | ||||
|         protected override async Task RenewContext() { | ||||
|             await base.RenewContext(); | ||||
|         protected override async Task OnRenewContext() { | ||||
|             await base.OnRenewContext(); | ||||
|             ControlUtils.RenewItemsSource(KgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr); | ||||
|             ControlUtils.RenewItemsSource(AreaComTypeInput, await Context.AreaCommitmentTypes.OrderBy(v => v.VtrgId).ToListAsync(), i => (i as AreaComType)?.VtrgId); | ||||
|             ControlUtils.RenewItemsSource(WineCultivationInput, await Context.WineCultivations.OrderBy(c => c.Name).ToListAsync(), i => (i as WineCult)?.CultId); | ||||
|   | ||||
| @@ -52,8 +52,8 @@ namespace Elwig.Windows { | ||||
|             FillInputs(App.Client); | ||||
|         } | ||||
|  | ||||
|         protected override async Task RenewContext() { | ||||
|             await base.RenewContext(); | ||||
|         protected override async Task OnRenewContext() { | ||||
|             await base.OnRenewContext(); | ||||
|             ControlUtils.RenewItemsSource(SeasonList, await Context.Seasons.OrderByDescending(s => s.Year).ToListAsync(), s => (s as Season)?.Year, null, ControlUtils.RenewSourceDefault.First); | ||||
|             var year = (SeasonList.SelectedItem as Season)?.Year; | ||||
|             ControlUtils.RenewItemsSource(SeasonModifierList, await Context.Modifiers.Where(m => m.Year == year).OrderBy(m => m.Ordering).ToListAsync(), m => (m as Modifier)?.ModId); | ||||
| @@ -117,6 +117,7 @@ namespace Elwig.Windows { | ||||
|             await Context.SaveChangesAsync(); | ||||
|  | ||||
|             foreach (var mod in ModifierList.Where(m => !ModifierIds.ContainsKey(m))) { | ||||
|                 if (mod.ModId == null) continue; | ||||
|                 await Context.AddAsync(mod); | ||||
|             } | ||||
|             await Context.SaveChangesAsync(); | ||||
| @@ -321,6 +322,7 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void SeasonModifierRelInput_TextChanged(object sender, TextChangedEventArgs evt) { | ||||
|             // DecimalInput_TextChanged(sender, evt); FIXME '-' is ignored | ||||
|             if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod) return; | ||||
|             ModifiersChanged = ModifiersChanged || (SeasonModifierRelInput.Text ?? "") != ((SeasonModifierList.SelectedItem as Modifier)?.Rel?.ToString() ?? ""); | ||||
|             if (ModifierUpdate) return; | ||||
| @@ -331,11 +333,13 @@ namespace Elwig.Windows { | ||||
|         } | ||||
|  | ||||
|         private void SeasonModifierAbsInput_TextChanged(object sender, TextChangedEventArgs evt) { | ||||
|             if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod) return; | ||||
|             // DecimalInput_TextChanged(sender, evt); FIXME '-' is ignored | ||||
|             if ((!IsEditing && !IsCreating) || SeasonModifierList.SelectedItem is not Modifier mod || SeasonList.SelectedItem is not Season s) return; | ||||
|             ModifiersChanged = ModifiersChanged || (SeasonModifierAbsInput.Text ?? "") != ((SeasonModifierList.SelectedItem as Modifier)?.Abs?.ToString() ?? ""); | ||||
|             if (ModifierUpdate) return; | ||||
|             mod.Abs = decimal.TryParse(SeasonModifierAbsInput.Text, out var v) ? v : null; | ||||
|             if (mod.Abs != null) SeasonModifierRelInput.Text = ""; | ||||
|             // FIXME ValueStr does not work in ModifierList when modifier is newly created | ||||
|             mod.AbsValue = decimal.TryParse(SeasonModifierAbsInput.Text, out var v) ? Utils.DecToDb(v, s.Precision) : null; | ||||
|             if (mod.AbsValue != null) SeasonModifierRelInput.Text = ""; | ||||
|             CollectionViewSource.GetDefaultView(ModifierList).Refresh(); | ||||
|             UpdateButtons(); | ||||
|         } | ||||
|   | ||||
| @@ -214,8 +214,8 @@ namespace Elwig.Windows { | ||||
|             FinishInputFilling(); | ||||
|         } | ||||
|  | ||||
|         protected override async Task RenewContext() { | ||||
|             await base.RenewContext(); | ||||
|         protected override async Task OnRenewContext() { | ||||
|             await base.OnRenewContext(); | ||||
|             await RefreshGraphList(); | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -7,30 +7,32 @@ using System.Windows.Threading; | ||||
| namespace Elwig.Windows { | ||||
|     public abstract class ContextWindow : Window { | ||||
|  | ||||
|         public static readonly int RenewSec = 10; | ||||
|  | ||||
|         protected AppDbContext Context { get; private set; } | ||||
|         protected bool LockContext { get; set; } = false; | ||||
|  | ||||
|         private readonly DispatcherTimer ContextRenewTimer; | ||||
|         private static readonly int ContextRenewSec = 10; | ||||
|         private readonly DispatcherTimer _timer; | ||||
|         private bool _renewPending = false; | ||||
|  | ||||
|         public ContextWindow() : base() { | ||||
|             ContextRenewTimer = new DispatcherTimer(); | ||||
|             ContextRenewTimer.Tick += new EventHandler(OnRenewContext); | ||||
|             ContextRenewTimer.Interval = new TimeSpan(0, 0, ContextRenewSec); | ||||
|             ContextRenewTimer.Start(); | ||||
|             _timer = new DispatcherTimer(); | ||||
|             _timer.Tick += new EventHandler(OnShouldRenewContext); | ||||
|             _timer.Interval = new TimeSpan(0, 0, RenewSec); | ||||
|             _timer.Start(); | ||||
|             Context = new(); | ||||
|             Loaded += OnLoaded; | ||||
|         } | ||||
|  | ||||
|         private void OnRenewContext(object? sender, EventArgs evt) { | ||||
|             if (LockContext || !Context.HasBackendChanged) return; | ||||
|             Context.Dispose(); | ||||
|             Context = new(); | ||||
|             RenewContext().GetAwaiter().GetResult(); | ||||
|         private async void OnShouldRenewContext(object? sender, EventArgs evt) { | ||||
|             if (!Context.HasBackendChanged) return; | ||||
|             _renewPending = true; | ||||
|             if (LockContext) return; | ||||
|             await RenewContext(); | ||||
|         } | ||||
|  | ||||
|         private void OnLoaded(object sender, RoutedEventArgs evt) { | ||||
|             RenewContext().GetAwaiter().GetResult(); | ||||
|             OnRenewContext().GetAwaiter().GetResult(); | ||||
|         } | ||||
|  | ||||
|         protected override void OnClosed(EventArgs evt) { | ||||
| @@ -38,6 +40,14 @@ namespace Elwig.Windows { | ||||
|             Context.Dispose(); | ||||
|         } | ||||
|  | ||||
|         abstract protected Task RenewContext(); | ||||
|         protected async Task RenewContext() { | ||||
|             if (!_renewPending) return; | ||||
|             Context.Dispose(); | ||||
|             Context = new(); | ||||
|             await OnRenewContext(); | ||||
|             _renewPending = false; | ||||
|         } | ||||
|  | ||||
|         abstract protected Task OnRenewContext(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -56,20 +56,25 @@ | ||||
|         </Grid.ColumnDefinitions> | ||||
|  | ||||
|         <Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White"> | ||||
|             <MenuItem Header="Lieferung"> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Drucken"> | ||||
|                 <MenuItem x:Name="Menu_Print_ShowDeliveryNote" Header="Lieferschein anzeigen" IsEnabled="False" | ||||
|                           Click="Menu_Print_ShowDeliveryNote_Click"/> | ||||
|                 <MenuItem x:Name="Menu_Print_PrintDeliveryNote" Header="Lieferschein drucken" IsEnabled="False" | ||||
|                           Click="Menu_Print_PrintDeliveryNote_Click"/> | ||||
|                 <MenuItem x:Name="Menu_Print_DeliveryJournal" Header="Lieferjournal"> | ||||
|                     <MenuItem x:Name="Menu_Print_DeliveryJournal_ShowToday" Header="von heute anzeigen" | ||||
|                               Click="Menu_Print_DeliveryJournal_ShowToday_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Print_DeliveryJournal_PrintToday" Header="von heute drucken" | ||||
|                               Click="Menu_Print_DeliveryJournal_PrintToday_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Print_DeliveryJournal_ShowFilter" Header="aus Filtern anzeigen" | ||||
|                               Click="Menu_Print_DeliveryJournal_ShowFilter_Click"/> | ||||
|                     <MenuItem x:Name="Menu_Print_DeliveryJournal_PrintFilter" Header="aus Filtern drucken" | ||||
|                               Click="Menu_Print_DeliveryJournal_PrintFilter_Click"/> | ||||
|                 </MenuItem> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Exportieren"> | ||||
|                 <MenuItem x:Name="Menu_Export_Bki" Header="Traubentransportscheinliste (BKI)"/> | ||||
|             </MenuItem> | ||||
|             <MenuItem Header="Werkzeuge"> | ||||
|                 <MenuItem Header="Alle Lieferscheine überprüfen"/> | ||||
|             </MenuItem> | ||||
|         </Menu> | ||||
|  | ||||
|         <Grid Grid.RowSpan="4" Grid.Row="1" Margin="5,0,5,0"> | ||||
| @@ -209,7 +214,7 @@ | ||||
|  | ||||
|                 <Label Content="Sorte:" Margin="10,10,0,0" Grid.Column="0"/> | ||||
|                 <TextBox x:Name="SortIdInput" Width="36" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" | ||||
|                          TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus"  KeyUp="Input_KeyUp"/> | ||||
|                          TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/> | ||||
|                 <ComboBox x:Name="WineVarietyInput" Grid.Row="1" Grid.Column="1" Margin="41,10,10,10" | ||||
|                           ItemTemplate="{StaticResource WineVarietyTemplate}" TextSearch.TextPath="Name"  | ||||
|                           SelectionChanged="WineVarietyInput_SelectionChanged" KeyUp="Input_KeyUp"/> | ||||
| @@ -230,20 +235,20 @@ | ||||
|                 <Label Content="Gradation:" Margin="10,10,10,10"/> | ||||
|                 <Grid Grid.Column="1" Width="54" Height="25" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"> | ||||
|                     <TextBox x:Name="GradationOeInput"  TextAlignment="Right" Padding="2,2,23,2" | ||||
|                              TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus"/> | ||||
|                              TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus" KeyUp="Input_KeyUp"/> | ||||
|                     <Label Content="°Oe" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/> | ||||
|                 </Grid> | ||||
|                 <Label Content="=" Margin="60,10,10,10" Grid.Column="1"/> | ||||
|                 <Grid Grid.Column="1" Width="68" Height="25" Margin="78,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top"> | ||||
|                     <TextBox x:Name="GradationKmwInput" TextAlignment="Right" Padding="2,2,34,2" SnapsToDevicePixels="True" | ||||
|                              TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus"/> | ||||
|                              TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus" KeyUp="Input_KeyUp"/> | ||||
|                     <Label Content="°KMW" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/> | ||||
|                 </Grid> | ||||
|  | ||||
|                 <Label Content="Qualitätsstufe:" Margin="10,40,10,10"/> | ||||
|                 <ComboBox x:Name="WineQualityLevelInput" Width="146" Margin="0,40,10,10" Grid.Column="1" HorizontalAlignment="Left" | ||||
|                           ItemTemplate="{StaticResource WineQualityLevelTemplate}" | ||||
|                           SelectionChanged="WineQualityLevelInput_SelectionChanged"/> | ||||
|                           SelectionChanged="WineQualityLevelInput_SelectionChanged" KeyUp="Input_KeyUp"/> | ||||
|  | ||||
|                 <CheckBox x:Name="AbgewertetInput" Content="Abgewertet" IsEnabled="False" | ||||
|                           VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"/> | ||||
|   | ||||
| @@ -111,8 +111,8 @@ namespace Elwig.Windows { | ||||
|             Mouse.OverrideCursor = Cursors.Wait; | ||||
|             using var doc = new DeliveryNote(d, Context); | ||||
|             await doc.Generate(); | ||||
|             doc.Show(); | ||||
|             Mouse.OverrideCursor = null; | ||||
|             doc.Show(); | ||||
|         } | ||||
|  | ||||
|         private async void Menu_Print_PrintDeliveryNote_Click(object sender, RoutedEventArgs evt) { | ||||
| @@ -128,8 +128,9 @@ namespace Elwig.Windows { | ||||
|             if (sender is not MenuItem m) return; | ||||
|             var year = int.Parse(m.Header.ToString()?.Split(" ")[^1] ?? Utils.CurrentLastSeason.ToString()); | ||||
|             var d = new SaveFileDialog() { | ||||
|                 FileName = $"{App.Client.NameToken}-Traubentransportscheinliste-{year}", | ||||
|                 FileName = $"{App.Client.NameToken}-Traubentransportscheinliste-{year}.{Bki.FileExtension}", | ||||
|                 DefaultExt = Bki.FileExtension, | ||||
|                 Filter = "CSV-Datei (*.csv)|*.csv", | ||||
|                 Title = $"Traubentransportscheinliste (BKI) speichern unter - Elwig" | ||||
|             }; | ||||
|             if (d.ShowDialog() == true) { | ||||
| @@ -140,6 +141,40 @@ namespace Elwig.Windows { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private async void Menu_Print_DeliveryJournal_ShowToday_Click(object sender, RoutedEventArgs evt) { | ||||
|             Mouse.OverrideCursor = Cursors.Wait; | ||||
|             var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today)); | ||||
|             await doc.Generate(); | ||||
|             Mouse.OverrideCursor = null; | ||||
|             doc.Show(); | ||||
|         } | ||||
|  | ||||
|         private async void Menu_Print_DeliveryJournal_PrintToday_Click(object sender, RoutedEventArgs evt) { | ||||
|             Mouse.OverrideCursor = Cursors.Wait; | ||||
|             var doc = new DeliveryJournal(Context, DateOnly.FromDateTime(Utils.Today)); | ||||
|             await doc.Generate(); | ||||
|             Mouse.OverrideCursor = null; | ||||
|             await doc.Print(); | ||||
|         } | ||||
|  | ||||
|         private async void Menu_Print_DeliveryJournal_ShowFilter_Click(object sender, RoutedEventArgs evt) { | ||||
|             Mouse.OverrideCursor = Cursors.Wait; | ||||
|             var (f, _, d, _) = await GetFilters(); | ||||
|             var doc = new DeliveryJournal(string.Join(" / ", f), d); | ||||
|             await doc.Generate(); | ||||
|             Mouse.OverrideCursor = null; | ||||
|             doc.Show(); | ||||
|         } | ||||
|  | ||||
|         private async void Menu_Print_DeliveryJournal_PrintFilter_Click(object sender, RoutedEventArgs evt) { | ||||
|             Mouse.OverrideCursor = Cursors.Wait; | ||||
|             var (f, _, d, _) = await GetFilters(); | ||||
|             var doc = new DeliveryJournal(string.Join(" / ", f), d); | ||||
|             await doc.Generate(); | ||||
|             Mouse.OverrideCursor = null; | ||||
|             doc.Show(); | ||||
|         } | ||||
|  | ||||
|         private void OnSecondPassed(object? sender, EventArgs? evt) { | ||||
|             if (IsReceipt && IsCreating) { | ||||
|                 var now = DateTime.Now; | ||||
| @@ -195,9 +230,14 @@ namespace Elwig.Windows { | ||||
|             if (sender is not Control ctrl) return; | ||||
|             if (evt.Key != Key.Enter) return; | ||||
|             if (ctrl == MgNrInput || ctrl == MemberInput) { | ||||
|                 SortIdInput.Focus(); SortIdInput.SelectAll(); | ||||
|                 SortIdInput.Focus(); | ||||
|                 SortIdInput.SelectAll(); | ||||
|             } else if (ctrl == SortIdInput || ctrl == WineVarietyInput || ctrl == AttributesInput) { | ||||
|                 GradationOeInput.Focus(); GradationOeInput.SelectAll(); | ||||
|                 GradationOeInput.Focus(); | ||||
|                 GradationOeInput.SelectAll(); | ||||
|             } else if (ctrl == GradationKmwInput || ctrl == GradationOeInput || ctrl == WineQualityLevelInput) { | ||||
|                 if (WeighingAButton.IsVisible) WeighingAButton.Focus(); | ||||
|                 else WeighingManualButton.Focus(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -205,19 +245,28 @@ namespace Elwig.Windows { | ||||
|             await RefreshDeliveryListQuery(); | ||||
|         } | ||||
|  | ||||
|         private async Task RefreshDeliveryListQuery(bool updateSort = false) { | ||||
|         private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, List<string>)> GetFilters() { | ||||
|             List<string> filterNames = new(); | ||||
|             IQueryable<Delivery> deliveryQuery = Context.Deliveries; | ||||
|             if (Member != null) { | ||||
|                 deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr); | ||||
|                 filterNames.Add(Member.AdministrativeName); | ||||
|             } | ||||
|             if (TodayOnlyInput.IsChecked == true) { | ||||
|                 deliveryQuery = deliveryQuery | ||||
|                     .Where(d => (d.DateString == Utils.Today.ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") > 0) || | ||||
|                                 (d.DateString == Utils.Today.AddDays(1).ToString("yyyy-MM-dd") && d.TimeString.CompareTo("03:00:00") <= 0)); | ||||
|                 filterNames.Add(Utils.Today.ToString("dd.MM.yyyy")); | ||||
|             } else if (AllSeasonsInput.IsChecked == false) { | ||||
|                 deliveryQuery = deliveryQuery.Where(d => d.Year == SeasonInput.Value); | ||||
|                 filterNames.Add(SeasonInput.Value.ToString() ?? ""); | ||||
|             } | ||||
|             deliveryQuery = deliveryQuery.OrderBy(d => d.DateString).ThenBy(d => d.TimeString); | ||||
|             IQueryable<DeliveryPart> dpq = deliveryQuery.SelectMany(d => d.Parts); | ||||
|  | ||||
|             // TODO add filter for: | ||||
|             //      attributes | ||||
|             //      branches | ||||
|             var filterVar = new List<string>(); | ||||
|             var filterQual = new List<string>(); | ||||
|             var filterMgNr = new List<int>(); | ||||
| @@ -234,21 +283,24 @@ namespace Elwig.Windows { | ||||
|  | ||||
|             var filter = TextFilter.ToList(); | ||||
|             if (filter.Count > 0) { | ||||
|                 var var = await Context.WineVarieties.Select(v => v.SortId).ToListAsync(); | ||||
|                 var qual = await Context.WineQualityLevels.Select(q => q.QualId).ToListAsync(); | ||||
|                 var mgnr = await Context.Members.Select(m => m.MgNr.ToString()).ToListAsync(); | ||||
|                 var var = await Context.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v); | ||||
|                 var qual = await Context.WineQualityLevels.ToDictionaryAsync(q => q.QualId, q => q); | ||||
|                 var mgnr = await Context.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m); | ||||
|  | ||||
|                 for (int i = 0; i < filter.Count; i++) { | ||||
|                     var e = filter[i]; | ||||
|                     if (e.Length == 2 && var.Contains(e.ToUpper())) { | ||||
|                     if (e.Length == 2 && var.ContainsKey(e.ToUpper())) { | ||||
|                         filterVar.Add(e.ToUpper()); | ||||
|                         filter.RemoveAt(i--); | ||||
|                     } else if (e.Length == 3 && qual.Contains(e.ToUpper())) { | ||||
|                         filterNames.Add(var[e.ToUpper()].Name); | ||||
|                     } else if (e.Length == 3 && qual.ContainsKey(e.ToUpper())) { | ||||
|                         filterQual.Add(e.ToUpper()); | ||||
|                         filter.RemoveAt(i--); | ||||
|                     } else if (e.All(char.IsAsciiDigit) && mgnr.Contains(e)) { | ||||
|                         filterNames.Add(qual[e.ToUpper()].Name); | ||||
|                     } else if (e.All(char.IsAsciiDigit) && mgnr.ContainsKey(e)) { | ||||
|                         filterMgNr.Add(int.Parse(e)); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add(mgnr[e].AdministrativeName); | ||||
|                     } else if (e.StartsWith(">") || e.StartsWith("<")) { | ||||
|                         if (double.TryParse(e[1..], out var num)) { | ||||
|                             switch ((e[0], num)) { | ||||
| @@ -297,12 +349,23 @@ namespace Elwig.Windows { | ||||
|                         filterTimeLt = TimeOnly.TryParse(parts[1], out var to) ? $"{to:HH:mm}" : null; | ||||
|                         filter.RemoveAt(i--); | ||||
|                     } else if (DateOnly.TryParse(e, out var date)) { | ||||
|                         filterDate.Add($"{date:yyyy-MM-dd}"); | ||||
|                         // TODO allow date ranges | ||||
|                         filterDate.Add(date.ToString("yyyy-MM-dd")); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         filterNames.Add(date.ToString("dd.MM.yyyy")); | ||||
|                     } else if (Utils.PartialDateRegex.IsMatch(e)) { | ||||
|                         // TODO allow date ranges | ||||
|                         var parts = e.Split("."); | ||||
|                         filterPartDate.Add($"-{int.Parse(parts[1]):00}-{int.Parse(parts[0]):00}"); | ||||
|                         var p0 = int.Parse(parts[0]); | ||||
|                         var p1 = int.Parse(parts[1]); | ||||
|                         filterPartDate.Add($"-{p1:00}-{p0:00}"); | ||||
|                         filter.RemoveAt(i--); | ||||
|                         if (filterNames.Contains(SeasonInput.Value.ToString())) { | ||||
|                             filterNames.Remove(SeasonInput.Value.ToString()); | ||||
|                             filterNames.Add($"{p0:00}.{p1:00}.{SeasonInput.Value:0000}"); | ||||
|                         } else { | ||||
|                             filterNames.Add($"{p0:00}.{p1:00}."); | ||||
|                         } | ||||
|                     } else if (e.Length > 2 && e.StartsWith("\"") && e.EndsWith("\"")) { | ||||
|                         filter[i] = e[1..^1]; | ||||
|                     } else if (e.Length <= 2) { | ||||
| @@ -310,22 +373,58 @@ namespace Elwig.Windows { | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (filterMgNr.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterMgNr.Contains(d.MgNr)); | ||||
|                 if (filterDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterDate.Contains(d.DateString)); | ||||
|                 if (filterPartDate.Count > 0) deliveryQuery = deliveryQuery.Where(d => filterPartDate.Contains(d.DateString.Substring(4))); | ||||
|                 if (filterYearGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year >= filterYearGt); | ||||
|                 if (filterYearLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Year < filterYearLt); | ||||
|                 if (filterTimeGt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeGt.CompareTo(d.TimeString) <= 0); | ||||
|                 if (filterTimeLt != null) deliveryQuery = deliveryQuery.Where(d => filterTimeLt.CompareTo(d.TimeString) > 0); | ||||
|                 if (filterVar.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterVar.Contains(p.SortId))); | ||||
|                 if (filterQual.Count > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => filterQual.Contains(p.QualId))); | ||||
|                 if (filterKmwGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw >= filterKmwGt)); | ||||
|                 if (filterKmwLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw < filterKmwLt)); | ||||
|                 if (filterOeGt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt)); | ||||
|                 if (filterOeLt > 0) deliveryQuery = deliveryQuery.Where(d => d.Parts.Any(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt)); | ||||
|                 if (filterMgNr.Count > 0) dpq = dpq.Where(p => filterMgNr.Contains(p.Delivery.MgNr)); | ||||
|                 if (filterDate.Count > 0) dpq = dpq.Where(p => filterDate.Contains(p.Delivery.DateString)); | ||||
|                 if (filterPartDate.Count > 0) dpq = dpq.Where(p => filterPartDate.Contains(p.Delivery.DateString.Substring(4))); | ||||
|                 if (filterYearGt > 0) dpq = dpq.Where(p => p.Year >= filterYearGt); | ||||
|                 if (filterYearLt > 0) dpq = dpq.Where(p => p.Year < filterYearLt); | ||||
|                 if (filterTimeGt != null) dpq = dpq.Where(p => filterTimeGt.CompareTo(p.Delivery.TimeString) <= 0); | ||||
|                 if (filterTimeLt != null) dpq = dpq.Where(p => filterTimeLt.CompareTo(p.Delivery.TimeString) > 0); | ||||
|                 if (filterVar.Count > 0) dpq = dpq.Where(p => filterVar.Contains(p.SortId)); | ||||
|                 if (filterQual.Count > 0) dpq = dpq.Where(p => filterQual.Contains(p.QualId)); | ||||
|                 if (filterKmwGt > 0) dpq = dpq.Where(p => p.Kmw >= filterKmwGt); | ||||
|                 if (filterKmwLt > 0) dpq = dpq.Where(p => p.Kmw < filterKmwLt); | ||||
|                 if (filterOeGt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt); | ||||
|                 if (filterOeLt > 0) dpq = dpq.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt); | ||||
|  | ||||
|                 if (filterYearGt > 0 && filterYearLt > 0) { | ||||
|                     filterNames.Insert(0, $"{filterYearGt}–{filterYearLt - 1}"); | ||||
|                 } else if (filterYearGt > 0) { | ||||
|                     filterNames.Insert(0, $"ab {filterYearGt}"); | ||||
|                 } else if (filterYearLt > 0) { | ||||
|                     filterNames.Insert(0, $"bis {filterYearLt - 1}"); | ||||
|                 } | ||||
|                 if (filterKmwGt > 0 && filterKmwLt > 0) { | ||||
|                     filterNames.Add($"{filterKmwGt:N1}–{filterKmwLt:N1} °KMW"); | ||||
|                 } else if (filterKmwGt > 0) { | ||||
|                     filterNames.Add($"ab {filterKmwGt:N1} °KMW"); | ||||
|                 } else if (filterKmwLt > 0) { | ||||
|                     filterNames.Add($"bis {filterKmwLt:N1} °KMW"); | ||||
|                 } | ||||
|                 if (filterOeGt > 0 && filterOeLt > 0) { | ||||
|                     filterNames.Add($"{filterOeGt:N1}–{filterOeLt:N1} °Oe"); | ||||
|                 } else if (filterOeGt > 0) { | ||||
|                     filterNames.Add($"ab {filterOeGt:N1} °Oe"); | ||||
|                 } else if (filterOeLt > 0) { | ||||
|                     filterNames.Add($"bis {filterOeLt:N1} °Oe"); | ||||
|                 } | ||||
|                 if (filterTimeGt != null && filterTimeLt != null) { | ||||
|                     filterNames.Add($"{filterTimeGt}–{filterTimeLt}"); | ||||
|                 } else if (filterTimeGt != null) { | ||||
|                     filterNames.Add($"ab {filterTimeGt}"); | ||||
|                 } else if (filterTimeLt != null) { | ||||
|                     filterNames.Add($"bis {filterTimeLt}"); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             List<Delivery> deliveries = await deliveryQuery.OrderByDescending(d => d.DateString).ThenByDescending(d => d.TimeString).ToListAsync(); | ||||
|             return (filterNames, dpq.Select(p => p.Delivery).Distinct(), dpq, filter); | ||||
|         } | ||||
|  | ||||
|         private async Task RefreshDeliveryListQuery(bool updateSort = false) { | ||||
|             var (_, deliveryQuery, deliveryPartsQuery, filter) = await GetFilters(); | ||||
|             var deliveries = await deliveryQuery.ToListAsync(); | ||||
|             deliveries.Reverse(); | ||||
|  | ||||
|             if (filter.Count > 0 && deliveries.Count > 0) { | ||||
|                 var dict = deliveries.AsParallel() | ||||
|                     .ToDictionary(d => d, d => d.SearchScore(TextFilter)) | ||||
| @@ -346,15 +445,7 @@ namespace Elwig.Windows { | ||||
|             StatusDeliveries.Text = $"Lieferungen: {deliveries.Count}"; | ||||
|  | ||||
|             if (filter.Count == 0) { | ||||
|                 var partsQuery = deliveryQuery.SelectMany(d => d.Parts); | ||||
|                 if (filterVar.Count > 0) partsQuery = partsQuery.Where(p => filterVar.Contains(p.SortId)); | ||||
|                 if (filterQual.Count > 0) partsQuery = partsQuery.Where(p => filterQual.Contains(p.QualId)); | ||||
|                 if (filterKmwGt > 0) partsQuery = partsQuery.Where(p => p.Kmw >= filterKmwGt); | ||||
|                 if (filterKmwLt > 0) partsQuery = partsQuery.Where(p => p.Kmw < filterKmwLt); | ||||
|                 if (filterOeGt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) >= filterOeGt); | ||||
|                 if (filterOeLt > 0) partsQuery = partsQuery.Where(p => p.Kmw * (4.54 + 0.022 * p.Kmw) < filterOeLt); | ||||
|                 var deliveryParts = partsQuery; | ||||
|  | ||||
|                 var deliveryParts = deliveryPartsQuery; | ||||
|                 var n = await deliveryParts.CountAsync(); | ||||
|                 StatusDeliveries.Text = $"Lieferungen: {deliveries.Count} ({n})"; | ||||
|                 var varieties = await deliveryParts.Select(d => d.SortId).Distinct().ToListAsync(); | ||||
| @@ -372,9 +463,8 @@ namespace Elwig.Windows { | ||||
|                     StatusGradation.Text = "Gradation: -"; | ||||
|                 } | ||||
|  | ||||
|  | ||||
|                 if (n > 0 && (n <= 200 || TodayOnlyInput.IsChecked == true)) { | ||||
|                     var parts = (await deliveryParts.ToListAsync()); | ||||
|                     var parts = await deliveryParts.ToListAsync(); | ||||
|                     var groups = parts | ||||
|                         .GroupBy(p => string.Join("/", p.Attributes.Select(a => a.Name))) | ||||
|                         .Select(g => (g.Key, g.Sum(p => p.Weight), g.Min(p => p.Kmw), Utils.AggregateDeliveryPartsKmw(g), g.Max(p => p.Kmw))) | ||||
| @@ -410,8 +500,8 @@ namespace Elwig.Windows { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         protected override async Task RenewContext() { | ||||
|             await base.RenewContext(); | ||||
|         protected override async Task OnRenewContext() { | ||||
|             await base.OnRenewContext(); | ||||
|  | ||||
|             if (Member != null) { | ||||
|                 if (Context.Members.Find(Member.MgNr) is not Member m) { | ||||
| @@ -651,7 +741,6 @@ namespace Elwig.Windows { | ||||
|                     WeightInput.Text = $"{res.Weight:N0}"; | ||||
|                     ScaleId = s.ScaleId; | ||||
|                     WeighingId = res.FullWeighingId; | ||||
|                     s.Empty(); | ||||
|                 } else { | ||||
|                     WeightInput.Text = ""; | ||||
|                     ScaleId = null; | ||||
| @@ -757,12 +846,19 @@ namespace Elwig.Windows { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private void EmptyScale() { | ||||
|             var scale = App.Scales.Where(s => s.ScaleId == ScaleId).FirstOrDefault(); | ||||
|             if (scale == null) return; | ||||
|             scale.Empty(); | ||||
|         } | ||||
|  | ||||
|         private async void NewDeliveryPartButton_Click(object sender, RoutedEventArgs evt) { | ||||
|             FinishButton.IsEnabled = false; | ||||
|             NewDeliveryPartButton.IsEnabled = false; | ||||
|             NewDeliveryPartButton.Cursor = Cursors.Wait; | ||||
|             DeliveryPartList.IsEnabled = false; | ||||
|             var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); | ||||
|             EmptyScale(); | ||||
|             await RefreshDeliveryList(); | ||||
|             await RefreshDeliveryParts(); | ||||
|             NewDeliveryPartButton.Cursor = null; | ||||
| @@ -778,6 +874,7 @@ namespace Elwig.Windows { | ||||
|             FinishButton.Cursor = Cursors.Wait; | ||||
|             DeliveryPartList.IsEnabled = false; | ||||
|             var p = await UpdateDeliveryPart(DeliveryList.SelectedItem as Delivery, DeliveryPartList.SelectedItem as DeliveryPart); | ||||
|             EmptyScale(); | ||||
|             await RefreshDeliveryList(); | ||||
|             await RefreshDeliveryParts(); | ||||
|             if (p?.Delivery != null) { | ||||
| @@ -789,10 +886,12 @@ namespace Elwig.Windows { | ||||
|                     doc.Show(); | ||||
|                 } else { | ||||
|                     await doc.Print(2); | ||||
|                     Activate(); | ||||
|                 } | ||||
|             } | ||||
|             FinishButton.Cursor = null; | ||||
|             DeliveryList.SelectedItem = null; | ||||
|             await RenewContext(); | ||||
|             RefreshInputs(); | ||||
|             InitInputs(); | ||||
|         } | ||||
| @@ -815,6 +914,7 @@ namespace Elwig.Windows { | ||||
|                 DisableWeighingButtons(); | ||||
|                 HideFinishNewPartDeliveryCancelButtons(); | ||||
|                 ShowNewEditDeleteButtons(); | ||||
|                 await RenewContext(); | ||||
|                 RefreshInputs(); | ||||
|                 ClearInputStates(); | ||||
|                 LockInputs(); | ||||
|   | ||||
| @@ -131,8 +131,8 @@ namespace Elwig.Windows { | ||||
|             ValidateRequiredInputs(); | ||||
|         } | ||||
|  | ||||
|         protected override async Task RenewContext() { | ||||
|             await base.RenewContext(); | ||||
|         protected override async Task OnRenewContext() { | ||||
|             await base.OnRenewContext(); | ||||
|             ControlUtils.RenewItemsSource(BranchInput, await Context.Branches.OrderBy(b => b.Name).ToListAsync(), i => (i as Branch)?.ZwstId); | ||||
|             ControlUtils.RenewItemsSource(DefaultKgInput, await Context.WbKgs.Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), i => (i as AT_Kg)?.KgNr); | ||||
|             await RefreshMemberList(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user