[#14] Windows: Add DeliveryAncmtWindow
All checks were successful
Test / Run tests (push) Successful in 2m5s
All checks were successful
Test / Run tests (push) Successful in 2m5s
This commit is contained in:
@ -292,6 +292,10 @@ namespace Elwig {
|
||||
return w;
|
||||
}
|
||||
|
||||
public static DeliveryAncmtAdminWindow FocusDeliveryAncmt() {
|
||||
return FocusWindow<DeliveryAncmtAdminWindow>(() => new());
|
||||
}
|
||||
|
||||
public static DeliveryScheduleAdminWindow FocusDeliverySchedule() {
|
||||
return FocusWindow<DeliveryScheduleAdminWindow>(() => new());
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
|
||||
namespace Elwig.Models.Entities {
|
||||
[Table("delivery_schedule"), PrimaryKey("Year", "DsNr")]
|
||||
@ -30,6 +31,10 @@ namespace Elwig.Models.Entities {
|
||||
|
||||
[Column("max_weight")]
|
||||
public int? MaxWeight { get; set; }
|
||||
[NotMapped]
|
||||
public int AnnouncedWeight => Announcements.Sum(a => a.Weight);
|
||||
[NotMapped]
|
||||
public double? Percent => (double)AnnouncedWeight / MaxWeight * 100;
|
||||
|
||||
[Column("ancmt_from")]
|
||||
public long? AncmtFromUnix { get; set; }
|
||||
@ -56,6 +61,9 @@ namespace Elwig.Models.Entities {
|
||||
[InverseProperty(nameof(DeliveryScheduleWineVar.Schedule))]
|
||||
public virtual ICollection<DeliveryScheduleWineVar> Varieties { get; private set; } = null!;
|
||||
|
||||
[InverseProperty(nameof(DeliveryAncmt.Schedule))]
|
||||
public virtual ICollection<DeliveryAncmt> Announcements { get; private set; } = null!;
|
||||
|
||||
public int SearchScore(IEnumerable<string> keywords) {
|
||||
return Utils.GetSearchScore([Description], keywords);
|
||||
}
|
||||
|
118
Elwig/Services/DeliveryAncmtService.cs
Normal file
118
Elwig/Services/DeliveryAncmtService.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.ViewModels;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Elwig.Services {
|
||||
public static class DeliveryAncmtService {
|
||||
|
||||
public static void InitInputs(this DeliveryAncmtAdminViewModel vm) {
|
||||
if (vm.SelectedDeliverySchedule is DeliverySchedule s)
|
||||
vm.DeliverySchedule = (DeliverySchedule?)ControlUtils.GetItemFromSourceWithPk(vm.DeliveryScheduleSource, s.Year, s.DsNr);
|
||||
}
|
||||
|
||||
public static void ClearInputs(this DeliveryAncmtAdminViewModel vm) {
|
||||
}
|
||||
|
||||
public static async Task FillInputs(this DeliveryAncmtAdminViewModel vm, DeliveryAncmt a) {
|
||||
vm.MgNr = a.MgNr;
|
||||
vm.DeliverySchedule = (DeliverySchedule?)ControlUtils.GetItemFromSourceWithPk(vm.DeliveryScheduleSource, a.Year, a.DsNr);
|
||||
vm.SortId = a.SortId;
|
||||
vm.Weight = a.Weight;
|
||||
}
|
||||
|
||||
public static async Task<(List<string>, IQueryable<DeliveryAncmt>, List<string>)> GetFilters(this DeliveryAncmtAdminViewModel vm, AppDbContext ctx) {
|
||||
List<string> filterNames = [];
|
||||
IQueryable<DeliveryAncmt> deliveryAncmtQuery = ctx.DeliveryAnnouncements;
|
||||
if (vm.SelectedDeliverySchedule is DeliverySchedule s) {
|
||||
deliveryAncmtQuery = deliveryAncmtQuery.Where(a => a.Year == s.Year && a.DsNr == s.DsNr);
|
||||
filterNames.Add($"{s.Date:dd.MM.yyyy} - {s.Branch.Name} - {s.Description}");
|
||||
} else {
|
||||
deliveryAncmtQuery = deliveryAncmtQuery.Where(a => a.Year == vm.FilterSeason);
|
||||
filterNames.Add($"{vm.FilterSeason}");
|
||||
}
|
||||
|
||||
var filterVar = new List<string>();
|
||||
var filterNotVar = new List<string>();
|
||||
var filterMgNr = new List<int>();
|
||||
|
||||
var filter = vm.TextFilter;
|
||||
if (filter.Count > 0) {
|
||||
var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v);
|
||||
var mgnr = await ctx.Members.ToDictionaryAsync(m => m.MgNr.ToString(), m => m);
|
||||
|
||||
for (int i = 0; i < filter.Count; i++) {
|
||||
var e = filter[i];
|
||||
if (e.ToLower() is "r" or "rot") {
|
||||
filterVar.AddRange(var.Values.Where(v => v.IsRed).Select(v => v.SortId));
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add("Rotweinsorten");
|
||||
} else if (e.ToLower() is "w" or "weiß" or "weiss") {
|
||||
filterVar.AddRange(var.Values.Where(v => v.IsWhite).Select(v => v.SortId));
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add("Weißweinsorten");
|
||||
} else if (e.Length == 2 && var.ContainsKey(e.ToUpper())) {
|
||||
filterVar.Add(e.ToUpper());
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add(var[e.ToUpper()].Name);
|
||||
} else if (e.Length == 3 && e[0] == '!' && var.ContainsKey(e[1..].ToUpper())) {
|
||||
filterNotVar.Add(e[1..].ToUpper());
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add("außer " + var[e[1..].ToUpper()].Name);
|
||||
} else if (e.All(char.IsAsciiDigit) && mgnr.TryGetValue(e, out var member)) {
|
||||
filterMgNr.Add(int.Parse(e));
|
||||
filter.RemoveAt(i--);
|
||||
filterNames.Add(member.AdministrativeName);
|
||||
} else if (e.Length > 2 && e.StartsWith('"') && e.EndsWith('"')) {
|
||||
filter[i] = e[1..^1];
|
||||
} else if (e.Length <= 2) {
|
||||
filter.RemoveAt(i--);
|
||||
}
|
||||
}
|
||||
|
||||
if (filterMgNr.Count > 0) deliveryAncmtQuery = deliveryAncmtQuery.Where(a => filterMgNr.Contains(a.MgNr));
|
||||
if (filterVar.Count > 0) deliveryAncmtQuery = deliveryAncmtQuery.Where(a => filterVar.Contains(a.SortId));
|
||||
if (filterNotVar.Count > 0) deliveryAncmtQuery = deliveryAncmtQuery.Where(a => !filterNotVar.Contains(a.SortId));
|
||||
}
|
||||
|
||||
return (filterNames, deliveryAncmtQuery, filter);
|
||||
}
|
||||
|
||||
public static async Task<(int, int, int, string)> UpdateDeliveryAncmt(this DeliveryAncmtAdminViewModel vm, int? oldYear, int? oldDsNr, int? oldMgNr, string? oldSortId, string? oldType) {
|
||||
int year = vm.DeliverySchedule!.Year;
|
||||
int dsnr = vm.DeliverySchedule!.DsNr;
|
||||
int newMgNr = vm.MgNr!.Value;
|
||||
string newSortId = vm.SortId!;
|
||||
|
||||
using (var ctx = new AppDbContext()) {
|
||||
var a = new DeliveryAncmt {
|
||||
Year = oldYear ?? year,
|
||||
DsNr = oldDsNr ?? dsnr,
|
||||
MgNr = oldMgNr ?? newMgNr,
|
||||
SortId = oldSortId ?? newSortId,
|
||||
Weight = vm.Weight!.Value,
|
||||
Type = oldType ?? "manual",
|
||||
};
|
||||
|
||||
if (oldDsNr != null) {
|
||||
ctx.Update(a);
|
||||
} else {
|
||||
ctx.Add(a);
|
||||
}
|
||||
|
||||
await ctx.SaveChangesAsync();
|
||||
|
||||
if (oldDsNr != null && (oldYear != year || oldDsNr != dsnr || oldMgNr != newMgNr || oldSortId != newSortId)) {
|
||||
await ctx.Database.ExecuteSqlRawAsync($"UPDATE delivery_announcement SET year = {year}, dsnr = {dsnr}, mgnr = {newMgNr}, sortid = '{newSortId}' WHERE (year, dsnr, mgnr, sortid) = ({a.Year}, {a.DsNr}, {a.MgNr}, '{a.SortId}')");
|
||||
}
|
||||
}
|
||||
|
||||
await App.HintContextChange();
|
||||
|
||||
return (year, dsnr, newMgNr, newSortId);
|
||||
}
|
||||
}
|
||||
}
|
70
Elwig/ViewModels/DeliveryAncmtAdminViewModel.cs
Normal file
70
Elwig/ViewModels/DeliveryAncmtAdminViewModel.cs
Normal file
@ -0,0 +1,70 @@
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Elwig.Models.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
|
||||
namespace Elwig.ViewModels {
|
||||
public partial class DeliveryAncmtAdminViewModel : ObservableObject {
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _searchQuery = "";
|
||||
public List<string> TextFilter => [.. SearchQuery?.ToLower().Split(' ').ToList().FindAll(e => e.Length > 0)];
|
||||
|
||||
[ObservableProperty]
|
||||
private bool _filterOnlyUpcoming;
|
||||
[ObservableProperty]
|
||||
private string? _filterSeasonString;
|
||||
public int? FilterSeason {
|
||||
get => int.TryParse(FilterSeasonString, out var year) ? year : null;
|
||||
set => FilterSeasonString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private DeliveryAncmt? _selectedDeliveryAncmt;
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliveryAncmt> _deliveryAncmts = [];
|
||||
[ObservableProperty]
|
||||
private DeliverySchedule? _selectedDeliverySchedule;
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliverySchedule> _deliverySchedules = [];
|
||||
[ObservableProperty]
|
||||
private bool _enableSearchInputs = true;
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _mgNrString;
|
||||
public int? MgNr {
|
||||
get => int.TryParse(MgNrString, out var mgnr) ? mgnr : null;
|
||||
set => MgNrString = $"{value}";
|
||||
}
|
||||
[ObservableProperty]
|
||||
private Member? _member;
|
||||
[ObservableProperty]
|
||||
private IEnumerable<Member> _memberSource = [];
|
||||
[ObservableProperty]
|
||||
private string? _memberAddress;
|
||||
|
||||
[ObservableProperty]
|
||||
private DeliverySchedule? _deliverySchedule;
|
||||
[ObservableProperty]
|
||||
private IEnumerable<DeliverySchedule> _deliveryScheduleSource = [];
|
||||
[ObservableProperty]
|
||||
private string? _sortId;
|
||||
[ObservableProperty]
|
||||
private WineVar? _wineVariety;
|
||||
[ObservableProperty]
|
||||
private IEnumerable<WineVar> _wineVarietySource = [];
|
||||
|
||||
[ObservableProperty]
|
||||
private string? _weightString;
|
||||
public int? Weight {
|
||||
get => int.TryParse(WeightString, out var w) ? w : null;
|
||||
set => WeightString = $"{value}";
|
||||
}
|
||||
|
||||
[ObservableProperty]
|
||||
private Visibility _controlButtonsVisibility = Visibility.Visible;
|
||||
[ObservableProperty]
|
||||
private Visibility _editingButtonsVisibility = Visibility.Hidden;
|
||||
}
|
||||
}
|
312
Elwig/Windows/DeliveryAncmtAdminWindow.xaml
Normal file
312
Elwig/Windows/DeliveryAncmtAdminWindow.xaml
Normal file
@ -0,0 +1,312 @@
|
||||
<local:AdministrationWindow
|
||||
x:Class="Elwig.Windows.DeliveryAncmtAdminWindow"
|
||||
AutomationProperties.AutomationId="DeliveryAncmtWindow"
|
||||
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:local="clr-namespace:Elwig.Windows"
|
||||
xmlns:vm="clr-namespace:Elwig.ViewModels"
|
||||
xmlns:ctrl="clr-namespace:Elwig.Controls"
|
||||
Title="Traubenanmeldungen - Elwig" Height="700" Width="900" MinWidth="600" MinHeight="400"
|
||||
Loaded="Window_Loaded">
|
||||
<Window.DataContext>
|
||||
<vm:DeliveryAncmtAdminViewModel/>
|
||||
</Window.DataContext>
|
||||
<Window.Resources>
|
||||
<Style TargetType="Label">
|
||||
<Setter Property="HorizontalAlignment" Value="Left"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="Padding" Value="2,4,2,4"/>
|
||||
<Setter Property="Height" Value="25"/>
|
||||
</Style>
|
||||
<Style TargetType="TextBox">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Padding" Value="2"/>
|
||||
<Setter Property="Height" Value="25"/>
|
||||
<Setter Property="TextWrapping" Value="NoWrap"/>
|
||||
</Style>
|
||||
<Style TargetType="ctrl:UnitTextBox">
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Padding" Value="2"/>
|
||||
<Setter Property="Height" Value="25"/>
|
||||
<Setter Property="TextWrapping" Value="NoWrap"/>
|
||||
</Style>
|
||||
<Style TargetType="ComboBox">
|
||||
<Setter Property="Height" Value="25"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
</Style>
|
||||
<Style TargetType="ctrl:CheckComboBox">
|
||||
<Setter Property="Height" Value="25"/>
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="VerticalAlignment" Value="Top"/>
|
||||
</Style>
|
||||
<Style TargetType="Button">
|
||||
<Setter Property="FontSize" Value="14"/>
|
||||
<Setter Property="Padding" Value="9,3"/>
|
||||
<Setter Property="Height" Value="27"/>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="19"/>
|
||||
<RowDefinition Height="1*"/>
|
||||
<RowDefinition Height="24"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" MinWidth="250"/>
|
||||
<ColumnDefinition Width="5"/>
|
||||
<ColumnDefinition Width="1*" MinWidth="300"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Menu Grid.ColumnSpan="3" BorderThickness="0,0,0,1" BorderBrush="LightGray" Background="White">
|
||||
</Menu>
|
||||
|
||||
<Grid Grid.Row="1" Margin="5,0,0,0">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="35"/>
|
||||
<RowDefinition Height="1*" MinHeight="100"/>
|
||||
<RowDefinition Height="5"/>
|
||||
<RowDefinition Height="2*" MinHeight="100"/>
|
||||
<RowDefinition Height="42"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBox x:Name="SearchInput" Text="{Binding SearchQuery, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding EnableSearchInputs}"
|
||||
Grid.ColumnSpan="3" Margin="5,5,174,0" IsReadOnly="False"
|
||||
TextChanged="SearchInput_TextChanged">
|
||||
<TextBox.ToolTip>
|
||||
<TextBlock>
|
||||
<Bold>Strg+F</Bold><LineBreak/><LineBreak/>
|
||||
Traubenanmeldungen filtern und durchsuchen. Die Filter sind beliebig kombinierbar.<LineBreak/>
|
||||
Groß- und Kleinschreibung ist in den meisten Fällen egal.<LineBreak/>
|
||||
<LineBreak/>
|
||||
Filtern nach:<LineBreak/>
|
||||
<Bold>Sorte</Bold>: z.B. GV, ZW, rr, sa, !gv (ausgenommen GV), ...<LineBreak/>
|
||||
<Bold>Rot/Weiß</Bold>: z.B. r, Rot, w, weiß, ...<LineBreak/>
|
||||
<Bold>Mitglied</Bold>: z.B. 1234, 987, ...
|
||||
</TextBlock>
|
||||
</TextBox.ToolTip>
|
||||
</TextBox>
|
||||
<ctrl:IntegerUpDown x:Name="SeasonInput" Text="{Binding FilterSeasonString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding EnableSearchInputs}"
|
||||
Grid.ColumnSpan="3" Height="25" Width="56" FontSize="14" Minimum="1900" Maximum="9999"
|
||||
Margin="5,5,113,0" VerticalAlignment="Top" HorizontalAlignment="Right"
|
||||
TextChanged="SeasonInput_TextChanged"/>
|
||||
<CheckBox x:Name="OnlyUpcomingInput" Content="Nur zukünftige" IsChecked="{Binding FilterOnlyUpcoming, Mode=TwoWay}" IsEnabled="{Binding EnableSearchInputs}"
|
||||
HorizontalAlignment="Right" Margin="0,10,10,0" VerticalAlignment="Top" Grid.Column="0" Grid.ColumnSpan="3"
|
||||
Checked="OnlyUpcomingInput_Changed" Unchecked="OnlyUpcomingInput_Changed"/>
|
||||
|
||||
<ListBox x:Name="DeliveryScheduleList" SelectedItem="{Binding SelectedDeliverySchedule, Mode=TwoWay}" ItemsSource="{Binding DeliverySchedules, Mode=TwoWay}"
|
||||
Grid.Row="1" Grid.ColumnSpan="3" Margin="5,0,5,5" VerticalAlignment="Stretch" IsEnabled="{Binding EnableSearchInputs}"
|
||||
SelectionChanged="DeliveryScheduleList_SelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Date, StringFormat='dd.MM.'}" Width="32"/>
|
||||
<TextBlock Text="{Binding ZwstId}" Width="25" TextAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Description}" Width="200"/>
|
||||
<TextBlock TextAlignment="Right">
|
||||
<TextBlock Text="{Binding AnnouncedWeight, StringFormat='{}{0:N0}'}" Width="42" TextAlignment="Right"/> kg
|
||||
/ <TextBlock Text="{Binding MaxWeight, StringFormat='{}{0:N0}'}" Width="42" TextAlignment="Right"/> kg
|
||||
(<TextBlock Text="{Binding Percent, StringFormat='{}{0:N0}'}" Width="20" TextAlignment="Right"/>%)
|
||||
</TextBlock>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<GridSplitter Grid.Row="2" Grid.ColumnSpan="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
|
||||
|
||||
<DataGrid x:Name="DeliveryAncmtList" AutoGenerateColumns="False" HeadersVisibility="Column" IsReadOnly="True" GridLinesVisibility="None" SelectionMode="Single"
|
||||
ItemsSource="{Binding DeliveryAncmts, Mode=TwoWay}" SelectedItem="{Binding SelectedDeliveryAncmt, Mode=TwoWay}"
|
||||
CanUserDeleteRows="False" CanUserResizeRows="False" CanUserAddRows="False"
|
||||
SelectionChanged="DeliveryAncmtList_SelectionChanged"
|
||||
Margin="5,5,5,0" Grid.Row="3" FontSize="14" Grid.ColumnSpan="3">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Header="MgNr." Binding="{Binding MgNr, StringFormat='{}{0} '}" Width="50">
|
||||
<DataGridTextColumn.CellStyle>
|
||||
<Style>
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.CellStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Mitglied" Binding="{Binding Member.AdministrativeName}" Width="180"/>
|
||||
<DataGridTextColumn Header="Sorte" Binding="{Binding SortId}" Width="50">
|
||||
<DataGridTextColumn.CellStyle>
|
||||
<Style>
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Center"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.CellStyle>
|
||||
</DataGridTextColumn>
|
||||
<DataGridTextColumn Header="Gewicht" Binding="{Binding Weight, StringFormat='{}{0:N0} kg'}" Width="75">
|
||||
<DataGridTextColumn.CellStyle>
|
||||
<Style>
|
||||
<Setter Property="TextBlock.TextAlignment" Value="Right"/>
|
||||
</Style>
|
||||
</DataGridTextColumn.CellStyle>
|
||||
</DataGridTextColumn>
|
||||
</DataGrid.Columns>
|
||||
</DataGrid>
|
||||
|
||||
<Button x:Name="NewDeliveryAncmtButton" Content="Neu" Visibility="{Binding ControlButtonsVisibility}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="4"
|
||||
Click="NewDeliveryAncmtButton_Click">
|
||||
<Button.ToolTip>
|
||||
<TextBlock FontWeight="Bold">Alt+Einfg</TextBlock>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
<Button x:Name="EditDeliveryAncmtButton" Content="Bearbeiten" IsEnabled="False" Visibility="{Binding ControlButtonsVisibility}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="4"
|
||||
Click="EditDeliveryAncmtButton_Click">
|
||||
<Button.ToolTip>
|
||||
<TextBlock FontWeight="Bold">Strg+B</TextBlock>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
<Button x:Name="DeleteDeliveryAncmtButton" Content="Löschen" IsEnabled="False" Visibility="{Binding ControlButtonsVisibility}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="4"
|
||||
Click="DeleteDeliveryAncmtButton_Click">
|
||||
<Button.ToolTip>
|
||||
<TextBlock FontWeight="Bold">Alt+Entf</TextBlock>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
|
||||
<Button x:Name="SaveButton" Content="Speichern" IsEnabled="False" Visibility="{Binding EditingButtonsVisibility}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="5,5,2.5,10" Grid.Column="0" Grid.Row="4"
|
||||
Click="SaveButton_Click">
|
||||
<Button.ToolTip>
|
||||
<TextBlock FontWeight="Bold">Strg+S</TextBlock>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
<Button x:Name="ResetButton" Content="Zurücksetzen" IsEnabled="False" Visibility="{Binding EditingButtonsVisibility}"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,2.5,10" Grid.Column="1" Grid.Row="4"
|
||||
Click="ResetButton_Click">
|
||||
<Button.ToolTip>
|
||||
<TextBlock FontWeight="Bold">Strg+Z</TextBlock>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
<Button x:Name="CancelButton" Content="Abbrechen" IsEnabled="False" Visibility="{Binding EditingButtonsVisibility}" IsCancel="True"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Bottom" Margin="2.5,5,5,10" Grid.Column="2" Grid.Row="4"
|
||||
Click="CancelButton_Click">
|
||||
<Button.ToolTip>
|
||||
<TextBlock FontWeight="Bold">Esc</TextBlock>
|
||||
</Button.ToolTip>
|
||||
</Button>
|
||||
</Grid>
|
||||
|
||||
<GridSplitter Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
|
||||
|
||||
<Grid Grid.Column="2" Grid.Row="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="2*"/>
|
||||
<RowDefinition Height="3*"/>
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<GroupBox Header="Mitglied" Grid.Row="0" Margin="5,5,5,5">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="70"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="Mitglied:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||
<TextBox x:Name="MgNrInput" Text="{Binding MgNrString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Width="48" Grid.Row="1" Grid.Column="1" Margin="0,10,0,0" HorizontalAlignment="Left" TextAlignment="Right"
|
||||
TextChanged="MgNrInput_TextChanged" LostFocus="MgNrInput_LostFocus" KeyUp="Input_KeyUp"/>
|
||||
<ComboBox x:Name="MemberInput" SelectedItem="{Binding Member, Mode=TwoWay}" ItemsSource="{Binding MemberSource, Mode=TwoWay}"
|
||||
Grid.Column="1" Margin="53,10,40,10" IsEditable="True"
|
||||
ItemTemplate="{StaticResource MemberAdminNameTemplate}" TextSearch.TextPath="AdministrativeName"
|
||||
SelectionChanged="MemberInput_SelectionChanged" KeyUp="Input_KeyUp"/>
|
||||
<Button x:Name="MemberReferenceButton" Grid.Column="1" Height="25" Width="25" FontFamily="Segoe MDL2 Assets" Content="" Padding="0,0,0,0"
|
||||
Margin="10,10,10,10" VerticalAlignment="Top" HorizontalAlignment="Right" ToolTip="Zu Mitglied springen"
|
||||
Click="MemberReferenceButton_Click"/>
|
||||
|
||||
<Label Content="Wohnort:" Margin="10,38,0,0" Grid.Column="0"/>
|
||||
<TextBox x:Name="MemberAddressField" Text="{Binding MemberAddress}"
|
||||
Grid.Column="1" Margin="0,40,10,10" FontSize="12" Height="22"
|
||||
IsReadOnly="True" IsTabStop="False"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Anmeldung" Grid.Row="1" Margin="5,5,5,5">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="70"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="Leseplan:" Margin="10,10,0,0" Grid.Column="0"/>
|
||||
<ComboBox x:Name="DeliveryScheduleInput" SelectedItem="{Binding DeliverySchedule, Mode=TwoWay}" ItemsSource="{Binding DeliveryScheduleSource, Mode=TwoWay}"
|
||||
Grid.Column="1" Margin="0,10,10,10"
|
||||
TextSearch.TextPath="Name"
|
||||
SelectionChanged="DeliveryScheduleInput_SelectionChanged">
|
||||
<ComboBox.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding Date, StringFormat='dd.MM.'}" Width="35"/>
|
||||
<TextBlock Text="{Binding ZwstId}" Width="30" TextAlignment="Center"/>
|
||||
<TextBlock Text="{Binding Description}"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ComboBox.ItemTemplate>
|
||||
</ComboBox>
|
||||
|
||||
<Label Content="Sorte:" Margin="10,40,0,0" Grid.Column="0"/>
|
||||
<TextBox x:Name="SortIdInput" Text="{Binding SortId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Width="36" Grid.Row="1" Grid.Column="1" Margin="0,40,0,0" HorizontalAlignment="Left"
|
||||
TextChanged="SortIdInput_TextChanged" LostFocus="SortIdInput_LostFocus" KeyUp="Input_KeyUp"/>
|
||||
<ComboBox x:Name="WineVarietyInput" SelectedItem="{Binding WineVariety, Mode=TwoWay}" ItemsSource="{Binding WineVarietySource, Mode=TwoWay}"
|
||||
Grid.Column="1" Margin="41,40,10,10"
|
||||
TextSearch.TextPath="Name"
|
||||
SelectionChanged="WineVarietyInput_SelectionChanged" KeyUp="Input_KeyUp">
|
||||
<ComboBox.ItemTemplateSelector>
|
||||
<ctrl:WineVarietyTemplateSelector/>
|
||||
</ComboBox.ItemTemplateSelector>
|
||||
</ComboBox>
|
||||
|
||||
<Label Content="Gewicht" Margin="10,70,0,0" Grid.Column="0"/>
|
||||
<ctrl:UnitTextBox x:Name="WeightInput" Unit="kg" Text="{Binding WeightString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
|
||||
Grid.Column="1" Margin="0,70,10,10" Width="61" HorizontalAlignment="Left"
|
||||
TextChanged="WeightInput_TextChanged" KeyUp="Input_KeyUp"/>
|
||||
</Grid>
|
||||
</GroupBox>
|
||||
|
||||
<Button x:Name="DeliveryScheduleButton" Content="Leseplanung"
|
||||
Grid.Row="2" Margin="10,10,10,10" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom"
|
||||
Click="DeliveryScheduleButton_Click"/>
|
||||
</Grid>
|
||||
|
||||
<StatusBar Grid.Row="2" Grid.ColumnSpan="3" BorderThickness="0,1,0,0" BorderBrush="Gray">
|
||||
<StatusBar.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="200"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="1*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem>
|
||||
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</local:AdministrationWindow>
|
426
Elwig/Windows/DeliveryAncmtAdminWindow.xaml.cs
Normal file
426
Elwig/Windows/DeliveryAncmtAdminWindow.xaml.cs
Normal file
@ -0,0 +1,426 @@
|
||||
using Elwig.Helpers;
|
||||
using Elwig.Models.Entities;
|
||||
using Elwig.ViewModels;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using Elwig.Services;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Elwig.Windows {
|
||||
public partial class DeliveryAncmtAdminWindow : AdministrationWindow {
|
||||
|
||||
public DeliveryAncmtAdminViewModel ViewModel => (DeliveryAncmtAdminViewModel)DataContext;
|
||||
|
||||
private readonly RoutedCommand CtrlF = new("CtrlF", typeof(DeliveryAncmtAdminWindow), [new KeyGesture(Key.F, ModifierKeys.Control)]);
|
||||
|
||||
public DeliveryAncmtAdminWindow() {
|
||||
InitializeComponent();
|
||||
CommandBindings.Add(new CommandBinding(CtrlF, FocusSearchInput));
|
||||
ExemptInputs = [
|
||||
SearchInput, SeasonInput, OnlyUpcomingInput, DeliveryScheduleList, DeliveryAncmtList,
|
||||
];
|
||||
RequiredInputs = [
|
||||
MgNrInput, MemberInput, DeliveryScheduleInput, SortIdInput, WineVarietyInput, WeightInput,
|
||||
];
|
||||
|
||||
InitializeDelayTimer(SearchInput, SearchInput_TextChanged);
|
||||
SearchInput.TextChanged -= SearchInput_TextChanged;
|
||||
ViewModel.FilterSeason = Utils.CurrentLastSeason;
|
||||
}
|
||||
|
||||
private void Window_Loaded(object sender, RoutedEventArgs evt) {
|
||||
ViewModel.FilterOnlyUpcoming = true;
|
||||
LockInputs();
|
||||
}
|
||||
|
||||
private void Input_KeyUp(object sender, KeyEventArgs evt) {
|
||||
if (sender is not Control ctrl) return;
|
||||
if (evt.Key != Key.Enter) return;
|
||||
if (ctrl == MgNrInput || ctrl == MemberInput) {
|
||||
SortIdInput.Focus();
|
||||
SortIdInput.SelectAll();
|
||||
} else if (ctrl == SortIdInput || ctrl == WineVarietyInput) {
|
||||
WeightInput.Focus();
|
||||
WeightInput.SelectAll();
|
||||
} else if (ctrl == WeightInput) {
|
||||
SaveButton_Click(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RefreshDeliveryScheduleList() {
|
||||
using var ctx = new AppDbContext();
|
||||
var deliverySchedules = await ctx.DeliverySchedules
|
||||
.Where(s => s.Year == ViewModel.FilterSeason)
|
||||
.Where(s => !ViewModel.FilterOnlyUpcoming || s.DateString.CompareTo(Utils.Today.ToString("yyyy-MM-dd")) >= 0)
|
||||
.Include(s => s.Branch)
|
||||
.Include(s => s.Announcements)
|
||||
.OrderBy(s => s.DateString)
|
||||
.ThenBy(s => s.Branch.Name)
|
||||
.ThenBy(s => s.Description)
|
||||
.ToListAsync();
|
||||
ControlUtils.RenewItemsSource(DeliveryScheduleList, deliverySchedules, DeliveryScheduleList_SelectionChanged, ControlUtils.RenewSourceDefault.First);
|
||||
ControlUtils.RenewItemsSource(DeliveryScheduleInput, deliverySchedules, DeliveryScheduleInput_SelectionChanged);
|
||||
}
|
||||
|
||||
private async Task RefreshList(bool updateSort = false) {
|
||||
using var ctx = new AppDbContext();
|
||||
var (_, deliveryAncmtQuery, filter) = await ViewModel.GetFilters(ctx);
|
||||
var deliveryAncmts = await deliveryAncmtQuery
|
||||
.Include(a => a.Member.BillingAddress)
|
||||
.Include(a => a.Schedule)
|
||||
.AsSplitQuery()
|
||||
.ToListAsync();
|
||||
|
||||
if (filter.Count > 0 && deliveryAncmts.Count > 0) {
|
||||
var dict = deliveryAncmts.AsParallel()
|
||||
.ToDictionary(a => a, a => a.SearchScore(filter))
|
||||
.OrderByDescending(a => a.Value)
|
||||
.ThenBy(a => a.Key.Member.FamilyName)
|
||||
.ThenBy(a => a.Key.Member.GivenName)
|
||||
.ThenBy(a => a.Key.Member.MgNr);
|
||||
var threshold = dict.Select(a => a.Value).Max() * 3 / 4;
|
||||
deliveryAncmts = dict
|
||||
.Where(a => a.Value > threshold)
|
||||
.Select(a => a.Key)
|
||||
.ToList();
|
||||
} else {
|
||||
deliveryAncmts = deliveryAncmts
|
||||
.OrderBy(a => a.Member.FamilyName)
|
||||
.ThenBy(a => a.Member.GivenName)
|
||||
.ThenBy(a => a.Member.MgNr)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
ControlUtils.RenewItemsSource(DeliveryAncmtList, deliveryAncmts,
|
||||
DeliveryAncmtList_SelectionChanged, ViewModel.TextFilter.Count > 0 ? ControlUtils.RenewSourceDefault.IfOnly : ControlUtils.RenewSourceDefault.None, !updateSort);
|
||||
if (updateSort && DeliveryAncmtList.SelectedItem != null)
|
||||
DeliveryAncmtList.ScrollIntoView(DeliveryAncmtList.SelectedItem);
|
||||
}
|
||||
|
||||
private async Task RefreshInputs(bool validate = false) {
|
||||
ClearInputStates();
|
||||
if (ViewModel.SelectedDeliveryAncmt is DeliveryAncmt a) {
|
||||
EditDeliveryAncmtButton.IsEnabled = true;
|
||||
DeleteDeliveryAncmtButton.IsEnabled = true;
|
||||
await FillInputs(a);
|
||||
} else {
|
||||
EditDeliveryAncmtButton.IsEnabled = false;
|
||||
DeleteDeliveryAncmtButton.IsEnabled = false;
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
ClearInputs(validate);
|
||||
ClearInputStates();
|
||||
}
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
private void InitInputs() {
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
ViewModel.InitInputs();
|
||||
ValidateRequiredInputs();
|
||||
}
|
||||
|
||||
protected override async Task OnRenewContext(AppDbContext ctx) {
|
||||
await base.OnRenewContext(ctx);
|
||||
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.FamilyName)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
ControlUtils.RenewItemsSource(WineVarietyInput, await ctx.WineVarieties.OrderBy(v => v.Name).ToListAsync());
|
||||
|
||||
await RefreshDeliveryScheduleList();
|
||||
await RefreshList();
|
||||
}
|
||||
|
||||
private async void DeliveryAncmtList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||
await RefreshInputs();
|
||||
}
|
||||
|
||||
private async void DeliveryScheduleList_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||
await RefreshList();
|
||||
}
|
||||
|
||||
private void DeliveryScheduleInput_SelectionChanged(object sender, RoutedEventArgs evt) {
|
||||
|
||||
}
|
||||
|
||||
private async void OnlyUpcomingInput_Changed(object sender, RoutedEventArgs evt) {
|
||||
await RefreshDeliveryScheduleList();
|
||||
}
|
||||
|
||||
private async void SearchInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
await RefreshList(true);
|
||||
}
|
||||
|
||||
private async void SeasonInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
if (ViewModel.FilterSeason == null) return;
|
||||
ViewModel.FilterOnlyUpcoming = false;
|
||||
await RefreshDeliveryScheduleList();
|
||||
await RefreshList();
|
||||
}
|
||||
|
||||
private void MgNrInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
var valid = InputTextChanged((TextBox)sender, Validator.CheckMgNr);
|
||||
var text = MgNrInput.Text;
|
||||
var caret = MgNrInput.CaretIndex;
|
||||
ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null);
|
||||
MgNrInput.Text = text;
|
||||
MgNrInput.CaretIndex = caret;
|
||||
}
|
||||
|
||||
private void MgNrInput_LostFocus(object sender, RoutedEventArgs evt) {
|
||||
var valid = InputLostFocus((TextBox)sender, Validator.CheckMgNr);
|
||||
ControlUtils.SelectItemWithPk(MemberInput, valid ? ViewModel.MgNr : null);
|
||||
}
|
||||
|
||||
private void MemberInput_SelectionChanged(object? sender, SelectionChangedEventArgs? evt) {
|
||||
var m = MemberInput.SelectedItem as Member;
|
||||
ViewModel.MgNr = m?.MgNr;
|
||||
ViewModel.MemberAddress = m?.FullAddress;
|
||||
}
|
||||
|
||||
protected override void ShortcutNew() {
|
||||
if (!NewDeliveryAncmtButton.IsEnabled || NewDeliveryAncmtButton.Visibility != Visibility.Visible)
|
||||
return;
|
||||
NewDeliveryAncmtButton_Click(null, null);
|
||||
}
|
||||
|
||||
private async void NewDeliveryAncmtButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
IsCreating = true;
|
||||
DeliveryAncmtList.IsEnabled = false;
|
||||
ViewModel.SelectedDeliveryAncmt = null;
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.FamilyName)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
|
||||
HideNewEditDeleteButtons();
|
||||
ShowSaveResetCancelButtons();
|
||||
UnlockInputs();
|
||||
InitInputs();
|
||||
ViewModel.EnableSearchInputs = false;
|
||||
}
|
||||
|
||||
protected override void ShortcutEdit() {
|
||||
if (!EditDeliveryAncmtButton.IsEnabled || EditDeliveryAncmtButton.Visibility != Visibility.Visible)
|
||||
return;
|
||||
EditDeliveryAncmtButton_Click(null, null);
|
||||
}
|
||||
|
||||
private void EditDeliveryAncmtButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
if (ViewModel.SelectedDeliveryAncmt == null) return;
|
||||
IsEditing = true;
|
||||
DeliveryAncmtList.IsEnabled = false;
|
||||
HideNewEditDeleteButtons();
|
||||
ShowSaveResetCancelButtons();
|
||||
UnlockInputs();
|
||||
ViewModel.EnableSearchInputs = false;
|
||||
}
|
||||
|
||||
protected override void ShortcutDelete() {
|
||||
if (!DeleteDeliveryAncmtButton.IsEnabled || DeleteDeliveryAncmtButton.Visibility != Visibility.Visible)
|
||||
return;
|
||||
DeleteDeliveryAncmtButton_Click(null, null);
|
||||
}
|
||||
|
||||
private async void DeleteDeliveryAncmtButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
if (ViewModel.SelectedDeliveryAncmt is not DeliveryAncmt a)
|
||||
return;
|
||||
var r = MessageBox.Show(
|
||||
$"Soll die Traubenanmeldung wirklich unwiderruflich gelöscht werden?",
|
||||
"Traubenanmeldung löschen", MessageBoxButton.OKCancel, MessageBoxImage.Warning, MessageBoxResult.Cancel);
|
||||
if (r == MessageBoxResult.OK) {
|
||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
try {
|
||||
using (var ctx = new AppDbContext()) {
|
||||
ctx.Remove(a);
|
||||
await ctx.SaveChangesAsync();
|
||||
}
|
||||
await App.HintContextChange();
|
||||
} catch (Exception exc) {
|
||||
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
|
||||
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
|
||||
MessageBox.Show(str, "Traubenanmeldung löschen", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
Mouse.OverrideCursor = null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ShortcutSave() {
|
||||
if (!SaveButton.IsEnabled || SaveButton.Visibility != Visibility.Visible)
|
||||
return;
|
||||
SaveButton_Click(null, null);
|
||||
}
|
||||
|
||||
private async void SaveButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
Mouse.OverrideCursor = Cursors.AppStarting;
|
||||
int year = -1, dsnr = -1, mgnr = -1;
|
||||
string? sortid = null;
|
||||
try {
|
||||
var s = ViewModel.SelectedDeliveryAncmt;
|
||||
(year, dsnr, mgnr, sortid) = await ViewModel.UpdateDeliveryAncmt(s?.Year, s?.DsNr, s?.MgNr, s?.SortId, s?.Type);
|
||||
} catch (Exception exc) {
|
||||
var str = "Der Eintrag konnte nicht in der Datenbank aktualisiert werden!\n\n" + exc.Message;
|
||||
if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
|
||||
MessageBox.Show(str, "Traubenanmeldung aktualisieren", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
Mouse.OverrideCursor = null;
|
||||
IsEditing = false;
|
||||
IsCreating = false;
|
||||
DeliveryAncmtList.IsEnabled = true;
|
||||
HideSaveResetCancelButtons();
|
||||
ShowNewEditDeleteButtons();
|
||||
LockInputs();
|
||||
ViewModel.EnableSearchInputs = true;
|
||||
FinishInputFilling();
|
||||
await RefreshList();
|
||||
await RefreshInputs();
|
||||
ViewModel.SearchQuery = "";
|
||||
if (sortid != null)
|
||||
ControlUtils.SelectItemWithPk(DeliveryAncmtList, year, dsnr, mgnr, sortid);
|
||||
}
|
||||
|
||||
protected override void ShortcutReset() {
|
||||
if (!ResetButton.IsEnabled || ResetButton.Visibility != Visibility.Visible)
|
||||
return;
|
||||
ResetButton_Click(null, null);
|
||||
}
|
||||
|
||||
private async void ResetButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
if (IsEditing) {
|
||||
await RefreshInputs();
|
||||
} else if (IsCreating) {
|
||||
ClearInputs();
|
||||
InitInputs();
|
||||
}
|
||||
UpdateButtons();
|
||||
}
|
||||
|
||||
private async void CancelButton_Click(object? sender, RoutedEventArgs? evt) {
|
||||
IsEditing = false;
|
||||
IsCreating = false;
|
||||
DeliveryAncmtList.IsEnabled = true;
|
||||
|
||||
using var ctx = new AppDbContext();
|
||||
ControlUtils.RenewItemsSource(MemberInput, await ctx.Members
|
||||
.Where(m => m.IsActive || !IsCreating)
|
||||
.Include(m => m.PostalDest.AtPlz!.Ort)
|
||||
.Include(m => m.DefaultWbKg!.AtKg)
|
||||
.OrderBy(m => m.FamilyName)
|
||||
.ThenBy(m => m.GivenName)
|
||||
.ThenBy(m => m.MgNr)
|
||||
.ToListAsync());
|
||||
|
||||
HideSaveResetCancelButtons();
|
||||
ShowNewEditDeleteButtons();
|
||||
await RefreshInputs();
|
||||
LockInputs();
|
||||
ViewModel.EnableSearchInputs = true;
|
||||
}
|
||||
|
||||
private async Task FillInputs(DeliveryAncmt a) {
|
||||
ClearOriginalValues();
|
||||
ClearDefaultValues();
|
||||
await ViewModel.FillInputs(a);
|
||||
FinishInputFilling();
|
||||
}
|
||||
|
||||
private void UpdateWineVariety(bool valid) {
|
||||
if (valid) {
|
||||
ViewModel.SortId = ViewModel.SortId![0..2];
|
||||
ControlUtils.SelectItemWithPk(WineVarietyInput, ViewModel.SortId);
|
||||
} else {
|
||||
WineVarietyInput.SelectedItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void SortIdInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
UpdateWineVariety(InputTextChanged((TextBox)sender, Validator.CheckSortId));
|
||||
}
|
||||
|
||||
private void SortIdInput_LostFocus(object sender, RoutedEventArgs evt) {
|
||||
UpdateWineVariety(InputLostFocus((TextBox)sender, Validator.CheckSortId));
|
||||
}
|
||||
|
||||
private void WineVarietyInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
|
||||
if (WineVarietyInput.SelectedItem is WineVar s)
|
||||
ViewModel.SortId = s.SortId;
|
||||
}
|
||||
|
||||
new protected void ClearInputs(bool validate = false) {
|
||||
ViewModel.ClearInputs();
|
||||
base.ClearInputs(validate);
|
||||
}
|
||||
|
||||
protected override void UpdateButtons() {
|
||||
if (!IsEditing && !IsCreating) return;
|
||||
bool ch = HasChanged, v = IsValid;
|
||||
ResetButton.IsEnabled = ch;
|
||||
SaveButton.IsEnabled = v && ch;
|
||||
}
|
||||
|
||||
private void FocusSearchInput(object sender, RoutedEventArgs evt) {
|
||||
if (!IsEditing && !IsCreating) {
|
||||
SearchInput.Focus();
|
||||
SearchInput.SelectAll();
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowSaveResetCancelButtons() {
|
||||
SaveButton.IsEnabled = false;
|
||||
ResetButton.IsEnabled = false;
|
||||
CancelButton.IsEnabled = true;
|
||||
ViewModel.EditingButtonsVisibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void HideSaveResetCancelButtons() {
|
||||
SaveButton.IsEnabled = false;
|
||||
ResetButton.IsEnabled = false;
|
||||
CancelButton.IsEnabled = false;
|
||||
ViewModel.EditingButtonsVisibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void ShowNewEditDeleteButtons() {
|
||||
NewDeliveryAncmtButton.IsEnabled = true;
|
||||
EditDeliveryAncmtButton.IsEnabled = ViewModel.SelectedDeliveryAncmt != null;
|
||||
DeleteDeliveryAncmtButton.IsEnabled = ViewModel.SelectedDeliveryAncmt != null;
|
||||
ViewModel.ControlButtonsVisibility = Visibility.Visible;
|
||||
}
|
||||
|
||||
private void HideNewEditDeleteButtons() {
|
||||
NewDeliveryAncmtButton.IsEnabled = false;
|
||||
EditDeliveryAncmtButton.IsEnabled = false;
|
||||
DeleteDeliveryAncmtButton.IsEnabled = false;
|
||||
ViewModel.ControlButtonsVisibility = Visibility.Hidden;
|
||||
}
|
||||
|
||||
private void WeightInput_TextChanged(object sender, TextChangedEventArgs evt) {
|
||||
InputTextChanged((TextBox)sender, Validator.CheckInteger((TextBox)sender, false, 5));
|
||||
}
|
||||
|
||||
private void MemberReferenceButton_Click(object sender, RoutedEventArgs evt) {
|
||||
if (MemberInput.SelectedItem is not Member m) return;
|
||||
App.FocusMember(m.MgNr);
|
||||
}
|
||||
|
||||
private void DeliveryScheduleButton_Click(object sender, RoutedEventArgs evt) {
|
||||
App.FocusDeliverySchedule();
|
||||
}
|
||||
}
|
||||
}
|
@ -214,7 +214,7 @@ namespace Elwig.Windows {
|
||||
}
|
||||
|
||||
private void DeliveryAncmtButton_Click(object sender, RoutedEventArgs evt) {
|
||||
App.FocusDeliverySchedule();
|
||||
App.FocusDeliveryAncmt();
|
||||
}
|
||||
|
||||
private void BaseDataButton_Click(object sender, RoutedEventArgs evt) {
|
||||
|
Reference in New Issue
Block a user