Compare commits
	
		
			20 Commits
		
	
	
		
			6e0da28ea3
			...
			v0.5.1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7efd34bc4d | |||
| 59553be571 | |||
| 8b9d62ea50 | |||
| 17d00a8524 | |||
| 47950afb67 | |||
| 08108f0c18 | |||
| 8a6086ba6d | |||
| b1c7b45523 | |||
| 2bca2aed97 | |||
| c25bfc9f1b | |||
| fb4dc613ae | |||
| 0413bc5afc | |||
| f4ec95cdca | |||
| 077e03ab2f | |||
| 9488c4c853 | |||
| e962d1e44b | |||
| df5007826d | |||
| 6db2e0a4ec | |||
| 363005ad49 | |||
| 22318e1b9a | 
@@ -84,6 +84,12 @@
 | 
				
			|||||||
            </DataTemplate.Triggers>
 | 
					            </DataTemplate.Triggers>
 | 
				
			||||||
        </DataTemplate>
 | 
					        </DataTemplate>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <DataTemplate x:Key="WineOriginTemplate">
 | 
				
			||||||
 | 
					            <StackPanel Orientation="Horizontal">
 | 
				
			||||||
 | 
					                <TextBlock Text="{Binding HkIdLevel}" MinWidth="70" Margin="0,0,10,0"/>
 | 
				
			||||||
 | 
					                <TextBlock Text="{Binding Name}"/>
 | 
				
			||||||
 | 
					            </StackPanel>
 | 
				
			||||||
 | 
					        </DataTemplate>
 | 
				
			||||||
        <ControlTemplate x:Key="WineOriginTemplateSimple">
 | 
					        <ControlTemplate x:Key="WineOriginTemplateSimple">
 | 
				
			||||||
            <StackPanel Orientation="Horizontal">
 | 
					            <StackPanel Orientation="Horizontal">
 | 
				
			||||||
                <TextBlock Text="{Binding Name}"/>
 | 
					                <TextBlock Text="{Binding Name}"/>
 | 
				
			||||||
@@ -95,7 +101,7 @@
 | 
				
			|||||||
                <TextBlock Text="{Binding Name}"/>
 | 
					                <TextBlock Text="{Binding Name}"/>
 | 
				
			||||||
            </StackPanel>
 | 
					            </StackPanel>
 | 
				
			||||||
        </ControlTemplate>
 | 
					        </ControlTemplate>
 | 
				
			||||||
        <DataTemplate x:Key="WineOriginTemplate">
 | 
					        <DataTemplate x:Key="WineOriginComboTemplate">
 | 
				
			||||||
            <Control x:Name="Control" Focusable="False" Template="{StaticResource WineOriginTemplateExtended}"/>
 | 
					            <Control x:Name="Control" Focusable="False" Template="{StaticResource WineOriginTemplateExtended}"/>
 | 
				
			||||||
            <DataTemplate.Triggers>
 | 
					            <DataTemplate.Triggers>
 | 
				
			||||||
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ComboBoxItem}}, Path=IsSelected}" Value="{x:Null}">
 | 
					                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ComboBoxItem}}, Path=IsSelected}" Value="{x:Null}">
 | 
				
			||||||
@@ -103,5 +109,31 @@
 | 
				
			|||||||
                </DataTrigger>
 | 
					                </DataTrigger>
 | 
				
			||||||
            </DataTemplate.Triggers>
 | 
					            </DataTemplate.Triggers>
 | 
				
			||||||
        </DataTemplate>
 | 
					        </DataTemplate>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <DataTemplate x:Key="GemTemplate">
 | 
				
			||||||
 | 
					            <StackPanel Orientation="Horizontal">
 | 
				
			||||||
 | 
					                <TextBlock Text="{Binding Name}"/>
 | 
				
			||||||
 | 
					                <TextBlock Text="{Binding Gkz, StringFormat='{} ({0:00000})'}"/>
 | 
				
			||||||
 | 
					            </StackPanel>
 | 
				
			||||||
 | 
					        </DataTemplate>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <DataTemplate x:Key="WbKgTemplate">
 | 
				
			||||||
 | 
					            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
 | 
				
			||||||
 | 
					                <TextBlock Width="250">
 | 
				
			||||||
 | 
					                    <TextBlock Text="{Binding Name}"/>
 | 
				
			||||||
 | 
					                    <TextBlock Text="{Binding KgNr, StringFormat='{}({0:00000})'}"/>
 | 
				
			||||||
 | 
					                </TextBlock>
 | 
				
			||||||
 | 
					                <TextBlock Text="{Binding Gem.WbGem.Origin.Name}"/>
 | 
				
			||||||
 | 
					            </StackPanel>
 | 
				
			||||||
 | 
					        </DataTemplate>
 | 
				
			||||||
 | 
					        <DataTemplate x:Key="WbKgGlTemplate">
 | 
				
			||||||
 | 
					            <StackPanel Orientation="Horizontal">
 | 
				
			||||||
 | 
					                <TextBlock Width="220">
 | 
				
			||||||
 | 
					                    <TextBlock Text="{Binding Name}"/>
 | 
				
			||||||
 | 
					                    <TextBlock Text="{Binding KgNr, StringFormat='{}({0:00000})'}"/>
 | 
				
			||||||
 | 
					                </TextBlock>
 | 
				
			||||||
 | 
					                <TextBlock Text="{Binding WbKg.Gl.Name}"/>
 | 
				
			||||||
 | 
					            </StackPanel>
 | 
				
			||||||
 | 
					        </DataTemplate>
 | 
				
			||||||
    </Application.Resources>
 | 
					    </Application.Resources>
 | 
				
			||||||
</Application>
 | 
					</Application>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,10 +13,16 @@ using System.Threading;
 | 
				
			|||||||
using System.Windows.Markup;
 | 
					using System.Windows.Markup;
 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
using Elwig.Helpers.Printing;
 | 
					using Elwig.Helpers.Printing;
 | 
				
			||||||
 | 
					using Elwig.Windows;
 | 
				
			||||||
 | 
					using Elwig.Dialogs;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig {
 | 
					namespace Elwig {
 | 
				
			||||||
    public partial class App : Application {
 | 
					    public partial class App : Application {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected static App CurrentApp;
 | 
				
			||||||
 | 
					        public static int NumWindows => CurrentApp.Windows.Count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static readonly string DataPath = @"C:\ProgramData\Elwig\";
 | 
					        public static readonly string DataPath = @"C:\ProgramData\Elwig\";
 | 
				
			||||||
        public static readonly string ExePath = @"C:\Program Files\Elwig\";
 | 
					        public static readonly string ExePath = @"C:\Program Files\Elwig\";
 | 
				
			||||||
        public static readonly string TempPath = Path.Combine(Path.GetTempPath(), "Elwig");
 | 
					        public static readonly string TempPath = Path.Combine(Path.GetTempPath(), "Elwig");
 | 
				
			||||||
@@ -35,6 +41,7 @@ namespace Elwig {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static int BranchNum { get; private set; }
 | 
				
			||||||
        public static string ZwstId { get; private set; }
 | 
					        public static string ZwstId { get; private set; }
 | 
				
			||||||
        public static string BranchName { get; private set; }
 | 
					        public static string BranchName { get; private set; }
 | 
				
			||||||
        public static int? BranchPlz { get; private set; }
 | 
					        public static int? BranchPlz { get; private set; }
 | 
				
			||||||
@@ -55,6 +62,7 @@ namespace Elwig {
 | 
				
			|||||||
            Directory.CreateDirectory(DataPath);
 | 
					            Directory.CreateDirectory(DataPath);
 | 
				
			||||||
            MainDispatcher = Dispatcher;
 | 
					            MainDispatcher = Dispatcher;
 | 
				
			||||||
            Scales = Array.Empty<IScale>();
 | 
					            Scales = Array.Empty<IScale>();
 | 
				
			||||||
 | 
					            CurrentApp = this;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected override void OnStartup(StartupEventArgs evt) {
 | 
					        protected override void OnStartup(StartupEventArgs evt) {
 | 
				
			||||||
@@ -71,7 +79,7 @@ namespace Elwig {
 | 
				
			|||||||
                new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))
 | 
					                new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Version = typeof(App).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "";
 | 
					            Version = typeof(App).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion.Split("+")[0] ?? "0.0.0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                AppDbUpdater.CheckDb();
 | 
					                AppDbUpdater.CheckDb();
 | 
				
			||||||
@@ -91,6 +99,7 @@ namespace Elwig {
 | 
				
			|||||||
                    Shutdown();
 | 
					                    Shutdown();
 | 
				
			||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                BranchNum = branches.Count;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Utils.RunBackground("HTML Initialization", () => Html.Init(PrintingReadyChanged));
 | 
					            Utils.RunBackground("HTML Initialization", () => Html.Init(PrintingReadyChanged));
 | 
				
			||||||
@@ -166,5 +175,74 @@ namespace Elwig {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task HintContextChange() {
 | 
				
			||||||
 | 
					            foreach (Window w in CurrentApp.Windows) {
 | 
				
			||||||
 | 
					                if (w is not ContextWindow c) continue;
 | 
				
			||||||
 | 
					                await c.HintContextChange();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static T FocusWindow<T>(Func<T> constructor, Predicate<T>? selector = null) where T : Window {
 | 
				
			||||||
 | 
					            foreach (Window w in CurrentApp.Windows) {
 | 
				
			||||||
 | 
					                if (w is T t && (selector == null || selector(t))) {
 | 
				
			||||||
 | 
					                    if (t.WindowState == WindowState.Minimized)
 | 
				
			||||||
 | 
					                        t.WindowState = WindowState.Normal;
 | 
				
			||||||
 | 
					                    t.Activate();
 | 
				
			||||||
 | 
					                    return t;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            var n = constructor();
 | 
				
			||||||
 | 
					            n.Show();
 | 
				
			||||||
 | 
					            return n;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DeliveryAdminWindow FocusReceipt() {
 | 
				
			||||||
 | 
					            return FocusWindow<DeliveryAdminWindow>(() => new(true), w => w.IsReceipt);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DeliveryAdminWindow FocusMemberDeliveries(int mgnr) {
 | 
				
			||||||
 | 
					            return FocusWindow<DeliveryAdminWindow>(() => new(mgnr), w => w.MgNr == mgnr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static AreaComAdminWindow FocusMemberAreaComs(int mgnr) {
 | 
				
			||||||
 | 
					            return FocusWindow<AreaComAdminWindow>(() => new(mgnr), w => w.MgNr == mgnr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static BaseDataWindow FocusBaseData() {
 | 
				
			||||||
 | 
					            return FocusWindow<BaseDataWindow>(() => new());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static BaseDataWindow FocusBaseDataAreaComType() {
 | 
				
			||||||
 | 
					            var w = FocusBaseData();
 | 
				
			||||||
 | 
					            w.AreaCommitmentTypes.Focus();
 | 
				
			||||||
 | 
					            return w;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static SeasonFinishWindow FocusSeasonFinish() {
 | 
				
			||||||
 | 
					            return FocusWindow<SeasonFinishWindow>(() => new());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static DeliveryConfirmationsWindow FocusDeliveryConfirmations(int year) {
 | 
				
			||||||
 | 
					            return FocusWindow<DeliveryConfirmationsWindow>(() => new(year), w => w.Year == year);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static OriginHierarchyWindow FocusOriginHierarchy() {
 | 
				
			||||||
 | 
					            return FocusWindow<OriginHierarchyWindow>(() => new());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static OriginHierarchyWindow FocusOriginHierarchyKg(int kgnr) {
 | 
				
			||||||
 | 
					            var w = FocusOriginHierarchy();
 | 
				
			||||||
 | 
					            w.FocusKgNr(kgnr);
 | 
				
			||||||
 | 
					            return w;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static PaymentVariantsWindow FocusPaymentVariantsWindow(int year) {
 | 
				
			||||||
 | 
					            return FocusWindow<PaymentVariantsWindow>(() => new(year), w => w.Year == year);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static ChartWindow FocusChartWindow(int year, int avnr) {
 | 
				
			||||||
 | 
					            return FocusWindow<ChartWindow>(() => new(year, avnr), w => w.Year == year && w.AvNr == avnr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,40 +1,31 @@
 | 
				
			|||||||
using Elwig.Helpers;
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
using Elwig.Models.Entities;
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					 | 
				
			||||||
using System.Linq;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Documents {
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
    public class CreditNote : BusinessDocument {
 | 
					    public class CreditNote : BusinessDocument {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public Credit Credit;
 | 
					        public Credit? Credit;
 | 
				
			||||||
 | 
					        public CreditNoteData Data;
 | 
				
			||||||
        public string? Text;
 | 
					        public string? Text;
 | 
				
			||||||
        public string CurrencySymbol;
 | 
					        public string CurrencySymbol;
 | 
				
			||||||
        public string[] BucketNames;
 | 
					 | 
				
			||||||
        public int Precision;
 | 
					        public int Precision;
 | 
				
			||||||
        public IEnumerable<DeliveryPart> Parts;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public CreditNote(Credit c, AppDbContext ctx) : base($"Traubengutschrift Nr. {c.TgId} – {c.Payment.Variant.Name}", c.Member) {
 | 
					        public CreditNote(AppDbContext ctx, PaymentMember p, CreditNoteData data) :
 | 
				
			||||||
 | 
					            base($"Traubengutschrift {(p.Credit != null ? $"Nr. {p.Credit.Year}/{p.Credit.TgNr}" : p.Member.Name)} – {p.Variant.Name}", p.Member) {
 | 
				
			||||||
            UseBillingAddress = true;
 | 
					            UseBillingAddress = true;
 | 
				
			||||||
            ShowDateAndLocation = true;
 | 
					            ShowDateAndLocation = true;
 | 
				
			||||||
            Credit = c;
 | 
					            Data = data;
 | 
				
			||||||
 | 
					            Credit = p.Credit;
 | 
				
			||||||
            Aside = Aside.Replace("</table>", "") +
 | 
					            Aside = Aside.Replace("</table>", "") +
 | 
				
			||||||
                $"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" +
 | 
					                $"<thead><tr><th colspan='2'>Gutschrift</th></tr></thead><tbody>" +
 | 
				
			||||||
                $"<tr><th>TG-Nr.</th><td>{c.TgId}</td></tr>" +
 | 
					                $"<tr><th>TG-Nr.</th><td>{(p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr}" : "-")}</td></tr>" +
 | 
				
			||||||
                $"<tr><th>Überw. am</th><td>{c.Payment.Variant.TransferDate:dd.MM.yyyy}</td></tr>" +
 | 
					                $"<tr><th>Überw. am</th><td>{p.Variant.TransferDate:dd.MM.yyyy}</td></tr>" +
 | 
				
			||||||
                $"<tr><th>Datum/Zeit</th><td>{c.ModifiedTimestamp:dd.MM.yyyy} / {c.ModifiedTimestamp:HH:mm}</td></tr>" +
 | 
					                $"<tr><th>Datum/Zeit</th><td>{p.Credit?.ModifiedTimestamp:dd.MM.yyyy} / {p.Credit?.ModifiedTimestamp:HH:mm}</td></tr>" +
 | 
				
			||||||
                $"</tbody></table>";
 | 
					                $"</tbody></table>";
 | 
				
			||||||
            Text = App.Client.TextDeliveryNote;
 | 
					            Text = App.Client.TextDeliveryNote;
 | 
				
			||||||
            DocumentId = $"Tr.-Gutschr. {c.TgId}";
 | 
					            DocumentId = $"Tr.-Gutschr. " + (p.Credit != null ? $"{p.Credit.Year}/{p.Credit.TgNr}" : p.MgNr);
 | 
				
			||||||
            CurrencySymbol = c.Payment.Variant.Season.Currency.Symbol ?? c.Payment.Variant.Season.Currency.Code;
 | 
					            CurrencySymbol = p.Variant.Season.Currency.Symbol ?? p.Variant.Season.Currency.Code;
 | 
				
			||||||
            BucketNames = new string[0]; // FIXME
 | 
					            Precision = p.Variant.Season.Precision;
 | 
				
			||||||
            Precision = c.Payment.Variant.Season.Precision;
 | 
					 | 
				
			||||||
            Parts = ctx.DeliveryParts.FromSql($"""
 | 
					 | 
				
			||||||
                SELECT p.*
 | 
					 | 
				
			||||||
                FROM v_delivery v
 | 
					 | 
				
			||||||
                JOIN delivery_part p ON (p.year, p.did, p.dpnr) = (v.year, v.did, v.dpnr)
 | 
					 | 
				
			||||||
                WHERE (v.year, v.mgnr) = ({c.Year}, {c.Member.MgNr})
 | 
					 | 
				
			||||||
                ORDER BY sortid, attribute_prio DESC, COALESCE(attrid, '~'), kmw DESC, date, time, dpnr
 | 
					 | 
				
			||||||
                """).ToList();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }}
 | 
					    }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,24 +3,22 @@
 | 
				
			|||||||
@model Elwig.Documents.CreditNote
 | 
					@model Elwig.Documents.CreditNote
 | 
				
			||||||
@{ Layout = "BusinessDocument"; }
 | 
					@{ Layout = "BusinessDocument"; }
 | 
				
			||||||
<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\CreditNote.css"/>
 | 
					<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\CreditNote.css"/>
 | 
				
			||||||
@{
 | 
					 | 
				
			||||||
    var bucketNum = Model.BucketNames.Length;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
<main>
 | 
					<main>
 | 
				
			||||||
    <h1>@Model.Title</h1>
 | 
					    <h1>@Model.Title</h1>
 | 
				
			||||||
    <table class="credit">
 | 
					    <table class="credit">
 | 
				
			||||||
        <colgroup>
 | 
					        <colgroup>
 | 
				
			||||||
            <col style="width: 24mm;"/>
 | 
					            <col style="width: 25mm;"/>
 | 
				
			||||||
            <col style="width: 6mm;"/>
 | 
					            <col style="width: 5mm;"/>
 | 
				
			||||||
            <col style="width: 31mm;"/>
 | 
					            <col style="width: 20mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 18mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
            <col style="width: 15mm;"/>
 | 
					            <col style="width: 15mm;"/>
 | 
				
			||||||
            <col style="width: 8mm;"/>
 | 
					 | 
				
			||||||
            <col style="width: 10mm;"/>
 | 
					 | 
				
			||||||
            <col style="width: 12mm;"/>
 | 
					 | 
				
			||||||
            <col style="width: 10mm;"/>
 | 
					 | 
				
			||||||
            <col style="width: 12mm;"/>
 | 
					            <col style="width: 12mm;"/>
 | 
				
			||||||
            <col style="width: 15mm;"/>
 | 
					            <col style="width: 15mm;"/>
 | 
				
			||||||
            <col style="width: 17mm;"/>
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 10mm;"/>
 | 
				
			||||||
 | 
					            <col style="width: 15mm;"/>
 | 
				
			||||||
        </colgroup>
 | 
					        </colgroup>
 | 
				
			||||||
        <thead>
 | 
					        <thead>
 | 
				
			||||||
            <tr>
 | 
					            <tr>
 | 
				
			||||||
@@ -29,58 +27,64 @@
 | 
				
			|||||||
                <th rowspan="3" style="text-align: left;">Sorte</th>
 | 
					                <th rowspan="3" style="text-align: left;">Sorte</th>
 | 
				
			||||||
                <th rowspan="3" style="text-align: left;">Attribut</th>
 | 
					                <th rowspan="3" style="text-align: left;">Attribut</th>
 | 
				
			||||||
                <th rowspan="2" colspan="2">Gradation</th>
 | 
					                <th rowspan="2" colspan="2">Gradation</th>
 | 
				
			||||||
 | 
					                <th rowspan="2" colspan="2">Flächenbindung</th>
 | 
				
			||||||
 | 
					                <th rowspan="2">Preis</th>
 | 
				
			||||||
                <th colspan="2">Zu-/Abschläge</th>
 | 
					                <th colspan="2">Zu-/Abschläge</th>
 | 
				
			||||||
                <th colspan="2">@Raw(string.Join("<br/>", Model.BucketNames))</th>
 | 
					 | 
				
			||||||
                <th rowspan="2">Betrag</th>
 | 
					                <th rowspan="2">Betrag</th>
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
            <tr>
 | 
					            <tr>
 | 
				
			||||||
                <th>Abs.</th>
 | 
					 | 
				
			||||||
                <th>Rel.</th>
 | 
					                <th>Rel.</th>
 | 
				
			||||||
                <th>Gewicht</th>
 | 
					                <th>Abs.</th>
 | 
				
			||||||
                <th>Preis</th>
 | 
					 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
            <tr>
 | 
					            <tr>
 | 
				
			||||||
                <th>[°Oe]</th>
 | 
					                <th>[°Oe]</th>
 | 
				
			||||||
                <th>[°KMW]</th>
 | 
					                <th>[°KMW]</th>
 | 
				
			||||||
 | 
					                <th colspan="2">[kg]</th>
 | 
				
			||||||
                <th>[@Model.CurrencySymbol/kg]</th>
 | 
					                <th>[@Model.CurrencySymbol/kg]</th>
 | 
				
			||||||
                <th>[%]</th>
 | 
					                <th>[%]</th>
 | 
				
			||||||
                <th>[kg]</th>
 | 
					 | 
				
			||||||
                <th>[@Model.CurrencySymbol/kg]</th>
 | 
					                <th>[@Model.CurrencySymbol/kg]</th>
 | 
				
			||||||
                <th>[@Model.CurrencySymbol]</th>
 | 
					                <th>[@Model.CurrencySymbol]</th>
 | 
				
			||||||
            </tr>
 | 
					            </tr>
 | 
				
			||||||
        </thead>
 | 
					        </thead>
 | 
				
			||||||
        <tbody>
 | 
					        <tbody>
 | 
				
			||||||
            @{
 | 
					            @foreach (var p in Model.Data.Rows) {
 | 
				
			||||||
                string FormatRow(int? weight, decimal? amount) {
 | 
					                var rows = Math.Max(p.Buckets.Length, p.Modifiers.Length + 1);
 | 
				
			||||||
                    var w = weight == null || weight == 0 ? "-" : $"{weight:N0}";
 | 
					                var first = true;
 | 
				
			||||||
                    return $"<td class='weight'>{w}</td><td class='amount'>{amount?.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision)))}</td>";
 | 
					                //var pmt = p.Payment;
 | 
				
			||||||
                }
 | 
					                var abs = 0; // pmt?.ModAbs == null || pmt?.ModAbs == 0 ? "-" : pmt?.ModAbs.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision)));
 | 
				
			||||||
                string? last = null;
 | 
					                var rel = 0; // pmt?.ModRel == null || pmt?.ModRel == 0 ? "-" : $"{pmt?.ModRel * 100:0.00##}";
 | 
				
			||||||
            }
 | 
					                @for (int i = 0; i < rows; i++) {
 | 
				
			||||||
            @foreach (var part in Model.Parts) {
 | 
					                    <tr class="@(first ? "first" : "") @(rows > i + 1 ? "trailing" : "")">
 | 
				
			||||||
                var pmt = part.Payment;
 | 
					                        @if (first) {
 | 
				
			||||||
                var abs = pmt?.ModAbs == null || pmt?.ModAbs == 0 ? "-" : pmt?.ModAbs.ToString("0." + string.Concat(Enumerable.Repeat('0', Model.Precision)));
 | 
					                            <td rowspan="@rows" class="lsnr">@p.LsNr</td>
 | 
				
			||||||
                var rel = pmt?.ModRel == null || pmt?.ModRel == 0 ? "-" : $"{pmt?.ModRel * 100:0.00##}";
 | 
					                            <td rowspan="@rows" class="dpnr">@p.DPNr</td>
 | 
				
			||||||
                <tr class="first @(bucketNum <= 1 ? "last" : "") @(last != null && last != part.SortId ? "new" : "")">
 | 
					                            <td class="variant small">@p.Variant</td>
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="lsnr">@part.Delivery.LsNr</td>
 | 
					                            <td class="attribute small">@p.Attribute</td>
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="dpnr">@part.DPNr</td>
 | 
					                            <td rowspan="@rows" class="oe">@($"{p.Gradation.Oe:N0}")</td>
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="variant">@part.Variant.Name</td>
 | 
					                            <td rowspan="@rows" class="kmw">@($"{p.Gradation.Kmw:N1}")</td>
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="attribute">@part.Attribute?.Name</td>
 | 
					                        }
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="oe">@($"{part.Oe:N0}")</td>
 | 
					                        @if (i > 0 && i <= p.Modifiers.Length) {
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="kmw">@($"{part.Kmw:N1}")</td>
 | 
					                            <td colspan="2" class="mod">@(p.Modifiers[i - 1])</td>
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="abs">@abs</td>
 | 
					                        } else if (i > 0) {
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="rel">@rel</td>
 | 
					                            <td colspan="2"></td>
 | 
				
			||||||
                    <!--FIXME price-->
 | 
					                        }
 | 
				
			||||||
                    @Raw(FormatRow(pmt?.DeliveryPart.Buckets?.ElementAtOrDefault(0)?.Value, 0))
 | 
					                        @if (i < p.Buckets.Length) {
 | 
				
			||||||
                    <td rowspan="@bucketNum" class="amount sum">@($"{pmt?.Amount:N2}")</td>
 | 
					                            var bucket = p.Buckets[i];
 | 
				
			||||||
                </tr>
 | 
					                            <td class="geb small">@bucket.Name:</td>
 | 
				
			||||||
                @for (int i = 1; i < bucketNum; i++) {
 | 
					                            <td class="weight">@($"{bucket.Value:N0}")</td>
 | 
				
			||||||
                    <tr class="@(i == bucketNum - 1 ? "last" : "")">
 | 
					                            <td class="price">@($"{bucket.Price:N4}")</td>
 | 
				
			||||||
                        <!--FIXME price-->
 | 
					                        } else {
 | 
				
			||||||
                        @Raw(FormatRow(pmt?.DeliveryPart.Buckets?.ElementAtOrDefault(i)?.Value, 0))
 | 
					                            <td colspan="3"></td>
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                        @if (first) {
 | 
				
			||||||
 | 
					                            <td rowspan="@rows" class="rel">@rel</td>
 | 
				
			||||||
 | 
					                            <td rowspan="@rows" class="abs">@abs</td>
 | 
				
			||||||
 | 
					                            <!-- FIXME rel/abs mods -->
 | 
				
			||||||
 | 
					                            <td rowspan="@rows" class="amount">@($"{p.Buckets.Sum(b => b.Amount):N2}")</td>
 | 
				
			||||||
 | 
					                            first = false;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                last = part.SortId;
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
    </table>
 | 
					    </table>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,8 @@ table.credit .dpnr {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
table.credit .amount,
 | 
					table.credit .amount,
 | 
				
			||||||
table.credit .weight {
 | 
					table.credit .weight,
 | 
				
			||||||
 | 
					table.credit .price {
 | 
				
			||||||
    text-align: right;
 | 
					    text-align: right;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,3 +63,7 @@ table.credit tbody tr.last td {
 | 
				
			|||||||
table.credit tbody tr.new {
 | 
					table.credit tbody tr.new {
 | 
				
			||||||
    border-top: 0.5pt solid black;
 | 
					    border-top: 0.5pt solid black;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.credit .small {
 | 
				
			||||||
 | 
					    font-size: 8pt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -79,8 +79,8 @@
 | 
				
			|||||||
                            first = false;
 | 
					                            first = false;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    </tr>
 | 
					                    </tr>
 | 
				
			||||||
                    lastVariant = p.Variant;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                lastVariant = p.Variant;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            <tr class="sum">
 | 
					            <tr class="sum">
 | 
				
			||||||
                <td colspan="8">Gesamt:</td>
 | 
					                <td colspan="8">Gesamt:</td>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -67,6 +67,8 @@ namespace Elwig.Documents {
 | 
				
			|||||||
                name = "Letterhead";
 | 
					                name = "Letterhead";
 | 
				
			||||||
            } else if (this is DeliveryConfirmation) {
 | 
					            } else if (this is DeliveryConfirmation) {
 | 
				
			||||||
                name = "DeliveryConfirmation";
 | 
					                name = "DeliveryConfirmation";
 | 
				
			||||||
 | 
					            } else if (this is MemberDataSheet) {
 | 
				
			||||||
 | 
					                name = "MemberDataSheet";
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                throw new InvalidOperationException("Invalid document object");
 | 
					                throw new InvalidOperationException("Invalid document object");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								Elwig/Documents/MemberDataSheet.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Elwig/Documents/MemberDataSheet.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Documents {
 | 
				
			||||||
 | 
					    public class MemberDataSheet : BusinessDocument {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public Season Season;
 | 
				
			||||||
 | 
					        public int Year = Utils.CurrentYear;
 | 
				
			||||||
 | 
					        public Dictionary<string, (string, int, int, int, int)> MemberBuckets;
 | 
				
			||||||
 | 
					        public Dictionary<string, int> BucketAreas;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public MemberDataSheet(Member m, AppDbContext ctx) : base($"Stammdatenblatt {m.AdministrativeName}", m) {
 | 
				
			||||||
 | 
					            DocumentId = $"Stammdatenblatt {m.MgNr}";
 | 
				
			||||||
 | 
					            Season = ctx.Seasons.Find(Year) ?? throw new ArgumentException("invalid season");
 | 
				
			||||||
 | 
					            MemberBuckets = ctx.GetMemberBuckets(Year, m.MgNr).GetAwaiter().GetResult();
 | 
				
			||||||
 | 
					            BucketAreas = ctx.GetMemberBucketAreas(Year, m.MgNr).GetAwaiter().GetResult();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										324
									
								
								Elwig/Documents/MemberDataSheet.cshtml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										324
									
								
								Elwig/Documents/MemberDataSheet.cshtml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,324 @@
 | 
				
			|||||||
 | 
					@using RazorLight
 | 
				
			||||||
 | 
					@inherits TemplatePage<Elwig.Documents.MemberDataSheet>
 | 
				
			||||||
 | 
					@model Elwig.Documents.MemberDataSheet
 | 
				
			||||||
 | 
					@{
 | 
				
			||||||
 | 
					    Layout = "BusinessDocument";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					<link rel="stylesheet" href="file:///@Raw(Model.DataPath)\resources\MemberDataSheet.css" />
 | 
				
			||||||
 | 
					<main>
 | 
				
			||||||
 | 
					    <h1>@Model.Title</h1>
 | 
				
			||||||
 | 
					    <table class="member">
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Persönliche Daten</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Mitglieds-Nr.</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.MgNr</td>
 | 
				
			||||||
 | 
					                <th>Vorgänger MgNr.</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.PredecessorMgNr</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Titel (vorangestellt)</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.Prefix</td>
 | 
				
			||||||
 | 
					                <th>Titel (nachgestellt)</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.Suffix</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Vorname</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.GivenName</td>
 | 
				
			||||||
 | 
					                <th>Nachname</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.FamilyName</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Weitere Vornamen</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.MiddleName</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Geburtsjahr/-tag</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@(string.Join('.', Model.Member.Birthday?.Split('-')?.Reverse()??Array.Empty<string>()))</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Anschrift</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Adresse</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.Address</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>PLZ/Ort</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.PostalDest.AtPlz?.Plz @Model.Member.PostalDest.AtPlz?.Dest (@Model.Member.PostalDest.AtPlz?.Ort.Name)</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Rechnungsadresse</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Name</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.BillingAddress?.Name</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Adresse</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.BillingAddress?.Address</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>PLZ/Ort</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.BillingAddress?.PostalDest.AtPlz?.Plz @Model.Member.BillingAddress?.PostalDest.AtPlz?.Dest @((Model.Member.BillingAddress != null && Model.Member.BillingAddress.PostalDest.AtPlz != null) ? "(" + Model.Member.BillingAddress?.PostalDest.AtPlz?.Ort.Name + ")" : "")</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Kontaktdaten</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            @foreach (var e in Model.Member.EmailAddresses) {
 | 
				
			||||||
 | 
					                var emailNumber = Model.Member.EmailAddresses.Count > 1 ? 1 : 0;
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th>E-Mail-Adresse @(emailNumber != 0 ? $"({emailNumber})" : "")</th>
 | 
				
			||||||
 | 
					                    <td colspan="3">@e.Address</td>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					                emailNumber++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            @foreach (var k in Model.Member.TelephoneNumbers) {
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    @if (k.Type.Equals("landline")) {
 | 
				
			||||||
 | 
					                        <th>Tel.-Nr. (Festnetz)</th>
 | 
				
			||||||
 | 
					                    } else if (k.Type.Equals("mobile")) {
 | 
				
			||||||
 | 
					                        <th>Tel.-Nr. (mobil)</th>
 | 
				
			||||||
 | 
					                    } else if (k.Type.Equals("fax")) {
 | 
				
			||||||
 | 
					                        <th>Fax-Nr.</th>
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    <td colspan="3">@k.Number</td>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Bankverbindung</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>IBAN</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@(Model.Member.Iban != null ? Elwig.Helpers.Utils.FormatIban(Model.Member.Iban) : "")</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>BIC</th>
 | 
				
			||||||
 | 
					                <td colspan="3">@Model.Member.Bic</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Betrieb</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>UID</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.UstIdNr</td>
 | 
				
			||||||
 | 
					                <th>Betriebs-Nr.</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.LfbisNr</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Buchführend</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.IsBuchführend ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					                <th>Bio</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.IsOrganic ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <thead>
 | 
				
			||||||
 | 
					            <tr><th colspan="4">Genossenschaft</th></tr>
 | 
				
			||||||
 | 
					        </thead>
 | 
				
			||||||
 | 
					        <tbody>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Eintritt</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.EntryDate</td>
 | 
				
			||||||
 | 
					                <th>Austritt</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.ExitDate</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Aktiv</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.IsActive ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					                <th>Geschäftsanteile</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.BusinessShares</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Volllierferant</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.IsVollLieferant ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					                <th>Funktionär</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.IsFunktionär ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Stamm-Zweigstelle</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.Branch?.Name</td>
 | 
				
			||||||
 | 
					                <th>Stammgemeinde</th>
 | 
				
			||||||
 | 
					                <td>@Model.Member.DefaultKg?.Name</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					            <tr>
 | 
				
			||||||
 | 
					                <th>Kontakt via Post</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.ContactViaPost ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					                <th>Kontakt via E-Mail</th>
 | 
				
			||||||
 | 
					                <td>@(Model.Member.ContactViaEmail ? "Ja" : "Nein")</td>
 | 
				
			||||||
 | 
					            </tr>
 | 
				
			||||||
 | 
					        </tbody>
 | 
				
			||||||
 | 
					    </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @{
 | 
				
			||||||
 | 
					        var areaComs = Model.Member.ActiveAreaCommitments.GroupBy(a => a.AreaComType).Select(group => new {
 | 
				
			||||||
 | 
					            AreaComType = group.Key,
 | 
				
			||||||
 | 
					            AreaComs = group.OrderBy(c => c.Kg.AtKg.Name),
 | 
				
			||||||
 | 
					            Size = group.Sum(c => c.Area)
 | 
				
			||||||
 | 
					        }).OrderByDescending(a => a.Size).ToList();
 | 
				
			||||||
 | 
					        var lastContract = "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @if (areaComs.Count != 0) {
 | 
				
			||||||
 | 
					        <h1>Flächenbindungen</h1>
 | 
				
			||||||
 | 
					        <table class="area-commitements">
 | 
				
			||||||
 | 
					            <colgroup>
 | 
				
			||||||
 | 
					                <col style="width: 40mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 30mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 35mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 15mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 25mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 20mm;" />
 | 
				
			||||||
 | 
					            </colgroup>
 | 
				
			||||||
 | 
					            <thead>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th rowspan="2" style="text-align: left;">Katastralgemeinde</th>
 | 
				
			||||||
 | 
					                    <th rowspan="2" style="text-align: left;">Ried</th>
 | 
				
			||||||
 | 
					                    <th rowspan="2" style="text-align: left;">Parzelle(n)</th>
 | 
				
			||||||
 | 
					                    <th>Fläche</th>
 | 
				
			||||||
 | 
					                    <th rowspan="2" style="text-align: center;">Bewirt.</th>
 | 
				
			||||||
 | 
					                    <th rowspan="2" style="text-align: center;">Laufzeit</th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th>[m²]</th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            </thead>
 | 
				
			||||||
 | 
					            <tbody>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                @foreach (var contractType in areaComs) {
 | 
				
			||||||
 | 
					                    <tr class="contract-type @(contractType.AreaComType.DisplayName != lastContract && lastContract != "" ? "new" : "")">
 | 
				
			||||||
 | 
					                        <th colspan="3" style="text-align: left">
 | 
				
			||||||
 | 
					                            @($"{contractType.AreaComType.WineVar.Name} {(contractType.AreaComType.WineAttr != null ? "(" + contractType.AreaComType.WineAttr + ")" : "")}")
 | 
				
			||||||
 | 
					                        </th>
 | 
				
			||||||
 | 
					                        <th style="text-align: right">@($"{contractType.Size:N0}")</th>
 | 
				
			||||||
 | 
					                        <th colspan="2"></th>
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                    @foreach (var areaCom in contractType.AreaComs) {
 | 
				
			||||||
 | 
					                        <tr class="area-commitment">
 | 
				
			||||||
 | 
					                            <td>@areaCom.Kg.AtKg.Name <span style="font-size: 8pt;">(@areaCom.Kg.AtKg.KgNr)</span></td>
 | 
				
			||||||
 | 
					                            <td>@areaCom.Rd?.Name</td>
 | 
				
			||||||
 | 
					                            <td>@areaCom.GstNr.Replace(",", ", ")</td>
 | 
				
			||||||
 | 
					                            <td style="text-align: right;">@($"{areaCom.Area:N0}")</td>
 | 
				
			||||||
 | 
					                            <td style="text-align: center;">@areaCom.WineCult.Name</td>
 | 
				
			||||||
 | 
					                            <td style="text-align: center;">Ab @areaCom.YearFrom</td>
 | 
				
			||||||
 | 
					                        </tr>
 | 
				
			||||||
 | 
					                        lastContract = contractType.AreaComType.DisplayName;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <tr class="new">
 | 
				
			||||||
 | 
					                    <th colspan="3" style="text-align: left">Gesamt</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: right">@($"{Model.Member.ActiveAreaCommitments.Select(a => a.Area).Sum():N0}")</th>
 | 
				
			||||||
 | 
					                    <th colspan="2"></th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </tbody>
 | 
				
			||||||
 | 
					        </table>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <table class="delivery-confirmation-stats">
 | 
				
			||||||
 | 
					            <colgroup>
 | 
				
			||||||
 | 
					                <col style="width: 102mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 21mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 21mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 21mm;" />
 | 
				
			||||||
 | 
					            </colgroup>
 | 
				
			||||||
 | 
					            <thead>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th rowspan="2"></th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">Fläche</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">Lieferpflicht</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">Lieferrecht</th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">[m²]</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">[kg]</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">[kg]</th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            </thead>
 | 
				
			||||||
 | 
					            <tbody>
 | 
				
			||||||
 | 
					                @{
 | 
				
			||||||
 | 
					                    string FormatRow(int mode, int area, int obligation, int right) {
 | 
				
			||||||
 | 
					                        return $"<td>{(mode == 0 || mode == 1 ? "" : area == 0 ? "-" : $"{area:N0}")}</td>" +
 | 
				
			||||||
 | 
					                        $"<td>{(mode == 1 ? "" : obligation == 0 ? "-" : $"{obligation:N0}")}</td>" +
 | 
				
			||||||
 | 
					                        $"<td>{(mode == 1 ? "" : right == 0 ? "-" : $"{right:N0}")}</td>";
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    var mBuckets = Model.MemberBuckets.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0 || b.Value.Item4 > 0).ToList();
 | 
				
			||||||
 | 
					                    var fbVars = mBuckets.Where(b => b.Value.Item2 > 0 || b.Value.Item3 > 0).Select(b => b.Key.Replace("_", "")).Order().ToArray();
 | 
				
			||||||
 | 
					                    var fbs = mBuckets.Where(b => fbVars.Contains(b.Key) && b.Key.Length == 2).OrderBy(b => b.Value.Item1);
 | 
				
			||||||
 | 
					                    var vtr = mBuckets.Where(b => fbVars.Contains(b.Key) && b.Key.Length > 2).OrderBy(b => b.Value.Item1);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th>Laut gezeichneten GA</th>
 | 
				
			||||||
 | 
					                    @Raw(FormatRow(
 | 
				
			||||||
 | 
					                        0,
 | 
				
			||||||
 | 
					                        0,
 | 
				
			||||||
 | 
					                        Model.Member.BusinessShares * Model.Season.MinKgPerBusinessShare,
 | 
				
			||||||
 | 
					                        Model.Member.BusinessShares * Model.Season.MaxKgPerBusinessShare
 | 
				
			||||||
 | 
					                        ))
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					                @if (fbs.Any()) {
 | 
				
			||||||
 | 
					                    <tr class="subheading"><th colspan="8">Flächenbindungen:</th></tr>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @foreach (var (id, (name, right, obligation, _, _)) in fbs) {
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
					                        <th>@name</th>
 | 
				
			||||||
 | 
					                        @Raw(FormatRow(2, Model.BucketAreas[id], obligation, right))
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @if (vtr.Any()) {
 | 
				
			||||||
 | 
					                    <tr class="subheading"><th colspan="8">Verträge:</th></tr>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                @foreach (var (id, (name, right, obligation, _, _)) in vtr) {
 | 
				
			||||||
 | 
					                    <tr>
 | 
				
			||||||
 | 
					                        <th>@name</th>
 | 
				
			||||||
 | 
					                        @Raw(FormatRow(2, Model.BucketAreas[id], obligation, right))
 | 
				
			||||||
 | 
					                    </tr>
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            </tbody>
 | 
				
			||||||
 | 
					        </table>
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        <table class="delivery-confirmation-stats" style="margin-top: 5mm;">
 | 
				
			||||||
 | 
					            <colgroup>
 | 
				
			||||||
 | 
					                <col style="width: 123mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 21mm;" />
 | 
				
			||||||
 | 
					                <col style="width: 21mm;" />
 | 
				
			||||||
 | 
					            </colgroup>
 | 
				
			||||||
 | 
					            <thead>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th rowspan="2"></th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">Lieferpflicht</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">Lieferrecht</th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">[kg]</th>
 | 
				
			||||||
 | 
					                    <th style="text-align: center;">[kg]</th>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            </thead>
 | 
				
			||||||
 | 
					            <tbody>
 | 
				
			||||||
 | 
					                <tr>
 | 
				
			||||||
 | 
					                    <th>Laut gezeichneten GA</th>
 | 
				
			||||||
 | 
					                    <td>@($"{Model.Member.BusinessShares * Model.Season.MinKgPerBusinessShare:N0}")</td>
 | 
				
			||||||
 | 
					                    <td>@($"{Model.Member.BusinessShares * Model.Season.MaxKgPerBusinessShare:N0}")</td>
 | 
				
			||||||
 | 
					                </tr>
 | 
				
			||||||
 | 
					            </tbody>
 | 
				
			||||||
 | 
					        </table>
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
							
								
								
									
										82
									
								
								Elwig/Documents/MemberDataSheet.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								Elwig/Documents/MemberDataSheet.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					table.member {
 | 
				
			||||||
 | 
					    border: 0.5pt solid black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.member, table.area-commitements {
 | 
				
			||||||
 | 
					    font-size: 10pt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.member tbody th {
 | 
				
			||||||
 | 
					    font-weight: normal;
 | 
				
			||||||
 | 
					    font-style: italic;
 | 
				
			||||||
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.member thead,
 | 
				
			||||||
 | 
					table.member tbody {
 | 
				
			||||||
 | 
					    border: 0.5pt solid black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.area-commitements td {
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.area-commitements thead tr th {
 | 
				
			||||||
 | 
					    font-weight: normal;
 | 
				
			||||||
 | 
					    font-style: italic; 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.area-commitements tbody tr.contract-type {
 | 
				
			||||||
 | 
					    margin-bottom: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.area-commitements tbody td {
 | 
				
			||||||
 | 
					    vertical-align: top;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.area-commitements tr.new th {
 | 
				
			||||||
 | 
					    border-top: 0.5pt solid black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats {
 | 
				
			||||||
 | 
					    font-size: 10pt;
 | 
				
			||||||
 | 
					    break-inside: avoid;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats th,
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats td {
 | 
				
			||||||
 | 
					    padding: 0.125mm 0;
 | 
				
			||||||
 | 
					    overflow: hidden;
 | 
				
			||||||
 | 
					    white-space: nowrap;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats tr.subheading th {
 | 
				
			||||||
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats thead th {
 | 
				
			||||||
 | 
					    font-weight: normal;
 | 
				
			||||||
 | 
					    font-style: italic;
 | 
				
			||||||
 | 
					    text-align: right;
 | 
				
			||||||
 | 
					    font-size: 10pt;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats thead th:first-child {
 | 
				
			||||||
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats td {
 | 
				
			||||||
 | 
					    text-align: right;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats tbody th {
 | 
				
			||||||
 | 
					    font-weight: normal;
 | 
				
			||||||
 | 
					    font-style: italic;
 | 
				
			||||||
 | 
					    text-align: left;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					table.delivery-confirmation-stats tr.subheading th {
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    border-top: 0.5pt solid black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
    <UseWPF>true</UseWPF>
 | 
					    <UseWPF>true</UseWPF>
 | 
				
			||||||
    <PreserveCompilationContext>true</PreserveCompilationContext>
 | 
					    <PreserveCompilationContext>true</PreserveCompilationContext>
 | 
				
			||||||
    <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
 | 
					    <ApplicationIcon>Resources\Images\Elwig.ico</ApplicationIcon>
 | 
				
			||||||
    <Version>0.5.0</Version>
 | 
					    <Version>0.5.1</Version>
 | 
				
			||||||
    <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
 | 
					    <SatelliteResourceLanguages>de-AT</SatelliteResourceLanguages>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,8 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
        public DbSet<WineVar> WineVarieties { get; private set; }
 | 
					        public DbSet<WineVar> WineVarieties { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public DbSet<ClientParam> ClientParameters { get; private set; }
 | 
					        public DbSet<ClientParam> ClientParameters { get; private set; }
 | 
				
			||||||
 | 
					        public DbSet<WbGl> WbGls { get; private set; }
 | 
				
			||||||
 | 
					        public DbSet<WbGem> WbGems { get; private set; }
 | 
				
			||||||
        public DbSet<WbKg> WbKgs { get; private set; }
 | 
					        public DbSet<WbKg> WbKgs { get; private set; }
 | 
				
			||||||
        public DbSet<WbRd> WbRde { get; private set; }
 | 
					        public DbSet<WbRd> WbRde { get; private set; }
 | 
				
			||||||
        public DbSet<WineAttr> WineAttributes { get; private set; }
 | 
					        public DbSet<WineAttr> WineAttributes { get; private set; }
 | 
				
			||||||
@@ -49,6 +51,7 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
        public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
 | 
					        public DbSet<OverUnderDeliveryRow> OverUnderDeliveryRows { get; private set; }
 | 
				
			||||||
        public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
 | 
					        public DbSet<AreaComUnderDeliveryRowSingle> AreaComUnderDeliveryRows { get; private set; }
 | 
				
			||||||
        public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; }
 | 
					        public DbSet<MemberDeliveryPerVariantRowSingle> MemberDeliveryPerVariantRows { get; private set; }
 | 
				
			||||||
 | 
					        public DbSet<CreditNoteRowSingle> CreditNoteRows { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly StreamWriter? LogFile = null;
 | 
					        private readonly StreamWriter? LogFile = null;
 | 
				
			||||||
        public static DateTime LastWriteTime => File.GetLastWriteTime(App.Config.DatabaseFile);
 | 
					        public static DateTime LastWriteTime => File.GetLastWriteTime(App.Config.DatabaseFile);
 | 
				
			||||||
@@ -60,6 +63,7 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
        private readonly Dictionary<int, Dictionary<int, Dictionary<string, (int, int)>>> _memberRightsAndObligations = new();
 | 
					        private readonly Dictionary<int, Dictionary<int, Dictionary<string, (int, int)>>> _memberRightsAndObligations = new();
 | 
				
			||||||
        private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = new();
 | 
					        private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberDeliveryBuckets = new();
 | 
				
			||||||
        private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = new();
 | 
					        private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberPaymentBuckets = new();
 | 
				
			||||||
 | 
					        private readonly Dictionary<int, Dictionary<int, Dictionary<string, int>>> _memberBucketAreas = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AppDbContext() {
 | 
					        public AppDbContext() {
 | 
				
			||||||
            if (App.Config.DatabaseLog != null) {
 | 
					            if (App.Config.DatabaseLog != null) {
 | 
				
			||||||
@@ -163,6 +167,13 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            return c + 1;
 | 
					            return c + 1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<int> NextRdNr(int kgnr) {
 | 
				
			||||||
 | 
					            int c = 0;
 | 
				
			||||||
 | 
					            (await WbRde.Where(r => r.KgNr == kgnr).Select(r => r.RdNr).ToListAsync())
 | 
				
			||||||
 | 
					                .ForEach(a => { if (a <= c + 100) c = a; });
 | 
				
			||||||
 | 
					            return c + 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<WineQualLevel> GetWineQualityLevel(double kmw) {
 | 
					        public async Task<WineQualLevel> GetWineQualityLevel(double kmw) {
 | 
				
			||||||
            return await WineQualityLevels
 | 
					            return await WineQualityLevels
 | 
				
			||||||
                .Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw))
 | 
					                .Where(q => !q.IsPredicate && (q.MinKmw == null || q.MinKmw <= kmw))
 | 
				
			||||||
@@ -246,6 +257,28 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            _memberPaymentBuckets[year] = buckets;
 | 
					            _memberPaymentBuckets[year] = buckets;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task FetchMemberBucketAreas(int year, SqliteConnection? cnx = null) {
 | 
				
			||||||
 | 
					            var ownCnx = cnx == null;
 | 
				
			||||||
 | 
					            cnx ??= await ConnectAsync();
 | 
				
			||||||
 | 
					            var buckets = new Dictionary<int, Dictionary<string, int>>();
 | 
				
			||||||
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                cmd.CommandText = $"SELECT mgnr, bucket, area FROM v_area_commitment_bucket_strict WHERE year = {year}";
 | 
				
			||||||
 | 
					                using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
 | 
					                while (await reader.ReadAsync()) {
 | 
				
			||||||
 | 
					                    var mgnr = reader.GetInt32(0);
 | 
				
			||||||
 | 
					                    var bucket = reader.GetString(1);
 | 
				
			||||||
 | 
					                    var v = reader.GetInt32(2);
 | 
				
			||||||
 | 
					                    if (!buckets.ContainsKey(mgnr)) buckets[mgnr] = new();
 | 
				
			||||||
 | 
					                    buckets[mgnr][bucket] = v;
 | 
				
			||||||
 | 
					                    if (bucket.Length > 2) {
 | 
				
			||||||
 | 
					                        buckets[mgnr][bucket[..2]] = buckets[mgnr].GetValueOrDefault(bucket[..2], 0) + v;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (ownCnx) await cnx.DisposeAsync();
 | 
				
			||||||
 | 
					            _memberBucketAreas[year] = buckets;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<Dictionary<string, (int, int)>> GetMemberRightsAndObligations(int year, int mgnr, SqliteConnection? cnx = null) {
 | 
					        public async Task<Dictionary<string, (int, int)>> GetMemberRightsAndObligations(int year, int mgnr, SqliteConnection? cnx = null) {
 | 
				
			||||||
            if (!_memberRightsAndObligations.ContainsKey(year))
 | 
					            if (!_memberRightsAndObligations.ContainsKey(year))
 | 
				
			||||||
                await FetchMemberRightsAndObligations(year, cnx);
 | 
					                await FetchMemberRightsAndObligations(year, cnx);
 | 
				
			||||||
@@ -264,6 +297,12 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            return _memberPaymentBuckets[year].GetValueOrDefault(mgnr, new());
 | 
					            return _memberPaymentBuckets[year].GetValueOrDefault(mgnr, new());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public async Task<Dictionary<string, int>> GetMemberBucketAreas(int year, int mgnr, SqliteConnection? cnx = null) {
 | 
				
			||||||
 | 
					            if (!_memberBucketAreas.ContainsKey(year))
 | 
				
			||||||
 | 
					                await FetchMemberBucketAreas(year, cnx);
 | 
				
			||||||
 | 
					            return _memberBucketAreas[year].GetValueOrDefault(mgnr, new());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task<Dictionary<string, (string, int, int, int, int)>> GetMemberBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
 | 
					        public async Task<Dictionary<string, (string, int, int, int, int)>> GetMemberBuckets(int year, int mgnr, SqliteConnection? cnx = null) {
 | 
				
			||||||
            var ownCnx = cnx == null;
 | 
					            var ownCnx = cnx == null;
 | 
				
			||||||
            cnx ??= await ConnectAsync();
 | 
					            cnx ??= await ConnectAsync();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,16 @@
 | 
				
			|||||||
using Microsoft.Data.Sqlite;
 | 
					using Microsoft.Data.Sqlite;
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Windows;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public static class AppDbUpdater {
 | 
					    public static class AppDbUpdater {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static readonly int RequiredSchemaVersion = 7;
 | 
					        public static readonly int RequiredSchemaVersion = 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static int _versionOffset = 0;
 | 
					        private static int _versionOffset = 0;
 | 
				
			||||||
        private static readonly Action<SqliteConnection>[] _updaters = new[] {
 | 
					        private static readonly Action<SqliteConnection>[] _updaters = new[] {
 | 
				
			||||||
            UpdateDbSchema_1_To_2, UpdateDbSchema_2_To_3, UpdateDbSchema_3_To_4, UpdateDbSchema_4_To_5,
 | 
					            UpdateDbSchema_1_To_2, UpdateDbSchema_2_To_3, UpdateDbSchema_3_To_4, UpdateDbSchema_4_To_5,
 | 
				
			||||||
            UpdateDbSchema_5_To_6, UpdateDBSchema_6_To_7
 | 
					            UpdateDbSchema_5_To_6, UpdateDBSchema_6_To_7, UpdateDbSchema_7_To_8, UpdateDbSchema_8_To_9,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void ExecuteNonQuery(SqliteConnection cnx, string sql) {
 | 
					        private static void ExecuteNonQuery(SqliteConnection cnx, string sql) {
 | 
				
			||||||
@@ -540,5 +541,178 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
                WHERE diff < 0;
 | 
					                WHERE diff < 0;
 | 
				
			||||||
                """);
 | 
					                """);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void UpdateDbSchema_7_To_8(SqliteConnection cnx) {
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT a.gkz, 'WLNO'
 | 
				
			||||||
 | 
					                FROM AT_gem a
 | 
				
			||||||
 | 
					                    LEFT JOIN wb_gem w ON w.gkz = a.gkz
 | 
				
			||||||
 | 
					                WHERE a.gkz / 10000 = 3 AND w.hkid IS NULL;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'SLVL'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 100 IN (617, 622, 623);
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'SLSS'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 100 = 610;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                UPDATE wb_gem
 | 
				
			||||||
 | 
					                SET hkid = 'SLVL'
 | 
				
			||||||
 | 
					                WHERE gkz IN (61007, 61052, 61001, 61055, 61027, 61057, 61008, 61057);
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'SLWS'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 100 IN (603, 616) OR gkz IN (60101, 60663, 60651, 60659, 60664, 60647, 60641, 60639, 60665, 60669, 60618, 60629, 60608, 60670, 60624, 60660, 60656, 60655);
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT g.gkz, 'SLVL'
 | 
				
			||||||
 | 
					                FROM AT_gem g
 | 
				
			||||||
 | 
					                    LEFT JOIN wb_gem w ON w.gkz = g.gkz
 | 
				
			||||||
 | 
					                WHERE g.gkz / 100 = 606 AND w.hkid IS NULL;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT g.gkz, 'SLST'
 | 
				
			||||||
 | 
					                FROM AT_gem g
 | 
				
			||||||
 | 
					                    LEFT JOIN wb_gem w ON w.gkz = g.gkz
 | 
				
			||||||
 | 
					                WHERE g.gkz / 10000 = 6 AND w.hkid IS NULL;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'BLOO'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 10000 = 4;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'BLKA'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 10000 = 2;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'BLSB'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 10000 = 5;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'BLTI'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 10000 = 7;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                INSERT INTO wb_gem
 | 
				
			||||||
 | 
					                SELECT gkz, 'BLVO'
 | 
				
			||||||
 | 
					                FROM AT_gem
 | 
				
			||||||
 | 
					                WHERE gkz / 10000 = 8;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static void UpdateDbSchema_8_To_9(SqliteConnection cnx) {
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TABLE payment_delivery_part_bucket (
 | 
				
			||||||
 | 
					                    year   INTEGER NOT NULL,
 | 
				
			||||||
 | 
					                    did    INTEGER NOT NULL,
 | 
				
			||||||
 | 
					                    dpnr   INTEGER NOT NULL,
 | 
				
			||||||
 | 
					                    bktnr  INTEGER NOT NULL,
 | 
				
			||||||
 | 
					                    avnr   INTEGER NOT NULL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    price  INTEGER NOT NULL,
 | 
				
			||||||
 | 
					                    amount INTEGER NOT NULL,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    CONSTRAINT pk_payment_delivery_part_bucket PRIMARY KEY (year, did, dpnr, bktnr, avnr),
 | 
				
			||||||
 | 
					                    CONSTRAINT fk_payment_delivery_part_bucket_delivery_part_bucket FOREIGN KEY (year, did, dpnr, bktnr) REFERENCES delivery_part_bucket (year, did, dpnr, bktnr)
 | 
				
			||||||
 | 
					                        ON UPDATE CASCADE
 | 
				
			||||||
 | 
					                        ON DELETE CASCADE,
 | 
				
			||||||
 | 
					                    CONSTRAINT fk_payment_delivery_part_bucket_payment_variant FOREIGN KEY (year, avnr) REFERENCES payment_variant (year, avnr)
 | 
				
			||||||
 | 
					                        ON UPDATE CASCADE
 | 
				
			||||||
 | 
					                        ON DELETE CASCADE
 | 
				
			||||||
 | 
					                ) STRICT;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "DROP TRIGGER IF EXISTS t_payment_delivery_part_i");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "DROP TRIGGER IF EXISTS t_payment_delivery_part_u");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "DROP TRIGGER IF EXISTS t_payment_delivery_part_d");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part RENAME COLUMN amount TO net_amount");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE payment_delivery_part ADD COLUMN amount INTEGER NOT NULL GENERATED ALWAYS AS (ROUND(net_amount * (1 + mod_rel) + mod_abs)) VIRTUAL");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TRIGGER t_payment_delivery_part_bucket_i
 | 
				
			||||||
 | 
					                    AFTER INSERT ON payment_delivery_part_bucket FOR EACH ROW
 | 
				
			||||||
 | 
					                BEGIN
 | 
				
			||||||
 | 
					                    INSERT INTO payment_delivery_part (year, did, dpnr, avnr, net_amount)
 | 
				
			||||||
 | 
					                    VALUES (NEW.year, NEW.did, NEW.dpnr, NEW.avnr, NEW.amount)
 | 
				
			||||||
 | 
					                    ON CONFLICT DO UPDATE SET net_amount = net_amount + NEW.amount;
 | 
				
			||||||
 | 
					                END;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TRIGGER t_payment_delivery_part_bucket_u
 | 
				
			||||||
 | 
					                    AFTER UPDATE OF amount ON payment_delivery_part_bucket FOR EACH ROW
 | 
				
			||||||
 | 
					                BEGIN
 | 
				
			||||||
 | 
					                    UPDATE payment_delivery_part
 | 
				
			||||||
 | 
					                    SET net_amount = net_amount - OLD.amount
 | 
				
			||||||
 | 
					                    WHERE (year, did, dpnr, avnr) = (NEW.year, NEW.did, NEW.dpnr, NEW.avnr);
 | 
				
			||||||
 | 
					                    UPDATE payment_delivery_part
 | 
				
			||||||
 | 
					                    SET net_amount = net_amount + NEW.amount
 | 
				
			||||||
 | 
					                    WHERE (year, did, dpnr, avnr) = (NEW.year, NEW.did, NEW.dpnr, NEW.avnr);
 | 
				
			||||||
 | 
					                END;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TRIGGER t_payment_delivery_part_bucket_d
 | 
				
			||||||
 | 
					                    AFTER DELETE ON payment_delivery_part_bucket FOR EACH ROW
 | 
				
			||||||
 | 
					                BEGIN
 | 
				
			||||||
 | 
					                    UPDATE payment_delivery_part
 | 
				
			||||||
 | 
					                    SET net_amount = net_amount - OLD.amount
 | 
				
			||||||
 | 
					                    WHERE (year, did, dpnr, avnr) = (OLD.year, OLD.did, OLD.dpnr, OLD.avnr);
 | 
				
			||||||
 | 
					                END;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE payment_member RENAME COLUMN amount TO net_amount");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE payment_member ADD COLUMN mod_abs INTEGER NOT NULL DEFAULT 0");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE payment_member ADD COLUMN mod_rel REAL NOT NULL DEFAULT 0");
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, "ALTER TABLE payment_member ADD COLUMN amount INTEGER NOT NULL GENERATED ALWAYS AS (ROUND(net_amount * (1 + mod_rel) + mod_rel)) VIRTUAL");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TRIGGER t_payment_delivery_part_i
 | 
				
			||||||
 | 
					                    AFTER INSERT ON payment_delivery_part FOR EACH ROW
 | 
				
			||||||
 | 
					                BEGIN
 | 
				
			||||||
 | 
					                    INSERT INTO payment_member (year, avnr, mgnr, net_amount)
 | 
				
			||||||
 | 
					                    VALUES (NEW.year, NEW.avnr, (SELECT mgnr FROM delivery WHERE (year, did) = (NEW.year, NEW.did)), NEW.amount)
 | 
				
			||||||
 | 
					                    ON CONFLICT DO UPDATE SET net_amount = net_amount + excluded.net_amount;
 | 
				
			||||||
 | 
					                END;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TRIGGER t_payment_delivery_part_u
 | 
				
			||||||
 | 
					                    AFTER UPDATE OF amount ON payment_delivery_part FOR EACH ROW
 | 
				
			||||||
 | 
					                BEGIN
 | 
				
			||||||
 | 
					                    UPDATE payment_member
 | 
				
			||||||
 | 
					                    SET net_amount = net_amount - OLD.amount
 | 
				
			||||||
 | 
					                    WHERE (year, avnr, mgnr) = (NEW.year, NEW.avnr, (SELECT mgnr FROM delivery WHERE (year, did) = (NEW.year, NEW.did)));
 | 
				
			||||||
 | 
					                    UPDATE payment_member
 | 
				
			||||||
 | 
					                    SET net_amount = net_amount + NEW.amount
 | 
				
			||||||
 | 
					                    WHERE (year, avnr, mgnr) = (NEW.year, NEW.avnr, (SELECT mgnr FROM delivery WHERE (year, did) = (NEW.year, NEW.did)));
 | 
				
			||||||
 | 
					                END;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            ExecuteNonQuery(cnx, """
 | 
				
			||||||
 | 
					                CREATE TRIGGER t_payment_delivery_part_d
 | 
				
			||||||
 | 
					                    AFTER DELETE ON payment_delivery_part FOR EACH ROW
 | 
				
			||||||
 | 
					                BEGIN
 | 
				
			||||||
 | 
					                    UPDATE payment_member
 | 
				
			||||||
 | 
					                    SET net_amount = net_amount - OLD.amount
 | 
				
			||||||
 | 
					                    WHERE (year, avnr, mgnr) = (OLD.year, OLD.avnr, (SELECT mgnr FROM delivery WHERE (year, did) = (OLD.year, OLD.did)));
 | 
				
			||||||
 | 
					                END;
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,3 @@
 | 
				
			|||||||
using Microsoft.Data.Sqlite;
 | 
					 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,5 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Text;
 | 
					 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers.Billing {
 | 
					namespace Elwig.Helpers.Billing {
 | 
				
			||||||
@@ -15,6 +13,10 @@ namespace Elwig.Helpers.Billing {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        protected async Task DeleteInDb() {
 | 
					        protected async Task DeleteInDb() {
 | 
				
			||||||
            using var cnx = await AppDbContext.ConnectAsync();
 | 
					            using var cnx = await AppDbContext.ConnectAsync();
 | 
				
			||||||
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                cmd.CommandText = $"DELETE FROM payment_delivery_part_bucket WHERE (year, avnr) = ({Year}, {AvNr})";
 | 
				
			||||||
 | 
					                await cmd.ExecuteNonQueryAsync();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            using (var cmd = cnx.CreateCommand()) {
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
                cmd.CommandText = $"DELETE FROM payment_delivery_part WHERE (year, avnr) = ({Year}, {AvNr})";
 | 
					                cmd.CommandText = $"DELETE FROM payment_delivery_part WHERE (year, avnr) = ({Year}, {AvNr})";
 | 
				
			||||||
                await cmd.ExecuteNonQueryAsync();
 | 
					                await cmd.ExecuteNonQueryAsync();
 | 
				
			||||||
@@ -27,15 +29,41 @@ namespace Elwig.Helpers.Billing {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        public async Task CalculatePrices() {
 | 
					        public async Task CalculatePrices() {
 | 
				
			||||||
            await DeleteInDb();
 | 
					            await DeleteInDb();
 | 
				
			||||||
            var tasks = new List<Task>();
 | 
					            using var cnx = await AppDbContext.ConnectAsync();
 | 
				
			||||||
            foreach (var mgnr in Context.Members.Select(m => m.MgNr)) {
 | 
					
 | 
				
			||||||
                tasks.Add(Task.Run(() => CalculateMemberPrices(mgnr)));
 | 
					            var parts = new List<(int Year, int DId, int DPNr, int BktNr, string SortId, string Discr, int Value, bool MinQuw, double Oe, double Kmw)>();
 | 
				
			||||||
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                cmd.CommandText = $"""
 | 
				
			||||||
 | 
					                    SELECT d.year, d.did, d.dpnr, b.bktnr, d.sortid, b.discr, b.value, d.min_quw, d.oe, d.kmw
 | 
				
			||||||
 | 
					                    FROM delivery_part_bucket b
 | 
				
			||||||
 | 
					                        JOIN v_delivery d ON (d.year, d.did, d.dpnr) = (b.year, b.did, b.dpnr)
 | 
				
			||||||
 | 
					                    WHERE b.year = {Year}
 | 
				
			||||||
 | 
					                    """;
 | 
				
			||||||
 | 
					                using var reader = await cmd.ExecuteReaderAsync();
 | 
				
			||||||
 | 
					                while (await reader.ReadAsync()) {
 | 
				
			||||||
 | 
					                    parts.Add((
 | 
				
			||||||
 | 
					                        reader.GetInt32(0), reader.GetInt32(1), reader.GetInt32(2), reader.GetInt32(3),
 | 
				
			||||||
 | 
					                        reader.GetString(4), reader.GetString(5), reader.GetInt32(6),
 | 
				
			||||||
 | 
					                        reader.GetBoolean(7), reader.GetDouble(8), reader.GetDouble(9)
 | 
				
			||||||
 | 
					                    ));
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            await Task.WhenAll(tasks);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected async Task CalculateMemberPrices(int mgnr) {
 | 
					            var inserts = new List<(int Year, int DId, int DPNr, int BktNr, long Price, long Amount)>();
 | 
				
			||||||
 | 
					            foreach (var part in parts) {
 | 
				
			||||||
 | 
					                var price = !part.MinQuw ? 0.5m : ((part.BktNr == 2 ? 0.8m : (part.BktNr == 1 ? 0.7m : 0.6m)) + ((decimal)(part.Oe - 73) * 0.005m));  // TODO
 | 
				
			||||||
 | 
					                var priceL = Utils.DecToDb(price, 4);
 | 
				
			||||||
 | 
					                var amount = Utils.DecToDb(price * part.Value, 4);
 | 
				
			||||||
 | 
					                inserts.Add((part.Year, part.DId, part.DPNr, part.BktNr, priceL, amount));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            using (var cmd = cnx.CreateCommand()) {
 | 
				
			||||||
 | 
					                cmd.CommandText = $"""
 | 
				
			||||||
 | 
					                    INSERT INTO payment_delivery_part_bucket (year, did, dpnr, bktnr, avnr, price, amount)
 | 
				
			||||||
 | 
					                    VALUES {string.Join(",\n       ", inserts.Select(i => $"({i.Year}, {i.DId}, {i.DPNr}, {i.BktNr}, {AvNr}, {i.Price}, {i.Amount})"))}
 | 
				
			||||||
 | 
					                    """;
 | 
				
			||||||
 | 
					                await cmd.ExecuteNonQueryAsync();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,8 @@ using System.Linq;
 | 
				
			|||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using System.Windows.Controls;
 | 
					using System.Windows.Controls;
 | 
				
			||||||
using System.Windows.Controls.Primitives;
 | 
					using System.Windows.Controls.Primitives;
 | 
				
			||||||
using System.Windows.Media;
 | 
					using Brush = System.Windows.Media.Brush;
 | 
				
			||||||
 | 
					using Brushes = System.Windows.Media.Brushes;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Helpers {
 | 
					namespace Elwig.Helpers {
 | 
				
			||||||
    public class ControlUtils {
 | 
					    public class ControlUtils {
 | 
				
			||||||
@@ -16,7 +17,7 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            First
 | 
					            First
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private static void SetControlBrush(Control input, Brush brush) {
 | 
					        private static void SetControlBorderBrush(Control input, Brush brush) {
 | 
				
			||||||
            if (input is ComboBox cb) {
 | 
					            if (input is ComboBox cb) {
 | 
				
			||||||
                var border = GetComboBoxBorder(cb);
 | 
					                var border = GetComboBoxBorder(cb);
 | 
				
			||||||
                if (border != null) border.BorderBrush = brush;
 | 
					                if (border != null) border.BorderBrush = brush;
 | 
				
			||||||
@@ -26,15 +27,15 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void SetInputNotDefault(Control input) {
 | 
					        public static void SetInputNotDefault(Control input) {
 | 
				
			||||||
            SetControlBrush(input, Brushes.Gold);
 | 
					            SetControlBorderBrush(input, Brushes.Gold);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void SetInputChanged(Control input) {
 | 
					        public static void SetInputChanged(Control input) {
 | 
				
			||||||
            SetControlBrush(input, Brushes.Orange);
 | 
					            SetControlBorderBrush(input, Brushes.Orange);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void SetInputInvalid(Control input) {
 | 
					        public static void SetInputInvalid(Control input) {
 | 
				
			||||||
            SetControlBrush(input, Brushes.Red);
 | 
					            SetControlBorderBrush(input, Brushes.Red);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void ClearInputState(Control input) {
 | 
					        public static void ClearInputState(Control input) {
 | 
				
			||||||
@@ -182,6 +183,15 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            SelectComboBoxItem(cb, getId, getId(item));
 | 
					            SelectComboBoxItem(cb, getId, getId(item));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SelectListBoxItem(ListBox lb, Func<object?, object?> getId, object? id) {
 | 
				
			||||||
 | 
					            lb.SelectedItem = GetItemFromSource(lb.ItemsSource, getId, id);
 | 
				
			||||||
 | 
					            lb.ScrollIntoView(lb.SelectedItem);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static void SelectListBoxItem(ListBox lb, object? item, Func<object?, object?> getId) {
 | 
				
			||||||
 | 
					            SelectListBoxItem(lb, getId, getId(item));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static IEnumerable<object?> GetItemsFromSource(IEnumerable source, Func<object?, object?> getId, IEnumerable<object?> ids) {
 | 
					        public static IEnumerable<object?> GetItemsFromSource(IEnumerable source, Func<object?, object?> getId, IEnumerable<object?> ids) {
 | 
				
			||||||
            if (source == null)
 | 
					            if (source == null)
 | 
				
			||||||
                return Array.Empty<object>();
 | 
					                return Array.Empty<object>();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -93,7 +93,7 @@ namespace Elwig.Helpers.Export {
 | 
				
			|||||||
                """);
 | 
					                """);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (int i = 1; i <= 100; i++) {
 | 
					            for (int i = 1; i <= 100; i++) {
 | 
				
			||||||
                await Content.WriteAsync($"  <style:style style:name=\"colw{i}\" style:family=\"table-column\"><style:table-column-properties style:column-width=\"{i}mm\"/></style:style>\r\n");
 | 
					                await Content.WriteAsync($"  <style:style style:name=\"col{i}mm\" style:family=\"table-column\"><style:table-column-properties style:column-width=\"{i}mm\"/></style:style>\r\n");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await Content.WriteAsync("""
 | 
					            await Content.WriteAsync("""
 | 
				
			||||||
@@ -179,7 +179,7 @@ namespace Elwig.Helpers.Export {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public async Task AddTable<T>(DataTable<T> table) {
 | 
					        public async Task AddTable<T>(DataTable<T> table, bool mergeSubRowCells = true) {
 | 
				
			||||||
            if (Content == null) await AddHeader();
 | 
					            if (Content == null) await AddHeader();
 | 
				
			||||||
            if (Content == null) return;
 | 
					            if (Content == null) return;
 | 
				
			||||||
            var totalSpan = table.ColumnSpans.Sum();
 | 
					            var totalSpan = table.ColumnSpans.Sum();
 | 
				
			||||||
@@ -188,7 +188,7 @@ namespace Elwig.Helpers.Export {
 | 
				
			|||||||
            await Content.WriteAsync($"    <table:table table:name=\"{table.Name}\" table:default-cell-style-name=\"default\">\r\n");
 | 
					            await Content.WriteAsync($"    <table:table table:name=\"{table.Name}\" table:default-cell-style-name=\"default\">\r\n");
 | 
				
			||||||
            foreach (var (s, w) in table.ColumnSpans.Zip(table.ColumnWidths)) {
 | 
					            foreach (var (s, w) in table.ColumnSpans.Zip(table.ColumnWidths)) {
 | 
				
			||||||
                for (int i = 0; i < s; i++) {
 | 
					                for (int i = 0; i < s; i++) {
 | 
				
			||||||
                    await Content.WriteAsync("     <table:table-column" + (w != null ? $" table:style-name=\"colw{w / s}\"" : "") + "/>\r\n");
 | 
					                    await Content.WriteAsync("     <table:table-column" + (w != null ? $" table:style-name=\"col{(int)(w / s)}mm\"" : "") + "/>\r\n");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -217,13 +217,13 @@ namespace Elwig.Helpers.Export {
 | 
				
			|||||||
            await Content.WriteAsync("     </table:table-row>\r\n");
 | 
					            await Content.WriteAsync("     </table:table-row>\r\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var row in table.GetData()) {
 | 
					            foreach (var row in table.GetData()) {
 | 
				
			||||||
                await FormatRow(row, table.ColumnUnits);
 | 
					                await FormatRow(row, table.ColumnUnits, mergeSubRowCells);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            await Content.WriteAsync("    </table:table>\r\n");
 | 
					            await Content.WriteAsync("    </table:table>\r\n");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected async Task FormatRow(IEnumerable<object?> row, IEnumerable<string?[]?> colUnits) {
 | 
					        protected async Task FormatRow(IEnumerable<object?> row, IEnumerable<string?[]?> colUnits, bool mergeSubRowCells) {
 | 
				
			||||||
            if (Content == null) throw new InvalidOperationException();
 | 
					            if (Content == null) throw new InvalidOperationException();
 | 
				
			||||||
            var arrays = row.Where(c => c is Array).Cast<Array>().Select(c => c.Length).ToArray();
 | 
					            var arrays = row.Where(c => c is Array).Cast<Array>().Select(c => c.Length).ToArray();
 | 
				
			||||||
            int rowNum = Math.Max(1, arrays.Length > 0 ? arrays.Max() : 0);
 | 
					            int rowNum = Math.Max(1, arrays.Length > 0 ? arrays.Max() : 0);
 | 
				
			||||||
@@ -232,6 +232,8 @@ namespace Elwig.Helpers.Export {
 | 
				
			|||||||
                foreach (var (data, units) in row.Zip(colUnits)) {
 | 
					                foreach (var (data, units) in row.Zip(colUnits)) {
 | 
				
			||||||
                    if (data is Array a) {
 | 
					                    if (data is Array a) {
 | 
				
			||||||
                        await Content.WriteAsync(i < a.Length ? FormatCell(a.GetValue(i), units: units) : $"      <table:table-cell table:number-columns-repeated=\"{GetSubCols(a.GetType().GetElementType())}\"/>\r\n");
 | 
					                        await Content.WriteAsync(i < a.Length ? FormatCell(a.GetValue(i), units: units) : $"      <table:table-cell table:number-columns-repeated=\"{GetSubCols(a.GetType().GetElementType())}\"/>\r\n");
 | 
				
			||||||
 | 
					                    } else if (!mergeSubRowCells) {
 | 
				
			||||||
 | 
					                        await Content.WriteAsync(FormatCell(data, units: units));
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        await Content.WriteAsync(FormatCell(data, rowSpan: i == 0 ? rowNum : 1, isCovered: i > 0, units: units));
 | 
					                        await Content.WriteAsync(FormatCell(data, rowSpan: i == 0 ? rowNum : 1, isCovered: i > 0, units: units));
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -146,6 +146,10 @@ namespace Elwig.Helpers {
 | 
				
			|||||||
            return CalcCrc16Modbus(Encoding.ASCII.GetBytes(data));
 | 
					            return CalcCrc16Modbus(Encoding.ASCII.GetBytes(data));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static string FormatIban(string iban) {
 | 
				
			||||||
 | 
					            return Regex.Replace(iban, ".{4}", "$0 ");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static void RunBackground(string title, Func<Task> a) {
 | 
					        public static void RunBackground(string title, Func<Task> a) {
 | 
				
			||||||
            Task.Run(async () => {
 | 
					            Task.Run(async () => {
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,8 +19,7 @@ namespace Elwig.Models.Dtos {
 | 
				
			|||||||
            ("Areas", "Fläche", "m²", 16),
 | 
					            ("Areas", "Fläche", "m²", 16),
 | 
				
			||||||
            ("DeliveryObligations", "Lieferpflicht", "kg", 22),
 | 
					            ("DeliveryObligations", "Lieferpflicht", "kg", 22),
 | 
				
			||||||
            ("Weights", "Geliefert", "kg", 22),
 | 
					            ("Weights", "Geliefert", "kg", 22),
 | 
				
			||||||
            ("UnderDeliveries", "Unterliefert", "kg", 22),
 | 
					            ("UnderDeliveries", "Unterliefert", "kg|%", 34),
 | 
				
			||||||
            ("Percents", "Prozent", "%", 16),
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
 | 
					        public AreaComUnderDeliveryData(IEnumerable<AreaComUnderDeliveryRow> rows, int year) :
 | 
				
			||||||
@@ -61,11 +60,8 @@ namespace Elwig.Models.Dtos {
 | 
				
			|||||||
        public int[] Areas;
 | 
					        public int[] Areas;
 | 
				
			||||||
        public int[] DeliveryObligations;
 | 
					        public int[] DeliveryObligations;
 | 
				
			||||||
        public int[] Weights;
 | 
					        public int[] Weights;
 | 
				
			||||||
        public int?[] UnderDeliveries => Weights.Zip(DeliveryObligations)
 | 
					        public (int? Kg, double? Percent)[] UnderDeliveries => Weights.Zip(DeliveryObligations)
 | 
				
			||||||
            .Select(v => v.First < v.Second ? (int?)v.First - v.Second : null)
 | 
					            .Select(v => v.First < v.Second ? ((int?, double?))(v.First - v.Second, v.First * 100.0 / v.Second - 100.0) : (null, null))
 | 
				
			||||||
            .ToArray();
 | 
					 | 
				
			||||||
        public double?[] Percents => Weights.Zip(DeliveryObligations)
 | 
					 | 
				
			||||||
            .Select(v => v.First < v.Second ? (double?)v.First * 100.0 / v.Second - 100.0 : null)
 | 
					 | 
				
			||||||
            .ToArray();
 | 
					            .ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public AreaComUnderDeliveryRow(IEnumerable<AreaComUnderDeliveryRowSingle> rows) {
 | 
					        public AreaComUnderDeliveryRow(IEnumerable<AreaComUnderDeliveryRowSingle> rows) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										140
									
								
								Elwig/Models/Dtos/CreditNoteData.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								Elwig/Models/Dtos/CreditNoteData.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,140 @@
 | 
				
			|||||||
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations.Schema;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Models.Dtos {
 | 
				
			||||||
 | 
					    public class CreditNoteData : DataTable<CreditNoteRow> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static readonly (string, string, string?)[] FieldNames = new[] {
 | 
				
			||||||
 | 
					            ("", "", (string?)null), // TODO
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private readonly int Year;
 | 
				
			||||||
 | 
					        private readonly int? TgNr;
 | 
				
			||||||
 | 
					        private readonly int? AvNr;
 | 
				
			||||||
 | 
					        private readonly int? MgNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private CreditNoteData(IEnumerable<CreditNoteRow> rows, int year, int? tgnr, int? avnr = null, int? mgnr = null) :
 | 
				
			||||||
 | 
					            base($"Traubengutschrift {year}/{tgnr}", rows, FieldNames) {
 | 
				
			||||||
 | 
					            Year = year;
 | 
				
			||||||
 | 
					            TgNr = tgnr;
 | 
				
			||||||
 | 
					            AvNr = avnr;
 | 
				
			||||||
 | 
					            MgNr = mgnr;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static async Task<IDictionary<int, CreditNoteData>> ForPaymentVariant(DbSet<CreditNoteRowSingle> table, int year, int avnr) {
 | 
				
			||||||
 | 
					            return (await FromDbSet(table, year, avnr))
 | 
				
			||||||
 | 
					                .GroupBy(
 | 
				
			||||||
 | 
					                    r => new { r.Year, r.AvNr, r.MgNr, r.TgNr, r.DId, r.DPNr },
 | 
				
			||||||
 | 
					                    (k, g) => new CreditNoteRow(g))
 | 
				
			||||||
 | 
					                .GroupBy(
 | 
				
			||||||
 | 
					                    r => new { r.Year, r.AvNr, r.MgNr, r.TgNr },
 | 
				
			||||||
 | 
					                    (k, g) => new CreditNoteData(g, k.Year, k.TgNr, mgnr: k.MgNr))
 | 
				
			||||||
 | 
					                .ToDictionary(d => d.MgNr ?? 0);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private static async Task<IEnumerable<CreditNoteRowSingle>> FromDbSet(DbSet<CreditNoteRowSingle> table, int? year = null, int? avnr = null, int? mgnr = null) {
 | 
				
			||||||
 | 
					            var y = year?.ToString() ?? "NULL";
 | 
				
			||||||
 | 
					            var v = avnr?.ToString() ?? "NULL";
 | 
				
			||||||
 | 
					            var m = mgnr?.ToString() ?? "NULL";
 | 
				
			||||||
 | 
					            return await table.FromSqlRaw($"""
 | 
				
			||||||
 | 
					                SELECT d.year, c.tgnr, p.avnr, d.mgnr, d.did, d.lsnr, d.dpnr, b.bktnr, d.sortid, b.discr, b.value, p.price, p.amount,
 | 
				
			||||||
 | 
					                       v.name AS variant, a.name AS attribute, q.name AS quality_level, d.oe, d.kmw
 | 
				
			||||||
 | 
					                FROM v_delivery d
 | 
				
			||||||
 | 
					                    JOIN wine_variety v ON d.sortid = v.sortid
 | 
				
			||||||
 | 
					                    LEFT JOIN wine_attribute a ON a.attrid = d.attrid
 | 
				
			||||||
 | 
					                    JOIN wine_quality_level q ON q.qualid = d.qualid
 | 
				
			||||||
 | 
					                    LEFT JOIN delivery_part_bucket b ON (b.year, b.did, b.dpnr) = (d.year, d.did, d.dpnr)
 | 
				
			||||||
 | 
					                    LEFT JOIN payment_delivery_part_bucket p ON (p.year, p.did, p.dpnr, p.bktnr) = (b.year, b.did, b.dpnr, b.bktnr)
 | 
				
			||||||
 | 
					                    LEFT JOIN credit c ON (c.year, c.avnr, c.mgnr) = (d.year, p.avnr, d.mgnr)
 | 
				
			||||||
 | 
					                WHERE b.value > 0 AND (d.year = {y} OR {y} IS NULL) AND (p.avnr = {v} OR {v} IS NULL OR p.avnr IS NULL) AND (d.mgnr = {m} OR {m} IS NULL)
 | 
				
			||||||
 | 
					                ORDER BY d.year, p.avnr, d.mgnr, d.lsnr, d.dpnr
 | 
				
			||||||
 | 
					                """).ToListAsync();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public class CreditNoteRow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int Year;
 | 
				
			||||||
 | 
					        public int? TgNr;
 | 
				
			||||||
 | 
					        public int AvNr;
 | 
				
			||||||
 | 
					        public int MgNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string LsNr;
 | 
				
			||||||
 | 
					        public int DPNr;
 | 
				
			||||||
 | 
					        public string Variant;
 | 
				
			||||||
 | 
					        public string? Attribute;
 | 
				
			||||||
 | 
					        public string[] Modifiers;
 | 
				
			||||||
 | 
					        public string QualityLevel;
 | 
				
			||||||
 | 
					        public (double Oe, double Kmw) Gradation;
 | 
				
			||||||
 | 
					        public (string Name, int Value, decimal? Price, decimal? Amount)[] Buckets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public CreditNoteRow(IEnumerable<CreditNoteRowSingle> rows) {
 | 
				
			||||||
 | 
					            var f = rows.First();
 | 
				
			||||||
 | 
					            Year = f.Year;
 | 
				
			||||||
 | 
					            TgNr = f.TgNr;
 | 
				
			||||||
 | 
					            MgNr = f.MgNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            LsNr = f.LsNr;
 | 
				
			||||||
 | 
					            DPNr = f.DPNr;
 | 
				
			||||||
 | 
					            Variant = f.Variant;
 | 
				
			||||||
 | 
					            Attribute = f.Attribute;
 | 
				
			||||||
 | 
					            Modifiers = Array.Empty<string>();  // TODO
 | 
				
			||||||
 | 
					            QualityLevel = f.QualityLevel;
 | 
				
			||||||
 | 
					            Gradation = (f.Oe, f.Kmw);
 | 
				
			||||||
 | 
					            Buckets = rows
 | 
				
			||||||
 | 
					                .Where(b => b.Value > 0)
 | 
				
			||||||
 | 
					                .OrderByDescending(b => b.BktNr)
 | 
				
			||||||
 | 
					                // FIXME precision
 | 
				
			||||||
 | 
					                .Select(b => (b.Discr == "_" ? "ungeb." : $"geb. {f.SortId}{b.Discr}", b.Value,
 | 
				
			||||||
 | 
					                              b.Price != null ? (decimal?)Utils.DecFromDb((long)b.Price, 4) : null,
 | 
				
			||||||
 | 
					                              b.Amount != null ? (decimal?)Utils.DecFromDb((long)b.Amount, 4) : null))
 | 
				
			||||||
 | 
					                .ToArray();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [Keyless]
 | 
				
			||||||
 | 
					    public class CreditNoteRowSingle {
 | 
				
			||||||
 | 
					        [Column("year")]
 | 
				
			||||||
 | 
					        public int Year { get; set; }
 | 
				
			||||||
 | 
					        [Column("tgnr")]
 | 
				
			||||||
 | 
					        public int? TgNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("avnr")]
 | 
				
			||||||
 | 
					        public int? AvNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("mgnr")]
 | 
				
			||||||
 | 
					        public int MgNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("did")]
 | 
				
			||||||
 | 
					        public int DId { get; set; }
 | 
				
			||||||
 | 
					        [Column("lsnr")]
 | 
				
			||||||
 | 
					        public string LsNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("dpnr")]
 | 
				
			||||||
 | 
					        public int DPNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("bktnr")]
 | 
				
			||||||
 | 
					        public int BktNr { get; set; }
 | 
				
			||||||
 | 
					        [Column("sortid")]
 | 
				
			||||||
 | 
					        public string SortId { get; set; }
 | 
				
			||||||
 | 
					        [Column("discr")]
 | 
				
			||||||
 | 
					        public string Discr { get; set; }
 | 
				
			||||||
 | 
					        [Column("value")]
 | 
				
			||||||
 | 
					        public int Value { get; set; }
 | 
				
			||||||
 | 
					        [Column("price")]
 | 
				
			||||||
 | 
					        public long? Price { get; set; }
 | 
				
			||||||
 | 
					        [Column("amount")]
 | 
				
			||||||
 | 
					        public long? Amount { get; set; }
 | 
				
			||||||
 | 
					        [Column("variant")]
 | 
				
			||||||
 | 
					        public string Variant { get; set; }
 | 
				
			||||||
 | 
					        [Column("attribute")]
 | 
				
			||||||
 | 
					        public string? Attribute { get; set; }
 | 
				
			||||||
 | 
					        [Column("quality_level")]
 | 
				
			||||||
 | 
					        public string QualityLevel { get; set; }
 | 
				
			||||||
 | 
					        [Column("oe")]
 | 
				
			||||||
 | 
					        public double Oe { get; set; }
 | 
				
			||||||
 | 
					        [Column("kmw")]
 | 
				
			||||||
 | 
					        public double Kmw { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -18,8 +18,7 @@ namespace Elwig.Models.Dtos {
 | 
				
			|||||||
            ("DeliveryObligation", "Lieferpflicht", "kg", 22),
 | 
					            ("DeliveryObligation", "Lieferpflicht", "kg", 22),
 | 
				
			||||||
            ("DeliveryRight", "Lieferrecht", "kg", 22),
 | 
					            ("DeliveryRight", "Lieferrecht", "kg", 22),
 | 
				
			||||||
            ("Weight", "Geliefert", "kg", 22),
 | 
					            ("Weight", "Geliefert", "kg", 22),
 | 
				
			||||||
            ("OverUnderDelivery", "Über-/Unterliefert", "kg", 35),
 | 
					            ("OverUnderDelivery", "Über-/Unterliefert", "kg|%", 34),
 | 
				
			||||||
            ("Percent", "Prozent", "%", 16),
 | 
					 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year) :
 | 
					        public OverUnderDeliveryData(IEnumerable<OverUnderDeliveryRow> rows, int year) :
 | 
				
			||||||
@@ -70,12 +69,8 @@ namespace Elwig.Models.Dtos {
 | 
				
			|||||||
        [Column("sum")]
 | 
					        [Column("sum")]
 | 
				
			||||||
        public int Weight { get; set; }
 | 
					        public int Weight { get; set; }
 | 
				
			||||||
        [NotMapped]
 | 
					        [NotMapped]
 | 
				
			||||||
        public int? OverUnderDelivery =>
 | 
					        public (int? Kg, double? Percent) OverUnderDelivery =>
 | 
				
			||||||
            Weight < DeliveryObligation ? Weight - DeliveryObligation :
 | 
					            Weight < DeliveryObligation ? (Weight - DeliveryObligation, Weight * 100.0 / DeliveryObligation - 100.0) :
 | 
				
			||||||
            Weight > DeliveryRight ? Weight - DeliveryRight : null;
 | 
					            Weight > DeliveryRight ? (Weight - DeliveryRight, Weight * 100.0 / DeliveryRight - 100) : (null, null);
 | 
				
			||||||
        [NotMapped]
 | 
					 | 
				
			||||||
        public double? Percent =>
 | 
					 | 
				
			||||||
            Weight < DeliveryObligation ? Weight * 100.0 / DeliveryObligation - 100.0 :
 | 
					 | 
				
			||||||
            Weight > DeliveryRight ? Weight * 100.0 / DeliveryRight - 100 : null;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,6 @@ namespace Elwig.Models.Entities {
 | 
				
			|||||||
        public virtual AT_Gem Gem { get; private set; }
 | 
					        public virtual AT_Gem Gem { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [InverseProperty("AtKg")]
 | 
					        [InverseProperty("AtKg")]
 | 
				
			||||||
        public virtual WbKg WbKg { get; private set; }
 | 
					        public virtual WbKg? WbKg { get; private set; }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -572,5 +572,9 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        protected void UpperCaseInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
					        protected void UpperCaseInput_LostFocus(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            InputLostFocus((TextBox)sender, Validator.CheckUpperCase);
 | 
					            InputLostFocus((TextBox)sender, Validator.CheckUpperCase);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected void AreaComTypeDetailsButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            App.FocusBaseDataAreaComType();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
        xmlns:ctrl="clr-namespace:Elwig.Controls"
 | 
					        xmlns:ctrl="clr-namespace:Elwig.Controls"
 | 
				
			||||||
        mc:Ignorable="d"
 | 
					        mc:Ignorable="d"
 | 
				
			||||||
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
					        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
				
			||||||
        Title="Flächenbindungen - Elwig" Height="500" Width="920" MinWidth="860"
 | 
					        Title="Flächenbindungen - Elwig" Height="500" MinHeight="440" Width="920" MinWidth="860"
 | 
				
			||||||
        Loaded="Window_Loaded">
 | 
					        Loaded="Window_Loaded">
 | 
				
			||||||
    <Window.Resources>
 | 
					    <Window.Resources>
 | 
				
			||||||
        <Style TargetType="Label">
 | 
					        <Style TargetType="Label">
 | 
				
			||||||
@@ -144,7 +144,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
					                    <Label Content="Vertragsart:" Margin="10,70,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
				
			||||||
                    <ComboBox x:Name="AreaComTypeInput" DisplayMemberPath="DisplayName" TextSearch.TextPath="DisplayName"
 | 
					                    <ComboBox x:Name="AreaComTypeInput" DisplayMemberPath="DisplayName" TextSearch.TextPath="DisplayName"
 | 
				
			||||||
                              HorizontalAlignment="Stretch" Margin="0,70,10,0" Grid.Column="1" Grid.ColumnSpan="3"/>
 | 
					                              HorizontalAlignment="Stretch" Margin="0,70,40,10" Grid.Column="1" Grid.ColumnSpan="3"/>
 | 
				
			||||||
 | 
					                    <Button x:Name="AreaComTypeDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
 | 
				
			||||||
 | 
					                            Click="AreaComTypeDetailsButton_Click"
 | 
				
			||||||
 | 
					                            Grid.Column="3" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,70,10,10"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
					                    <Label Content="Bewirt.-Art:" Margin="10,100,0,0" Grid.Column="0" Grid.ColumnSpan="2"/>
 | 
				
			||||||
                    <ComboBox x:Name="WineCultivationInput" DisplayMemberPath="Name" TextSearch.TextPath="Name"
 | 
					                    <ComboBox x:Name="WineCultivationInput" DisplayMemberPath="Name" TextSearch.TextPath="Name"
 | 
				
			||||||
@@ -165,13 +168,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <Label Content="KG:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
					                    <Label Content="KG:" Margin="10,10,0,0" Grid.Column="0"/>
 | 
				
			||||||
                    <ComboBox x:Name="KgInput" ItemTemplate="{StaticResource KgNrTemplate}" TextSearch.TextPath="Name"
 | 
					                    <ComboBox x:Name="KgInput" ItemTemplate="{StaticResource KgNrTemplate}" TextSearch.TextPath="Name"
 | 
				
			||||||
                              HorizontalAlignment="Stretch" Margin="0,10,10,0" Grid.Column="1"
 | 
					                              HorizontalAlignment="Stretch" Margin="0,10,40,10" Grid.Column="1"
 | 
				
			||||||
                              SelectionChanged="KgInput_SelectionChanged"/>
 | 
					                              SelectionChanged="KgInput_SelectionChanged"/>
 | 
				
			||||||
 | 
					                    <Button x:Name="KgDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
 | 
				
			||||||
 | 
					                            Click="KgDetailsButton_Click"
 | 
				
			||||||
 | 
					                            Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,10,10,10"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Ried:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
					                    <Label Content="Ried:" Margin="10,40,0,0" Grid.Column="0"/>
 | 
				
			||||||
                    <ComboBox x:Name="RdInput" DisplayMemberPath="Name" TextSearch.TextPath="Name"
 | 
					                    <ComboBox x:Name="RdInput" DisplayMemberPath="Name" TextSearch.TextPath="Name" IsEditable="True"
 | 
				
			||||||
                              HorizontalAlignment="Stretch" Margin="0,40,10,0" Grid.Column="1"/>
 | 
					                              HorizontalAlignment="Stretch" Margin="0,40,40,10" Grid.Column="1"
 | 
				
			||||||
 | 
					                              SelectionChanged="RdInput_SelectionChanged"/>
 | 
				
			||||||
 | 
					                    <Button x:Name="RdAddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0,0,0,0" IsEnabled="False"
 | 
				
			||||||
 | 
					                            Click="RdAddButton_Click"
 | 
				
			||||||
 | 
					                            Grid.Column="1" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,40,10,10"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Parzelle(n):" Margin="10,70,0,0" Grid.Column="0"/>
 | 
					                    <Label Content="Parzelle(n):" Margin="10,70,0,0" Grid.Column="0"/>
 | 
				
			||||||
                    <TextBox x:Name="GstNrInput" Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Stretch"
 | 
					                    <TextBox x:Name="GstNrInput" Margin="0,70,10,0" Grid.Column="1" HorizontalAlignment="Stretch"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,9 @@ using Xceed.Wpf.Toolkit.Primitives;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Elwig.Windows {
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
    public partial class AreaComAdminWindow : AdministrationWindow {
 | 
					    public partial class AreaComAdminWindow : AdministrationWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public int MgNr => Member.MgNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly Member Member;
 | 
					        private readonly Member Member;
 | 
				
			||||||
        private List<string> TextFilter = new();
 | 
					        private List<string> TextFilter = new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,8 +69,9 @@ namespace Elwig.Windows {
 | 
				
			|||||||
                StatusAreaCommitments.Text = $"Flächenbindungen: {areaComs.Count}";
 | 
					                StatusAreaCommitments.Text = $"Flächenbindungen: {areaComs.Count}";
 | 
				
			||||||
                StatusArea.Text = $"Fläche: {areaComs.Select(a => a.Area).Sum():N0} m²";
 | 
					                StatusArea.Text = $"Fläche: {areaComs.Select(a => a.Area).Sum():N0} m²";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var groups = areaComs.GroupBy(a => a.AreaComType.DisplayName).Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
 | 
					            var groups = areaComs.GroupBy(a => $"{a.AreaComType.SortId}{a.AreaComType.AttrId}").Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
 | 
				
			||||||
            StatusContracts.Text = $"Vertragsarten: {groups.Count} (" + string.Join(", ", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²")) + ")";
 | 
					            StatusContracts.Text = $"Vertragsarten: {groups.Count} (" + string.Join(", ", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²")) + ")";
 | 
				
			||||||
 | 
					            groups = areaComs.GroupBy(a => a.AreaComType.DisplayName).Select(a => (a.Key, a.Sum(b => b.Area))).OrderByDescending(a => a.Item2).ToList();
 | 
				
			||||||
            StatusContracts.ToolTip = $"Vertragsarten: {groups.Count}\n" + string.Join($"\n", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²"));
 | 
					            StatusContracts.ToolTip = $"Vertragsarten: {groups.Count}\n" + string.Join($"\n", groups.Select(g => $"{g.Key}: {g.Item2:N0} m²"));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,8 +79,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            List<string> filterNames = new();
 | 
					            List<string> filterNames = new();
 | 
				
			||||||
            IQueryable<AreaCom> areaComQuery = Context.AreaCommitments.Where(a => a.MgNr == Member.MgNr).OrderBy(a => a.FbNr);
 | 
					            IQueryable<AreaCom> areaComQuery = Context.AreaCommitments.Where(a => a.MgNr == Member.MgNr).OrderBy(a => a.FbNr);
 | 
				
			||||||
            if (ActiveAreaCommitmentInput.IsChecked == true) {
 | 
					            if (ActiveAreaCommitmentInput.IsChecked == true) {
 | 
				
			||||||
                areaComQuery = areaComQuery.Where(a => a.YearTo == null);
 | 
					                areaComQuery = areaComQuery.Where(a => (a.YearFrom <= Utils.CurrentNextSeason) && (a.YearTo == null || a.YearTo >= Utils.CurrentNextSeason));
 | 
				
			||||||
                filterNames.Add("ohne Enddatum");
 | 
					                filterNames.Add("aktiv");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var filterVar = new List<string>();
 | 
					            var filterVar = new List<string>();
 | 
				
			||||||
@@ -165,6 +169,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            FbNrInput.Text = (await Context.NextFbNr()).ToString();
 | 
					            FbNrInput.Text = (await Context.NextFbNr()).ToString();
 | 
				
			||||||
            MgNrInput.Text = Member.MgNr.ToString();
 | 
					            MgNrInput.Text = Member.MgNr.ToString();
 | 
				
			||||||
 | 
					            YearFromInput.Text = DateTime.Now.Year.ToString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SetDefaultValue(FbNrInput);
 | 
					            SetDefaultValue(FbNrInput);
 | 
				
			||||||
            ValidateRequiredInputs();
 | 
					            ValidateRequiredInputs();
 | 
				
			||||||
@@ -231,11 +236,21 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            EntityEntry<AreaCom>? tr = null;
 | 
					            EntityEntry<AreaCom>? tr = null;
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
 | 
					                if (RdInput.SelectedItem is WbRd wbRd) {
 | 
				
			||||||
 | 
					                    a.RdNr = wbRd.RdNr;
 | 
				
			||||||
 | 
					                    var e = Context.Entry(wbRd);
 | 
				
			||||||
 | 
					                    if (e.State == EntityState.Detached) {
 | 
				
			||||||
 | 
					                        await Context.AddAsync(wbRd);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    a.RdNr = null;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if (IsEditing) {
 | 
					                if (IsEditing) {
 | 
				
			||||||
                    tr = Context.Update(a);
 | 
					                    tr = Context.Update(a);
 | 
				
			||||||
                } else if (IsCreating) {
 | 
					                } else if (IsCreating) {
 | 
				
			||||||
                    a.FbNr = newFbNr;
 | 
					                    a.FbNr = newFbNr;
 | 
				
			||||||
                    tr = (await Context.AddAsync(a));
 | 
					                    tr = await Context.AddAsync(a);
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    throw new Exception();
 | 
					                    throw new Exception();
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -387,6 +402,27 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            ComboBox_SelectionChanged(sender, evt);
 | 
					            ComboBox_SelectionChanged(sender, evt);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void KgDetailsButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (KgInput.SelectedItem is AT_Kg kg) {
 | 
				
			||||||
 | 
					                App.FocusOriginHierarchyKg(kg.KgNr);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                App.FocusOriginHierarchy();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void RdInput_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
 | 
				
			||||||
 | 
					            RdAddButton.IsEnabled = RdInput.SelectedIndex == -1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void RdAddButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (KgInput.SelectedItem is not AT_Kg kg) return;
 | 
				
			||||||
 | 
					            string name = RdInput.Text.Trim();
 | 
				
			||||||
 | 
					            if (name.Length == 0) return;
 | 
				
			||||||
 | 
					            var s = RdInput.ItemsSource.Cast<object?>();
 | 
				
			||||||
 | 
					            RdInput.ItemsSource = s.Append(new WbRd() { KgNr = kg.KgNr, Name = name, RdNr = await Context.NextRdNr(kg.KgNr)});
 | 
				
			||||||
 | 
					            RdInput.SelectedIndex = s.Count();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected void InputTextChanged(TextBox input, Func<TextBox, bool, AppDbContext, AreaCom?, ValidationResult> checker) {
 | 
					        protected void InputTextChanged(TextBox input, Func<TextBox, bool, AppDbContext, AreaCom?, ValidationResult> checker) {
 | 
				
			||||||
            InputTextChanged(input, checker(input, SenderIsRequired(input), Context, (AreaCom)AreaCommitmentList.SelectedItem));
 | 
					            InputTextChanged(input, checker(input, SenderIsRequired(input), Context, (AreaCom)AreaCommitmentList.SelectedItem));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -309,7 +309,7 @@
 | 
				
			|||||||
                </Grid>
 | 
					                </Grid>
 | 
				
			||||||
            </TabItem>
 | 
					            </TabItem>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <TabItem Header="Flächenbindungsverträge">
 | 
					            <TabItem Header="Flächenbindungsverträge" x:Name="AreaCommitmentTypes">
 | 
				
			||||||
                <Grid>
 | 
					                <Grid>
 | 
				
			||||||
                    <Grid.ColumnDefinitions>
 | 
					                    <Grid.ColumnDefinitions>
 | 
				
			||||||
                        <ColumnDefinition Width="260"/>
 | 
					                        <ColumnDefinition Width="260"/>
 | 
				
			||||||
@@ -545,6 +545,10 @@
 | 
				
			|||||||
            </TabItem>
 | 
					            </TabItem>
 | 
				
			||||||
        </TabControl>
 | 
					        </TabControl>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Button x:Name="OriginButton" Content="Herkunftshierarchie"
 | 
				
			||||||
 | 
					                HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10,10,10,10" Width="150"
 | 
				
			||||||
 | 
					                Click="OriginButton_Click"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <Button x:Name="EditButton" Content="Bearbeiten"
 | 
					        <Button x:Name="EditButton" Content="Bearbeiten"
 | 
				
			||||||
                HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,10" Width="120"
 | 
					                HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,10" Width="120"
 | 
				
			||||||
                Click="EditButton_Click"/>
 | 
					                Click="EditButton_Click"/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -167,6 +167,10 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            SeasonModifierDeleteButton.IsEnabled = SeasonModifierList.SelectedIndex != -1;
 | 
					            SeasonModifierDeleteButton.IsEnabled = SeasonModifierList.SelectedIndex != -1;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void OriginButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            App.FocusOriginHierarchy();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void EditButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void EditButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            IsEditing = true;
 | 
					            IsEditing = true;
 | 
				
			||||||
            EditButton.Visibility = Visibility.Hidden;
 | 
					            EditButton.Visibility = Visibility.Hidden;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,5 @@
 | 
				
			|||||||
<local:AdministrationWindow x:Class="Elwig.Windows.ChartWindow"
 | 
					<local:AdministrationWindow
 | 
				
			||||||
 | 
					        x:Class="Elwig.Windows.ChartWindow"
 | 
				
			||||||
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
					        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 | 
				
			||||||
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
					        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 | 
				
			||||||
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
					        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,8 +18,8 @@ using ScottPlot.Plottable;
 | 
				
			|||||||
namespace Elwig.Windows {
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
    public partial class ChartWindow : AdministrationWindow {
 | 
					    public partial class ChartWindow : AdministrationWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private readonly int Year = 2021;
 | 
					        public readonly int Year;
 | 
				
			||||||
        private readonly int AvNr = 2;
 | 
					        public readonly int AvNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private ScatterPlot OechslePricePlotScatter;
 | 
					        private ScatterPlot OechslePricePlotScatter;
 | 
				
			||||||
        private MarkerPlot HighlightedPoint;
 | 
					        private MarkerPlot HighlightedPoint;
 | 
				
			||||||
@@ -39,9 +39,12 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private Graph? Graph;
 | 
					        private Graph? Graph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public ChartWindow() {
 | 
					        public ChartWindow(int year, int avnr) {
 | 
				
			||||||
            InitializeComponent();
 | 
					            InitializeComponent();
 | 
				
			||||||
 | 
					            Year = year;
 | 
				
			||||||
 | 
					            AvNr = avnr;
 | 
				
			||||||
 | 
					            var v = Context.PaymentVariants.Find(year, avnr);
 | 
				
			||||||
 | 
					            Title = $"{v?.Name} - Lese {year} - Elwig";
 | 
				
			||||||
            ExemptInputs = new Control[] {
 | 
					            ExemptInputs = new Control[] {
 | 
				
			||||||
                GraphList, OechsleInput, PriceInput, FreeZoomInput, GradationLinesInput, TooltipInput
 | 
					                GraphList, OechsleInput, PriceInput, FreeZoomInput, GradationLinesInput, TooltipInput
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,14 +24,18 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            Loaded += OnLoaded;
 | 
					            Loaded += OnLoaded;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void OnShouldRenewContext(object? sender, EventArgs evt) {
 | 
					        public async Task HintContextChange() {
 | 
				
			||||||
            if (!Context.HasBackendChanged) return;
 | 
					 | 
				
			||||||
            _renewPending = true;
 | 
					            _renewPending = true;
 | 
				
			||||||
            if (LockContext) return;
 | 
					            if (LockContext) return;
 | 
				
			||||||
            await RenewContext();
 | 
					            await RenewContext();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected async void OnLoaded(object sender, RoutedEventArgs evt) {
 | 
					        private async void OnShouldRenewContext(object? sender, EventArgs? evt) {
 | 
				
			||||||
 | 
					            if (!Context.HasBackendChanged) return;
 | 
				
			||||||
 | 
					            await HintContextChange();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected async void OnLoaded(object? sender, RoutedEventArgs? evt) {
 | 
				
			||||||
            await OnRenewContext();
 | 
					            await OnRenewContext();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -417,7 +417,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Weinbaugebiet:" Margin="10,10,0,10" Grid.Column="0"/>
 | 
					                    <Label Content="Weinbaugebiet:" Margin="10,10,0,10" Grid.Column="0"/>
 | 
				
			||||||
                    <ComboBox x:Name="WineOriginInput" Margin="0,10,10,10" Grid.Column="1"
 | 
					                    <ComboBox x:Name="WineOriginInput" Margin="0,10,10,10" Grid.Column="1"
 | 
				
			||||||
                              ItemTemplate="{StaticResource WineOriginTemplate}"/>
 | 
					                              ItemTemplate="{StaticResource WineOriginComboTemplate}"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Weinbau-KG:" Margin="10,40,0,10" Grid.Column="0"/>
 | 
					                    <Label Content="Weinbau-KG:" Margin="10,40,0,10" Grid.Column="0"/>
 | 
				
			||||||
                    <ComboBox x:Name="WineKgInput" Margin="0,40,10,10" Grid.Column="1"
 | 
					                    <ComboBox x:Name="WineKgInput" Margin="0,40,10,10" Grid.Column="1"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,8 +19,10 @@ using Xceed.Wpf.Toolkit.Primitives;
 | 
				
			|||||||
namespace Elwig.Windows {
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
    public partial class DeliveryAdminWindow : AdministrationWindow {
 | 
					    public partial class DeliveryAdminWindow : AdministrationWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public readonly bool IsReceipt = false;
 | 
				
			||||||
 | 
					        public int? MgNr => Member?.MgNr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private bool IsUpdatingGradation = false;
 | 
					        private bool IsUpdatingGradation = false;
 | 
				
			||||||
        private readonly bool IsReceipt = false;
 | 
					 | 
				
			||||||
        private Member? Member = null;
 | 
					        private Member? Member = null;
 | 
				
			||||||
        private readonly DispatcherTimer Timer;
 | 
					        private readonly DispatcherTimer Timer;
 | 
				
			||||||
        private List<string> TextFilter = new();
 | 
					        private List<string> TextFilter = new();
 | 
				
			||||||
@@ -296,6 +298,10 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, List<string>)> GetFilters() {
 | 
					        private async Task<(List<string>, IQueryable<Delivery>, IQueryable<DeliveryPart>, List<string>)> GetFilters() {
 | 
				
			||||||
            List<string> filterNames = new();
 | 
					            List<string> filterNames = new();
 | 
				
			||||||
            IQueryable<Delivery> deliveryQuery = Context.Deliveries;
 | 
					            IQueryable<Delivery> deliveryQuery = Context.Deliveries;
 | 
				
			||||||
 | 
					            if (IsReceipt && App.BranchNum > 1) {
 | 
				
			||||||
 | 
					                deliveryQuery = deliveryQuery.Where(d => d.ZwstId == App.ZwstId);
 | 
				
			||||||
 | 
					                filterNames.Add($"Zweigstelle {App.BranchName}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            if (Member != null) {
 | 
					            if (Member != null) {
 | 
				
			||||||
                deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr);
 | 
					                deliveryQuery = deliveryQuery.Where(d => d.MgNr == Member.MgNr);
 | 
				
			||||||
                filterNames.Add(Member.AdministrativeName);
 | 
					                filterNames.Add(Member.AdministrativeName);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,11 +23,8 @@
 | 
				
			|||||||
        <TextBox x:Name="TextElement" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
 | 
					        <TextBox x:Name="TextElement" TextWrapping="Wrap" VerticalScrollBarVisibility="Visible" AcceptsReturn="True"
 | 
				
			||||||
                 HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="200,10,10,10" Height="Auto"/>
 | 
					                 HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="200,10,10,10" Height="Auto"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <ProgressBar x:Name="ProgressBar" Margin="10,10,10,106" Height="27" Width="180"
 | 
					        <ProgressBar x:Name="ProgressBar" Margin="10,0,0,74" Height="27" Width="180"
 | 
				
			||||||
                     VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
					                     VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
				
			||||||
        <Button x:Name="TestButton" Content="Stichprobe" FontSize="14" Width="180" Margin="10,10,10,74" Height="27" Tag="Print" IsEnabled="False"
 | 
					 | 
				
			||||||
                Click="TestButton_Click"
 | 
					 | 
				
			||||||
                VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
					 | 
				
			||||||
        <Button x:Name="ShowButton" Content="Vorschau" FontSize="14" Width="180" Margin="10,10,10,42" Height="27" Tag="Print" IsEnabled="False"
 | 
					        <Button x:Name="ShowButton" Content="Vorschau" FontSize="14" Width="180" Margin="10,10,10,42" Height="27" Tag="Print" IsEnabled="False"
 | 
				
			||||||
                Click="ShowButton_Click"
 | 
					                Click="ShowButton_Click"
 | 
				
			||||||
                VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
					                VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,15 +20,9 @@ namespace Elwig.Dialogs {
 | 
				
			|||||||
            Year = year;
 | 
					            Year = year;
 | 
				
			||||||
            Title = $"Anlieferungsbestätigungen - Lese {Year} - Elwig";
 | 
					            Title = $"Anlieferungsbestätigungen - Lese {Year} - Elwig";
 | 
				
			||||||
            TextElement.Text = App.Client.TextDeliveryConfirmation;
 | 
					            TextElement.Text = App.Client.TextDeliveryConfirmation;
 | 
				
			||||||
            if (!App.Config.Debug) {
 | 
					 | 
				
			||||||
                TestButton.Visibility = Visibility.Hidden;
 | 
					 | 
				
			||||||
                var m = ProgressBar.Margin;
 | 
					 | 
				
			||||||
                ProgressBar.Margin = new(m.Left, m.Top, m.Right, m.Bottom - 32);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
					        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            TestButton.IsEnabled = App.IsPrintingReady;
 | 
					 | 
				
			||||||
            ShowButton.IsEnabled = App.IsPrintingReady;
 | 
					            ShowButton.IsEnabled = App.IsPrintingReady;
 | 
				
			||||||
            PrintButton.IsEnabled = App.IsPrintingReady;
 | 
					            PrintButton.IsEnabled = App.IsPrintingReady;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -80,11 +74,6 @@ namespace Elwig.Dialogs {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            IEnumerable<Member> list = await members.ToListAsync();
 | 
					            IEnumerable<Member> list = await members.ToListAsync();
 | 
				
			||||||
            if (mode == 0) {
 | 
					 | 
				
			||||||
                var r = new Random().Next(0, 10);
 | 
					 | 
				
			||||||
                list = list.Where((_, n) => n % 10 == r);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var data = await DeliveryConfirmationData.ForSeason(Context.DeliveryParts, Year);
 | 
					            var data = await DeliveryConfirmationData.ForSeason(Context.DeliveryParts, Year);
 | 
				
			||||||
            using var doc = Document.Merge(list.Select(m =>
 | 
					            using var doc = Document.Merge(list.Select(m =>
 | 
				
			||||||
                new DeliveryConfirmation(Context, Year, m, data[m.MgNr]) {
 | 
					                new DeliveryConfirmation(Context, Year, m, data[m.MgNr]) {
 | 
				
			||||||
@@ -109,10 +98,6 @@ namespace Elwig.Dialogs {
 | 
				
			|||||||
            Close();
 | 
					            Close();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void TestButton_Click(object sender, RoutedEventArgs evt) {
 | 
					 | 
				
			||||||
            await Generate(0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private async void ShowButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void ShowButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            await Generate(1);
 | 
					            await Generate(1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
					        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
				
			||||||
        xmlns:local="clr-namespace:Elwig.Windows"
 | 
					        xmlns:local="clr-namespace:Elwig.Windows"
 | 
				
			||||||
        Title="Elwig" MinHeight="400" MinWidth="325" Height="450" Width="800" ResizeMode="CanResize"
 | 
					        Title="Elwig" MinHeight="400" MinWidth="325" Height="450" Width="800" ResizeMode="CanResize"
 | 
				
			||||||
        Loaded="Window_Loaded">
 | 
					        Loaded="Window_Loaded" Closing="Window_Closing">
 | 
				
			||||||
    <Window.Resources>
 | 
					    <Window.Resources>
 | 
				
			||||||
        <Style TargetType="Button">
 | 
					        <Style TargetType="Button">
 | 
				
			||||||
            <Setter Property="VerticalAlignment" Value="Top"/>
 | 
					            <Setter Property="VerticalAlignment" Value="Top"/>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					using System.ComponentModel;
 | 
				
			||||||
using System.Reflection;
 | 
					using System.Reflection;
 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,6 +17,11 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) { }
 | 
					        private void Window_Loaded(object sender, RoutedEventArgs evt) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Window_Closing(object sender, CancelEventArgs evt) {
 | 
				
			||||||
 | 
					            if (App.NumWindows > 1)
 | 
				
			||||||
 | 
					                evt.Cancel = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void MemberAdminButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void MemberAdminButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var w = new MemberAdminWindow();
 | 
					            var w = new MemberAdminWindow();
 | 
				
			||||||
            w.Show();
 | 
					            w.Show();
 | 
				
			||||||
@@ -27,8 +33,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void ReceiptButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void ReceiptButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var w = new DeliveryAdminWindow(true);
 | 
					            App.FocusReceipt();
 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void DeliveryAdminButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void DeliveryAdminButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
@@ -51,13 +56,11 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void BaseDataButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void BaseDataButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var w = new BaseDataWindow();
 | 
					            App.FocusBaseData();
 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void SeasonFinishButton_Click(object sender, RoutedEventArgs e) {
 | 
					        private void SeasonFinishButton_Click(object sender, RoutedEventArgs e) {
 | 
				
			||||||
            var w = new SeasonFinishWindow();
 | 
					            App.FocusSeasonFinish();
 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,7 +53,8 @@
 | 
				
			|||||||
            <MenuItem Header="Drucken">
 | 
					            <MenuItem Header="Drucken">
 | 
				
			||||||
                <MenuItem x:Name="Menu_Print_Letterhead" Header="Briefkopf drucken"
 | 
					                <MenuItem x:Name="Menu_Print_Letterhead" Header="Briefkopf drucken"
 | 
				
			||||||
                          Click="Menu_Print_Letterhead_Click"/>
 | 
					                          Click="Menu_Print_Letterhead_Click"/>
 | 
				
			||||||
                <MenuItem Header="Stammdatenblatt drucken"/>
 | 
					                <MenuItem x:Name="Menu_Show_Memberdata" Header="Stammdatenblatt anzeigen" Click="Menu_Show_Memberdata_Click"/>
 | 
				
			||||||
 | 
					                <MenuItem x:Name="Menu_Print_Memberdata" Header="Stammdatenblatt drucken" Click="Menu_Print_Memberdata_Click"/>
 | 
				
			||||||
                <MenuItem Header="Briefköpfe drucken">
 | 
					                <MenuItem Header="Briefköpfe drucken">
 | 
				
			||||||
                    <MenuItem x:Name="Menu_Print_Letterheads_MgNr" Header="nach MgNr. sortiert" IsEnabled="False" Tag="Print"
 | 
					                    <MenuItem x:Name="Menu_Print_Letterheads_MgNr" Header="nach MgNr. sortiert" IsEnabled="False" Tag="Print"
 | 
				
			||||||
                              Click="Menu_Print_Letterheads_MgNr_Click"/>
 | 
					                              Click="Menu_Print_Letterheads_MgNr_Click"/>
 | 
				
			||||||
@@ -381,7 +382,10 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Stammgemeinde:" Margin="10,160,0,0" Grid.Column="0"/>
 | 
					                    <Label Content="Stammgemeinde:" Margin="10,160,0,0" Grid.Column="0"/>
 | 
				
			||||||
                    <ComboBox x:Name="DefaultKgInput" DisplayMemberPath="Name" TextSearch.TextPath="Name"
 | 
					                    <ComboBox x:Name="DefaultKgInput" DisplayMemberPath="Name" TextSearch.TextPath="Name"
 | 
				
			||||||
                              Margin="0,160,10,0" Grid.Column="1" Grid.ColumnSpan="2"/>
 | 
					                              Margin="0,160,40,10" Grid.Column="1" Grid.ColumnSpan="2"/>
 | 
				
			||||||
 | 
					                    <Button x:Name="KgDetailsButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="14" Padding="0,1,0,0"
 | 
				
			||||||
 | 
					                            Click="KgDetailsButton_Click"
 | 
				
			||||||
 | 
					                            Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Right" Width="25" Height="25" Margin="10,160,10,10"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <Label Content="Anmerkung:" Margin="10,190,0,0" Grid.Column="0"/>
 | 
					                    <Label Content="Anmerkung:" Margin="10,190,0,0" Grid.Column="0"/>
 | 
				
			||||||
                    <TextBox x:Name="CommentInput" Margin="0,190,10,0" Grid.Column="1" Grid.ColumnSpan="2"
 | 
					                    <TextBox x:Name="CommentInput" Margin="0,190,10,0" Grid.Column="1" Grid.ColumnSpan="2"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
					        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            Menu_Print_Letterheads_MgNr.IsEnabled = App.IsPrintingReady;
 | 
					            Menu_Print_Letterheads_MgNr.IsEnabled = App.IsPrintingReady;
 | 
				
			||||||
            Menu_Print_Letterheads_Name.IsEnabled = App.IsPrintingReady;
 | 
					            Menu_Print_Letterheads_Name.IsEnabled = App.IsPrintingReady;
 | 
				
			||||||
 | 
					            Menu_Show_Memberdata.IsEnabled = App.IsPrintingReady;
 | 
				
			||||||
 | 
					            Menu_Print_Memberdata.IsEnabled = App.IsPrintingReady;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ActiveMemberInput.IsChecked = true;
 | 
					            ActiveMemberInput.IsChecked = true;
 | 
				
			||||||
            UpdatePhoneNrInputVisibility();
 | 
					            UpdatePhoneNrInputVisibility();
 | 
				
			||||||
@@ -257,13 +259,11 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void AreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void AreaCommitmentButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var w = new AreaComAdminWindow(((Member)MemberList.SelectedItem).MgNr);
 | 
					            App.FocusMemberAreaComs(((Member)MemberList.SelectedItem).MgNr);
 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void DeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void DeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var w = new DeliveryAdminWindow(((Member)MemberList.SelectedItem).MgNr);
 | 
					            App.FocusMemberDeliveries(((Member)MemberList.SelectedItem).MgNr);
 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
					        private async void SearchInput_TextChanged(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
@@ -339,6 +339,30 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            await PrintLetterheads(2);
 | 
					            await PrintLetterheads(2);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void Menu_Print_Memberdata_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (MemberList.SelectedItem is not Member m)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
 | 
					            using var doc = new MemberDataSheet(m, Context);
 | 
				
			||||||
 | 
					            await doc.Generate();
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					            if (App.Config.Debug) {
 | 
				
			||||||
 | 
					                doc.Show();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                await doc.Print();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void Menu_Show_Memberdata_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (MemberList.SelectedItem is not Member m)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
 | 
					            using var doc = new MemberDataSheet(m, Context);
 | 
				
			||||||
 | 
					            await doc.Generate();
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					            doc.Show();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void FocusSearchInput(object sender, RoutedEventArgs evt) {
 | 
					        private void FocusSearchInput(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            if (!IsEditing && !IsCreating) {
 | 
					            if (!IsEditing && !IsCreating) {
 | 
				
			||||||
                SearchInput.Focus();
 | 
					                SearchInput.Focus();
 | 
				
			||||||
@@ -625,6 +649,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            Menu_Member_SendEmail.IsEnabled = m.EmailAddresses.Count > 0;
 | 
					            Menu_Member_SendEmail.IsEnabled = m.EmailAddresses.Count > 0;
 | 
				
			||||||
            Menu_Print_Letterhead.IsEnabled = true;
 | 
					            Menu_Print_Letterhead.IsEnabled = true;
 | 
				
			||||||
 | 
					            Menu_Show_Memberdata.IsEnabled = true;
 | 
				
			||||||
 | 
					            Menu_Print_Memberdata.IsEnabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            FinishInputFilling();
 | 
					            FinishInputFilling();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -632,6 +658,8 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        new protected void ClearInputs(bool validate = false) {
 | 
					        new protected void ClearInputs(bool validate = false) {
 | 
				
			||||||
            Menu_Member_SendEmail.IsEnabled = false;
 | 
					            Menu_Member_SendEmail.IsEnabled = false;
 | 
				
			||||||
            Menu_Print_Letterhead.IsEnabled = false;
 | 
					            Menu_Print_Letterhead.IsEnabled = false;
 | 
				
			||||||
 | 
					            Menu_Show_Memberdata.IsEnabled = false;
 | 
				
			||||||
 | 
					            Menu_Print_Memberdata.IsEnabled = false;
 | 
				
			||||||
            StatusDeliveriesLastSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason - 1}): -";
 | 
					            StatusDeliveriesLastSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason - 1}): -";
 | 
				
			||||||
            StatusDeliveriesThisSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason}): -";
 | 
					            StatusDeliveriesThisSeason.Text = $"Lieferungen ({Utils.CurrentLastSeason}): -";
 | 
				
			||||||
            StatusAreaCommitment.Text = "Gebundene Fläche: -";
 | 
					            StatusAreaCommitment.Text = "Gebundene Fläche: -";
 | 
				
			||||||
@@ -674,5 +702,13 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            base.PhoneNrInput_TextChanged(sender, evt);
 | 
					            base.PhoneNrInput_TextChanged(sender, evt);
 | 
				
			||||||
            UpdatePhoneNrInputVisibility(IsEditing || IsCreating);
 | 
					            UpdatePhoneNrInputVisibility(IsEditing || IsCreating);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void KgDetailsButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (DefaultKgInput.SelectedItem is AT_Kg kg) {
 | 
				
			||||||
 | 
					                App.FocusOriginHierarchyKg(kg.KgNr);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                App.FocusOriginHierarchy();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										114
									
								
								Elwig/Windows/OriginHierarchyWindow.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								Elwig/Windows/OriginHierarchyWindow.xaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
				
			|||||||
 | 
					<local:ContextWindow
 | 
				
			||||||
 | 
					        x:Class="Elwig.Windows.OriginHierarchyWindow"
 | 
				
			||||||
 | 
					        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"
 | 
				
			||||||
 | 
					        mc:Ignorable="d"
 | 
				
			||||||
 | 
					        Title="Herkunftshierarchie - Elwig" Height="800" Width="1200" MinHeight="500" MinWidth="1000">
 | 
				
			||||||
 | 
					    <Grid>
 | 
				
			||||||
 | 
					        <Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="1*" MinWidth="300"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="25"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="1*"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="25"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="1*" MinWidth="400"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="25"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="1*"/>
 | 
				
			||||||
 | 
					        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
 | 
					            <RowDefinition Height="1*"/>
 | 
				
			||||||
 | 
					            <RowDefinition Height="25"/>
 | 
				
			||||||
 | 
					            <RowDefinition Height="1*"/>
 | 
				
			||||||
 | 
					            <RowDefinition Height="25"/>
 | 
				
			||||||
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="Weinbaugebiete" Margin="10,0,0,0" VerticalAlignment="Top" Grid.RowSpan="3"/>
 | 
				
			||||||
 | 
					        <ListBox x:Name="WineOrigins" Margin="10,25,0,10" Grid.RowSpan="3"
 | 
				
			||||||
 | 
					                 ItemTemplate="{StaticResource WineOriginTemplate}"
 | 
				
			||||||
 | 
					                 SelectionChanged="WineOrigins_SelectionChanged"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="Großlagen" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Column="2"/>
 | 
				
			||||||
 | 
					        <ListBox x:Name="WbGls" Margin="0,25,0,5" Grid.Column="2"
 | 
				
			||||||
 | 
					                 DisplayMemberPath="Name"
 | 
				
			||||||
 | 
					                 SelectionChanged="WbGls_SelectionChanged"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0" Grid.Row="2" Grid.Column="1"
 | 
				
			||||||
 | 
					               VerticalAlignment="Center" HorizontalAlignment="Center"/>
 | 
				
			||||||
 | 
					        <Label x:Name="WbGemsHeader" Content="Gemeinden" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Column="2" Grid.Row="2"/>
 | 
				
			||||||
 | 
					        <ListBox x:Name="WbGems" Margin="0,25,0,10" Grid.Column="2" Grid.Row="2"
 | 
				
			||||||
 | 
					                 ItemTemplate="{StaticResource GemTemplate}" TextSearch.TextPath="Name"
 | 
				
			||||||
 | 
					                 SelectionChanged="WbGems_SelectionChanged"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0" Grid.Column="3"
 | 
				
			||||||
 | 
					               VerticalAlignment="Center" HorizontalAlignment="Center"/>
 | 
				
			||||||
 | 
					        <Label x:Name="WbGlKgsHeader" Content="Aktive KG" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Column="4"/>
 | 
				
			||||||
 | 
					        <Label Content="Weinbaugebiet" Margin="250,0,0,0" VerticalAlignment="Top" Grid.Column="4" Background="White"/>
 | 
				
			||||||
 | 
					        <ListBox x:Name="WbGlKgs" Margin="0,25,0,5" Grid.Column="4"
 | 
				
			||||||
 | 
					                 ItemTemplate="{StaticResource WbKgTemplate}" TextSearch.TextPath="Name"
 | 
				
			||||||
 | 
					                 SelectionChanged="WbGlKgs_SelectionChanged"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Button x:Name="ActivateKgButton" Content="" Grid.Column="4" Grid.Row="1" Height="25" Width="25" Margin="0,0,30,0"
 | 
				
			||||||
 | 
					                FontFamily="Segoe MDL2 Assets" FontSize="14"
 | 
				
			||||||
 | 
					                Click="ActivateKgButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Center" HorizontalAlignment="Center"/>
 | 
				
			||||||
 | 
					        <Button x:Name="DeactivateKgButton" Content="" Grid.Column="4" Grid.Row="1" Height="25" Width="25" Margin="30,0,0,0"
 | 
				
			||||||
 | 
					                FontFamily="Segoe MDL2 Assets" FontSize="14"
 | 
				
			||||||
 | 
					                Click="DeactivateKgButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Center" HorizontalAlignment="Center"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0" Grid.Row="2" Grid.Column="3"
 | 
				
			||||||
 | 
					               VerticalAlignment="Center" HorizontalAlignment="Center"/>
 | 
				
			||||||
 | 
					        <Label x:Name="WbKgsHeader" Content="Verfügbare KG" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Column="4" Grid.Row="2"/>
 | 
				
			||||||
 | 
					        <Label Content="Zugewiesen zu Großlage" Margin="220,0,0,0" VerticalAlignment="Top" Grid.Column="4" Grid.Row="2" Background="White"/>
 | 
				
			||||||
 | 
					        <ListBox x:Name="WbKgs" Margin="0,25,0,10" Grid.Column="4" Grid.Row="2"
 | 
				
			||||||
 | 
					                 ItemTemplate="{StaticResource WbKgGlTemplate}" TextSearch.TextPath="Name"
 | 
				
			||||||
 | 
					                 SelectionChanged="WbKgs_SelectionChanged"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="" FontFamily="Segoe MDL2 Assets" FontSize="16" Padding="0" Grid.Column="5"
 | 
				
			||||||
 | 
					               VerticalAlignment="Center" HorizontalAlignment="Center"/>
 | 
				
			||||||
 | 
					        <Label x:Name="WbRdsHeader" Content="Riede" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Column="6" Grid.RowSpan="3"/>
 | 
				
			||||||
 | 
					        <ListBox x:Name="WbRds" Margin="0,25,10,10" Grid.Column="6" Grid.RowSpan="3"
 | 
				
			||||||
 | 
					                 DisplayMemberPath="Name" TextSearch.TextPath="Name"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <StatusBar Grid.Row="3" Grid.ColumnSpan="7" BorderThickness="0,1,0,0" BorderBrush="Gray">
 | 
				
			||||||
 | 
					            <StatusBar.ItemsPanel>
 | 
				
			||||||
 | 
					                <ItemsPanelTemplate>
 | 
				
			||||||
 | 
					                    <Grid>
 | 
				
			||||||
 | 
					                        <Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="1.5*"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="Auto"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="*"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="Auto"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="*"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="Auto"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="*"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="Auto"/>
 | 
				
			||||||
 | 
					                            <ColumnDefinition Width="*"/>
 | 
				
			||||||
 | 
					                        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					                    </Grid>
 | 
				
			||||||
 | 
					                </ItemsPanelTemplate>
 | 
				
			||||||
 | 
					            </StatusBar.ItemsPanel>
 | 
				
			||||||
 | 
					            <StatusBarItem>
 | 
				
			||||||
 | 
					                <TextBlock Name="StatusKgName" Text="Katastralgemeinde: -"/>
 | 
				
			||||||
 | 
					            </StatusBarItem>
 | 
				
			||||||
 | 
					            <Separator Grid.Column="1"/>
 | 
				
			||||||
 | 
					            <StatusBarItem Grid.Column="2">
 | 
				
			||||||
 | 
					                <TextBlock Name="StatusWbRds" Text="Riede: -"/>
 | 
				
			||||||
 | 
					            </StatusBarItem>
 | 
				
			||||||
 | 
					            <Separator Grid.Column="3"/>
 | 
				
			||||||
 | 
					            <StatusBarItem Grid.Column="4">
 | 
				
			||||||
 | 
					                <TextBlock Name="StatusDefaultKgs" Text="Stammgemeinde: -"/>
 | 
				
			||||||
 | 
					            </StatusBarItem>
 | 
				
			||||||
 | 
					            <Separator Grid.Column="5"/>
 | 
				
			||||||
 | 
					            <StatusBarItem Grid.Column="6">
 | 
				
			||||||
 | 
					                <TextBlock Name="StatusAreaCommitments" Text="Flächenbindungen: -"/>
 | 
				
			||||||
 | 
					            </StatusBarItem>
 | 
				
			||||||
 | 
					            <Separator Grid.Column="7"/>
 | 
				
			||||||
 | 
					            <StatusBarItem Grid.Column="8">
 | 
				
			||||||
 | 
					                <TextBlock Name="StatusDeliveries" Text="Lieferungen: -"/>
 | 
				
			||||||
 | 
					            </StatusBarItem>
 | 
				
			||||||
 | 
					        </StatusBar>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					</local:ContextWindow>
 | 
				
			||||||
							
								
								
									
										218
									
								
								Elwig/Windows/OriginHierarchyWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										218
									
								
								Elwig/Windows/OriginHierarchyWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,218 @@
 | 
				
			|||||||
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using Microsoft.EntityFrameworkCore.ChangeTracking;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using System.Windows;
 | 
				
			||||||
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public partial class OriginHierarchyWindow : ContextWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private bool isUpdating = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public OriginHierarchyWindow() {
 | 
				
			||||||
 | 
					            InitializeComponent();
 | 
				
			||||||
 | 
					            ActivateKgButton.IsEnabled = false;
 | 
				
			||||||
 | 
					            DeactivateKgButton.IsEnabled = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
 | 
					            ControlUtils.RenewItemsSource(WineOrigins, (await Context.WineOrigins.ToListAsync()).OrderByDescending(o => o.SortKey).ThenBy(o => o.HkId), i => (i as WineOrigin)?.HkId, WineOrigins_SelectionChanged);
 | 
				
			||||||
 | 
					            if (WineOrigins.SelectedItem == null) {
 | 
				
			||||||
 | 
					                var hkid = await Context.WbKgs
 | 
				
			||||||
 | 
					                    .GroupBy(k => k.AtKg.Gem.WbGem.HkId)
 | 
				
			||||||
 | 
					                    .Where(g => g.Count() > 0)
 | 
				
			||||||
 | 
					                    .OrderByDescending(g => g.Count())
 | 
				
			||||||
 | 
					                    .Select(g => g.Key)
 | 
				
			||||||
 | 
					                    .FirstOrDefaultAsync();
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WineOrigins, o => (o as WineOrigin)?.HkId, hkid);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            ControlUtils.RenewItemsSource(WbGls, await Context.WbGls.OrderBy(g => g.GlNr).ToListAsync(), g => (g as WbGl)?.GlNr, WbGls_SelectionChanged, ControlUtils.RenewSourceDefault.First);
 | 
				
			||||||
 | 
					            await UpdateWbGems();
 | 
				
			||||||
 | 
					            await UpdateWbKgs();
 | 
				
			||||||
 | 
					            await UpdateWbGlKgs();
 | 
				
			||||||
 | 
					            await UpdateWbRds();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task UpdateWbGems() {
 | 
				
			||||||
 | 
					            WbGemsHeader.Content = "Gemeinden" + (WineOrigins.SelectedItem is WineOrigin o ? $" ({o.Name})" : "");
 | 
				
			||||||
 | 
					            var selHkId = (WineOrigins.SelectedItem as WineOrigin)?.HkId;
 | 
				
			||||||
 | 
					            ControlUtils.RenewItemsSource(WbGems, await Context.WbGems.Where(g => g.HkId == selHkId).Select(g => g.AtGem).OrderBy(g => g.Name).ToListAsync(), g => (g as AT_Gem)?.Gkz, WbGems_SelectionChanged);
 | 
				
			||||||
 | 
					            await UpdateWbKgs();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task UpdateWbKgs() {
 | 
				
			||||||
 | 
					            WbKgsHeader.Content = "Verfügbare KG";
 | 
				
			||||||
 | 
					            IQueryable<AT_Kg>? kgs = null;
 | 
				
			||||||
 | 
					            if (WbGems.SelectedItem is AT_Gem g) {
 | 
				
			||||||
 | 
					                WbKgsHeader.Content += $" ({g.Name})";
 | 
				
			||||||
 | 
					                kgs = Context.Katastralgemeinden.Where(k => k.Gkz == g.Gkz);
 | 
				
			||||||
 | 
					            } else if (WineOrigins.SelectedItem is WineOrigin o) {
 | 
				
			||||||
 | 
					                WbKgsHeader.Content += $" ({o.Name})";
 | 
				
			||||||
 | 
					                kgs = Context.WbGems.Where(g => g.HkId == o.HkId).SelectMany(g => g.AtGem.Kgs);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                kgs = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (kgs == null) {
 | 
				
			||||||
 | 
					                WbKgs.ItemsSource = null;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                ControlUtils.RenewItemsSource(WbKgs, await kgs.OrderBy(k => k.WbKg.Gl == null).ThenBy(k => k.WbKg.GlNr).ThenBy(k => k.Name).ToListAsync(), k => (k as AT_Kg)?.KgNr, WbKgs_SelectionChanged);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task UpdateWbGlKgs() {
 | 
				
			||||||
 | 
					            WbGlKgsHeader.Content = "Aktive KG";
 | 
				
			||||||
 | 
					            if (WbGls.SelectedItem is WbGl g) {
 | 
				
			||||||
 | 
					                WbGlKgsHeader.Content += $" ({g.Name})";
 | 
				
			||||||
 | 
					                ControlUtils.RenewItemsSource(WbGlKgs, await Context.WbKgs.Where(k => k.GlNr == g.GlNr).Select(k => k.AtKg).OrderBy(k => k.Name).ToListAsync(), k => (k as AT_Kg)?.KgNr, WbGlKgs_SelectionChanged);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                WbGlKgs.ItemsSource = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            UpdateButtons();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task UpdateStatusBar() {
 | 
				
			||||||
 | 
					            StatusKgName.Text = "Katastralgemeinde: ";
 | 
				
			||||||
 | 
					            StatusWbRds.Text = "Riede: ";
 | 
				
			||||||
 | 
					            StatusDefaultKgs.Text = "Stammgemeinde: ";
 | 
				
			||||||
 | 
					            StatusAreaCommitments.Text = "Flächenbindungen: ";
 | 
				
			||||||
 | 
					            StatusDeliveries.Text = "Lieferungen: ";
 | 
				
			||||||
 | 
					            if (WbGlKgs.SelectedItem is AT_Kg k && k.WbKg != null) {
 | 
				
			||||||
 | 
					                StatusKgName.Text += $"{k.Name} ({k.KgNr:00000})";
 | 
				
			||||||
 | 
					                var reeds = await Context.WbRde.Where(r => r.KgNr == k.KgNr).CountAsync();
 | 
				
			||||||
 | 
					                StatusWbRds.Text += $"{reeds:N0}";
 | 
				
			||||||
 | 
					                var activeMembers = await Context.Members.Where(m => m.IsActive && m.DefaultKgNr == k.KgNr).CountAsync();
 | 
				
			||||||
 | 
					                var allMembers = await Context.Members.Where(m => m.DefaultKgNr == k.KgNr).CountAsync();
 | 
				
			||||||
 | 
					                StatusDefaultKgs.Text += $"{activeMembers:N0} ({allMembers:N0})";
 | 
				
			||||||
 | 
					                var year = Utils.CurrentNextSeason;
 | 
				
			||||||
 | 
					                var activeAreaComs = await Context.AreaCommitments.Where(c => c.KgNr == k.KgNr && c.YearFrom <= year && (c.YearTo == null || c.YearTo >= year)).CountAsync();
 | 
				
			||||||
 | 
					                var allAreaComs = await Context.AreaCommitments.Where(c => c.KgNr == k.KgNr).CountAsync();
 | 
				
			||||||
 | 
					                StatusAreaCommitments.Text += $"{activeAreaComs:N0} ({allAreaComs:N0})";
 | 
				
			||||||
 | 
					                var deliveryParts = await Context.DeliveryParts.Where(p => p.KgNr == k.KgNr).CountAsync();
 | 
				
			||||||
 | 
					                var deliveries = await Context.Deliveries.Where(d => d.Parts.Any(p => p.KgNr == k.KgNr)).CountAsync();
 | 
				
			||||||
 | 
					                StatusDeliveries.Text += $"{deliveries:N0} ({deliveryParts:N0})";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                StatusKgName.Text += "-";
 | 
				
			||||||
 | 
					                StatusWbRds.Text += "-";
 | 
				
			||||||
 | 
					                StatusDefaultKgs.Text += "-";
 | 
				
			||||||
 | 
					                StatusAreaCommitments.Text += "-";
 | 
				
			||||||
 | 
					                StatusDeliveries.Text += "-";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task UpdateWbRds() {
 | 
				
			||||||
 | 
					            WbRdsHeader.Content = "Riede";
 | 
				
			||||||
 | 
					            if (WbGlKgs.SelectedItem is AT_Kg k) {
 | 
				
			||||||
 | 
					                WbRdsHeader.Content += $" ({k.Name})";
 | 
				
			||||||
 | 
					                ControlUtils.RenewItemsSource(WbRds, await Context.WbRde.Where(r => r.KgNr == k.KgNr).OrderBy(r => r.Name).ToListAsync(), k => (k as AT_Kg)?.KgNr);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                WbRds.ItemsSource = null;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            UpdateButtons();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void WineOrigins_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
 | 
				
			||||||
 | 
					            await UpdateWbGems();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void WbGls_SelectionChanged(object? sender, SelectionChangedEventArgs? e) {
 | 
				
			||||||
 | 
					            await UpdateWbGlKgs();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void WbGems_SelectionChanged(object? sender, SelectionChangedEventArgs? e) {
 | 
				
			||||||
 | 
					            await UpdateWbKgs();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void WbGlKgs_SelectionChanged(object sender, SelectionChangedEventArgs e) {
 | 
				
			||||||
 | 
					            await UpdateWbRds();
 | 
				
			||||||
 | 
					            if (!isUpdating && WbGlKgs.SelectedItem is AT_Kg k) {
 | 
				
			||||||
 | 
					                isUpdating = true;
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WineOrigins, o => (o as WineOrigin)?.HkId, k.Gem.WbGem?.HkId);
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WbGems, g => (g as AT_Gem)?.Gkz, k.Gkz);
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WbKgs, k => (k as AT_Kg)?.KgNr, k.KgNr);
 | 
				
			||||||
 | 
					                isUpdating = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            await UpdateStatusBar();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void WbKgs_SelectionChanged(object sender, SelectionChangedEventArgs e) {
 | 
				
			||||||
 | 
					            UpdateButtons();
 | 
				
			||||||
 | 
					            if (!isUpdating && WbKgs.SelectedItem is AT_Kg k && k.WbKg != null && ((WbGls.SelectedItem as WbGl)?.GlNr == k.WbKg?.GlNr || WbGls.SelectedItem == null)) {
 | 
				
			||||||
 | 
					                isUpdating = true;
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WbGls, g => (g as WbGl)?.GlNr, k.WbKg?.GlNr);
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WbGlKgs, k => (k as AT_Kg)?.KgNr, k.KgNr);
 | 
				
			||||||
 | 
					                isUpdating = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void UpdateButtons() {
 | 
				
			||||||
 | 
					            if (WbKgs.SelectedItem is AT_Kg v) {
 | 
				
			||||||
 | 
					                ActivateKgButton.IsEnabled = v.WbKg?.GlNr != (WbGls.SelectedItem as WbGl)?.GlNr;
 | 
				
			||||||
 | 
					                ActivateKgButton.ToolTip = $"KG {v.Name} Großlage {(WbGls.SelectedItem as WbGl)?.Name} zuweisen";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                ActivateKgButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                ActivateKgButton.ToolTip = $"Verfügbare Katastralgemeinde Großlage {(WbGls.SelectedItem as WbGl)?.Name} zuweisen";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (WbGlKgs.SelectedItem is AT_Kg a) {
 | 
				
			||||||
 | 
					                DeactivateKgButton.IsEnabled = true;
 | 
				
			||||||
 | 
					                DeactivateKgButton.ToolTip = $"KG {a.Name} deaktivieren";
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                DeactivateKgButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                DeactivateKgButton.ToolTip = "Aktive Katastralgemeinde deaktivieren";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void ActivateKgButton_Click(object sender, RoutedEventArgs e) {
 | 
				
			||||||
 | 
					            if (WbKgs.SelectedItem is not AT_Kg k || WbGls.SelectedItem is not WbGl g) return;
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                if (k.WbKg != null) {
 | 
				
			||||||
 | 
					                    k.WbKg.GlNr = g.GlNr;
 | 
				
			||||||
 | 
					                    Context.Update(k.WbKg);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    var wbKg = Context.CreateProxy<WbKg>();
 | 
				
			||||||
 | 
					                    wbKg.KgNr = k.KgNr;
 | 
				
			||||||
 | 
					                    wbKg.GlNr = g.GlNr;
 | 
				
			||||||
 | 
					                    await Context.AddAsync(wbKg);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                await Context.SaveChangesAsync();
 | 
				
			||||||
 | 
					                await App.HintContextChange();
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WbGlKgs, kg => (kg as AT_Kg)?.KgNr, k.KgNr);
 | 
				
			||||||
 | 
					            } 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, "Katastralgemeinde aktivieren", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void DeactivateKgButton_Click(object sender, RoutedEventArgs e) {
 | 
				
			||||||
 | 
					            if (WbGlKgs.SelectedItem is not AT_Kg k || k.WbKg == null) return;
 | 
				
			||||||
 | 
					            var r = MessageBox.Show(
 | 
				
			||||||
 | 
					                $"Sollen alle Riede und Stammgemeinden-Einträge von der KG {k.Name} wirklich unwiderruflich gelöscht werden?",
 | 
				
			||||||
 | 
					                "Katastralgemeinde deaktivieren", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
 | 
				
			||||||
 | 
					            if (r != MessageBoxResult.Yes) return;
 | 
				
			||||||
 | 
					            try {
 | 
				
			||||||
 | 
					                Context.Remove(k.WbKg);
 | 
				
			||||||
 | 
					                await Context.SaveChangesAsync();
 | 
				
			||||||
 | 
					                await App.HintContextChange();
 | 
				
			||||||
 | 
					                ControlUtils.SelectListBoxItem(WbKgs, kg => (kg as AT_Kg)?.KgNr, k.KgNr);
 | 
				
			||||||
 | 
					            } catch (Exception exc) {
 | 
				
			||||||
 | 
					                await HintContextChange();
 | 
				
			||||||
 | 
					                var str = "Der Eintrag konnte nicht aus der Datenbank gelöscht werden!\n\n" + exc.Message;
 | 
				
			||||||
 | 
					                if (exc.InnerException != null) str += "\n\n" + exc.InnerException.Message;
 | 
				
			||||||
 | 
					                MessageBox.Show(str, "Katastralgemeinde deaktivieren", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public void FocusKgNr(int kgnr) {
 | 
				
			||||||
 | 
					            var kg = Context.Katastralgemeinden.Find(kgnr);
 | 
				
			||||||
 | 
					            ControlUtils.SelectListBoxItem(WbGls, kg.WbKg.Gl, g => (g as WbGl)?.GlNr);
 | 
				
			||||||
 | 
					            ControlUtils.SelectListBoxItem(WbGlKgs, kg, k => (k as AT_Kg)?.KgNr);
 | 
				
			||||||
 | 
					            WbGlKgs.Focus();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										99
									
								
								Elwig/Windows/PaymentVariantsWindow.xaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								Elwig/Windows/PaymentVariantsWindow.xaml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,99 @@
 | 
				
			|||||||
 | 
					<local:ContextWindow
 | 
				
			||||||
 | 
					        x:Class="Elwig.Windows.PaymentVariantsWindow"
 | 
				
			||||||
 | 
					        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"
 | 
				
			||||||
 | 
					        mc:Ignorable="d"
 | 
				
			||||||
 | 
					        Title="Auszahlungsvarianten - Elwig" Height="450" Width="800" MinHeight="400" MinWidth="700">
 | 
				
			||||||
 | 
					    <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="ComboBox">
 | 
				
			||||||
 | 
					            <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.ColumnDefinitions>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="320"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="100"/>
 | 
				
			||||||
 | 
					            <ColumnDefinition Width="*"/>
 | 
				
			||||||
 | 
					        </Grid.ColumnDefinitions>
 | 
				
			||||||
 | 
					        <Grid.RowDefinitions>
 | 
				
			||||||
 | 
					            <RowDefinition Height="200"/>
 | 
				
			||||||
 | 
					            <RowDefinition Height="*"/>
 | 
				
			||||||
 | 
					        </Grid.RowDefinitions>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <ListBox x:Name="PaymentVariantList" Margin="10,10,35,10" Grid.RowSpan="2" SelectionChanged="PaymentVariantList_SelectionChanged">
 | 
				
			||||||
 | 
					            <ListBox.ItemTemplate>
 | 
				
			||||||
 | 
					                <DataTemplate>
 | 
				
			||||||
 | 
					                    <StackPanel Orientation="Horizontal">
 | 
				
			||||||
 | 
					                        <TextBlock Text="{Binding Name}" Width="200"/>
 | 
				
			||||||
 | 
					                        <TextBlock Text="{Binding Date}" Width="60"/>
 | 
				
			||||||
 | 
					                    </StackPanel>
 | 
				
			||||||
 | 
					                </DataTemplate>
 | 
				
			||||||
 | 
					            </ListBox.ItemTemplate>
 | 
				
			||||||
 | 
					        </ListBox>
 | 
				
			||||||
 | 
					        <Button x:Name="AddButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0"
 | 
				
			||||||
 | 
					                Click="AddButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,60" Grid.RowSpan="2"/>
 | 
				
			||||||
 | 
					        <Button x:Name="CopyButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="12" Padding="0,0,0,0" IsEnabled="False"
 | 
				
			||||||
 | 
					                Click="CopyButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,0,5,0" Grid.RowSpan="2"/>
 | 
				
			||||||
 | 
					        <Button x:Name="DeleteButton" Content="" FontFamily="Segoe MDL2 Assets" FontSize="11" Padding="0,1.5,0,0" IsEnabled="False"
 | 
				
			||||||
 | 
					                Click="DeleteButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Center" HorizontalAlignment="Right" Width="25" Height="25" Margin="5,60,5,0" Grid.RowSpan="2"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="Name:" Margin="10,10,0,0" Grid.Column="1"/>
 | 
				
			||||||
 | 
					        <TextBox x:Name="NameInput" Width="200" Grid.Column="2" HorizontalAlignment="Left" Margin="0,10,0,0"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="Beschreibung:" Margin="10,40,0,0" Grid.Column="1"/>
 | 
				
			||||||
 | 
					        <TextBox x:Name="CommentInput" Grid.Column="2" HorizontalAlignment="Stretch" Margin="0,40,10,0"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="Erstellt am:" Margin="10,70,0,0" Grid.Column="1"/>
 | 
				
			||||||
 | 
					        <TextBox x:Name="DateInput" Grid.Column="2" Width="77" HorizontalAlignment="Left" Margin="0,70,10,0"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <Label Content="Überwiesen am:" Margin="10,100,0,0" Grid.Column="1"/>
 | 
				
			||||||
 | 
					        <TextBox x:Name="TransferDateInput" Grid.Column="2" Width="77" HorizontalAlignment="Left" Margin="0,100,10,0"/>
 | 
				
			||||||
 | 
					        <Button x:Name="CalculateButton" Content="Berechnen" Grid.Column="1" Grid.ColumnSpan="2"
 | 
				
			||||||
 | 
					                Click="CalculateButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="100" Margin="10,10,115,10"/>
 | 
				
			||||||
 | 
					        <Button x:Name="EditButton" Content="Bearbeiten" Grid.Column="1" Grid.ColumnSpan="2"
 | 
				
			||||||
 | 
					                Click="EditButton_Click"
 | 
				
			||||||
 | 
					                VerticalAlignment="Bottom" HorizontalAlignment="Right" Width="100" Margin="10,10,10,10"/>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <GroupBox Header="Abschluss" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Margin="10,0,10,10">
 | 
				
			||||||
 | 
					            <Grid>
 | 
				
			||||||
 | 
					                <ProgressBar x:Name="ProgressBar" Margin="10,0,0,74" Height="27" Width="180"
 | 
				
			||||||
 | 
					                             VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
				
			||||||
 | 
					                <Button x:Name="ShowButton" Content="Vorschau" FontSize="14" Width="180" Margin="10,10,10,42" Height="27" Tag="Print" IsEnabled="False"
 | 
				
			||||||
 | 
					                        Click="ShowButton_Click"
 | 
				
			||||||
 | 
					                        VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
				
			||||||
 | 
					                <Button x:Name="PrintButton" Content="Drucken" FontSize="14" Width="180" Margin="10,10,10,10" Height="27" Tag="Print" IsEnabled="False"
 | 
				
			||||||
 | 
					                        Click="PrintButton_Click"
 | 
				
			||||||
 | 
					                        VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
 | 
				
			||||||
 | 
					            </Grid>
 | 
				
			||||||
 | 
					        </GroupBox>
 | 
				
			||||||
 | 
					    </Grid>
 | 
				
			||||||
 | 
					</local:ContextWindow>
 | 
				
			||||||
							
								
								
									
										134
									
								
								Elwig/Windows/PaymentVariantsWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								Elwig/Windows/PaymentVariantsWindow.xaml.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,134 @@
 | 
				
			|||||||
 | 
					using Elwig.Documents;
 | 
				
			||||||
 | 
					using Elwig.Helpers;
 | 
				
			||||||
 | 
					using Elwig.Models.Dtos;
 | 
				
			||||||
 | 
					using Elwig.Models.Entities;
 | 
				
			||||||
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using System.Windows;
 | 
				
			||||||
 | 
					using System.Windows.Controls;
 | 
				
			||||||
 | 
					using System.Windows.Input;
 | 
				
			||||||
 | 
					using Elwig.Helpers.Billing;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Elwig.Windows {
 | 
				
			||||||
 | 
					    public partial class PaymentVariantsWindow : ContextWindow {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public readonly int Year;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public PaymentVariantsWindow(int year) {
 | 
				
			||||||
 | 
					            InitializeComponent();
 | 
				
			||||||
 | 
					            Year = year;
 | 
				
			||||||
 | 
					            Title = $"Auszahlungsvarianten - Lese {Year} - Elwig";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        protected override async Task OnRenewContext() {
 | 
				
			||||||
 | 
					            ControlUtils.RenewItemsSource(PaymentVariantList, await Context.PaymentVariants.Where(v => v.Year == Year).OrderBy(v => v.AvNr).ToListAsync(), v => (v as PaymentVar)?.AvNr);
 | 
				
			||||||
 | 
					            Update();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void Update() {
 | 
				
			||||||
 | 
					            if (PaymentVariantList.SelectedItem is PaymentVar v) {
 | 
				
			||||||
 | 
					                var locked = v.TransferDate != null || !v.TestVariant;
 | 
				
			||||||
 | 
					                DeleteButton.IsEnabled = !locked;
 | 
				
			||||||
 | 
					                CalculateButton.IsEnabled = !locked;
 | 
				
			||||||
 | 
					                CopyButton.IsEnabled = true;
 | 
				
			||||||
 | 
					                EditButton.IsEnabled = true;
 | 
				
			||||||
 | 
					                ShowButton.IsEnabled = true;
 | 
				
			||||||
 | 
					                PrintButton.IsEnabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                NameInput.Text = v.Name;
 | 
				
			||||||
 | 
					                CommentInput.Text = v.Comment;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                EditButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                CopyButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                CalculateButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                DeleteButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                ShowButton.IsEnabled = false;
 | 
				
			||||||
 | 
					                PrintButton.IsEnabled = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                NameInput.Text = "";
 | 
				
			||||||
 | 
					                CommentInput.Text = "";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void PaymentVariantList_SelectionChanged(object sender, SelectionChangedEventArgs evt) {
 | 
				
			||||||
 | 
					            Update();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void AddButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void CopyButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void DeleteButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void CalculateButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (PaymentVariantList.SelectedValue is not PaymentVar v)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            CalculateButton.IsEnabled = false;
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
 | 
					            var b = new BillingVariant(v.Year, v.AvNr);
 | 
				
			||||||
 | 
					            await b.CalculatePrices();
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					            CalculateButton.IsEnabled = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private void EditButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            if (PaymentVariantList.SelectedItem is not PaymentVar v)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            App.FocusChartWindow(v.Year, v.AvNr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void ShowButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            await Generate(1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async void PrintButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
 | 
					            await Generate(2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private async Task Generate(int mode) {
 | 
				
			||||||
 | 
					            if (PaymentVariantList.SelectedItem is not PaymentVar v)
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var members = Context.Members.FromSqlRaw($"""
 | 
				
			||||||
 | 
					                SELECT m.*
 | 
				
			||||||
 | 
					                FROM member m
 | 
				
			||||||
 | 
					                    INNER JOIN delivery d ON d.mgnr = m.mgnr
 | 
				
			||||||
 | 
					                WHERE d.year = {Year}
 | 
				
			||||||
 | 
					                GROUP BY m.mgnr
 | 
				
			||||||
 | 
					                """);
 | 
				
			||||||
 | 
					            members = members.OrderBy(m => m.MgNr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            IEnumerable<Member> list = await members.ToListAsync();
 | 
				
			||||||
 | 
					            var data = await CreditNoteData.ForPaymentVariant(Context.CreditNoteRows, v.Year, v.AvNr);
 | 
				
			||||||
 | 
					            var payments = await Context.MemberPayments.Where(p => p.Year == v.Year && p.AvNr == v.AvNr).ToDictionaryAsync(c => c.MgNr);
 | 
				
			||||||
 | 
					            using var doc = Document.Merge(list.Select(m =>
 | 
				
			||||||
 | 
					                new CreditNote(Context, payments[m.MgNr], data[m.MgNr])
 | 
				
			||||||
 | 
					            ));
 | 
				
			||||||
 | 
					            await doc.Generate(new Progress<double>(v => {
 | 
				
			||||||
 | 
					                ProgressBar.Value = v;
 | 
				
			||||||
 | 
					            }));
 | 
				
			||||||
 | 
					            Mouse.OverrideCursor = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (mode < 2) {
 | 
				
			||||||
 | 
					                doc.Show();
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (App.Config.Debug) {
 | 
				
			||||||
 | 
					                doc.Show();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                await doc.Print();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -31,6 +31,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            CalculateBucketsButton.IsEnabled = valid && last;
 | 
					            CalculateBucketsButton.IsEnabled = valid && last;
 | 
				
			||||||
            DeliveryConfirmationButton.IsEnabled = valid;
 | 
					            DeliveryConfirmationButton.IsEnabled = valid;
 | 
				
			||||||
            OverUnderDeliveryButton.IsEnabled = valid;
 | 
					            OverUnderDeliveryButton.IsEnabled = valid;
 | 
				
			||||||
 | 
					            PaymentButton.IsEnabled = valid;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void CalculateBucketsButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void CalculateBucketsButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
@@ -51,8 +52,7 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void DeliveryConfirmationButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            if (SeasonInput.Value is not int year)
 | 
					            if (SeasonInput.Value is not int year)
 | 
				
			||||||
                return;
 | 
					                return;
 | 
				
			||||||
            var w = new DeliveryConfirmationsWindow(year);
 | 
					            App.FocusDeliveryConfirmations(year);
 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void OverUnderDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
@@ -69,10 +69,13 @@ namespace Elwig.Windows {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
					            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
 | 
					                var tbl1 = await OverUnderDeliveryData.ForSeason(Context.OverUnderDeliveryRows, year);
 | 
				
			||||||
 | 
					                var tbl2 = await AreaComUnderDeliveryData.ForSeason(Context.AreaComUnderDeliveryRows, year);
 | 
				
			||||||
 | 
					                var tbl3 = await MemberDeliveryPerVariantData.ForSeason(Context.MemberDeliveryPerVariantRows, year);
 | 
				
			||||||
                using var ods = new OdsFile(d.FileName);
 | 
					                using var ods = new OdsFile(d.FileName);
 | 
				
			||||||
                await ods.AddTable(await OverUnderDeliveryData.ForSeason(Context.OverUnderDeliveryRows, year));
 | 
					                await ods.AddTable(tbl1);
 | 
				
			||||||
                await ods.AddTable(await AreaComUnderDeliveryData.ForSeason(Context.AreaComUnderDeliveryRows, year));
 | 
					                await ods.AddTable(tbl2);
 | 
				
			||||||
                await ods.AddTable(await MemberDeliveryPerVariantData.ForSeason(Context.MemberDeliveryPerVariantRows, year));
 | 
					                await ods.AddTable(tbl3);
 | 
				
			||||||
            } catch (Exception exc) {
 | 
					            } catch (Exception exc) {
 | 
				
			||||||
                MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
					                MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -80,8 +83,9 @@ namespace Elwig.Windows {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void PaymentButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private void PaymentButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            var w = new ChartWindow();
 | 
					            if (SeasonInput.Value is not int year)
 | 
				
			||||||
            w.Show();
 | 
					                return;
 | 
				
			||||||
 | 
					            App.FocusPaymentVariantsWindow(year);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@
 | 
				
			|||||||
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
					        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
 | 
				
			||||||
        xmlns:local="clr-namespace:Elwig.Windows"
 | 
					        xmlns:local="clr-namespace:Elwig.Windows"
 | 
				
			||||||
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
					        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
 | 
				
			||||||
        Title="Test Fenster - Elwig" MinHeight="400" MinWidth="325" Height="450" Width="800" ResizeMode="CanResize" Loaded="Window_Loaded">
 | 
					        Title="Test Fenster - Elwig" MinHeight="400" MinWidth="325" Height="450" Width="800" ResizeMode="CanResize">
 | 
				
			||||||
    <Grid>
 | 
					    <Grid>
 | 
				
			||||||
        <xctk:CheckComboBox x:Name="MyComboBox" HorizontalAlignment="Left" Margin="216,186,0,0" VerticalAlignment="Top" Delimiter=", "
 | 
					        <xctk:CheckComboBox x:Name="MyComboBox" HorizontalAlignment="Left" Margin="216,186,0,0" VerticalAlignment="Top" Delimiter=", "
 | 
				
			||||||
                            SelectedValue="{Binding SelectedValue}"
 | 
					                            SelectedValue="{Binding SelectedValue}"
 | 
				
			||||||
@@ -16,14 +16,7 @@
 | 
				
			|||||||
        <Button x:Name="WeighingButton1" Click="WeighingButton1_Click" Height="30" Content="Aktuelles Gewicht" Width="110" Margin="515,246,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
					        <Button x:Name="WeighingButton1" Click="WeighingButton1_Click" Height="30" Content="Aktuelles Gewicht" Width="110" Margin="515,246,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
				
			||||||
        <Button x:Name="WeighingButton2" Click="WeighingButton2_Click" Height="30" Content="Wiegen" Width="110" Margin="515,285,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
					        <Button x:Name="WeighingButton2" Click="WeighingButton2_Click" Height="30" Content="Wiegen" Width="110" Margin="515,285,0,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
				
			||||||
        <TextBlock x:Name="Output" Height="20" Width="200" Margin="470,329,0,0"  HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
					        <TextBlock x:Name="Output" Height="20" Width="200" Margin="470,329,0,0"  HorizontalAlignment="Left" VerticalAlignment="Top"/>
 | 
				
			||||||
        <Button x:Name="ChartButton" Content="Chart" Click="ChartButton_Click"
 | 
					 | 
				
			||||||
                Margin="50,240,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					 | 
				
			||||||
        <Button x:Name="ZipButton" Content="ZIP-File" Click="ZipButton_Click"
 | 
					        <Button x:Name="ZipButton" Content="ZIP-File" Click="ZipButton_Click"
 | 
				
			||||||
                Margin="50,270,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					                Margin="50,270,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
				
			||||||
 | 
					 | 
				
			||||||
        <Button x:Name="PdfDeliveryButton" Content="Lieferschein Erzeugen" Click="PdfDeliveryButton_Click" Tag="Print" IsEnabled="False"
 | 
					 | 
				
			||||||
                Margin="260,190,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					 | 
				
			||||||
        <Button x:Name="PdfCreditButton" Content="Gutschrift Erzeugen" Click="PdfCreditButton_Click" Tag="Print" IsEnabled="False"
 | 
					 | 
				
			||||||
                Margin="260,160,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
 | 
					 | 
				
			||||||
    </Grid>
 | 
					    </Grid>
 | 
				
			||||||
</Window>
 | 
					</Window>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,11 +21,6 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            MyListBox.ItemsSource = new string[] { "Test 1", "Test 2", "Test 3", "Test 4" };
 | 
					            MyListBox.ItemsSource = new string[] { "Test 1", "Test 2", "Test 3", "Test 4" };
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void Window_Loaded(object sender, RoutedEventArgs evt) {
 | 
					 | 
				
			||||||
            PdfDeliveryButton.IsEnabled = App.IsPrintingReady;
 | 
					 | 
				
			||||||
            PdfCreditButton.IsEnabled = App.IsPrintingReady;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private void OnItemSelectionChanged(object sender, ItemSelectionChangedEventArgs e) {
 | 
					        private void OnItemSelectionChanged(object sender, ItemSelectionChangedEventArgs e) {
 | 
				
			||||||
            MyText.Text = string.Join(", ", MyComboBox.SelectedItems.Cast<string>());
 | 
					            MyText.Text = string.Join(", ", MyComboBox.SelectedItems.Cast<string>());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -50,33 +45,10 @@ namespace Elwig.Windows {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void ChartButton_Click(object sender, RoutedEventArgs evt) {
 | 
					 | 
				
			||||||
            var w = new ChartWindow();
 | 
					 | 
				
			||||||
            w.Show();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private async void ZipButton_Click(object sender, RoutedEventArgs evt) {
 | 
					        private async void ZipButton_Click(object sender, RoutedEventArgs evt) {
 | 
				
			||||||
            using var ctx = new AppDbContext();
 | 
					            using var ctx = new AppDbContext();
 | 
				
			||||||
            using var ods = new OdsFile(@"C:\Users\Lorenz\Desktop\test.ods");
 | 
					            using var ods = new OdsFile(@"C:\Users\Lorenz\Desktop\test.ods");
 | 
				
			||||||
            await ods.AddTable(await DeliveryConfirmationData.ForMember(ctx.DeliveryParts, 2023, ctx.Members.Find(2948)));
 | 
					            await ods.AddTable(await DeliveryConfirmationData.ForMember(ctx.DeliveryParts, 2023, ctx.Members.Find(2948)));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        private async void PdfDeliveryButton_Click(object sender, RoutedEventArgs evt) {
 | 
					 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
					 | 
				
			||||||
            using var ctx = new AppDbContext();
 | 
					 | 
				
			||||||
            using var doc = new DeliveryNote(await ctx.Deliveries.OrderBy(d => d.Parts.Count).ThenBy(d => d.Year).ThenBy(d => d.DId).LastAsync(), ctx);
 | 
					 | 
				
			||||||
            await doc.Generate();
 | 
					 | 
				
			||||||
            doc.Show();
 | 
					 | 
				
			||||||
            Mouse.OverrideCursor = null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private async void PdfCreditButton_Click(object sender, RoutedEventArgs evt) {
 | 
					 | 
				
			||||||
            Mouse.OverrideCursor = Cursors.AppStarting;
 | 
					 | 
				
			||||||
            using var ctx = new AppDbContext();
 | 
					 | 
				
			||||||
            using var doc = new CreditNote(await ctx.Credits.FirstAsync(), ctx);
 | 
					 | 
				
			||||||
            await doc.Generate();
 | 
					 | 
				
			||||||
            doc.Show();
 | 
					 | 
				
			||||||
            Mouse.OverrideCursor = null;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user