DeliveryAdminWindow is now able to look at deliveries

This commit is contained in:
2023-07-13 21:10:48 +02:00
parent e8919cc629
commit fd26ee4f52
7 changed files with 390 additions and 55 deletions

View File

@ -119,5 +119,12 @@ namespace Elwig.Helpers {
.ForEach(a => { if (a <= c + 10) c = a; });
return c + 1;
}
public async Task<WineQualLevel> GetWineQualityLevel(double kmw) {
return await WineQualityLevels
.Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw))
.OrderBy(q => q.MinKmw)
.LastOrDefaultAsync();
}
}
}

View File

@ -15,7 +15,9 @@ using System.Collections;
namespace Elwig.Helpers {
public static partial class Utils {
public static int CurrentSeason => DateTime.Now.Year - (DateTime.Now.Month <= 3 ? 1 : 0);
public static int CurrentNextSeason => DateTime.Now.Year - (DateTime.Now.Month <= 3 ? 1 : 0);
public static int CurrentLastSeason => DateTime.Now.Year - (DateTime.Now.Month <= 7 ? 1 : 0);
public static DateTime Today => (DateTime.Now.Hour >= 3) ? DateTime.Today : DateTime.Today.AddDays(-1);
public static readonly Regex SerialRegex = GeneratedSerialRegex();
public static readonly Regex TcpRegex = GeneratedTcpRegex();
@ -164,6 +166,13 @@ namespace Elwig.Helpers {
dataGrid.CurrentCell = new(dataGrid.SelectedItem, column);
}
public static void RenewItemsSource(ListBox listBox, IEnumerable? source, Func<object?, object?> getId) {
var selectedId = getId(listBox.SelectedItem);
listBox.ItemsSource = source;
if (selectedId != null && source != null)
listBox.SelectedItem = source.Cast<object>().FirstOrDefault(i => selectedId.Equals(getId(i)));
}
public static int Modulo(string a, int b) {
if (a.Length == 0 || !a.All(char.IsAsciiDigit)) {
throw new ArgumentException("First argument has to be a decimal string");
@ -214,5 +223,28 @@ namespace Elwig.Helpers {
var b = (birthday.Year * 100 + birthday.Month) * 100 + birthday.Day;
return (a - b) / 10000;
}
public static int GetSearchScore(IEnumerable<string?> words, IEnumerable<string> searchKeywords) {
searchKeywords = searchKeywords.Where(s => s.Length >= 2 || (s.Length > 0 && s.All(c => char.IsAsciiDigit(c))));
if (!searchKeywords.Any())
return 0;
words = words.Select(w => w?.ToLower());
int i = 0;
foreach (string? c in words) {
if (c == null) continue;
var parts = c.Split(" ");
if (searchKeywords.Any(f => c == f)) {
i += 100;
} else if (searchKeywords.Any(f => parts.Any(a => a == f))) {
i += 90;
} else if (searchKeywords.Any(f => parts.Any(a => a.StartsWith(f)))) {
i += 50;
} else if (searchKeywords.Any(f => f != null && c.Contains(f))) {
i += 1;
}
}
return i;
}
}
}

View File

@ -1,7 +1,9 @@
using Elwig.Helpers;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
namespace Elwig.Models {
[Table("delivery"), PrimaryKey("Year", "DId"), Index("DateString", "ZwstId", "LNr", IsUnique = true), Index("LsNr", IsUnique = true)]
@ -72,5 +74,25 @@ namespace Elwig.Models {
[InverseProperty("Delivery")]
public virtual ISet<DeliveryPart> Parts { get; private set; }
public int Weight => Parts.Select(p => p.Weight).Sum();
public IEnumerable<string> SortIds => Parts
.GroupBy(p => p.SortId)
.OrderByDescending(g => g.Select(p => p.Weight).Sum())
.Select(g => g.Select(p => p.SortId).First());
public string SortIdString => string.Join(", ", SortIds);
public int SearchScore(IEnumerable<string> keywords) {
var list = new string?[] {
LsNr, Year.ToString(), Date.ToString("dd.MM.yyyy"), Time.ToString("HH:ss"),
MgNr.ToString(), Member.FamilyName, Member.MiddleName, Member.GivenName, Member.BillingAddress?.Name,
Comment
}.ToList();
list.AddRange(Parts.Select(p => p.SortId).Distinct());
list.AddRange(Parts.Select(p => p.Comment).Distinct());
return Utils.GetSearchScore(list, keywords);
}
}
}

View File

@ -160,7 +160,7 @@ namespace Elwig.Models {
[NotMapped]
public IEnumerable<AreaCom> ActiveAreaCommitments => AreaCommitments
.Where(c => c.YearFrom <= Utils.CurrentSeason && (c.YearTo ?? int.MaxValue) >= Utils.CurrentSeason);
.Where(c => c.YearFrom <= Utils.CurrentNextSeason && (c.YearTo ?? int.MaxValue) >= Utils.CurrentNextSeason);
[InverseProperty("Member")]
public virtual BillingAddr? BillingAddress { get; private set; }
@ -174,32 +174,12 @@ namespace Elwig.Models {
public string FullAddress => $"{Address}, {PostalDest.AtPlz.Plz} {PostalDest.AtPlz.Ort.Name}";
public int SearchScore(IEnumerable<string> keywords) {
keywords = keywords.Where(s => s.Length >= 2 || (s.Length > 0 && s.All(c => char.IsAsciiDigit(c))));
if (!keywords.Any())
return 0;
string?[] check = new string?[] {
return Utils.GetSearchScore(new string?[] {
MgNr.ToString(),
FamilyName.ToLower(), MiddleName?.ToLower(), GivenName.ToLower(),
BillingAddress?.Name.ToLower(),
Comment?.ToLower(),
};
int i = 0;
foreach (string? c in check) {
if (c == null) continue;
var parts = c.Split(" ");
if (keywords.Any(f => c == f)) {
i += 100;
} else if (keywords.Any(f => parts.Any(a => a == f))) {
i += 90;
} else if (keywords.Any(f => parts.Any(a => a.StartsWith(f)))) {
i += 50;
} else if (keywords.Any(f => f != null && c.Contains(f))) {
i += 1;
}
}
return i;
FamilyName, MiddleName, GivenName,
BillingAddress?.Name,
Comment,
}, keywords);
}
}
}

View File

@ -106,6 +106,7 @@ namespace Elwig.Windows {
Utils.ClearInputState(tb);
foreach (var cb in ComboBoxInputs)
Utils.ClearInputState(cb);
// TODO ComboCheckBox
foreach (var cb in CheckBoxInputs)
Utils.ClearInputState(cb);
foreach (var rb in RadioButtonInputs)
@ -128,6 +129,8 @@ namespace Elwig.Windows {
tb.IsReadOnly = true;
foreach (var cb in ComboBoxInputs)
cb.IsEnabled = false;
foreach (var ccb in CheckComboBoxInputs)
ccb.IsEnabled = false;
foreach (var cb in CheckBoxInputs)
cb.IsEnabled = false;
foreach (var rb in RadioButtonInputs)
@ -139,6 +142,8 @@ namespace Elwig.Windows {
tb.IsReadOnly = false;
foreach (var cb in ComboBoxInputs)
cb.IsEnabled = true;
foreach (var ccb in CheckComboBoxInputs)
ccb.IsEnabled = true;
foreach (var cb in CheckBoxInputs)
cb.IsEnabled = true;
foreach (var rb in RadioButtonInputs)
@ -154,6 +159,7 @@ namespace Elwig.Windows {
OriginalValues[tb] = tb.Text;
foreach (var cb in ComboBoxInputs)
OriginalValues[cb] = cb.SelectedItem;
// TODO ComboCheckBox
foreach (var cb in CheckBoxInputs)
OriginalValues[cb] = (cb.IsChecked ?? false) ? bool.TrueString : null;
foreach (var rb in RadioButtonInputs)

View File

@ -5,7 +5,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Elwig.Windows"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
Title="Lieferungsverwaltung - Elwig" Height="600" Width="1000" MinHeight="400" MinWidth="800"
Title="Lieferungsverwaltung - Elwig" Height="700" Width="1100" MinHeight="700" MinWidth="1000"
Loaded="Window_Loaded">
<Window.Resources>
<Style TargetType="Label">
@ -19,19 +19,16 @@
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="2"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="Height" Value="25"/>
<Setter Property="TextWrapping" Value="NoWrap"/>
</Style>
<Style TargetType="ComboBox">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="Height" Value="25"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Top"/>
</Style>
<Style TargetType="xctk:CheckComboBox">
<Setter Property="IsEnabled" Value="False"/>
<Setter Property="Height" Value="25"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
@ -46,13 +43,13 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="19"/>
<RowDefinition Height="*"/>
<RowDefinition Height="0.625*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300"/>
<ColumnDefinition Width="1*" MinWidth="400"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
@ -68,6 +65,60 @@
</MenuItem>
</Menu>
<Grid Grid.RowSpan="5" Grid.Row="1" Margin="5,0,5,0">
<Grid.RowDefinitions>
<RowDefinition Height="42"/>
<RowDefinition Height="*"/>
<RowDefinition Height="47"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="SearchInput" Grid.ColumnSpan="3" Margin="5,10,95,0" IsReadOnly="False"
TextChanged="SearchInput_TextChanged"/>
<CheckBox x:Name="TodayOnlyInput" Content="Nur heute"
HorizontalAlignment="Right" Margin="0,7,14.125,0" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"
Checked="TodayOnlyInput_Changed" Unchecked="TodayOnlyInput_Changed"/>
<CheckBox x:Name="SeasonOnlyInput" Content="Nur Saison" IsChecked="True"
HorizontalAlignment="Right" Margin="0,24,10,0" VerticalAlignment="Top" Grid.Column="1" Grid.ColumnSpan="2"
Checked="SeasonOnlyInput_Changed" Unchecked="SeasonOnlyInput_Changed"/>
<DataGrid x:Name="DeliveryList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single"
SelectionChanged="DeliveryList_SelectionChanged"
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False"
Margin="5,0,5,0" Grid.Row="1" FontSize="14" Grid.ColumnSpan="3">
<DataGrid.Columns>
<DataGridTextColumn Header="MgNr." Binding="{Binding MgNr}" Width="70"/>
<DataGridTextColumn Header="Datum" Binding="{Binding Date, StringFormat='dd.MM.yy'}" Width="70"/>
<DataGridTextColumn Header="Zeit" Binding="{Binding Time, StringFormat='HH:mm'}" Width="70"/>
<DataGridTextColumn Header="Sorte" Binding="{Binding SortIdString}" Width="60"/>
<DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="70">
<DataGridTextColumn.CellStyle>
<Style>
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
</Style>
</DataGridTextColumn.CellStyle>
</DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
<Button x:Name="NewMemberButton" Content="Neu"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,5,10" Grid.Column="0" Grid.Row="2"/>
<Button x:Name="EditMemberButton" Content="Bearbeiten" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,5,10" Grid.Column="1" Grid.Row="2"/>
<Button x:Name="DeleteMemberButton" Content="Löschen" IsEnabled="False"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,5,10" Grid.Column="2" Grid.Row="2"/>
<Button x:Name="SaveButton" Content="Speichern" IsEnabled="False" Visibility="Hidden"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,5,10" Grid.Column="0"/>
<Button x:Name="ResetButton" Content="Zurücksetzen" IsEnabled="False" Visibility="Hidden"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,5,10" Grid.Column="1"/>
<Button x:Name="CancelButton" Content="Abbrechen" IsEnabled="False" Visibility="Hidden" IsCancel="True"
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,10,5,10" Grid.Column="2"/>
</Grid>
<GroupBox Header="Mitglied" Grid.Column="1" Grid.Row="1" Margin="5,5,5,5">
<Grid>
<Grid.ColumnDefinitions>
@ -77,14 +128,13 @@
<Label Content="Mitglied:" Margin="10,10,0,0" Grid.Column="0"/>
<TextBox x:Name="MgNrInput" Width="48" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" TextAlignment="Right"
IsReadOnly="False" IsEnabled="True"
TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus"/>
<ComboBox x:Name="MemberInput" Grid.Row="1" Grid.Column="1" Margin="53,10,10,10" IsEditable="True" IsEnabled="True"
<ComboBox x:Name="MemberInput" Grid.Column="1" Margin="53,10,10,10" IsEditable="True"
ItemTemplate="{StaticResource MemberAdminNameTemplate}" TextSearch.TextPath="AdministrativeName"
SelectionChanged="MemberInput_SelectionChanged"/>
<Label Content="Wohnort:" Margin="10,38,0,0" Grid.Column="0"/>
<TextBox x:Name="MemberAddressField" Grid.Row="1" Grid.Column="1" Margin="0,40,10,10" FontSize="12" Height="22"
<TextBox x:Name="MemberAddressField" Grid.Column="1" Margin="0,40,10,10" FontSize="12" Height="22"
IsReadOnly="True" IsTabStop="False"/>
</Grid>
</GroupBox>
@ -109,7 +159,11 @@
<Label Content="Zweigstelle:" Margin="10,70,0,0" Grid.Column="0"/>
<ComboBox x:Name="BranchInput" Width="126" Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Left"
IsEnabled="False"
DisplayMemberPath="Name" TextSearch.TextPath="Name"/>
<Label Content="Anmerkung:" Margin="10,100,0,10"/>
<TextBox x:Name="CommentInput" Grid.Column="1" Margin="0,100,10,10"/>
</Grid>
</GroupBox>
@ -122,14 +176,13 @@
<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"
IsReadOnly="False" IsEnabled="True"
TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus"/>
<ComboBox x:Name="WineVarietyInput" Grid.Row="1" Grid.Column="1" Margin="41,10,10,10" IsEnabled="True"
<ComboBox x:Name="WineVarietyInput" Grid.Row="1" Grid.Column="1" Margin="41,10,10,10"
ItemTemplate="{StaticResource WineVarietyTemplate}" TextSearch.TextPath="Name"
SelectionChanged="WineVarietyInput_SelectionChanged"/>
<Label Content="Attribute:" Margin="10,40,0,0" Grid.Column="0"/>
<xctk:CheckComboBox x:Name="AttributesInput" Grid.Row="1" Grid.Column="1" Margin="0,40,10,10" IsEnabled="True"
<xctk:CheckComboBox x:Name="AttributesInput" Grid.Row="1" Grid.Column="1" Margin="0,40,10,10"
DisplayMemberPath="Name" Delimiter=", " AllItemsSelectedContent="Alle"
ItemSelectionChanged="AttributesInput_SelectionChanged"/>
</Grid>
@ -144,36 +197,111 @@
<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"
IsReadOnly="False" IsEnabled="True"
TextChanged="GradationOeInput_TextChanged" LostFocus="GradationOeInput_LostFocus"/>
<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"
IsReadOnly="False" IsEnabled="True"
TextChanged="GradationKmwInput_TextChanged" LostFocus="GradationKmwInput_LostFocus"/>
<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" IsEnabled="True" Width="146" Margin="0,40,10,10" Grid.Column="1" HorizontalAlignment="Left"
<ComboBox x:Name="WineQualityLevelInput" Width="146" Margin="0,40,10,10" Grid.Column="1" HorizontalAlignment="Left"
ItemTemplate="{StaticResource WineQualityLevelTemplate}"
SelectionChanged="WineQualityLevelInput_SelectionChanged"/>
<CheckBox x:Name="AbgewertetInput" Content="Abgewertet"
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="0,75,10,10" Grid.Column="1"/>
</Grid>
</GroupBox>
<GroupBox Header="Gewicht" Grid.Column="2" Grid.Row="3" Margin="5,5,5,5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="Gewicht:" Margin="10,10,10,10"/>
<Grid Grid.Column="1" Width="70" Height="25" Margin="0,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBox x:Name="WeightInput" TextAlignment="Right" Padding="2,2,17,2"
IsReadOnly="True"/>
<Label Content="kg" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
</Grid>
<CheckBox x:Name="ManualWeighingInput" Content="Handwiegung"
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,45,10,10" Grid.Column="0" Grid.ColumnSpan="2"/>
<CheckBox x:Name="GerebeltGewogenInput" Content="Gerebelt gewogen"
VerticalAlignment="Top" HorizontalAlignment="Left" Margin="10,75,10,10" Grid.Column="0" Grid.ColumnSpan="2"/>
<Button x:Name="WeighingManualButton" Content="Handwiegung" Width="120"
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,10,10,10" Grid.Column="2"/>
<Button x:Name="WeighingAButton" Content="Wiegen A" Width="120"
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,42,10,10" Grid.Column="2"/>
<Button x:Name="WeighingBButton" Content="Wiegen B" Width="120"
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,74,10,10" Grid.Column="2"/>
<Button x:Name="WeighingCButton" Content="Wiegen C" Width="120"
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,106,10,10" Grid.Column="2"/>
<Button x:Name="WeighingDButton" Content="Wiegen D" Width="120"
VerticalAlignment="Top" HorizontalAlignment="Right" Margin="10,138,10,10" Grid.Column="2"/>
</Grid>
</GroupBox>
<GroupBox Header="Zu-/Abschläge" Grid.Column="2" Grid.Row="4" Margin="5,5,5,5">
<GroupBox Header="Sonstiges" Grid.Column="2" Grid.Row="4" Margin="5,5,5,5">
<Grid>
<xctk:CheckComboBox x:Name="ModifiersInput" IsEnabled="True" Margin="10,10,10,10"
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="65"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label Content="Zu-/Abschläge:" Margin="10,10,0,10"/>
<xctk:CheckComboBox x:Name="ModifiersInput" Margin="0,10,10,10" Grid.Column="1" Grid.ColumnSpan="2"
ItemTemplate="{StaticResource ModifierTemplate}" Delimiter=", " AllItemsSelectedContent="Alle"
ItemSelectionChanged="ModifiersInput_SelectionChanged"/>
<Label Content="Anmerkung:" Margin="10,40,0,10"/>
<TextBox x:Name="PartCommentInput" Grid.Column="1" Margin="0,40,10,10" Grid.ColumnSpan="2"/>
<Label Content="Temperatur:" Margin="10,70,0,10"/>
<Grid Grid.Column="1" Height="25" Margin="0,70,10,10" VerticalAlignment="Top">
<TextBox x:Name="TemperatureInput" TextAlignment="Right" Padding="2,2,16,2"/>
<Label Content="°C" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
</Grid>
<Label Content="Säure:" Margin="10,100,0,10"/>
<Grid Grid.Column="1" Height="25" Margin="0,100,10,10" VerticalAlignment="Top">
<TextBox x:Name="AcidInput" TextAlignment="Right" Padding="2,2,19,2"/>
<Label Content="g/l" Margin="0,4,3,0" HorizontalAlignment="Right" FontSize="10"/>
</Grid>
<CheckBox x:Name="LesewagenInput" Content="Lesewagen" Margin="10,75,0,0" Grid.Column="2"
VerticalAlignment="Top" HorizontalAlignment="Left"/>
<CheckBox x:Name="HandPickedInput" Content="Handlese" Margin="10,105,0,0" Grid.Column="2" IsThreeState="True"
VerticalAlignment="Top" HorizontalAlignment="Left"/>
</Grid>
</GroupBox>
<GroupBox Header="Teillieferungen" Grid.Column="1" Grid.Row="3" Margin="5,5,5,5">
<Grid>
<ListBox x:Name="DeliveryPartList" Margin="5,5,5,5"
SelectionChanged="DeliveryPartList_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DPNr}" Width="20"/>
<TextBlock Text="{Binding SortId}" Width="30"/>
<TextBlock Text="{Binding Kmw, StringFormat='{}{0:0.0}°'}" Width="40" TextAlignment="Right" Padding="0,0,10,0"/>
<TextBlock Text="{Binding QualId}" Width="30"/>
<TextBlock Text="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="60" TextAlignment="Right"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</GroupBox>
@ -185,16 +313,16 @@
</Grid.ColumnDefinitions>
<Label Content="Weinbaugebiet:" Margin="10,10,0,10" Grid.Column="0"/>
<ComboBox x:Name="WineOriginInput" IsEnabled="True" Margin="0,10,10,10" Grid.Column="1"
<ComboBox x:Name="WineOriginInput" Margin="0,10,10,10" Grid.Column="1"
ItemTemplate="{StaticResource WineOriginTemplate}"/>
<Label Content="Weinbau-KG:" Margin="10,40,0,10" Grid.Column="0"/>
<ComboBox x:Name="WineKgInput" IsEnabled="True" Margin="0,40,10,10" Grid.Column="1"
<ComboBox x:Name="WineKgInput" Margin="0,40,10,10" Grid.Column="1"
DisplayMemberPath="Name"
SelectionChanged="WineKgInput_SelectionChanged"/>
<Label Content="Ried:" Margin="10,70,0,10" Grid.Column="0"/>
<ComboBox x:Name="WineRdInput" IsEnabled="True" Margin="0,70,10,10" Grid.Column="1"
<ComboBox x:Name="WineRdInput" Margin="0,70,10,10" Grid.Column="1"
DisplayMemberPath="Name"/>
</Grid>
</GroupBox>

View File

@ -2,10 +2,12 @@ using Elwig.Helpers;
using Elwig.Models;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Threading;
using Xceed.Wpf.Toolkit.Primitives;
@ -13,20 +15,29 @@ namespace Elwig.Windows {
public partial class DeliveryAdminWindow : AdministrationWindow {
private bool IsUpdatingGradation = false;
private bool IsRefreshingInputs = false;
private readonly bool IsReceipt = false;
private readonly DispatcherTimer Timer;
private List<string> TextFilter = new();
private readonly RoutedCommand CtrlF = new();
public DeliveryAdminWindow() {
InitializeComponent();
CtrlF.InputGestures.Add(new KeyGesture(Key.F, ModifierKeys.Control));
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
RequiredInputs = new Control[] {
MgNrInput, MemberInput,
SortIdInput, WineVarietyInput,
GradationOeInput, GradationKmwInput,
WineQualityLevelInput,
WineOriginInput, WineKgInput
WineOriginInput, WineKgInput,
WeightInput
};
ExemptInputs = new Control[] {
SearchInput, TodayOnlyInput, SeasonOnlyInput,
DeliveryList, DeliveryPartList,
MemberAddressField,
LsNrInput, DateInput, TimeInput, BranchInput,
MemberAddressField
};
Timer = new DispatcherTimer();
@ -34,23 +45,82 @@ namespace Elwig.Windows {
Timer.Interval = new TimeSpan(0, 0, 1);
}
public DeliveryAdminWindow(bool receipt) : this() {
IsReceipt = receipt;
}
public DeliveryAdminWindow(int mgnr) : this() {
// TODO
}
private void Window_Loaded(object sender, RoutedEventArgs evt) {
OnSecondPassed(null, null);
Timer.Start();
LockInputs();
}
private void OnSecondPassed(object? sender, EventArgs? evt) {
if (IsReceipt && (IsEditing || IsCreating)) {
var now = DateTime.Now;
TimeInput.Text = now.ToString("HH:mm");
DateInput.Text = now.ToString("dd.MM.yyyy");
}
}
protected override void UpdateButtons() {
}
private async Task RefreshDeliveryList() {
await RefreshDeliveryListQuery();
}
private async Task RefreshDeliveryListQuery(bool updateSort = false) {
IQueryable<Delivery> deliveryQuery = Context.Deliveries;
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));
} else if (SeasonOnlyInput.IsChecked == true) {
deliveryQuery = deliveryQuery.Where(d => d.Year == Utils.CurrentLastSeason);
}
List<Delivery> deliveries = await deliveryQuery.OrderByDescending(d => d.DateString).ThenByDescending(d => d.TimeString).ToListAsync();
if (TextFilter.Count > 0) {
deliveries = deliveries
.ToDictionary(d => d, d => d.SearchScore(TextFilter))
.OrderByDescending(a => a.Value)
.ThenBy(a => a.Key.DateTime)
.Where(a => a.Value > 0)
.Select(a => a.Key)
.ToList();
}
Utils.RenewItemsSource(DeliveryList, deliveries, d => ((d as Delivery)?.Year, (d as Delivery)?.DId), !updateSort);
if (deliveries.Count == 1)
DeliveryList.SelectedIndex = 0;
RefreshInputs();
}
private void RefreshDeliveryPartList(bool updateSort = false) {
if (DeliveryList.SelectedItem is not Delivery d) {
DeliveryPartList.ItemsSource = null;
return;
}
Utils.RenewItemsSource(DeliveryPartList, d.Parts.OrderBy(p => p.DPNr), i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId, (i as DeliveryPart)?.DPNr));
if (d.Parts.Count == 1)
DeliveryPartList.SelectedIndex = 0;
RefreshInputs();
}
protected override async Task RenewContext() {
await base.RenewContext();
await RefreshDeliveryList();
RefreshDeliveryPartList();
Utils.RenewItemsSource(MemberInput, await Context.Members.OrderBy(m => m.FamilyName).ThenBy(m => m.GivenName).ToListAsync(), i => (i as Member)?.MgNr);
Utils.RenewItemsSource(BranchInput, await Context.Branches.OrderBy(b => b.Name).ToListAsync(), i => (i as Branch)?.ZwstId);
BranchInput.SelectedItem = BranchInput.ItemsSource.Cast<Branch>().First(b => b.ZwstId == App.ZwstId);
@ -68,6 +138,85 @@ namespace Elwig.Windows {
await UpdateLsNr();
}
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
if (!IsEditing && !IsCreating) {
SearchInput.Focus();
SearchInput.SelectAll();
}
}
private void RefreshInputs() {
IsRefreshingInputs = true;
ClearInputStates();
if (DeliveryList.SelectedItem is Delivery d) {
FillInputs(d);
} else {
ClearOriginalValues();
ClearInputs();
}
IsRefreshingInputs = false;
GC.Collect();
}
private void FillInputs(Delivery d) {
ClearOriginalValues();
MgNrInput.Text = d.MgNr.ToString();
LsNrInput.Text = d.LsNr;
DateInput.Text = d.Date.ToString("dd.MM.yyyy");
TimeInput.Text = d.Time.ToString("HH:mm");
CommentInput.Text = d.Comment ?? "";
Utils.RenewItemsSource(DeliveryPartList, d.Parts, i => ((i as DeliveryPart)?.Year, (i as DeliveryPart)?.DId));
if (DeliveryPartList.SelectedItem == null && DeliveryPartList.ItemsSource != null) {
DeliveryPartList.SelectedIndex = 0;
}
var p = DeliveryPartList.SelectedItem as DeliveryPart;
SortIdInput.Text = p?.SortId ?? "";
AttributesInput.SelectedItems.Clear();
foreach (var a in p?.Attributes ?? Array.Empty<WineAttr>())
AttributesInput.SelectedItems.Add(AttributesInput.ItemsSource.Cast<WineAttr>().Where(i => i.AttrId == a.AttrId).First());
GradationKmwInput.Text = p?.Kmw.ToString() ?? "";
WineQualityLevelInput.SelectedItem = p?.Quality ?? null;
WeightInput.Text = p?.Weight.ToString() ?? "";
ManualWeighingInput.IsChecked = p?.ManualWeighing ?? false;
GerebeltGewogenInput.IsChecked = p?.IsGerebelt ?? false;
ModifiersInput.SelectedItems.Clear();
foreach (var m in p?.Modifiers ?? Array.Empty<Modifier>())
ModifiersInput.SelectedItems.Add(ModifiersInput.ItemsSource.Cast<Modifier>().Where(i => i.ModId == m.ModId).First());
PartCommentInput.Text = p?.Comment ?? "";
TemperatureInput.Text = p?.Temperature?.ToString() ?? "";
AcidInput.Text = p?.Acid?.ToString() ?? "";
LesewagenInput.IsChecked = p?.IsLesewagen ?? false;
HandPickedInput.IsChecked = p?.IsHandPicked;
FillOriginalValues();
}
private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
TextFilter = SearchInput.Text.ToLower().Split(" ").ToList().FindAll(e => e.Length > 0);
await RefreshDeliveryListQuery(true);
}
private async void TodayOnlyInput_Changed(object sender, RoutedEventArgs evt) {
if (TodayOnlyInput.IsChecked == true && SeasonOnlyInput.IsChecked == true) SeasonOnlyInput.IsChecked = false;
await RefreshDeliveryListQuery();
}
private async void SeasonOnlyInput_Changed(object sender, RoutedEventArgs evt) {
if (!IsInitialized) return;
if (SeasonOnlyInput.IsChecked == true && TodayOnlyInput.IsChecked == true) TodayOnlyInput.IsChecked = false;
await RefreshDeliveryListQuery();
}
private void DeliveryList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
RefreshInputs();
}
private void DeliveryPartList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
if (!IsRefreshingInputs) RefreshInputs();
}
private void MgNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
var valid = InputTextChanged((TextBox)sender, Validator.CheckMgNr);
MemberInput.SelectedItem = valid ? Context.Members.Find(int.Parse(MgNrInput.Text)) : null;
@ -138,7 +287,7 @@ namespace Elwig.Windows {
}
var kmw = double.Parse(GradationKmwInput.Text);
WineQualityLevelInput.ItemsSource = Context.WineQualityLevels.Where(q => q.MinKmw == null || q.MinKmw <= kmw).ToList();
var qual = Context.WineQualityLevels.Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw)).OrderBy(q => q.MinKmw).LastOrDefault();
var qual = Context.GetWineQualityLevel(kmw).GetAwaiter().GetResult();
SetOriginalValue(WineQualityLevelInput, qual);
if (WineQualityLevelInput.SelectedItem == null || (WineQualityLevelInput.SelectedItem is WineQualLevel selected && !selected.IsPredicate)) {
WineQualityLevelInput.SelectedItem = qual;
@ -202,7 +351,7 @@ namespace Elwig.Windows {
var qual = WineQualityLevelInput.SelectedItem as WineQualLevel;
var kg = (WineKgInput.SelectedItem as AT_Kg)?.WbKg;
if (qual == null || kg == null) {
WineOriginInput.IsEnabled = true;
WineOriginInput.IsEnabled = (IsEditing || IsCreating);
return;
}
WineOriginInput.IsEnabled = false;
@ -213,6 +362,7 @@ namespace Elwig.Windows {
private void WineQualityLevelInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
UpdateWineOrigin();
UpdateAbgewertet();
}
private void UpdateRdInput() {
@ -221,7 +371,7 @@ namespace Elwig.Windows {
list.Insert(0, new NullItem());
Utils.RenewItemsSource(WineRdInput, list, i => ((i as WbRd)?.KgNr, (i as WbRd)?.RdNr));
if (WineRdInput.SelectedItem == null) WineRdInput.SelectedIndex = 0;
WineRdInput.IsEnabled = list.Count > 1;
WineRdInput.IsEnabled = (IsEditing || IsCreating) && list.Count > 1;
} else {
WineRdInput.ItemsSource = null;
WineRdInput.IsEnabled = false;
@ -232,5 +382,15 @@ namespace Elwig.Windows {
UpdateWineOrigin();
UpdateRdInput();
}
private void UpdateAbgewertet() {
var qual = WineQualityLevelInput.SelectedItem as WineQualLevel;
if (qual == null) {
AbgewertetInput.IsChecked = false;
return;
}
var defQual = Context.GetWineQualityLevel(double.Parse(GradationKmwInput.Text)).GetAwaiter().GetResult();
AbgewertetInput.IsChecked = !qual.IsPredicate && defQual != qual;
}
}
}